Skip to content

HabIcon ​

The glyph renderer. Path data in, four sizes, decorative.

The closed scale: 16 / 18 / 20 / 24, from --hab-icon-*. There is no fifth.
The glyph is currentColor, so it takes the ink of whatever it sits in
Read-only — ask an admin to unlock 3 attachments
What it is actually for: a glyph belonging to no component. Each one sits beside text that carries the meaning — the icon is decorative and always aria-hidden.
vue
<script setup>
import { mdiLockOutline } from "@mdi/js";
</script>

<template>
	<HabIcon :icon="mdiLockOutline" />
</template>

Most icons in this system never reach for it: they are a prop on the component that owns them — HabButton's icon, HabListRow's, a column's, a nav item's — and that is still the right way to spell one. Reach for HabIcon for the glyph that belongs to no component: beside a heading, in a table cell you are rendering yourself, as a static mark on a row.

It takes path data, not a name ​

icon is an SVG path string, so import the glyph from @mdi/js:

ts
import { mdiCheck } from "@mdi/js";

Every MDI name maps to its export by one rule — kebab-case to mdi plus PascalCase — so cog-outline transcribes to mdiCogOutline with no lookup. A typo is a typecheck failure rather than a hole in the UI. An icon whose identity arrives at runtime cannot be served this way; render your own markup instead.

The size is a control step, not a type step ​

sm, md, lg, xl, from --hab-icon-*. Never size an icon off the type ladder — doing that once created a fifth icon size in a system that documents four. An icon beside a control takes the control's step: sm controls take sm.

It is always decorative ​

aria-hidden is unconditional and there is no way to turn it off. Every icon here sits beside a label, or inside a control that carries its own accessible name. An icon that needs its own name means the thing around it is missing one — give the button an aria-label rather than reaching for a labelled glyph.

That also means an icon must never be the only thing carrying a meaning. A status mark needs its status in text as well.

API ​

Props ​

PropTypeDefaultDescription
iconstringundefinedSVG path data, e.g. mdiCheck from @mdi/js.
size"md" | "sm" | "lg" | "xl""md"One of the four icon sizes. Never sized off the type ladder.

Proprietary — internal use only.