Sharing Code: Help Icon for Components

Just sharing some cool code I put together for a real world problem. I was frustrated by the inability of Vaadin to integrate a help icon with hoverable help text within Fields.

This will give you hoverable help text when the interface is implemented on a subclass of anything descended from AbstractComponent(essentially all Components including fields). To use, instantiate HelpableTextField(or a similar subclass of any Component) and call setHelp on it. As a plus, it provides a real case scenario for default methods other than backwards compatability.

Note: this requires Java 8 for the default method, but that’s just sugar, you can implement setHelp on an extension of any Component, or for that matter call setCaption directly on the object.

// interface with default method, consider it a mix-in if you're familiar with those languages
public interface IHelpable extends Component {
    
    public default void setHelp(String help) {
        String caption = String.format("%s <span class='tooltip' tooltipText='%s'>%s</span>",
                getCaption(), help, FontAwesome.INFO_CIRCLE.getHtml());
        setCaption(caption);
        setCaptionAsHtml(true);
    }

    public abstract void setCaptionAsHtml(boolean captionAsHtml);
}

// Any subclass of component will work
@SuppressWarnings("serial")
public class HelpableTextField extends TextField implements IHelpable {
}

// css
    .tooltip:hover:after {
        content: attr(tooltipText);
        padding: 4px 12px;
        position: absolute;
        left: 0;
        top: 20px;
        max-width: 350px;
        white-space: normal;
            
        padding: 4px 4px;
        border-radius: 4px;
        background-color: white;
        color: #474747;
        box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.1), 0 3px 5px 0 rgba(0, 0, 0, 0.05), 0 0 0 1px rgba(0, 0, 0, 0.09098);
        z-index: 20;

        font-style: normal;
        font-weight: 300;
        font-size: 16px;
        line-height: 1.55;
        font-family: "Open Sans", sans-serif;
    }