# CLAUDE.md

This is `@surrealdb/ui` — the SurrealDB design system and UI component library, published to npm as a reusable package for all SurrealDB frontend projects.

## Tooling

- **Runtime & package manager:** Bun (do NOT use npm, yarn, or pnpm)
- **Build:** Vite 7 in library mode, targeting ES2022 with source maps
- **Language:** TypeScript with `isolatedDeclarations` enabled — all exported types must be explicitly annotated
- **UI framework:** React 19 with JSX transform (`react-jsx`)
- **Component library:** Mantine v8 (peer dependency)
- **Linter/formatter:** Biome 2.x — 4-space indentation, 100-character line width
- **Storybook:** Storybook 10 with `@storybook/react-vite`
- **Testing:** Vitest with Playwright browser provider for Storybook integration tests

## Commands

| Command | Description |
|---|---|
| `bun install` | Install dependencies |
| `bun run build` | Production build (outputs to `dist/`) |
| `bun run storybook:dev` | Start Storybook dev server on port 6006 |
| `bun run storybook:build` | Build static Storybook site |
| `bun qc` | Run Biome lint/format check |
| `bun qa` | Auto-fix Biome lint/format issues |
| `bun qau` | Auto-fix including unsafe fixes |
| `bun qts` | TypeScript type check (`tsc --noEmit`) |
| `bun run test` | Run all Vitest projects (unit + e2e + storybook). Use `bun run test`, not `bun test`, since `bun test` invokes Bun's own test runner. |
| `bun run test:unit` | Run jsdom-based unit tests in `tests/unit/` |
| `bun run test:e2e` | Run browser-driven E2E tests in `tests/e2e/` (Playwright + Chromium) |
| `bun run test:storybook` | Run in-story `play` interaction tests via the Storybook Vitest plugin |
| `bun run test:watch` | Watch all projects |
| `bun run icons` | Regenerate icon constants from `icons.zip` (requires `picosvg`) |

## Path Aliases

`@src/*` maps to `./src/*` (configured in `tsconfig.json` and resolved by `vite-tsconfig-paths`).

## Styling

- SCSS modules (`.module.scss`) with `dashesOnly` locals convention — access classes as `styles.myClass`, not `styles["my-class"]`
- All `.scss` files auto-import `@surrealdb/ui/mixins` via Vite's `additionalData`, providing global access to theme-aware mixins:
  - `@include light { ... }` / `@include dark { ... }` — color scheme scoping
  - `@include sm-and-up { ... }`, `@include md-and-down { ... }`, etc. — responsive breakpoints
- Global CSS variables are defined in `src/assets/styles/global.scss` (prefixed `--surreal-*`)
- Mantine design tokens available as `--mantine-color-*` CSS variables
- Build output CSS is automatically wrapped in `@layer surreal` by a custom Vite plugin

## Exports

The package exposes three entry points:
- `@surrealdb/ui` — all components, hooks, helpers, and constants (from `src/index.ts`)
- `@surrealdb/ui/styles.css` — compiled CSS (wrapped in `@layer surreal`)
- `@surrealdb/ui/mixins` — raw SCSS mixins (from `res/_mixins.scss`)

## Source Structure

```
src/
├── assets/          # Static assets: brand SVGs, picto WebPs, global SCSS styles
├── constants/       # Generated/static constants (icons.ts, brands.ts, pictos.ts)
├── editor/          # CodeMirror editor setup: extensions, keybinds, commands, theme
├── helpers/         # Utility functions (clsx, CDN URL helper, ID generator)
├── hooks/           # React hooks (useEditor, useStable, useLater, useSort, useSwitch)
├── lib/
│   ├── editor/      # Custom Code Mirror editor configuration and extensions
│   └── markdown/    # Custom Code Mirror based markdown editor and renderer
├── primitives/      # React UI components (Icon, CodeBlock, Spinner, VideoPlayer, etc.)
├── stories/         # Storybook stories organized by category
├── syntax/          # Syntax highlighting: language definitions, highlighter, theme
├── theme/           # Mantine theme override (mantine.ts)
└── types/           # TypeScript module augmentations for Mantine (colors, variants, spacing)
```

Other top-level directories:
- `res/` — SCSS mixins exported as `@surrealdb/ui/mixins`
- `tests/` — Vitest test suites: `tests/unit/<Feature>/` (jsdom) and `tests/e2e/<Feature>/` (Playwright + Chromium); shared mount/composeStories helpers live in `tests/_setup/`
- `tools/` — Icon parser script (`icon-parser.ts`)
- `.storybook/` — Storybook configuration (main, preview, vitest setup)
- `.github/workflows/` — CI (`check.yml`) and publish (`publish.yml`) workflows
- `dist/` — Build output (gitignored)

## Peer Dependencies

Consumers must provide: React 19, Mantine 8, CodeMirror 6 suite, and Slate. These are externalized during build.

## CI/CD

- **check.yml** — Runs on push/PR to `main`: Biome lint, TypeScript check, build, and three independent test jobs (`test-unit`, `test-e2e`, `test-storybook`) on Bun 1.2.23. The two browser jobs install Playwright Chromium with `bunx playwright install --with-deps chromium`.
- **publish.yml** — Triggered by GitHub release: asserts `package.json` version matches git tag, builds, packs, and publishes to npm

## Conventions

- `useStable` hook is configured as returning a stable reference in Biome's `useExhaustiveDependencies` rule — do not list its return value in dependency arrays
- The `src/constants/icons.ts` file is auto-generated — do not edit it manually
- Biome excludes: `.vscode/`, `.github/`, `.storybook/`, `src/constants/icons.ts`, `dist/`, and `*.js` files

## Variants

When adding new variants, take the following into consideration:

- Styling is defined in `src/assets/styles/variants.scss`
- Types are defined in `src/types/variants.ts`
- The default variant is configured in `src/theme/mantine.ts`
- Update the relevant storybook story to show the new variant