Skip to content

Icon

A thin wrapper around Nuxt Icon - one shared component, everywhere an icon shows up in this library or your own markup.

Usage

Every icon-accepting prop across this library (Button's icon, Input's icon, Select's slots, ...) already renders through SIcon internally - each one just supplies its own precise size class (size-3.5, size-4.5, ...) via class, the same way you would. SIcon doesn't have an opinion on size at all; it's a bare pass-through to Nuxt Icon plus one optional convenience prop for semantic color.

vue-html
<SIcon name="hugeicons:star" class="size-4" />
<SIcon name="hugeicons:star" class="size-5" />
<SIcon name="hugeicons:star" class="size-6" />
<SIcon name="hugeicons:favourite" color="danger" />

name accepts any registered icon name, not just the hugeicons:* set used throughout this library's own docs.

Sizes

There's no size prop - pass whatever Tailwind size class you need via class directly, same as any other icon usage. This library's own components each pick their own scale internally (Badge's icons run size-2.5/size-3/size-3.5, Button's size-4/size-4.5/size-5, and so on) - none of those map cleanly onto one shared enum, so SIcon doesn't try to impose one.

Color

color is unset by default, so the icon inherits currentColor from whatever text color surrounds it - the same behavior every internal icon usage in this library already relies on (an input's leading icon takes --selaras-resolved-text-muted from its wrapper, not a color prop of its own). Pass a registered semantic role to force a specific color instead:

vue-html
<SIcon name="hugeicons:checkmark-circle-01" color="success" />

A plain class="text-[var(--selaras-resolved-color-danger-text)]" still overrides color if you need something the preset roles don't cover - both flow through the same tailwind-merge, so whichever text-* class you add wins.

Overriding the default icon set

SIcon itself only ever renders whatever name it's given - it has no default of its own. But every icon a component renders on its own (a button's loading spinner, a chip's remove glyph, a select's dropdown chevron, ...) resolves from a separate semantic-purpose registry instead of a hardcoded name - see useIcons for the full registry and how to override it globally in app.config.ts.

In markdown

Every Selaras component is already globally registered under its S-prefixed name - a bare ::s-icon{...} block works with no extra wiring (see Callout's own "In markdown" section for how the pattern works generally). Icon has no body content, but the block still needs its own closing line:

md
::s-icon{name="hugeicons:star" color="warning"}
::

Custom :ui

Global and scoped recipe overrides use ui.icon. This is deliberately a shared primitive hook: it affects direct <SIcon> instances and icons rendered inside other Selaras components. The owning component's icon slot is merged later, so its size and other conflicting Tailwind classes remain more specific.

To see exactly what you'd be overriding - the current default classes for every slot and variant - here's Icon's own theme file:

Theme source "icon" not found

Props

PropTypeDefault
namestring-
color'primary' | 'neutral' | 'secondary' | 'success' | 'danger' | 'info' | 'warning'-
uiPartial<Record<'base', string | object>>-
Edit this page