Skip to main content

Icon

Render decorative or named icons from utility names or JSX.

Use Icon for decoration or a named symbol alongside text. If the icon alone conveys meaning, give it an accessible name; otherwise it is hidden from assistive technology.

Basic usage#

import { Icon } from 'moraine'

export function Example() {
  return <Icon name="i-lucide:check" />
}

Playground#

Props
Slots

Anatomy#

Icon [component; slot=root; <div>]

Usage#

Icon sources#

Pass a supported icon name, JSX element, or component source. Use an icon as decoration only when adjacent text already names the meaning; otherwise provide an accessible label on the meaningful control or icon.

Use <Icon name="icon-search" /> or <Icon name="icon-success" /> for Moraine’s semantic aliases. Editor completion suggests the built-in names, while <Icon name="i-lucide-search" /> and <Icon name="app-logo" /> remain valid. Icon applies string names as classes; your UnoCSS or Tailwind setup must generate the corresponding CSS for custom names.

Solid control-flow nodes such as <Show>, <For>, and <Switch> are not supported as the top-level name value. Keep control flow outside Icon so it owns whether the component is rendered:

<Show when={visible()}>
  <Icon name={<StatusGlyph />} />
</Show>
import { Icon } from 'moraine'

export function Sources() {
  return (
    <div class="text-xl flex gap-4 items-center">
      <Icon name="i-lucide:heart" />
      <Icon name="i-lucide:sparkles" class="text-amber-500" />
      <Icon name="i-lucide:check-circle-2" class="text-emerald-500" />
    </div>
  )
}

Root styling#

Icon has one rendered root. Use class and style for an individual icon, or configure icon.base.root in your Theme for shared defaults. classes and styles are not instance props because there are no child slots to target. slotName only changes the emitted data-slot value.

import { Icon, MoraineProvider } from 'moraine'
import { defineTheme } from 'moraine/theme'

const theme = defineTheme({
  icon: { base: { root: 'text-emerald-600' } },
})

export function Slots() {
  return (
    <div class="w-full space-y-6">
      <div class="space-y-2">
        <p class="text-sm text-muted-foreground">Instance class and style</p>
        <Icon
          name="i-lucide:info"
          slotName="custom-icon"
          class="text-blue-500"
          style={{ width: '28px', height: '28px' }}
        />
      </div>
      <MoraineProvider theme={theme}>
        <div class="space-y-2">
          <p class="text-sm text-muted-foreground">Local Theme defaults</p>
          <Icon name="i-lucide:info" />
        </div>
      </MoraineProvider>
    </div>
  )
}

Examples#

JSX icon#

import { Icon } from 'moraine'

export function IconAsJSX() {
  return (
    <div class="flex flex-wrap gap-6 items-center">
      <div class="flex flex-col gap-1 items-center">
        <Icon
          name={
            <svg
              viewBox="0 0 24 24"
              width="24"
              height="24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
            >
              <circle cx="12" cy="12" r="10" />
              <path d="M8 14s1.5 2 4 2 4-2 4-2" />
              <line x1="9" y1="9" x2="9.01" y2="9" />
              <line x1="15" y1="9" x2="15.01" y2="9" />
            </svg>
          }
        />
        <span class="text-[10px] text-muted-foreground">JSX element</span>
      </div>
      <div class="flex flex-col gap-1 items-center">
        <Icon name={() => <div class="i-lucide-zap size-6" />} />
        <span class="text-[10px] text-muted-foreground">Solid component</span>
      </div>
    </div>
  )
}

Accessibility#

import { Icon } from 'moraine'

export function Accessibility() {
  return (
    <div class="flex gap-5 items-center">
      <p class="text-sm flex gap-2 items-center">
        <Icon name="i-lucide:circle-check" aria-hidden="true" class="text-success" />
        Changes saved
      </p>
      <Icon name="i-lucide:triangle-alert" aria-label="Warning" class="text-warning size-5" />
    </div>
  )
}

Props#

Props for the Icon component. Renders a <div> element by default.

Prop