In this post I wanted to explain the feature recently added in the main UI (oh-icon component improvements, Iconify icon support by ghys · Pull Request #1149 · openhab/openhab-webui · Git) and what it means for users and widget authors.
The first obvious change is that from now on, the
oh-icon component that you might as a widget author assimilated to be for only displaying openHAB icons, now can display icons from several sources, if you specify the
icon property with a prefix. Those are:
oh:for openHAB icons
f7:for built-in Framework7 icons
material:for built-in Material Icons
if:for a remote Iconify icon, a new (online) source, see below
Backwards compatibility is paramount so if you are already using the
oh-icon component to display OH icons, don’t worry, if you don’t have a prefix with a colon
: in the
icon parameter, it will be assumed to be a OH icon like before.
The Iconify icon source
To help with the authoring of widgets, the Iconify source (
if: as a shorthand alias) has been added as a way to get more icons - it’s a online service curating dozens of iconsets with more than 100,000 icons in total. It’s important to note that you need an internet connection to fetch the icons initially from https://api.iconify.design, so you need to trust the service as well. If you don’t, or want everything locally, I’ll provide an alternative below.
Iconify icons are cached in the browser’s local storage the first time they are accessed, so as long as you don’t purge your local browser storage, the icons won’t be retrieved from the “cloud” once they’re in the cache.
You want a fire extinguisher icon, but didn’t find any that suited in the built-in iconsets.
So after searching on https://icon-sets.iconify.design you find this icon:
All you have to do now to integrate it, is to use the
iconify:<iconSet>:<iconName> syntax, like this:
component: oh-button config: round: true outline: true class: - margin - display-flex - flex-direction-column style: height: auto slots: default: - component: oh-icon config: height: 200px icon: iconify:noto:fire-extinguisher class: - padding - component: Label config: text: A Fire Extinguisher Button style: font-size: 30px class: - margin-left-half - margin-bottom
Note that this particular icon doesn’t support colors, because it has some of its own, but most of those which are monochrome do, so you can use the
iconColor property when appropriate. Also note that certain components using
oh-icon under the hood now support this source as well, not just
component: f7-list config: mediaList: true slots: default: - component: oh-list-item config: title: Tesla Model 3 icon: iconify:simple-icons:tesla iconColor: green badge: ONLINE badgeColor: green - component: oh-list-item config: title: Audi Q5 icon: iconify:simple-icons:audi iconColor: teal badge: UNKNOWN badgeColor: teal - component: oh-list-item config: title: BMW 720i icon: iconify:simple-icons:bmw iconColor: green badge: ONLINE badgeColor: green - component: oh-list-item config: title: Mercedes GLC icon: iconify:simple-icons:mercedes iconColor: red badge: OFFLINE badgeColor: red
(icons found in Simple Icons • Iconify)
However native Framework7 components and derivatives do not support icons beyond what they were designed to support (namely Framework7 and Material icons), so YMMV. But most openHAB components will - check the descriptions in the components’ docs as they will mention Iconify as a source if they support it.
What if I don’t want to rely on a remote service to display my icons?
material: icons are still fetched locally. If you like some of the Iconify icons that you find and want to use them completely offline, you have a couple of options:
So let’s say you want to use this icon server security • Material Design Icons • Iconify in your widget:
And let’s say to want it in red so you specify
#ff0000 in the “color” text box.
If you click on the “SVG” button and then the “SVG as data: URI” buttons, you’ll end up with some encoded SVG code:
Now what you have to do is add this code to the
background: CSS style of one of your UI components, the simplest being
Label, and the icon will be rendered locally, without any additional network request (add
center / contain no-repeat at the end):
component: Label config: style: background: url('data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20width%3D%221em%22%20height%3D%221em%22%20preserveAspectRatio%3D%22xMidYMid%20meet%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M3%201h16a1%201%200%200%201%201%201v4a1%201%200%200%201-1%201H3a1%201%200%200%201-1-1V2a1%201%200%200%201%201-1m0%208h16a1%201%200%200%201%201%201v.67l-2.5-1.11l-6.5%202.88V15H3a1%201%200%200%201-1-1v-4a1%201%200%200%201%201-1m0%208h8c.06%202.25%201%204.4%202.46%206H3a1%201%200%200%201-1-1v-4a1%201%200%200%201%201-1M8%205h1V3H8v2m0%208h1v-2H8v2m0%208h1v-2H8v2M4%203v2h2V3H4m0%208v2h2v-2H4m0%208v2h2v-2H4m13.5-7l4.5%202v3c0%202.78-1.92%205.37-4.5%206c-2.58-.63-4.5-3.22-4.5-6v-3l4.5-2m0%201.94L15%2015.06v2.66c0%201.54%201.07%202.98%202.5%203.34v-7.12z%22%20fill%3D%22red%22%2F%3E%3C%2Fsvg%3E') center / contain no-repeat height: 100px
Please note that this approach has caveats, it increases the weight of your widget code, and you can’t benefit from the caching features of the regular API.
Hope it helps!