ui/packages/consul-ui/app/styles/base/icons/README.mdx
We recently started adopting the @hashicorp/ember-flight-icons package, in particular the
usage of the <FlightIcon> component to render icons. This enables us to use all the
icons listed on the flight icons page. If an icon is not present in the flight-icons package,
you may resort to the techniques listed below.
All our iconography uses native CSS properties for adding iconography from The
Outside. You can also add icons using the same properties within style=""
attributes, but you should think twice before adding decorative content into
HTML and only do so if you have a good reason/have tried everything else.
Available icons properties are:
--icon-name: See below for available names--icon-color: By default our icons are set to be monochrome, using
--icon-color will color the icon, you can also use currentColor--icon-size: Set the size of the icon, see below for available values. Our
values use a icon-000 naming scheme similar to all our ther naming scales (and
font-weight). We default this to icon-300 i.e. 1rem/16px and icon-000
means 'use the font-size'--icon-resolution: Set the resolution of the icon. Currently you can set
either 1 or .5 here resolution happens to mean the thickness of the lines
used in the icon. 1 equals thicker lines and should be used at sizes lower than
icon-500. .5 equals thinner lines and should be used at sizes larger than
icon-500.All of the above properties can be suffixed with -start or -end, these are
mainly used for specifying icons using style="" attributes. Here start and
end refer to either the ::before or ::after pseudo element to use to
display the icon. If you are not using the style="" attribute (which you
probably aren't) consider just using normal ::before and ::after CSS
selectors.
.selector::before {
--icon-name: icon-alert-circle;
content: '';
}
.selector::after {
--icon-name: icon-alert-circle;
--icon-color: var(--token-color-surface-primary);
content: '';
}
If you cannot use CSS or have a good reason to do so, you can very easily add icons in HTML using these CSS properties.
<h2
style={{style-map
(array '--icon-name-start' 'icon-alert-circle')
(array '--icon-color-start' 'var(--token-color-consul-brand)')
(array '--icon-name-end' 'icon-vault')
(array '--icon-color-end' 'var(--color-vault)')
}}
>
Header Name
</h2>
It's probably worth noting that we could make an icon component using the following. Under different circumstances this would give us an option that works "For Everyone, Everywhere" (in Every Framework as it's just native CSS).
<span
class={{class-map 'visually-hidden'}}
style={{style-map
(array '--icon-name-start' @name)
(array '--icon-color' @color)
(array '--icon-size' @size)
}}
...attributes
>{{yield}}</span>
<Icon @name='icon-name' @color='#FF0000' @size='icon-300' />
Please prefer our Constructable %placeholder styles over singular CSS
properties. If you need to drop back, to something not covered there then you
can also use CSS properties directly.
All icons use a %with- prefix for example %with-alert-circle-fill-icon or
%with-alert-circle-fill-mask. We mostly use the -mask suffix and also use
the %as-pseudo placeholder to tell CSS that we are using the background on a
pseudo element:
If you are not using a pseudo element for whatever reason, then you do not need
to use %as-pseudo.
When using -mask icons, color will use the currentColor of the element. If
you need the color of the icon to be different to the text you can define the
color of the icon itself via the color CSS property (preferred) but you can
also use background-color.
.selector::before {
@extend %with-alert-circle-fill-mask, %as-pseudo;
color: var(--token-color-consul-brand);
}
If you need to use a colored icon (usually an existing brand icon) then don't
use -mask, use -icon instead:
.selector::before {
@extend %with-alert-circle-icon, %as-pseudo;
}
<figure>
<select onchange={{action (mut this.type) value='target.value'}}>
<option>colored</option>
<option>monochrome</option>
</select>
<select onchange={{action (mut this.theme) value='target.value'}}>
<option>light</option>
<option>dark</option>
</select>
<input
oninput={{action (mut this.size) value='target.value'}}
type='range'
min='100'
max='900'
step='100'
/>
{{this.size}}
</figure>
<ul
{{css-props (set this 'icons') prefix='icon-'}}
class={{class-map (concat 'theme-' (or this.theme 'light'))}}
style={{style-map
(array '--icon-color' (if (eq this.type 'monochrome') 'var(--token-color-hashicorp-brand)'))
(array '--icon-size' (concat 'icon-' (or this.size '500')))
(array '--icon-resolution' (if (gt this.size 500) '.5' '1'))
}}
>
{{#each-in this.icons as |prop value|}}
{{#if
(and
(not (includes prop (array '--icon-name' '--icon-color' '--icon-size' '--icon-resolution')))
(not (string-includes prop '-24'))
)
}}
{{#let (string-replace (string-replace prop '-16' '') '--' '') as |name|}}
<li>
<figure
{{with-copyable (concat '--icon-name: ' name ';content: "";')}}
style={{style-map (array '--icon-name-start' name)}}
>
<figcaption>{{name}}</figcaption>
</figure>
</li>
{{/let}}
{{/if}}
{{/each-in}}
</ul>