Hi all,
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 - (new!)
iconify:
orif:
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 (iconify:
, 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.
Example
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 oh-icon
itself:
Example:
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?
That’s fine, oh:
/f7:
/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 red
or #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!