Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add icon to field title #6756

Open
gunnarschmid opened this issue Oct 28, 2024 · 5 comments
Open

Add icon to field title #6756

gunnarschmid opened this issue Oct 28, 2024 · 5 comments

Comments

@gunnarschmid
Copy link

Describe your motivation

In Vaadin 8 each input field had the option to specify an icon with setIcon() which would be rendered before the field's label. In Flow this does not exist anymore. Some, but not all components have prefix/suffic icons which are rendered inside the field. There are helper components which are either rendered above or below input field, but when used at runtime (e. g. for marking a changed field) it makes the layout very bumpy.

Describe the solution you'd like

Please add setIcon() to input fields and render that icon before the label just as in Vaadin 8
OR
make the caption/title a component so one can set e. g. a HorizontalLayout, similar to DialogHeader.

Describe alternatives you've considered

I tried tweaking CSS so that the helper component would be rendered before the label. I also tried the NativeLabel component. Appropriate styling seems cumbersome in both cases.

@gunnarschmid gunnarschmid added the enhancement New feature or request label Oct 28, 2024
@mshabarov mshabarov transferred this issue from vaadin/flow Oct 29, 2024
@sissbruecker
Copy link
Contributor

Related to vaadin/web-components#5786

As a workaround, a custom label element can be slotted into the component:

var labelIcon = VaadinIcon.ALARM.create();
labelIcon.setSize("1em");

var labelText = new Span("Label");

var label = new NativeLabel();
label.add(labelIcon, labelText);
label.addClassNames(LumoUtility.Display.FLEX, LumoUtility.AlignItems.CENTER, LumoUtility.Gap.XSMALL);
label.getElement().setAttribute("slot", "label");

var textField = new TextField();
textField.getElement().appendChild(label.getElement());
Bildschirmfoto 2024-10-29 um 17 16 09

@gunnarschmid
Copy link
Author

Thanks, Sascha, this looks promising, I will try that.

@gunnarschmid
Copy link
Author

gunnarschmid commented Oct 31, 2024

I made this utility method, but not sure about unsetting the icon. Is there a more elegant way?

	public static void setIcon(HasLabel component, Icon icon) {
		if (component == null) {
			return;
		}
		
		if (icon == null) {
			Optional<Element> optElement = component.getElement().getChildren().filter(e -> "label".equals(e.getAttribute("slot"))).findFirst();
			if (optElement.isPresent() && !optElement.get().getChild(0).isTextNode()) {
				optElement.get().removeChild(0);
			}
			return;
		}

		icon.setSize("1em");
		var labelText = new Span(component.getLabel());
		var label = new NativeLabel();
		label.add(icon, labelText);
		label.addClassNames(LumoUtility.Display.FLEX, LumoUtility.AlignItems.CENTER, LumoUtility.Gap.XSMALL);
		label.getElement().setAttribute("slot", "label");

		component.getElement().appendChild(label.getElement());
	}

@sissbruecker
Copy link
Contributor

sissbruecker commented Oct 31, 2024

I think the logic doesn't quite add up. You remove the icon component from a potentially existing label component, but when you actually want to set an icon then you create a new label component anyway. So if you call this method multiple times you'll end up with multiple label components.

The easiest would be to just remove the existing label, if it exists, and then create a new one. If you want to optimize then you'd have to get the existing label or create a new one if it doesn't exist. Then update the icon and label text on it. If you want to avoid iterating through children, then you could create a LabelWithIcon component extending from NativeLabel and store the icon as a class field.

@gunnarschmid
Copy link
Author

Thanks for pointing this out.

So the workaround works well, now waiting for an "official" solution. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants