# Toku UI

Vue 3 component library that ships Toku's design system as prebuilt components. Internal: published to npm and consumed by `webapp-frontend`, `frontend`, and `client-payment-portal-frontend`.

## Setup

```bash
# Toolchain: Node 24 LTS + pnpm 11. Pinned in package.json#volta.
# Volta auto-switches both on cd. nvm users fall back to .nvmrc (Node only).
pnpm install
```

If you're new and don't have Volta:

```bash
curl https://get.volta.sh | bash
# new shell, then cd into the repo — Node + pnpm auto-install at the pinned versions
```

## Commands

| Command                | What it does                                                         |
| ---------------------- | -------------------------------------------------------------------- |
| `pnpm storybook`       | Storybook on port 6006 — primary dev surface                         |
| `pnpm build`           | Library build + emit `dist/*.d.ts` (also the only way to type-check) |
| `pnpm test`            | Vitest, run once                                                     |
| `pnpm test:watch`      | Vitest in watch mode                                                 |
| `pnpm lint`            | ESLint over `./src`                                                  |
| `pnpm lint:fix`        | ESLint with `--fix`                                                  |
| `pnpm build-storybook` | Static Storybook for Chromatic                                       |

There is no separate `typecheck` script — type errors surface during `pnpm build`'s declaration-emit step.

## How a release happens

1. Land a PR that bumps `package.json#version` (per [ADR 002](.agents/decisions/002-versioning-policy.md)).
2. On merge to `master`, [`.github/workflows/release.yml`](.github/workflows/release.yml) builds and runs `npm publish`.
3. Authentication is via npm Trusted Publishing (OIDC) — no tokens to rotate.
4. If you forget to bump, the publish step is skipped (no red CI), and the next versioned merge will publish.

## Repo orientation

| Area           | Where                                                                  |
| -------------- | ---------------------------------------------------------------------- |
| Components     | `src/components/T<Name>/` — one folder per component                   |
| Tokens & theme | `src/theme/` — base theme; ADR 003 covers the consumer flow            |
| Composables    | `src/composables/` — `useTheme`, `useDialog`, etc.                     |
| Public API     | `src/index.ts` — every shipped surface re-exports through here         |
| Tests          | `*.spec.ts(x)` next to the component (vitest + `@testing-library/vue`) |
| Stories        | `*.stories.ts` next to the component (Storybook + Chromatic)           |

## AI agent context (`.agents/`)

The repo uses the Toku-wide [`.agents/` standard](https://toku-espacio.slack.com/archives/C0AL3MBF4LU/p1776430860920449) — a single `.agents/` directory committed to the repo, with per-tool reference files (`.claude/`, `.cursor/`, root `AGENTS.md`) generated locally and `.gitignore`d.

To generate the local per-tool files (run once after cloning, or whenever you add files under `.agents/`):

```bash
bash scripts/agents-setup.sh                 # both Claude and Cursor
bash scripts/agents-setup.sh --claude        # Claude only
bash scripts/agents-setup.sh --cursor        # Cursor only
```

Start with [`.agents/AGENTS.md`](.agents/AGENTS.md) for the canonical contributor + agent reference. Architecture, conventions, and decisions live in `.agents/context/`, `.agents/rules/`, and `.agents/decisions/`.

## Installing in a consumer app

```bash
pnpm add toku-ui @emotion/css @iconify/vue
# or: yarn add toku-ui @emotion/css @iconify/vue
# or: npm install toku-ui @emotion/css @iconify/vue
```

Plus the Poppins font in your root HTML:

```html
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
  href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100..900;1,100..900&display=swap"
  rel="stylesheet"
/>
```
