From 3cf51f07ae2fadce2700c08a892c5193ac0f05e8 Mon Sep 17 00:00:00 2001 From: Artur Date: Fri, 10 May 2024 15:43:41 +0300 Subject: [PATCH] feat!: allow changing the icon (#4594) --- .../com/vaadin/flow/component/icon/Icon.java | 91 +++++++++++++++++-- .../flow/component/icon/tests/IconTest.java | 38 ++++++++ 2 files changed, 123 insertions(+), 6 deletions(-) diff --git a/vaadin-icons-flow-parent/vaadin-icons-flow/src/main/java/com/vaadin/flow/component/icon/Icon.java b/vaadin-icons-flow-parent/vaadin-icons-flow/src/main/java/com/vaadin/flow/component/icon/Icon.java index fceb7c4abb1..3222ac1fb4c 100644 --- a/vaadin-icons-flow-parent/vaadin-icons-flow/src/main/java/com/vaadin/flow/component/icon/Icon.java +++ b/vaadin-icons-flow-parent/vaadin-icons-flow/src/main/java/com/vaadin/flow/component/icon/Icon.java @@ -31,14 +31,13 @@ public class Icon extends AbstractIcon { private static final String ICON_ATTRIBUTE_NAME = "icon"; - private static final String ICON_COLLECTION_NAME = "vaadin"; + private static final String VAADIN_ICON_COLLECTION_NAME = "vaadin"; private static final String STYLE_FILL = "fill"; /** - * Creates an Icon component that displays a Vaadin logo. + * Creates an empty Icon. */ public Icon() { - this(VaadinIcon.VAADIN_H); } /** @@ -49,8 +48,7 @@ public Icon() { * the icon to display */ public Icon(VaadinIcon icon) { - this(ICON_COLLECTION_NAME, - icon.name().toLowerCase(Locale.ENGLISH).replace('_', '-')); + setIcon(icon); } /** @@ -61,7 +59,7 @@ public Icon(VaadinIcon icon) { * the icon name */ public Icon(String icon) { - this(ICON_COLLECTION_NAME, icon); + setIcon(icon); } /** @@ -85,9 +83,90 @@ public Icon(String icon) { * the icon name */ public Icon(String collection, String icon) { + setIcon(collection, icon); + } + + /** + * Sets the icon to the given icon. + *

+ * If the icon name contains a ":", the first part is used as the collection + * and the second part as the icon name. If the icon name does not contain a + * ":", the current collection is used (vaadin by default). + * + * @param icon + * the icon name + */ + public void setIcon(String icon) { + if (icon.contains(":")) { + String[] parts = icon.split(":", 2); + setIcon(parts[0], parts[1]); + } else { + String collection = getCollection(); + if (collection == null) { + collection = VAADIN_ICON_COLLECTION_NAME; + } + setIcon(collection, icon); + } + } + + /** + * Sets the icon to the given Vaadin icon. + * + * @param icon + * the icon name + */ + public void setIcon(VaadinIcon icon) { + setIcon(VAADIN_ICON_COLLECTION_NAME, + icon.name().toLowerCase(Locale.ENGLISH).replace('_', '-')); + } + + /** + * Gets the full icon name, including the collection. + * + * @return the icon name or {@code null} if no icon is set + */ + public String getIcon() { + return getElement().getAttribute(ICON_ATTRIBUTE_NAME); + } + + /** + * Sets the icon to the given {@code icon} from the given + * {@code collection}. + * + * If you want to use a custom {@code } -based icon set, you + * also need to add a dependency and an import for it, example: + * + *

+     * 
+     * @NpmPackage(value = "custom-icons", version = "1.0.0")
+     * @JsModule("custom-icons/iconset.js")
+     * public class MyView extends Div {
+     * 
+     * 
+ * + * @param collection + * the icon collection + * @param icon + * the icon name + */ + public void setIcon(String collection, String icon) { getElement().setAttribute(ICON_ATTRIBUTE_NAME, collection + ':' + icon); } + /** + * Gets the collection of the icon (the part before {@literal :}). + * + * @return the collection of the icon or {@code null} if no collection is + * set + */ + public String getCollection() { + String icon = getIcon(); + if (icon != null && icon.contains(":")) { + return icon.substring(0, icon.indexOf(':')); + } + return null; + } + @Override public void setColor(String color) { if (color == null) { diff --git a/vaadin-icons-flow-parent/vaadin-icons-flow/src/test/java/com/vaadin/flow/component/icon/tests/IconTest.java b/vaadin-icons-flow-parent/vaadin-icons-flow/src/test/java/com/vaadin/flow/component/icon/tests/IconTest.java index a8676bf1c93..10ef3e11fbf 100644 --- a/vaadin-icons-flow-parent/vaadin-icons-flow/src/test/java/com/vaadin/flow/component/icon/tests/IconTest.java +++ b/vaadin-icons-flow-parent/vaadin-icons-flow/src/test/java/com/vaadin/flow/component/icon/tests/IconTest.java @@ -19,12 +19,50 @@ import org.junit.Test; import com.vaadin.flow.component.icon.Icon; +import com.vaadin.flow.component.icon.VaadinIcon; import com.vaadin.flow.component.shared.HasTooltip; public class IconTest { + @Test public void implementsHasTooltip() { Icon icon = new Icon(); Assert.assertTrue(icon instanceof HasTooltip); } + + @Test + public void emptyIconIsEmpty() { + Assert.assertNull(new Icon().getIcon()); + } + + @Test + public void usesVaadinCollectionByDefault() { + Assert.assertEquals("vaadin:foo", new Icon("foo").getIcon()); + } + + @Test + public void canDefineCollectionInConstructor() { + Assert.assertEquals("bar:foo", new Icon("bar:foo").getIcon()); + } + + @Test + public void canDefineCollectionInSetter() { + Icon icon = new Icon(); + icon.setIcon("bar:foo"); + Assert.assertEquals("bar:foo", icon.getIcon()); + } + + @Test + public void setterUsesCurrentCollection() { + Icon icon = new Icon("bar:foo"); + icon.setIcon("baz"); + Assert.assertEquals("bar:baz", icon.getIcon()); + } + + @Test + public void canSetNewVaadinIcon() { + Icon icon = new Icon("bar:foo"); + icon.setIcon(VaadinIcon.ABSOLUTE_POSITION); + Assert.assertEquals("vaadin:absolute-position", icon.getIcon()); + } }