@primitiv-ui/icons
Fill-based SVG icon library for the Primitiv ecosystem. Icons inherit currentColor, scale via a size prop, and accept all native SVG attributes. Zero styles, zero runtime overhead, full tree-shaking.
Usage
Within the Primitiv workspace, import directly — no build step required:
import { Check } from "@primitiv-ui/icons";
// Default size (24px)
<Check />
// Custom pixel size
<Check size={16} />
// Rem-based size
<Check size="1rem" />
// Tailwind color via currentColor inheritance
<Check className="text-green-500" />
// Accessible (not decorative)
<Check aria-label="Confirmed" />
Props
All icons share the same props via IconProps:
| Prop | Type | Default | Description |
|---|---|---|---|
size |
number | string |
24 |
Sets both width and height. Accepts pixel numbers (16) or CSS strings ("1rem"). |
className |
string |
— | Applied to the <svg> element. Use Tailwind's text-* utilities to set currentColor. |
aria-label |
string |
— | Makes the icon accessible to screen readers. When absent the icon is aria-hidden="true" (decorative). |
fill |
string |
"currentColor" |
Override the fill colour directly. |
ref |
Ref<SVGSVGElement> |
— | Forwarded to the underlying <svg> element. |
All other SVG element attributes are accepted and forwarded.
Icons
| Icon | Import |
|---|---|
| ArrowLeft | import { ArrowLeft } from "@primitiv-ui/icons" |
| ArrowRight | import { ArrowRight } from "@primitiv-ui/icons" |
| Bell | import { Bell } from "@primitiv-ui/icons" |
| Calendar | import { Calendar } from "@primitiv-ui/icons" |
| Check | import { Check } from "@primitiv-ui/icons" |
| ChevronDown | import { ChevronDown } from "@primitiv-ui/icons" |
| ChevronLeft | import { ChevronLeft } from "@primitiv-ui/icons" |
| ChevronRight | import { ChevronRight } from "@primitiv-ui/icons" |
| ChevronUp | import { ChevronUp } from "@primitiv-ui/icons" |
| Close | import { Close } from "@primitiv-ui/icons" |
| Copy | import { Copy } from "@primitiv-ui/icons" |
| Delete | import { Delete } from "@primitiv-ui/icons" |
| Download | import { Download } from "@primitiv-ui/icons" |
| Edit | import { Edit } from "@primitiv-ui/icons" |
| Error | import { Error } from "@primitiv-ui/icons" |
| ExternalLink | import { ExternalLink } from "@primitiv-ui/icons" |
| Eye | import { Eye } from "@primitiv-ui/icons" |
| EyeOff | import { EyeOff } from "@primitiv-ui/icons" |
| File | import { File } from "@primitiv-ui/icons" |
| Filter | import { Filter } from "@primitiv-ui/icons" |
| Folder | import { Folder } from "@primitiv-ui/icons" |
| Grid | import { Grid } from "@primitiv-ui/icons" |
| Home | import { Home } from "@primitiv-ui/icons" |
| Image | import { Image } from "@primitiv-ui/icons" |
| Info | import { Info } from "@primitiv-ui/icons" |
| Link | import { Link } from "@primitiv-ui/icons" |
| List | import { List } from "@primitiv-ui/icons" |
import { Mail } from "@primitiv-ui/icons" |
|
| Maximize | import { Maximize } from "@primitiv-ui/icons" |
| Menu | import { Menu } from "@primitiv-ui/icons" |
| Minimize | import { Minimize } from "@primitiv-ui/icons" |
| Minus | import { Minus } from "@primitiv-ui/icons" |
| Moon | import { Moon } from "@primitiv-ui/icons" |
| Plus | import { Plus } from "@primitiv-ui/icons" |
| Search | import { Search } from "@primitiv-ui/icons" |
| Settings | import { Settings } from "@primitiv-ui/icons" |
| Share | import { Share } from "@primitiv-ui/icons" |
| Sort | import { Sort } from "@primitiv-ui/icons" |
| Success | import { Success } from "@primitiv-ui/icons" |
| Sun | import { Sun } from "@primitiv-ui/icons" |
| Upload | import { Upload } from "@primitiv-ui/icons" |
| User | import { User } from "@primitiv-ui/icons" |
| Warning | import { Warning } from "@primitiv-ui/icons" |
Adding icons from Figma
Export the icon at 24 × 24 px (the
mdcanonical size) as an SVG from Figma.Drop the
.svgfile intoicons/svg/, using kebab-case for the filename (e.g.arrow-right.svg).Run the generator:
pnpm generateReview the generated component in
src/icons/. The generator optimises paths via SVGO and converts hyphenated SVG attribute names to JSX camelCase. Hand-edit the output if needed — the generated files are committed source, not disposable artifacts.Add a row to the Icons table in this README.
Write a smoke test in
src/icons/<Name>.test.tsx(seeCheck.test.tsxas a template).
The five design sizes (xs=16, sm=20, md=24, lg=32, xl=48) are all driven by the size prop at runtime — only the md SVG needs to be exported from Figma.
Architecture
icons/svg/*.svg ← source files from Figma (committed)
↓ pnpm generate
src/icons/*.tsx ← generated components (committed, reviewable)
src/IconBase.tsx ← shared SVG wrapper (sets viewBox, fill, aria-hidden)
src/types.ts ← IconProps interface
src/index.ts ← re-exports everything
IconBase is exported for advanced use cases (e.g. building custom icon wrappers) but is not needed for normal icon consumption.
Testing
# Run all icon tests once
npx vitest run
# Watch mode
npx vitest
# With coverage
npx vitest run --coverage