@hirobius/design-system 0.23.1 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +57 -0
- package/DESIGN.md +8 -9
- package/README.md +29 -21
- package/UPGRADING.md +55 -1
- package/codemods/hds-prefix.mjs +0 -1
- package/codemods/jsx-fold.mjs +0 -1
- package/codemods/lib/scan.mjs +0 -1
- package/codemods/patterns-subpath.mjs +0 -1
- package/dist/chunks/{empty-state-ChC_xZfg.js → empty-state-BQ1v7ZIx.js} +15 -15
- package/dist/css-contract.json +1 -1
- package/dist/hirobius-ui.js +274 -273
- package/dist/manifest.js +9 -9
- package/dist/patterns.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/tokens.css +1 -1
- package/dist/tokens.js +25 -12
- package/dist/types/src/app/design-system/generated-token-refs.d.ts +25 -12
- package/dist/types/src/app/design-system/generated-token-values.d.ts +25 -12
- package/dist/types/src/index.d.ts +48 -9
- package/dist/types/src/lib/deprecation.d.ts +1 -1
- package/dist/variables.css +48 -37
- package/docs/CONSUMING.md +7 -7
- package/hirobius.tokens.json +113 -74
- package/llms.txt +5 -14
- package/package.json +5 -26
- package/public/hds-manifest.json +360 -1342
- package/public/llms/scroll.txt +2 -2
- package/public/llms-full.txt +13 -23
- package/public/llms.txt +5 -14
- package/src/app/data/component-api.json +1 -1
- package/upgrade/index.json +15 -1
- package/upgrade/releases/0.23.2.json +47 -0
- package/upgrade/releases/0.24.0.json +661 -0
package/AGENTS.md
CHANGED
|
@@ -110,7 +110,7 @@ the full engineering protocol; this section is the home for autonomous-loop rule
|
|
|
110
110
|
## Ralph quality bar
|
|
111
111
|
|
|
112
112
|
REPO_TYPE: library
|
|
113
|
-
QUALITY BAR: Public npm package. Backward compatibility matters. Tests
|
|
113
|
+
QUALITY BAR: Public npm package. Backward compatibility matters. Tests required, and a live demo on the docs site (docs-site/components/component-demos.tsx) for a core component or pattern.
|
|
114
114
|
|
|
115
115
|
Rules for any autonomous loop in this repo:
|
|
116
116
|
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,62 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.24.0
|
|
4
|
+
|
|
5
|
+
### Upgrade
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npx @hirobius/design-system@latest upgrade
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
- Do by hand: The --primitive-color-apple-100 variable is gone; use --primitive-color-graphite-100 for the same accent step.
|
|
12
|
+
- Do by hand: The --primitive-color-apple-200 variable is gone; use --primitive-color-graphite-200 for the same accent step.
|
|
13
|
+
- Do by hand: The --primitive-color-apple-300 variable is gone; use --primitive-color-graphite-300 for the same accent step.
|
|
14
|
+
- Do by hand: The --primitive-color-apple-400 variable is gone; use --primitive-color-graphite-400 for the same accent step.
|
|
15
|
+
- And 31 more: see [UPGRADING.md](https://github.com/hirobius/hds/blob/main/UPGRADING.md#0240).
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- 72800bc: feat(brand): change the default accent from apple green to graphite (warm charcoal).
|
|
20
|
+
|
|
21
|
+
The base brand accent moves from the bright apple green shipped in 0.23.0 to a warm
|
|
22
|
+
graphite — a full-monochrome accent that reads calmer and more considered. A new
|
|
23
|
+
`primitive.color.graphite` scale replaces `primitive.color.apple`; feedback hues
|
|
24
|
+
(`green`/`red`/`amber` for success/danger/warning) are untouched, so the system stays
|
|
25
|
+
monochrome without flattening its status colors.
|
|
26
|
+
- `semantic.accent.{rest,hover,pressed,content,contentHover,subtle}`, `semantic.color.surface.accent`/`accentSubtle`, `semantic.color.content.accent`, and `semantic.color.border.accent` now resolve through `primitive.color.graphite.*`.
|
|
27
|
+
- The accent **inverts per theme** so fills never vanish on a dark page: a dark graphite step in light mode (near-white on-accent text) and a light warm-grey step in dark mode (dark on-accent text). `semantic.color.content.onAccent` flips to `neutral.50` in light mode and `graphite.900` in dark mode — `content.onAccent / surface.accent` is 10.5:1 light / 10.0:1 dark.
|
|
28
|
+
- Per-tenant accents are unchanged: `accent-lilac` and `concrete-creations` set their own accent (and their own `onAccent`); `brutalist-demo` inherits the new graphite base.
|
|
29
|
+
|
|
30
|
+
The `--primitive-color-apple-*` CSS variables (introduced in 0.23.0) are removed in favor of `--primitive-color-graphite-*`; consumers who referenced a raw accent primitive should repoint to the graphite scale, though the semantic accent tokens are the intended surface and the per-tenant accent knob is unchanged — set your own accent overlay to override the base.
|
|
31
|
+
|
|
32
|
+
### Patch Changes
|
|
33
|
+
|
|
34
|
+
- 72800bc: fix(theming): the font dial now works.
|
|
35
|
+
|
|
36
|
+
Setting `--hds-font-family` / `--hds-font-family-mono` (or `<HdsThemeProvider fontFamily fontFamilyMono>`) used to change nothing: the type roles were resolved once on `:root`, so descendants inherited the default stack. They are now re-declared on each element of the `[data-hds]` subtree, so the dial applies at whatever scope you set it — headings, body, UI text, captions, code, and the JS style objects (`hds.fontFamily`, `hds.typeStyles`) all follow it. With no override, nothing changes: the default is still the brand typeface.
|
|
37
|
+
|
|
38
|
+
- 72800bc: feat(tokens): add a reserved mauve primitive scale.
|
|
39
|
+
|
|
40
|
+
`primitive.color.mauve.{50…950}` (anchor `#734B5E` at 500) is added alongside graphite, lightness-matched to it step for step. Nothing maps to it yet: graphite stays the brand accent, and no semantic or component token reads mauve. It is available as `--primitive-color-mauve-*` for exploration.
|
|
41
|
+
|
|
42
|
+
## 0.23.2
|
|
43
|
+
|
|
44
|
+
### Upgrade
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
npx @hirobius/design-system@latest upgrade
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
- Looks different: The disabled primary Button fill is now the muted surface instead of the accent-subtle surface.
|
|
51
|
+
- Looks different: The disabled primary Button text is now the disabled content colour instead of the on-accent colour.
|
|
52
|
+
- Every step is also in [UPGRADING.md](https://github.com/hirobius/hds/blob/main/UPGRADING.md#0232).
|
|
53
|
+
|
|
54
|
+
### Patch Changes
|
|
55
|
+
|
|
56
|
+
- b2ebd7d: A disabled primary Button now reads as a neutral muted button in light and dark: `component.button.primary.bgDisabled` points at `semantic.color.surface.muted` and `textDisabled` at `semantic.color.content.disabled` (they were `accentSubtle` and `onAccent`, which assumed a coloured accent), and Button binds those tokens. The small Button's icon is 12px, as its `component.button.size.sm.iconSize` token says (it was 14px); medium and large are unchanged at 16px and 20px.
|
|
57
|
+
- 4626131: Storybook is gone from the repo (retirement, step 3): the `storybook` package keyword, the story files, the Storybook config and the Storybook-only scripts are removed. The docs site is the visual verification surface. Nothing for a consumer to change.
|
|
58
|
+
- 9f1acfc: The manifest (`public/hds-manifest.json`) points each core component and pattern at its docs-site page with `docsPage` (for example `/docs/components/button`), replacing `storyFiles` and `storyIds`. `AGENTS.md` and the llms files now point agents at the docs site instead of the Storybook stories.
|
|
59
|
+
|
|
3
60
|
## 0.23.1
|
|
4
61
|
|
|
5
62
|
### Upgrade
|
package/DESIGN.md
CHANGED
|
@@ -6,14 +6,14 @@ A machine- and human-readable specification of the Hirobius Design System for AI
|
|
|
6
6
|
|
|
7
7
|
## Overview
|
|
8
8
|
|
|
9
|
-
Hirobius is a clean,
|
|
9
|
+
Hirobius is a clean, structured visual language that bridges digital precision and physical fabrication through a high-contrast monochromatic neutral palette and a single accent that each tenant sets — a warm graphite by default. Its personality is disciplined, tactile, and quietly technical: structure is explicit, motion is purposeful, and visual noise is stripped away. Whitespace is treated as material, not leftover space, so every screen should feel deliberate, breathable, and exact.
|
|
10
10
|
|
|
11
11
|
## Colors
|
|
12
12
|
|
|
13
13
|
<!-- auto:start:colors -->
|
|
14
14
|
**One accent — one neutral system.**
|
|
15
15
|
|
|
16
|
-
- **Accent** (`#
|
|
16
|
+
- **Accent** (`#433A3F`): CTAs, active states, selected focus rings, and the single brand accent. `semantic.accent.rest` — a per-tenant knob, not a fixed hue (#208).
|
|
17
17
|
- **Neutral**: backgrounds, surfaces, borders, text. True monochromatic — `primitive.color.neutral.50` through `950`. Use `semantic.color.surface.*`, `semantic.color.content.*`, `semantic.color.border.*`; never reach directly for primitives in components.
|
|
18
18
|
- **Feedback — Error** (`#B91C1C`): destructive confirms, error banners, validation failures. `semantic.color.feedback.error`.
|
|
19
19
|
- **Feedback — Success** (`#047857`): positive confirmations, completed states. `semantic.color.feedback.success`.
|
|
@@ -26,10 +26,9 @@ Feedback hues are never decorative; do not use them as accents. Light and dark m
|
|
|
26
26
|
## Typography
|
|
27
27
|
|
|
28
28
|
<!-- auto:start:typography -->
|
|
29
|
-
HDS ships
|
|
29
|
+
HDS ships two typefaces:
|
|
30
30
|
|
|
31
|
-
- **
|
|
32
|
-
- **Body / UI font**: Plus Jakarta Sans. All prose, labels, small text, captions, and UI copy.
|
|
31
|
+
- **Text font**: Plus Jakarta Sans. Headings, prose, labels, captions, and UI copy; the type roles set size and weight.
|
|
33
32
|
- **Mono font**: IBM Plex Mono. Reserved for tokens, code, technical callouts, and metric readouts.
|
|
34
33
|
|
|
35
34
|
Weights declared: `400` regular, `500` medium, `700` bold. Heading styles (display · title) use `700` bold; body, UI, and caption use `400` regular / `500` medium.
|
|
@@ -65,7 +64,7 @@ Layout rhythm, padding, and gaps use the `semantic.space.scale.{xs…xl}` steps
|
|
|
65
64
|
|
|
66
65
|
## Layout contract (v1)
|
|
67
66
|
|
|
68
|
-
Approved 2026-10-07. Data: `docs/guardrails/layout-contract.json`; gates: `pnpm check:layout-contract` and `pnpm check:spacing-scale` (warn mode; baseline in `docs/audits/layout-contract-baseline.md`).
|
|
67
|
+
Approved 2026-10-07 as the **target**; adoption is in progress, so some components below (Container, Sidebar, Switcher) still ship until they fold in. Data: `docs/guardrails/layout-contract.json`; gates: `pnpm check:layout-contract` and `pnpm check:spacing-scale` (warn mode; baseline in `docs/audits/layout-contract-baseline.md`).
|
|
69
68
|
|
|
70
69
|
1. **Sizing.** Every component declares `fill` or `hug` on each axis. Leaves hug. Input, Textarea, Select, Combobox, Table, Progress and Divider fill width. One override prop, `width="hug|fill"`, on every component. Height always hugs; stretching is the parent's job (`align="stretch"`). No component sets `h-full`, `height: 100%` or `self-*` on its root.
|
|
71
70
|
2. **Padding.** Only containers pad: Card, Surface, Alert, Callout, Dialog, Page. Compound parts (`Card.Header`, `Body`, `Footer`, `Metric`) have zero padding and the container's `gap` spaces them. Padding is `none | sm | md`, default `md`, density-aware. A padded container directly inside a padded container is an error unless the inner one is `padding="none"`.
|
|
@@ -209,7 +208,7 @@ Three more needs are props on an existing component, not components of their own
|
|
|
209
208
|
## Do's and Don'ts
|
|
210
209
|
|
|
211
210
|
- Don't invent new corner behavior for interactive controls; buttons, inputs, disclosures, and similar action surfaces should follow the shared action radius (`semantic.radius.action`).
|
|
212
|
-
- Don't introduce additional accent hues; Hirobius uses exactly one accent, resolved from `semantic.accent.rest`, over a true monochromatic neutral system. The accent is a per-tenant knob
|
|
211
|
+
- Don't introduce additional accent hues; Hirobius uses exactly one accent, resolved from `semantic.accent.rest`, over a true monochromatic neutral system. The accent is a per-tenant knob and defaults to a warm graphite — read the token, never assume a hue.
|
|
213
212
|
- Don't tint neutrals warm or cool; greys should remain genuinely neutral and high-contrast.
|
|
214
213
|
- Don't reach for shadow values directly — bind to a `semantic.elevation.*` role so surface + shadow + border stay paired. Cards default to `flat` (border, no shadow). Popovers/tooltips/dropdowns use `floating`. Dialogs/sheets use `overlay`.
|
|
215
214
|
- Don't hardcode colors, spacing, radius, or typography values when governed tokens already exist.
|
|
@@ -223,11 +222,11 @@ Three more needs are props on an existing component, not components of their own
|
|
|
223
222
|
|
|
224
223
|
## Open Questions
|
|
225
224
|
|
|
226
|
-
Unresolved rules that the live repo cannot yet answer confidently are tracked
|
|
225
|
+
Unresolved rules that the live repo cannot yet answer confidently are tracked as GitHub issues. Do not invent rules here to fill those gaps.
|
|
227
226
|
|
|
228
227
|
<!-- auto:start:build-meta -->
|
|
229
228
|
---
|
|
230
229
|
|
|
231
|
-
> Generated from `hirobius.tokens.json` (
|
|
230
|
+
> Generated from `hirobius.tokens.json` (411 tokens) and `public/hds-manifest.json` by `scripts/build-design-md.mjs`.
|
|
232
231
|
> Hand-edit `DESIGN.source.md`; this file (`DESIGN.md`) is overwritten by `pnpm tokens`.
|
|
233
232
|
<!-- auto:end:build-meta -->
|
package/README.md
CHANGED
|
@@ -13,46 +13,47 @@ pnpm add @hirobius/design-system
|
|
|
13
13
|
|
|
14
14
|
Upgrading: [UPGRADING.md](UPGRADING.md) lists what each release asks of you. From 0.22.0, `npx @hirobius/design-system@latest upgrade` does it for you.
|
|
15
15
|
|
|
16
|
-
[](https://hirobius-hds-components.vercel.app)
|
|
17
17
|
|
|
18
18
|
<!-- auto:start:front-door-counts -->
|
|
19
19
|
|
|
20
20
|
- **53** public component modules, exported from `src/index.ts`
|
|
21
|
-
- **
|
|
22
|
-
- **341** Storybook stories in **71** story files
|
|
21
|
+
- **411** DTCG tokens in `hirobius.tokens.json`, compiled to CSS variables and TypeScript constants
|
|
23
22
|
|
|
24
23
|
<!-- auto:end:front-door-counts -->
|
|
25
24
|
|
|
26
25
|
What the system includes:
|
|
27
26
|
|
|
28
27
|
- **Token pipeline.** DTCG tokens in `hirobius.tokens.json` compile to CSS variables and TypeScript constants through a validated alias chain, with AA-contrast gates in light and dark.
|
|
29
|
-
- **Gates with proof-of-firing.** Typecheck, zero-warning ESLint, token validity and contrast, Vitest unit and contract tests,
|
|
28
|
+
- **Gates with proof-of-firing.** Typecheck, zero-warning ESLint, token validity and contrast, Vitest unit and contract tests, and a consumer smoke build run in git hooks and CI; bundle budgets and a docs-site accessibility (axe) gate run in CI. Many gates carry a passing and a violating fixture that demonstrate the gate catches what it describes.
|
|
30
29
|
- **Upgrade path.** A release ledger and one consumer command: `npx @hirobius/design-system@latest upgrade`.
|
|
31
30
|
- **One-way Figma sync.** Code is the source of truth; tokens project into Figma, and `pnpm check:figma-drift` compares a committed snapshot against the model.
|
|
32
31
|
- **Theming without JavaScript.** Four root attributes — theme, density, brand, font — re-skin HDS descendants through CSS variables.
|
|
33
32
|
|
|
34
33
|
The counts are generated from source by `pnpm readme:counts`, which `pnpm tokens` also runs. `scripts/__tests__/front-door.test.mjs` fails if this README claims more than the source has.
|
|
35
34
|
|
|
35
|
+
**How it's built:** [How HDS is engineered](docs/ENGINEERING.md) walks the token pipeline, the quality gates (and how they're proven to fire), testing, release and upgrade, and Figma sync.
|
|
36
|
+
|
|
36
37
|
Agents: install the consumer skill with `npx skills add hirobius/hds --skill hds-consumer` (see `docs/CONSUMING.md`, "Agent skill").
|
|
37
38
|
|
|
38
39
|
## In use
|
|
39
40
|
|
|
40
41
|
<!-- auto:start:consumer-usage -->
|
|
41
42
|
|
|
42
|
-
|
|
43
|
+
An internal operations dashboard is the only product app that uses components: **33** of its source files import from `@hirobius/design-system`, using **25** distinct components. The two screenshots below are pages of that app, rendered from its `main` branch.
|
|
43
44
|
|
|
44
45
|
| Consumer kind | Count | How it uses HDS |
|
|
45
46
|
| ----------------- | ----- | ----------------------------------------- |
|
|
46
47
|
| Product apps | 1 | Components and tokens |
|
|
47
48
|
| Token-level sites | 4 | Tokens and CSS only, no component imports |
|
|
48
49
|
|
|
49
|
-
[](docs/images/product-app-library.png)
|
|
50
51
|
|
|
51
|
-
[](docs/images/product-app-audit.png)
|
|
52
53
|
|
|
53
54
|
<!-- auto:end:consumer-usage -->
|
|
54
55
|
|
|
55
|
-
The numbers come from `pnpm consumer:usage --root <
|
|
56
|
+
The numbers come from `pnpm consumer:usage --root <consumer checkout>`, which measures that checkout's `src/` and records its commit in `docs/data/consumer-usage.json` (pass `--commit <sha>` when the root is a `git archive` export); without a root it reuses the committed snapshot. A deprecated alias counts as the component it points to (`HdsCheckbox` as `Checkbox`). The components that the app's page- and video-clone prompts tell generated code to import are listed there as `promptContracts` and are not counted here. `scripts/__tests__/consumer-usage.test.mjs` fails if this section drifts from that snapshot. The product-app and token-level-site split is a declared figure in that file, not a measurement. It was confirmed on 2026-10-01 (there is no second product app), so `consumersConfirmed` there is true and the table above shows it.
|
|
56
57
|
|
|
57
58
|
## What belongs in the system
|
|
58
59
|
|
|
@@ -178,7 +179,7 @@ What each Figma plan allows, and the Pro-plan architecture this follows, are in
|
|
|
178
179
|
pnpm install
|
|
179
180
|
# Generated data files are gitignored; create them once (the same step CI runs):
|
|
180
181
|
node scripts/generate-manifest.mjs && node scripts/generate-component-api.mjs && node scripts/enrich-manifest.mjs && node scripts/sync-icons.mjs && node scripts/audit-tokens.mjs --full
|
|
181
|
-
pnpm
|
|
182
|
+
pnpm docs:dev # docs site (component pages with live demos)
|
|
182
183
|
```
|
|
183
184
|
|
|
184
185
|
Core verification commands:
|
|
@@ -189,7 +190,7 @@ pnpm lint
|
|
|
189
190
|
pnpm test # pretest gates + unit + contract tests, exactly as the pre-push hook and CI run them
|
|
190
191
|
pnpm tokens:verify
|
|
191
192
|
pnpm check:size
|
|
192
|
-
pnpm build-
|
|
193
|
+
pnpm docs:publish # docs-site build, then: node scripts/check-docs-axe.mjs
|
|
193
194
|
```
|
|
194
195
|
|
|
195
196
|
## Architecture
|
|
@@ -219,7 +220,6 @@ What CI and the hooks check today, and nothing more:
|
|
|
219
220
|
- **Contrast:** `scripts/check-contrast.mjs` enforces WCAG AA contrast on the core token pairs, in light and dark. It runs in CI and the pre-commit hook.
|
|
220
221
|
- **Lint:** `jsx-a11y` rules run inside ESLint with zero warnings allowed.
|
|
221
222
|
- **Focus:** `scripts/check-focus-states.mjs` (`pnpm check:focus`) audits focus styles on interactive components. It runs in `pretest` under `pnpm test`, so in the pre-push hook and in CI, and passes with 0 violations.
|
|
222
|
-
- **Storybook:** the `addon-a11y` panel shows axe results for each story while you review it. The gate is `scripts/check-storybook-axe.mjs`: CI scans every built story in light and dark, including the open Select and Combobox, and fails on serious or critical violations outside its allowlist (`scripts/axe-allowlist.json`). The allowlist has one entry: `aria-hidden-focus` on the open Select story, where Radix Select hides the page around its listbox while focus stays trapped inside it (hds#407).
|
|
223
223
|
- **Docs site:** `scripts/check-docs-axe.mjs` (`pnpm check:docs-axe`, after `pnpm docs:publish`) scans the live demo of every `/docs/components/*` and `/docs/patterns/*` page of the built docs site in light and dark with the same axe rules, scoped to the demo frame so the Fumadocs chrome does not count. CI runs it and fails on serious or critical violations outside `scripts/docs-axe-allowlist.json`, which is empty.
|
|
224
224
|
|
|
225
225
|
Screen-reader output is checked by `tests/primitive-contracts/screen-reader.contract.test.tsx`, which runs in `pnpm test` and walks Dialog, Menu, Select, Combobox, Table and Alert with a virtual screen-reader (`@guidepup/virtual-screen-reader`) under jsdom, asserting the role, name and state phrases it reads and the alert's live-region announcement; it reads the jsdom accessibility tree, not what a desktop or mobile screen-reader says.
|
|
@@ -237,10 +237,10 @@ The governing direction is "Editorial Enterprise" — enterprise rigor with edit
|
|
|
237
237
|
|
|
238
238
|
The gates are deterministic and need no browser or live site:
|
|
239
239
|
|
|
240
|
-
- **pre-commit** (`.husky/pre-commit`): secrets scan, Prettier on staged files, typecheck, zero-warning ESLint, and token validity and contrast.
|
|
240
|
+
- **pre-commit** (`.husky/pre-commit`): secrets scan (when `gitleaks` is installed locally; not yet in CI), Prettier on staged files, typecheck, zero-warning ESLint, and token validity and contrast.
|
|
241
241
|
- **pre-push** (`.husky/pre-push`): `pnpm test` (the pretest gates, then Vitest unit and contract tests), then the consumer smoke build (library build, subpath resolution, publint, consumer typecheck).
|
|
242
|
-
- **CI** (`.github/workflows/ci.yml`): typecheck, zero-warning ESLint, token validity and contrast, Vitest, and the consumer smoke build, plus bundle budgets and
|
|
243
|
-
- **Visual review:**
|
|
242
|
+
- **CI** (`.github/workflows/ci.yml`): typecheck, zero-warning ESLint, token validity and contrast, Vitest, and the consumer smoke build, plus bundle budgets and the docs-site build with its axe gate.
|
|
243
|
+
- **Visual review:** the docs site (`docs-site/`) is the visual verification surface: every core component and pattern has a page with a live demo, `check-docs-axe` gates its accessibility.
|
|
244
244
|
|
|
245
245
|
### Agent consistency
|
|
246
246
|
|
|
@@ -265,18 +265,26 @@ Releases are cut with [Changesets](https://github.com/changesets/changesets). A
|
|
|
265
265
|
```text
|
|
266
266
|
src/
|
|
267
267
|
app/
|
|
268
|
-
components/
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
styles/
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
268
|
+
components/ the components
|
|
269
|
+
context/ theme provider
|
|
270
|
+
design-system/ generated token constants
|
|
271
|
+
styles/ tokens.css, theme.css, generated CSS
|
|
272
|
+
brand/ form/ mui/ scroll/ subpath entry points
|
|
273
|
+
hirobius.tokens.json the single token source
|
|
274
|
+
scripts/ generators and gates
|
|
275
|
+
codemods/ the upgrade command and its codemods
|
|
276
|
+
mcp/ the MCP server shipped in the package
|
|
277
|
+
docs-site/ the documentation site
|
|
278
|
+
content/ docs-site pages
|
|
279
|
+
eval/ agent-consistency eval
|
|
280
|
+
docs/ ADRs, ENGINEERING.md, guardrail registry
|
|
281
|
+
public/ manifest, llms.txt
|
|
275
282
|
```
|
|
276
283
|
|
|
277
284
|
## Primary docs
|
|
278
285
|
|
|
279
286
|
- [`docs/CONSUMING.md`](docs/CONSUMING.md) — installing & using the published package
|
|
287
|
+
- [`docs/ENGINEERING.md`](docs/ENGINEERING.md) — how the system is built (pipeline, gates, release, Figma sync)
|
|
280
288
|
- `CLAUDE.md` — agent operating contract
|
|
281
289
|
- `DESIGN.md` — lean visual spec
|
|
282
290
|
- `DESIGN-HANDOFF.md` — verbose visual mirror
|
package/UPGRADING.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Upgrading @hirobius/design-system
|
|
2
2
|
|
|
3
|
-
This file only knows the releases up to the version you have installed, 0.
|
|
3
|
+
This file only knows the releases up to the version you have installed, 0.24.0. For newer releases, run `npx @hirobius/design-system@latest upgrade`: it always fetches the newest steps.
|
|
4
4
|
|
|
5
5
|
## How to upgrade
|
|
6
6
|
|
|
@@ -10,6 +10,60 @@ npx @hirobius/design-system@latest upgrade
|
|
|
10
10
|
|
|
11
11
|
It finds the version you have, moves you to the newest release, runs each release's codemods (Fixed for you) and lists what is left for you (Do by hand). It works from 0.16.0 on; from an older version, first reach 0.16.0 with the notes in CHANGELOG.md. MIGRATIONS.md has longer guides for the big releases.
|
|
12
12
|
|
|
13
|
+
## 0.24.0
|
|
14
|
+
|
|
15
|
+
Released 2026-10-12 (minor). 11 changes to make by hand (11 breaking) and 24 that look different.
|
|
16
|
+
|
|
17
|
+
### Looks different
|
|
18
|
+
|
|
19
|
+
- This variable now follows the font dial (--hds-font-family) at any scope; if you overrode it directly, override the dial instead.
|
|
20
|
+
- This variable now follows the code-font dial (--hds-font-family-mono) at any scope; if you overrode it directly, override the dial instead.
|
|
21
|
+
- This variable now follows the font dial (--hds-font-family) at any scope; if you overrode it directly, override the dial instead.
|
|
22
|
+
- Accent-intent text and icons (such as links) now render in graphite instead of a dark apple green.
|
|
23
|
+
- Hovered accent text now shifts within the graphite scale instead of toward a darker apple green.
|
|
24
|
+
- The accent fill on hover is now a deeper graphite (light mode) or lighter warm-grey (dark mode) instead of a green.
|
|
25
|
+
- The accent fill while pressed is now a darker graphite (light mode) or lighter warm-grey (dark mode) instead of a green.
|
|
26
|
+
- Interactive accent fills at rest (primary buttons, selected controls) now render in warm graphite — a dark fill in light mode and a light warm-grey fill in dark mode — instead of a bright apple green.
|
|
27
|
+
- The low-emphasis accent tint (hover and selection backgrounds) is now a faint graphite tint instead of a faint apple green.
|
|
28
|
+
- Accent borders now render in graphite instead of apple green.
|
|
29
|
+
- Accent-intent text and icons on page and card surfaces now render in graphite instead of a dark apple green.
|
|
30
|
+
- Text and icons on accent fills are now near-white in light mode and dark graphite in dark mode (the fill inverts per theme), instead of a dark neutral in both modes.
|
|
31
|
+
- Accent background surfaces now render in warm graphite that inverts per theme instead of a bright apple green.
|
|
32
|
+
- Faint accent background surfaces are now a pale graphite tint instead of a pale apple green.
|
|
33
|
+
- This variable now follows the font dial (--hds-font-family) at any scope; if you overrode it directly, override the dial instead.
|
|
34
|
+
- This variable now follows the font dial (--hds-font-family) at any scope; if you overrode it directly, override the dial instead.
|
|
35
|
+
- This variable now follows the font dial (--hds-font-family) at any scope; if you overrode it directly, override the dial instead.
|
|
36
|
+
- This variable now follows the font dial (--hds-font-family) at any scope; if you overrode it directly, override the dial instead.
|
|
37
|
+
- This variable now follows the font dial (--hds-font-family) at any scope; if you overrode it directly, override the dial instead.
|
|
38
|
+
- This variable now follows the font dial (--hds-font-family) at any scope; if you overrode it directly, override the dial instead.
|
|
39
|
+
- This variable now follows the font dial (--hds-font-family) at any scope; if you overrode it directly, override the dial instead.
|
|
40
|
+
- This variable now follows the code-font dial (--hds-font-family-mono) at any scope; if you overrode it directly, override the dial instead.
|
|
41
|
+
- This variable now follows the font dial (--hds-font-family) at any scope; if you overrode it directly, override the dial instead.
|
|
42
|
+
- This variable now follows the font dial (--hds-font-family) at any scope; if you overrode it directly, override the dial instead.
|
|
43
|
+
|
|
44
|
+
### Do by hand
|
|
45
|
+
|
|
46
|
+
- The --primitive-color-apple-100 variable is gone; use --primitive-color-graphite-100 for the same accent step.
|
|
47
|
+
- The --primitive-color-apple-200 variable is gone; use --primitive-color-graphite-200 for the same accent step.
|
|
48
|
+
- The --primitive-color-apple-300 variable is gone; use --primitive-color-graphite-300 for the same accent step.
|
|
49
|
+
- The --primitive-color-apple-400 variable is gone; use --primitive-color-graphite-400 for the same accent step.
|
|
50
|
+
- The --primitive-color-apple-50 variable is gone; use --primitive-color-graphite-50 for the same lightest accent step.
|
|
51
|
+
- The --primitive-color-apple-500 variable is gone; use --primitive-color-graphite-500 (or a semantic accent token) instead.
|
|
52
|
+
- The --primitive-color-apple-600 variable is gone; use --primitive-color-graphite-600 for the same accent step.
|
|
53
|
+
- The --primitive-color-apple-700 variable is gone; use --primitive-color-graphite-700 for the rest accent step.
|
|
54
|
+
- The --primitive-color-apple-800 variable is gone; use --primitive-color-graphite-800 for the same accent step.
|
|
55
|
+
- The --primitive-color-apple-900 variable is gone; use --primitive-color-graphite-900 for the same accent step.
|
|
56
|
+
- The --primitive-color-apple-950 variable is gone; use --primitive-color-graphite-950 for the darkest accent step.
|
|
57
|
+
|
|
58
|
+
## 0.23.2
|
|
59
|
+
|
|
60
|
+
Released 2026-10-11 (patch). 2 that look different.
|
|
61
|
+
|
|
62
|
+
### Looks different
|
|
63
|
+
|
|
64
|
+
- The disabled primary Button fill is now the muted surface instead of the accent-subtle surface.
|
|
65
|
+
- The disabled primary Button text is now the disabled content colour instead of the on-accent colour.
|
|
66
|
+
|
|
13
67
|
## 0.23.1
|
|
14
68
|
|
|
15
69
|
Released 2026-10-11 (patch). 6 that look different.
|
package/codemods/hds-prefix.mjs
CHANGED
package/codemods/jsx-fold.mjs
CHANGED
package/codemods/lib/scan.mjs
CHANGED
|
@@ -128,7 +128,7 @@ const Ne = {
|
|
|
128
128
|
spacious: "var(--semantic-space-layout-spacious)"
|
|
129
129
|
},
|
|
130
130
|
numbers: "units"
|
|
131
|
-
},
|
|
131
|
+
}, z = (t, e) => Object.prototype.hasOwnProperty.call(t, e) ? t[e] : void 0, _e = {
|
|
132
132
|
tight: "sm",
|
|
133
133
|
normal: "md",
|
|
134
134
|
inset: "lg",
|
|
@@ -153,7 +153,7 @@ const Ne = {
|
|
|
153
153
|
columnGap: ["column-gap"]
|
|
154
154
|
};
|
|
155
155
|
function $(t, e) {
|
|
156
|
-
return "closed" in e ? typeof t == "string" ?
|
|
156
|
+
return "closed" in e ? typeof t == "string" ? z(e.names, t) : void 0 : typeof t == "number" ? e.numbers === "raw" ? t : Re.has(t) ? `var(--primitive-space-${t})` : `calc(var(--primitive-space-1) * ${t})` : z(e.names, t) ?? t;
|
|
157
157
|
}
|
|
158
158
|
const Oe = {
|
|
159
159
|
color: "color",
|
|
@@ -161,7 +161,7 @@ const Oe = {
|
|
|
161
161
|
borderColor: "border-color",
|
|
162
162
|
fill: "fill",
|
|
163
163
|
stroke: "stroke"
|
|
164
|
-
}, $e = /* @__PURE__ */ new Set(["primary", "secondary", "disabled", "inverse", "accent"]), Ie = /* @__PURE__ */ new Set(["page", "raised", "overlay", "accent"]), Le = /* @__PURE__ */ new Set(["default", "subtle", "subdued", "strong", "accent"]),
|
|
164
|
+
}, $e = /* @__PURE__ */ new Set(["primary", "secondary", "disabled", "inverse", "accent"]), Ie = /* @__PURE__ */ new Set(["page", "raised", "overlay", "accent"]), Le = /* @__PURE__ */ new Set(["default", "subtle", "subdued", "strong", "accent"]), ze = /* @__PURE__ */ new Set(["success", "warning", "error", "info"]), je = /* @__PURE__ */ new Set(["hover", "pressed", "subtle", "content"]);
|
|
165
165
|
function Me(t) {
|
|
166
166
|
if (t === "accent") return "var(--semantic-accent-rest)";
|
|
167
167
|
const e = t.indexOf(".");
|
|
@@ -170,8 +170,8 @@ function Me(t) {
|
|
|
170
170
|
if (r === "content" && $e.has(n)) return `var(--semantic-color-content-${n})`;
|
|
171
171
|
if (r === "surface" && Ie.has(n)) return `var(--semantic-color-surface-${n})`;
|
|
172
172
|
if (r === "border" && Le.has(n)) return `var(--semantic-color-border-${n})`;
|
|
173
|
-
if (r === "feedback" &&
|
|
174
|
-
if (r === "accent" &&
|
|
173
|
+
if (r === "feedback" && ze.has(n)) return `var(--semantic-color-feedback-${n})`;
|
|
174
|
+
if (r === "accent" && je.has(n)) return `var(--semantic-accent-${n})`;
|
|
175
175
|
}
|
|
176
176
|
function Be(t) {
|
|
177
177
|
return t.replace(/[A-Z]/g, (e) => `-${e.toLowerCase()}`);
|
|
@@ -179,7 +179,7 @@ function Be(t) {
|
|
|
179
179
|
function W(t, e) {
|
|
180
180
|
const r = Pe[t];
|
|
181
181
|
if (r) {
|
|
182
|
-
const c = typeof e == "string" ?
|
|
182
|
+
const c = typeof e == "string" ? z(_e, e) : void 0;
|
|
183
183
|
c && Ae(
|
|
184
184
|
`box-sx-spacing-${e}`,
|
|
185
185
|
`Box sx spacing name '${e}' is deprecated (hds#206) and is removed in 1.0.0. Use '${c}': same pixels at the default density, tighter under compact (MIGRATIONS.md).`
|
|
@@ -237,8 +237,8 @@ function Ge(t, e) {
|
|
|
237
237
|
}
|
|
238
238
|
return d;
|
|
239
239
|
}
|
|
240
|
-
function
|
|
241
|
-
return t === void 0 ? "undefined" : t === null || typeof t != "object" ? JSON.stringify(t) : Array.isArray(t) ? `[${t.map(
|
|
240
|
+
function j(t) {
|
|
241
|
+
return t === void 0 ? "undefined" : t === null || typeof t != "object" ? JSON.stringify(t) : Array.isArray(t) ? `[${t.map(j).join(",")}]` : `{${Object.keys(t).sort().map((r) => `${JSON.stringify(r)}:${j(t[r])}`).join(",")}}`;
|
|
242
242
|
}
|
|
243
243
|
function He(t) {
|
|
244
244
|
let e = 5381;
|
|
@@ -247,7 +247,7 @@ function He(t) {
|
|
|
247
247
|
return (e >>> 0).toString(36);
|
|
248
248
|
}
|
|
249
249
|
function Ke(t) {
|
|
250
|
-
return `hds-sx-${He(
|
|
250
|
+
return `hds-sx-${He(j(t))}`;
|
|
251
251
|
}
|
|
252
252
|
const U = /* @__PURE__ */ new Set();
|
|
253
253
|
let T = null;
|
|
@@ -273,7 +273,7 @@ function Xt(t) {
|
|
|
273
273
|
return e;
|
|
274
274
|
}
|
|
275
275
|
const Ue = /* @__PURE__ */ E(
|
|
276
|
-
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md transition-[colors,filter] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:bg-
|
|
276
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md transition-[colors,filter] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:bg-[var(--component-button-primary-bgDisabled)] disabled:text-[var(--component-button-primary-textDisabled)] active:inset-shadow-[0_0_0_9999px] active:inset-shadow-pressed-overlay/5 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
277
277
|
{
|
|
278
278
|
variants: {
|
|
279
279
|
variant: {
|
|
@@ -307,9 +307,9 @@ const Ue = /* @__PURE__ */ E(
|
|
|
307
307
|
info: "border-transparent bg-feedback-bg-info text-feedback-info hover:bg-feedback-bg-info hover:border-transparent hover:brightness-95 dark:hover:brightness-110"
|
|
308
308
|
},
|
|
309
309
|
size: {
|
|
310
|
-
sm: "h-8 px-3 hds-type-caption [&_svg]:size-
|
|
311
|
-
md: "h-10 px-4 py-2 hds-type-ui [&_svg]:size-
|
|
312
|
-
lg: "h-12 px-6 hds-type-ui [&_svg]:size-
|
|
310
|
+
sm: "h-8 px-3 hds-type-caption [&_svg]:size-[var(--component-button-size-sm-iconSize)]",
|
|
311
|
+
md: "h-10 px-4 py-2 hds-type-ui [&_svg]:size-[var(--component-button-size-md-iconSize)]",
|
|
312
|
+
lg: "h-12 px-6 hds-type-ui [&_svg]:size-[var(--component-button-size-lg-iconSize)]"
|
|
313
313
|
},
|
|
314
314
|
iconOnly: {
|
|
315
315
|
true: "p-0",
|
|
@@ -1171,7 +1171,7 @@ const Tt = A.Trigger, ie = /* @__PURE__ */ se(A.Portal), _t = A.Action, Pt = A.C
|
|
|
1171
1171
|
);
|
|
1172
1172
|
}), Lt = /* @__PURE__ */ h.forwardRef(function({ className: e, children: r, ...n }, a) {
|
|
1173
1173
|
return /* @__PURE__ */ s(A.Title, { asChild: !0, children: /* @__PURE__ */ s(I, { ref: a, as: "h2", variant: "title", className: e, ...n, children: r }) });
|
|
1174
|
-
}),
|
|
1174
|
+
}), zt = /* @__PURE__ */ h.forwardRef(function({ className: e, children: r, ...n }, a) {
|
|
1175
1175
|
return /* @__PURE__ */ s(A.Description, { asChild: !0, children: /* @__PURE__ */ s(
|
|
1176
1176
|
I,
|
|
1177
1177
|
{
|
|
@@ -1191,7 +1191,7 @@ const Tt = A.Trigger, ie = /* @__PURE__ */ se(A.Portal), _t = A.Action, Pt = A.C
|
|
|
1191
1191
|
Header: $t,
|
|
1192
1192
|
Footer: It,
|
|
1193
1193
|
Title: Lt,
|
|
1194
|
-
Description:
|
|
1194
|
+
Description: zt,
|
|
1195
1195
|
Action: _t,
|
|
1196
1196
|
Cancel: Pt,
|
|
1197
1197
|
// Set here, not by a later `AlertDialog.displayName = …` write: a top-level
|