Components · v0.1 · Stable
Icon
A thin wrapper around lucide-react that enforces the two rules every icon system fails at: consistent sizes across the app, and correct accessibility whenever an icon carries meaning.
Example
A decorative icon inline with text.
Installation
Install and import from Nova. Lucide is a peer dependency.
bun add lucide-reactimport { Icon } from "@novix-ui/react";import { Sparkles } from "lucide-react";When to use
Use it for
- Any lucide icon inside your app UI
- Icons in menu rows, cards, and empty states
Skip it for
- Icons already inside Button, IconButton, Input — they size for you
- Custom SVGs — inline them directly and set aria attributes by hand
Sizes
Decorative vs. meaningful
If the icon adds meaning that text does not, it needs a label. If it's redundant with adjacent copy, it stays decorative.
API
iconLucideIcon—Any icon component exported by lucide-react.size"xs" | "sm" | "md" | "lg" | "xl" | number"md"Semantic size token or a raw pixel value.decorativebooleantrueWhen true, hides from assistive tech (aria-hidden).labelstring—Required when decorative is false. Becomes the accessible name.
Accessibility
Design guidelines
One weight per surface
Nova sets stroke-width 1.75 across all icons. Don't mix stroke variants in the same view.
Size follows text
Menu row = sm, section title = md, hero eyebrow = lg. Match the neighboring text.
Color inherits currentColor
Style the parent, not the icon. This keeps hover and state changes coherent.
Common mistakes
- Passing a JSX element instead of the component reference — pass
icon={Search}, noticon={<Search />}. - Setting fixed pixel color — use
text-*on the parent.