# Sigil Component

> Sigil Component

- Skill: `kevin-liu-01/sigil-component` (Agent Skill)
- Install (CLI): `npx skillmds@latest add kevin-liu-01/sigil-component`
- Raw SKILL.md: https://api.skillmd.com/api/skills/kevin-liu-01/sigil-component/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: kevin-liu-01 (https://skillmd.com/u/kevin-liu-01)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/kevin-liu-01/sigil-component

---


# Sigil Component

> Create and modify React components that consume Sigil design tokens via CSS custom properties.

## When to Use

- User asks to create a new Sigil UI component
- User asks to modify an existing component in `packages/components/`
- User says "add a component", "create component", "build a button/card/input"
- User asks to style a component using Sigil tokens
- User wants to add a component to the CLI registry

## How to Use

### 1. Understand the component structure

Every Sigil component lives in `packages/components/src/` and follows this pattern:

```tsx
import { forwardRef, type ComponentPropsWithoutRef } from "react";
import { clsx } from "clsx";

type ButtonProps = ComponentPropsWithoutRef<"button"> & {
  variant?: "default" | "outline" | "ghost";
  size?: "sm" | "md" | "lg";
};

export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
  ({ className, variant = "default", size = "md", children, ...props }, ref) => {
    return (
      <button
        ref={ref}
        className={clsx(
          "sigil-button",
          `sigil-button--${variant}`,
          `sigil-button--${size}`,
          className,
        )}
        {...props}
      >
        {children}
      </button>
    );
  },
);

Button.displayName = "Button";
```

### 2. Token consumption rules

Components consume tokens exclusively through CSS custom properties. Never hardcode colors, spacing, or typography values.

```css
.sigil-button {
  font-family: var(--s-font-body);
  background: var(--s-primary);
  color: var(--s-text-light);
  border-radius: var(--s-radius-md);
  padding: var(--s-spacing-2) var(--s-spacing-4);
  box-shadow: var(--s-shadow-sm);
  transition-duration: var(--s-duration-fast);
  transition-timing-function: var(--s-easing-default);
}
```

### 3. Register in CLI

After creating a component, add it to `packages/cli/src/utils/registry.ts`:

```ts
"my-component": {
  name: "my-component",
  files: ["my-component.tsx"],
  dependencies: [],          // npm deps like @radix-ui/*
  devDependencies: [],
  registryDependencies: [],  // other sigil components this depends on
},
```

### 4. Export from barrel

Add to `packages/components/src/index.ts`:

```ts
export { MyComponent } from "./my-component.js";
```

## Rules

1. **Always use `forwardRef`** — every component must forward refs for composition.
2. **Always accept `className`** — merge with `clsx(internalClasses, className)` so consumers can extend.
3. **Never import token values directly** — use CSS custom properties (`var(--s-*)`).
4. **Use semantic class names** — prefix with `sigil-` (e.g., `sigil-card`, `sigil-button--ghost`).
5. **Props over classes** — expose variant/size/intent as typed props, map to class names internally.
6. **Slot pattern** — use `@radix-ui/react-slot` with an `asChild` prop when the component should render as a different element.
7. **No inline styles for tokens** — all token-dependent styling goes through CSS classes that reference custom properties.
8. **All colors in OKLCH** — the token system uses OKLCH exclusively. Never use hex/rgb/hsl in component CSS.
9. **Respect motion tokens** — all transitions use `--s-duration-`* and `--s-easing-*`.
10. **Barrel export** — every component must be exported from `packages/components/src/index.ts`.

## Examples

### Creating a Badge component

```tsx
// packages/components/src/badge.tsx
import { forwardRef, type ComponentPropsWithoutRef } from "react";
import { clsx } from "clsx";

type BadgeProps = ComponentPropsWithoutRef<"span"> & {
  variant?: "default" | "success" | "warning" | "error" | "info";
};

export const Badge = forwardRef<HTMLSpanElement, BadgeProps>(
  ({ className, variant = "default", children, ...props }, ref) => {
    return (
      <span
        ref={ref}
        className={clsx("sigil-badge", `sigil-badge--${variant}`, className)}
        {...props}
      >
        {children}
      </span>
    );
  },
);

Badge.displayName = "Badge";
```

### Sigil-specific components

The `sigil-grid`, `sigil-cross`, and `sigil-rail` components use tokens from the `sigil` namespace:

```css
.sigil-grid {
  --cell: var(--s-grid-cell);
  background-size: var(--cell) var(--cell);
}

.sigil-cross {
  --arm: var(--s-cross-arm);
  --stroke: var(--s-cross-stroke);
}
```


