@godxjp/ui 2.1.0 → 5.0.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.
Files changed (46) hide show
  1. package/BRAND.md +39 -29
  2. package/CHANGELOG.md +554 -10
  3. package/README.md +143 -168
  4. package/config/eslint.js +54 -0
  5. package/config/prettier.cjs +20 -0
  6. package/config/tsconfig.base.json +22 -0
  7. package/config/vitest.base.ts +26 -0
  8. package/dist/MiniMonth-YAmPGEpC.d.ts +143 -0
  9. package/dist/Table.types-BbsxoIYE.d.ts +352 -0
  10. package/dist/color-DO0qqUAb.d.ts +38 -0
  11. package/dist/components/composites.d.ts +963 -0
  12. package/dist/components/composites.js +7340 -0
  13. package/dist/components/composites.js.map +1 -0
  14. package/dist/components/primitives.d.ts +2633 -163
  15. package/dist/components/primitives.js +7264 -165
  16. package/dist/components/primitives.js.map +1 -1
  17. package/dist/components/shell.d.ts +82 -12
  18. package/dist/components/shell.js +168 -162
  19. package/dist/components/shell.js.map +1 -1
  20. package/dist/hooks.d.ts +83 -8
  21. package/dist/hooks.js +497 -83
  22. package/dist/hooks.js.map +1 -1
  23. package/dist/i18n.d.ts +55 -3
  24. package/dist/i18n.js +456 -5
  25. package/dist/i18n.js.map +1 -1
  26. package/dist/index.d.ts +24 -5
  27. package/dist/index.js +12522 -267
  28. package/dist/index.js.map +1 -1
  29. package/dist/padding-DY0JV5Ja.d.ts +16 -0
  30. package/dist/preferences.d.ts +132 -0
  31. package/dist/preferences.js +262 -0
  32. package/dist/preferences.js.map +1 -0
  33. package/dist/props.d.ts +86 -0
  34. package/dist/props.js +16 -0
  35. package/dist/props.js.map +1 -0
  36. package/dist/size-CQwNvOWd.d.ts +19 -0
  37. package/dist/{data.d.ts → types-LTj-2bl-.d.ts} +7 -12
  38. package/dist/useTableViews-D5NIAJ7h.d.ts +154 -0
  39. package/package.json +92 -34
  40. package/src/tokens/tailwind.css +158 -0
  41. package/dist/components/screens.d.ts +0 -51
  42. package/dist/components/screens.js +0 -806
  43. package/dist/components/screens.js.map +0 -1
  44. package/dist/data.js +0 -93
  45. package/dist/data.js.map +0 -1
  46. package/src/tokens/tokens.css +0 -765
package/CHANGELOG.md CHANGED
@@ -3,18 +3,558 @@
3
3
  All notable changes to `@godxjp/ui`. Follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
4
4
  and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5
5
 
6
+ ## [5.0.0] — 2026-05-18
7
+
8
+ ### BREAKING CHANGES
9
+
10
+ - **`<Table>` chrome props removed.** The legacy "data-table page"
11
+ props moved off the primitive into the `<DataTable>` composite.
12
+ TypeScript compilation will fail for any call site that passes:
13
+ `toolbar`, `views`, `batchActions`, `filters`, `onFiltersChange`,
14
+ `filterBar`, `onResetFilters`, `pagination`, `tableKey`. See
15
+ ADR-0007 and `docs/how-to/migrate-to-data-table.md` for the
16
+ required migration (1:1 prop-to-hook diff for every removed prop).
17
+ - **`<Table batchActions>` → `<Table selection>`.** Consumers that
18
+ used the primitive's batch-actions config strictly for the
19
+ checkbox column switch to the slimmer `selection` prop. Same
20
+ `selectedRowKeys` / `onSelectedRowKeysChange` /
21
+ `getCheckboxDisabled` shape; the batch action band UI moves to
22
+ the composite.
23
+ - **`Table.persistence.ts` relocated** to
24
+ `src/components/composites/data-table/persistence.ts`. The slim
25
+ primitive no longer reads or writes localStorage; the composite
26
+ threads persistence through `useDataTable`.
27
+
28
+ ### Changed
29
+
30
+ - **`Table.tsx`: 1,842 → 901 lines** (~51% reduction). Forking the
31
+ primitive in place (rule 4) is achievable again.
32
+ - **`DataTable.tsx`: 86 → ~280 lines.** The composite renders view
33
+ tabs, toolbar bar, batch action band, filter chip bar, pagination
34
+ band, column manager Sheet, and save-view Dialog directly.
35
+ TanStack `useReactTable` lives in `useDataTable`; the primitive
36
+ accepts the instance via a new `instance?` prop and falls back to
37
+ a local hook only when standalone.
38
+ - **CSS split** — chrome rules moved from
39
+ `src/styles/shell/40-table.css` into a new
40
+ `src/styles/shell/41-data-table.css`. `shell.css` imports the new
41
+ file directly after the old one so cascade order is unchanged.
42
+ - **Story migration** — `WithToolbar`, `InteractionRegression`,
43
+ `Pagination_Numbered`, `Pagination_LoadMore`, `Pagination_Cursor`
44
+ moved from `data-display/Table.stories.tsx` to
45
+ `composites/DataTable.stories.tsx`. Bare-primitive stories that
46
+ passed chrome props (`StickyColumns`) updated to drop them.
47
+ `Table.stories::BulkActions` deleted (covered by the composite
48
+ story of the same name).
49
+
50
+ ### Migration
51
+
52
+ - See [`docs/how-to/migrate-to-data-table.md`](docs/how-to/migrate-to-data-table.md)
53
+ for the required v5 codemod. Each removed prop has a 1:1
54
+ composite + hook equivalent — there is no functionality loss.
55
+ - Consumers on v4 that still pass chrome props see a once-per-prop
56
+ `console.warn` from the primitive (introduced in
57
+ 4.0.x → 5.0.0-prep). The warning text links to the migration guide.
58
+
59
+ ## [Unreleased]
60
+
61
+ ### Added
62
+
63
+ - **`<DataTable>` composite + table hooks** (ADR-0006). New
64
+ ergonomic surface for the "data-table page" pattern. Pairs the
65
+ `<Table>` primitive with hook-based state slices:
66
+ - `useTablePagination` — page + pageSize slice with unified
67
+ `onChange`, `resetPage`, `reset`.
68
+ - `useTableSelection` — row selection with single / multiple mode +
69
+ `toggle` / `select` / `deselect` / `clear` helpers.
70
+ - `useTableViews` — saved-view state for tabbed table headers;
71
+ optional localStorage persistence via `storageKey`.
72
+ - `useTableState` — versioned localStorage useState (storageKey,
73
+ version, migrate, custom storage adapter). The canonical
74
+ persistence helper — industry-standard pattern (TanStack / MRT /
75
+ MantineRT).
76
+ - `useDataTable` — composite-level config builder that threads the
77
+ slices into a typed instance ready for `<DataTable table={…}>`.
78
+ Exported from `@godxjp/ui` (hooks) and `@godxjp/ui/components/composites`
79
+ (composite). See [`docs/reference/composites/DataTable.md`](docs/reference/composites/DataTable.md)
80
+ and [`docs/how-to/migrate-to-data-table.md`](docs/how-to/migrate-to-data-table.md).
81
+ - **`<Pagination variant="embedded">`** — table-footer layout
82
+ (info + page-size changer + numeric pager with optional first / last
83
+ chevron buttons). Reused inside `<Table pagination=…>`. New props on
84
+ the existing `<Pagination>`: `defaultPageSize` / `onPageSizeChange`,
85
+ `pageSizeOptions`, `showSizeChanger`, `showFirstLast`,
86
+ `hideOnSinglePage`, `boundary`, `firstPageLabel` / `previousPageLabel`
87
+ / `nextPageLabel` / `lastPageLabel` / `pageSizeLabel`. Exported
88
+ helper `computePageRange(current, total, sibling, boundary)`.
89
+ - **i18n key `table.lastPage`** added to all four locales
90
+ (ja / en / vi / fil) for the new last-page button.
91
+ - **ADR-0006** documenting the Table primitive vs DataTable
92
+ composite split.
93
+
94
+ ### Changed
95
+
96
+ - **`<Table>` file split** — extracted types + ColumnMeta
97
+ augmentation into `Table.types.ts` and localStorage helpers into
98
+ `Table.persistence.ts`. Public API unchanged; existing
99
+ `from "@godxjp/ui"` imports of any Table-related symbol continue
100
+ to resolve. Source file dropped from 2,353 → 1,838 lines (~22%).
101
+ - **`<Pagination>` is now the single pagination primitive** —
102
+ the inline numbered renderer that lived inside `<Table>` is gone;
103
+ `<Table pagination={{ type: "numbered", … }}>` now renders
104
+ `<Pagination variant="embedded">` under the hood. Cardinal rule 32
105
+ (no redundant components) is now satisfied.
106
+ - **`.tbl-pagination` numbered styles** migrated to
107
+ `.pagination[data-variant="embedded"]` in `90-navigation.css`.
108
+ `.tbl-pagination` remains the layout wrapper for the load-more and
109
+ cursor pagination variants only.
110
+ - **Lucide icons** replace the inline SVG chevrons inside
111
+ `<Pagination>` (rule 14 — locked stack).
112
+ - **`<Select>` gained `searchable`** + `searchPlaceholder`, `emptyLabel`,
113
+ `loading`, `loadingLabel` props. When `searchable` is set the
114
+ primitive flips from Radix Select to a cmdk + Popover render tree
115
+ with a filter input above the list; value semantics stay constrained
116
+ to `options[i].value`.
117
+ - **Docs consolidation** — moved the five canonical specs from
118
+ `new-docs/` to `docs/specs/` so the framework ships ONE
119
+ documentation tree. The umbrella binding table, CLAUDE.md
120
+ trigger table, AGENTS.md routing table, and every doc /
121
+ story / source comment that referenced `new-docs/*` now
122
+ cite `docs/specs/*`. Pruned outdated `docs/explanation/`
123
+ pages (brand-bible, compatibility, versioning,
124
+ tokens-architecture) that duplicated specs/BRAND.md/CLAUDE.md.
125
+
126
+ ### Fixed
127
+
128
+ - **Tour spotlight cutout** — the target area now uses an SVG mask
129
+ cutout so the active element stays undimmed while the rest of the
130
+ viewport is subdued.
131
+ - **Tree React Aria foundation** — `Tree` now delegates ARIA tree
132
+ keyboard navigation, selection, expansion, and disabled state to
133
+ `react-aria-components` while preserving the single public `Tree`
134
+ primitive. Row content customization now goes through `renderItem`;
135
+ local row spacing uses the shared `density` vocabulary, and
136
+ connector lines are rendered from tree structure instead of guessed
137
+ from the flattened React Aria DOM.
138
+
139
+ ### Added
140
+
141
+ - **Table A5 — sort + resize** — `sort` accepts
142
+ `TableSort | TableSort[] | null`; shift-click on a sortable header
143
+ extends the multi-sort list and the header renders a numbered
144
+ priority badge (1 / 2 / 3) at the right edge. `resizable` enables
145
+ a 4px right-edge grip on each header; double-click auto-fits via
146
+ TanStack `column.resetSize()`.
147
+ - **Table A6 — expand row** — `expandable` adds a 32px first cell
148
+ with a ▶ toggle; the detail panel sits in a full-width row with
149
+ the canonical 3px primary left border. Exclusive by default;
150
+ `allowMultiple` keeps prior opens.
151
+ - **Table A7 — inline editing** — `editing` carries `rowId` (current
152
+ editing row), `dirtyRowIds` / `dirtyCellIds` (warning-dot
153
+ tracking), `renderEditCell`, `isRowReadOnly`, and a built-in
154
+ footer banner (`.tbl-footer[data-state="dirty"]`) with Save-all /
155
+ Cancel-all when any row is dirty. Confirmed rows are read-only
156
+ via `isRowReadOnly` — double-click is suppressed.
157
+ - **Table A8 — grouped + tree rows** — `groupBy` buckets rows by
158
+ key, emits a full-width `.group-row` header with title + count
159
+ badge + right-floated total. `tree.children` walks data
160
+ recursively, emitting 14px / level indent and a twirl button on
161
+ parent rows.
162
+ - **Table A9 — column-manager lock toggle** — the column-manager
163
+ Sheet renders a 🔒 / 🔓 button next to each row to pin / unpin
164
+ columns at runtime; changes fire through `onColumnPinningChange`
165
+ (TanStack-canonical `ColumnPinningState`).
166
+ - **Table A10 — pagination variants** — `TablePaginationVariantConfig`
167
+ discriminates on `type`: `numbered` (default + back-compat),
168
+ `load-more` (feed lists with `hasMore` + `onLoadMore`), and
169
+ `cursor` (time-series jump-to-month via `value` + `inputType`).
170
+ - **Table A11 — Import / Export composite** — new
171
+ `TableImportFlow` (4-step stepper + file card + error preview)
172
+ and `TableExportDialog` (format / range / hidden-column toggles)
173
+ in `@godxjp/ui/components/composites`. Separate from the Table
174
+ primitive per cardinal rule 32 (no redundant props on Table).
175
+ - **Table saved views** — `TableViewsConfig` now lets saved-view tabs
176
+ apply `filters`, `sort`, and `columnVisibility` snapshots while
177
+ keeping persistence in consumer state. The Table story opens a
178
+ naming dialog before saving and warns when another view already
179
+ has the same filters and column visibility. Views can opt into
180
+ deletion with `deletable` + `onDeleteView`, while built-in views
181
+ remain protected by default. `getTableViewsStorageKey` provides
182
+ the localStorage namespace next to column visibility.
183
+ - **`GodxConfigProvider` + format helpers** — canonical alias of
184
+ `PreferencesProvider` per ADR 0005. The provider now wraps
185
+ children in React Aria's `<I18nProvider>` so every date / time /
186
+ number primitive picks up the locale automatically. Three thin
187
+ helper files (`src/i18n/format.ts`, `src/i18n/relative.ts`,
188
+ `src/hooks/useFormatters.ts`) wrap native `Intl` APIs +
189
+ `@internationalized/date` values; no new runtime dependency. The
190
+ legacy `PreferencesProvider` / `usePreferences` names remain as
191
+ deprecated aliases until v4.0.0.
192
+ - **`currency` preference + `setCurrency`** — `Preferences.currency`
193
+ carries an ISO 4217 default for `formatCurrency()`. Persisted to
194
+ the same storage backend as locale / timezone.
195
+ - **Timeline `time` accepts temporal values** — `time` now takes
196
+ `Date | CalendarDate | CalendarDateTime | ZonedDateTime` (in
197
+ addition to `ReactNode`). The active provider's locale + timezone
198
+ format it via `useFormatters` per the new `timeFormat` prop
199
+ (`"relative" | "datetime" | "date" | "time"`, default
200
+ `"relative"` for `feed`, `"datetime"` elsewhere).
201
+ - **Separator labels** — horizontal `Separator` now accepts
202
+ `children`, `titlePlacement`, `orientationMargin`, and `variant`
203
+ for Ant Design-style labeled dividers, replacing manual Flex +
204
+ two-separator composition. Prop vocabulary docs and the
205
+ Storybook vocabulary catalogue now include those concepts.
206
+ - **Descriptions data API** — `Descriptions` now renders from
207
+ `items` and supports `renderItem` for custom rows. The
208
+ `Descriptions.Item` sub-component shape was removed so consumers
209
+ use one component consistently.
210
+ - **Table data API** — `Table` is now a single-component TanStack
211
+ Table wrapper. Legacy table subcomponent exports were removed
212
+ from the public surface; use `columns`, `data`, `ColumnDef.cell`,
213
+ and the `toolbar` prop.
214
+ - **Statistic loading + animation** — `loading` renders skeleton
215
+ placeholders with `aria-busy`, while `animated` /
216
+ `animationDuration` count finite numeric values from zero /
217
+ previous value and respect `prefers-reduced-motion`.
218
+ - **Cardinal rule 32 — no redundant props.** A new top-level prop /
219
+ item field / variant is rejected at review if an existing prop /
220
+ item field / variant already covers the use case. Lifted from the
221
+ Timeline `pending` audit; future PRs must justify every new prop
222
+ against the existing surface.
223
+ - **Timeline `connector` prop** — `boolean`, default `true`. Toggles
224
+ the vertical line that joins markers in `list` + `branching`
225
+ variants. `feed` variant has no connector by design.
226
+ - **Timeline per-item `animate` field** — `TimelineItem.animate:
227
+ boolean` adds a pulsing ring around the marker dot for that single
228
+ item, replacing the previous top-level `animate` Timeline-level
229
+ prop (now removed — animate is a per-item concept). Honours
230
+ `prefers-reduced-motion`.
231
+ - **Storybook test gate** — `@storybook/addon-vitest` wired with
232
+ Playwright (browser-mode Chromium) so every `play()` runs as a
233
+ Vitest test. `pnpm test:stories` → 419 tests / 89 files / ~7s.
234
+ Interactive primitives now ship with regression-pinned focus, click,
235
+ hover, type, open/close flows (PR #18 + extended in #19, #20).
236
+ - **Code panel default on Story view** — `@storybook/addon-docs`
237
+ `parameters.docs.codePanel: true` so consumers see runnable JSX
238
+ beside Controls / Actions / Interactions without click-through.
239
+ - **Actions panel auto-spy** — `parameters.actions.argTypesRegex:
240
+ "^on[A-Z].*"` logs every `on*` callback invocation globally.
241
+ - **Cardinal rule 30** — story `render` must return JSX directly. No
242
+ `<XyzDemo />` wrapper components, no parameterised helpers. Storybook
243
+ source view stays copy-pasteable.
244
+ - **Parity scripts + pre-commit gate** —
245
+ `scripts/check-stories-parity.mjs` (rule 17) +
246
+ `scripts/check-docs-parity.mjs` (rule 18). Husky pre-commit runs
247
+ `lint:tokens` + both parity checks + `sync:skills` + `type-check`
248
+ in ~5s; CI re-runs them on push.
249
+ - **DatePicker stories** — `Placeholder`, `Granularity_DateTime`
250
+ (hour / minute via `granularity` + `hourCycle`), `MinMaxConstrained`,
251
+ `Format_Locales` (ja-JP / en-US / de-DE segment order via
252
+ `I18nProvider`).
253
+ - **`Select` `options` prop** — Ant / MUI / Mantine canonical
254
+ data-driven API. `<Select options={[{value,label}]} />`. Children
255
+ API remains for advanced layouts (groups / dividers / custom item
256
+ rendering).
257
+ - **40 reference doc stubs** — `docs/reference/<group>/<Name>.md`
258
+ draft scaffold for the previously undocumented primitives (Flex,
259
+ Form, Transfer, Field, LocaleTabs, Checklist, Spinner, IconButton,
260
+ PageHeader, SegmentedControl, Statistic, Empty, Tag, Alert, Result,
261
+ Typography, Descriptions, Radio, Slider, Watermark, Popconfirm,
262
+ Anchor, Menu, Pagination, Steps, Progress, DatePicker,
263
+ AutoComplete, Cascader, Tree, ColorPicker, Rate, Carousel, Collapse,
264
+ List, Image, QRCode, Tooltip, Timeline, Tour). `check:docs-parity`
265
+ now exits clean at 63/63.
266
+
267
+ ### Fixed
268
+
269
+ - **Separator vertical styling** — vertical separators now render via
270
+ `.divider-vertical` instead of inline style, so Card divider stories
271
+ can compose the Separator primitive without raw `<hr>` elements.
272
+ - **Skeleton default animation** — ported Ant Design's active
273
+ skeleton gradient pattern (`25% / 37% / 63%`, `400% 100%`,
274
+ `1.4s ease`) to godx tokens, with reduced-motion fallback.
275
+ - **Skeleton shape atoms** — `.sk-line` / `.sk-block` now have
276
+ explicit full-width defaults and `.sk-circle` keeps its 34px
277
+ width in flex rows, fixing list/table loading stories.
278
+ - **Sidebar collapsed labels** — collapsed mode now omits nav label
279
+ and badge nodes from the DOM while preserving `aria-label` /
280
+ `title`, so standalone Sidebar stories cannot leak clipped text
281
+ when the wrapper selector changes.
282
+ - **SegmentedControl WAI-ARIA roving-tabindex** — radiogroup now ships
283
+ the APG-compliant keyboard pattern: only the active radio carries
284
+ `tabIndex={0}`; Arrow keys (Left/Right or Up/Down per the new
285
+ `orientation` prop) move focus + selection; Home / End jump to
286
+ first / last enabled item; disabled items are skipped. Root reflects
287
+ `aria-orientation`. Replaces the previous native-Tab-order fallback
288
+ that the docs claimed but didn't implement.
289
+ - **IconButton accessible-name warn** — dev-mode `console.warn` when
290
+ none of `aria-label` / `aria-labelledby` / `title` is supplied
291
+ (`process.env.NODE_ENV !== "production"` only — production bundles
292
+ strip the check). Catches the most common a11y regression on
293
+ icon-only controls without forcing a breaking TS signature.
294
+ - **Tooltip nested-provider double-wrap** — data-driven `<Tooltip>`
295
+ detects an ancestor `<TooltipProvider>` (via a private React
296
+ marker context the framework's Provider populates) and skips its
297
+ inner Provider so the outer `delayDuration` / other Provider
298
+ config is no longer silently overridden. Falls back to the
299
+ previous double-wrap when the ancestor is Radix's Provider imported
300
+ directly (not the framework's re-export) — documented in the
301
+ Tooltip reference doc.
302
+ - **AutoComplete focus closing the dropdown** —
303
+ `onFocusOutside={preventDefault}` so opening on focus survives the
304
+ focus-leaves-anchor lifecycle.
305
+ - **AutoComplete label vs value** — input shows the selected option's
306
+ `label`; `onValueChange` reports the option's `value` (Ant / shadcn
307
+ convention).
308
+ - **`<List>` and `<Menu>` nested `<li>`** — `List` renderItem no
309
+ longer wraps in an extra `<li>`; `Menu` switched from
310
+ `<li role="none">` to `<div role="group">` (ARIA-compliant).
311
+ - **`Collapse` Tailwind utility collision** — root class renamed
312
+ `.collapse` → `.collapse-root` so Tailwind v4's
313
+ `.collapse { visibility: collapse }` utility no longer hides the
314
+ subtree.
315
+ - **Carousel vertical** — `height: 100%` cascades through `.carousel`
316
+ / `-viewport` / `-track`, clipping to one slide at a time.
317
+ - **Card banner double-border + radius** (B3 / C1) — `.ph.striped`
318
+ resets the inherited `.ph` chrome (border / radius / margin-bottom).
319
+ - **Card B3 stats footer** — uses `.card-footer-block` primitive class
320
+ instead of inline `borderTop` + manual padding.
321
+ - **Card H8 tabs underline rounding** — `<button>` instead of
322
+ `<Button>` for tab elements + `border-radius: 0` explicit on
323
+ `.card-header-tabs .tab` so an accidental `<Button>` doesn't
324
+ contaminate the underline.
325
+ - **Card H13 / H14 / H17 stories** — `<div className="card-body-block">` /
326
+ `<Card footer block>` sub-component pattern instead of raw
327
+ `<div className="card-body">` (rule 29).
328
+ - **Card H17 sticky-shadow scroll** — `max-height: 140 + overflow-y:
329
+ auto` instead of `height: 80 + overflow: hidden` so the story
330
+ actually demonstrates scrolling.
331
+ - **Descriptions bordered title overflow** — gap-as-border trick (1px
332
+ body bg) so the outer frame wraps the body only, title sits above.
333
+ - **Checkbox + Radio sizing** — 1rem (16px @ base) matching
334
+ shadcn / Ant / Tailwind canon, not the density-element scale
335
+ intended for full-height controls.
336
+ - **Checkbox glyph stroke** — `strokeWidth=3` +
337
+ `absoluteStrokeWidth` so the check / minus glyphs read at 12px.
338
+ - **Image fallback visible** — fills wrapper 100% with secondary bg
339
+ - border instead of 64×64 inline-flex chip against near-white body.
340
+ - **PageHeader `padding` prop** — vocabulary aligned with Card per
341
+ rule 23 §B (`tight` / `default` / `cozy` / `none`). Stacked variant
342
+ releases the fixed `--header-height` so breadcrumb + title get
343
+ vertical room.
344
+ - **Slider / InputSearch / Textarea controlled-uncontrolled props** —
345
+ conditional spread so the inner `<input>` never receives both
346
+ `value` and `defaultValue`.
347
+ - **TweaksPanel Dialog a11y** — `aria-describedby={undefined}` on
348
+ `Dialog.Content` since the panel doesn't use `Dialog.Description`.
349
+ - **Drawer Left story** — added `<DrawerDescription>` for a11y.
350
+ - **Sidebar collapsed text overflow** — CSS selectors broadened from
351
+ `.app-root[data-collapsed]` to `[data-collapsed]`, and Sidebar
352
+ wraps children in `<div data-collapsed style="display: contents">`
353
+ so the collapsed-state rules apply in both AppShell and standalone
354
+ contexts.
355
+ - **Storybook Docs source chip rendering** — `preview.css` forces
356
+ `.prismjs .token { display: inline; border: 0 }` to defeat
357
+ Storybook 10's per-token-pill style; consumers now see plain
358
+ syntax-highlighted JSX.
359
+ - **Storybook Docs canvas height** — `.sb-stage` no longer
360
+ `min-height: 100vh` so each story preview shrinks to content
361
+ instead of 707px frames.
362
+ - **Build warnings** — removed broken `banner: { js: '"use client"' }`
363
+ from `tsup.config.ts` (never reached output, only produced 7×
364
+ "module-level directive ignored" warnings per build). Posture now
365
+ matches MUI / Radix / shadcn (consumers mark App Router boundary
366
+ themselves).
367
+
368
+ ### Changed
369
+
370
+ - **Card story display names** — stripped section-code prefixes
371
+ (`A1·`, `B3·`, `H13·`, etc.) from 50 `name:` fields. URL slug
372
+ (const name) still carries the code for dev reference.
373
+ - **Story render demos inlined** — sweep of 14 stories in
374
+ `data-entry/` that wrapped their body in `<XyzDemo />` (DefaultDemo
375
+ / ControlledDemo / ValidatedDemo / PrefectureDemo / etc.) — bodies
376
+ now inline in `render: function StoryName() {…}` so Storybook's
377
+ dynamic source shows real JSX. `<ExampleForm disabled />` exemption
378
+ also removed.
379
+ - **`Card.stories.tsx` raw card-body / card-footer divs** —
380
+ ~27 occurrences replaced with `<div className="card-body-block">` / `<Card footer
381
+ block>` React sub-components per rule 29.
382
+ - **`docs.source.type`** — `"dynamic"` (was `"code"`) so the source
383
+ view renders the JSX, not the wrapping story object.
384
+ - **`docs.canvas.sourceState`** — `"hidden"` (was attempted `"shown"`)
385
+ so the Docs view doesn't auto-expand every story's source
386
+ (bloated 5-story pages to thousands of px).
387
+
388
+ ### Removed
389
+
390
+ - **Dialog legacy compositional API** — removed the multi-part modal
391
+ surface. `Dialog` is now the single public component with `trigger`,
392
+ `title`, `description`, `children`, `footer`, and optional `form`
393
+ props.
394
+ - **`Timeline pending` prop** — removed. The trailing "ongoing"
395
+ marker is now expressed as a regular item with
396
+ `{ animate: true, color: "primary", title: "…" }`. Per cardinal
397
+ rule 32 (no redundant props), a separate top-level prop was a
398
+ duplicate of the items-array shape.
399
+ - **`Timeline animate` Timeline-level prop** — removed. `animate`
400
+ is a per-item concept: set `items[i].animate = true` on the items
401
+ that should pulse. The previous Timeline-level prop animated only
402
+ the `current` item, which couldn't express trailing-pending
403
+ markers or multi-item indication.
404
+ - **`docs/reference/primitives` advisory drift** — 40 stubs landed,
405
+ parity now strict at 63/63.
406
+ - **`<Step color>` prop + `StepColor` type** — the prop was declared
407
+ but never read; per-step state is locked to the dxs-kintai canon
408
+ (`done` → `--success`, `cur` → `--primary`, future → `--muted-foreground`)
409
+ and not overridable. Consumers needing per-event colour should use
410
+ `<Timeline>` instead. No release migration needed — the prop had no
411
+ runtime effect.
412
+
413
+ ## [3.0.0] — 2026-05-16
414
+
415
+ `@godxjp/ui` v3 is a clean-break major that fulfils the **zero-config professional
416
+ framework** promise described in the umbrella's frontend-architecture spec. Services
417
+ upgrading from 2.x gain a complete toolchain preset and a fourth mandatory locale
418
+ (`fil`) with no API removals beyond the deprecated symbol renames below.
419
+
420
+ ### Added
421
+
422
+ - **Filipino (`fil`) locale** — `src/i18n/locales/fil.ts`. Full key parity with
423
+ `ja`. Mandatory per the umbrella frontend-architecture spec §6 (all four
424
+ locales: `ja`, `en`, `vi`, `fil`).
425
+ - **`GodxLocale` type** — replaces the Forge-branded `ForgeLocale`. Both are
426
+ exported; `ForgeLocale` is `@deprecated` but still resolves to the same type so
427
+ existing consumers compile without changes.
428
+ - **`GODX_LOCALE_STORAGE_KEY`** — replaces `FORGE_LOCALE_STORAGE_KEY`. Old name
429
+ re-exported as deprecated alias.
430
+ - **Zero-config toolchain presets** under `config/` — consumed via sub-path exports:
431
+ - `@godxjp/ui/eslint-config` → ESLint 9 flat config (typescript-eslint strict,
432
+ jsx-a11y, react-hooks rules). Service `eslint.config.js` = one line.
433
+ - `@godxjp/ui/prettier-config` → Prettier 3 config. Service `.prettierrc` = one
434
+ string.
435
+ - `@godxjp/ui/tsconfig` → TypeScript 6 strict base (`exactOptionalPropertyTypes`,
436
+ `noUncheckedIndexedAccess`, `verbatimModuleSyntax`).
437
+ - `@godxjp/ui/vitest-config` → Vitest 4 base with `jsdom` + 75%/70% coverage
438
+ thresholds.
439
+ - **Vitest test runner** added to devDependencies. `pnpm test` now works in the
440
+ package itself.
441
+ - **Locale parity smoke test** at `src/i18n/__tests__/locales.test.ts` — ensures
442
+ every key in `ja` is present in `en`, `vi`, and `fil` (test ID: GDXUI-I-LOCALE-001).
443
+ - **`ForgeProduct.tenant` type broadened** from a closed literal union to `string`
444
+ — makes the framework deployable by operators who define their own tenant slugs
445
+ without forking the package. The four built-in PRODUCTS fixtures remain unchanged.
446
+
447
+ ### Changed
448
+
449
+ - **package.json `description`** updated from Forge-specific wording to generic
450
+ professional framework copy.
451
+ - **`useTweaks` storage key** changed from `"forge.tweaks"` to `"godx.tweaks"`.
452
+ On first load after upgrade, the stored tweaks key is not found and falls back
453
+ to defaults (density/theme/tenant reset to defaults). User-visible tweaks
454
+ (density, theme, tenant) persist again on next save.
455
+ - **`initI18n` detection key** changed from `"forge.locale"` to `"godx.locale"`.
456
+ User locale preference is reset to browser/navigator default on first load after
457
+ upgrade. User re-selects locale via TweaksPanel and it persists under new key.
458
+ - **README** rewritten as professional framework intro (≥300 words) with import
459
+ surface table, primitives table with a11y column, adoption tracker, zero-config
460
+ quick start, and npm/license/types badges.
461
+ - **`sideEffects`** in `package.json` already `["**/*.css"]` — confirmed correct.
462
+ JS entries remain tree-shakable.
463
+
464
+ ### Deprecated
465
+
466
+ - `ForgeLocale` — use `GodxLocale`. Will be removed in v4.
467
+ - `FORGE_LOCALE_STORAGE_KEY` — use `GODX_LOCALE_STORAGE_KEY`. Will be removed in v4.
468
+
469
+ ### Migration guide (2.x → 3.0.0)
470
+
471
+ 1. **Locale storage key reset (non-breaking but visible):** The first page load
472
+ after upgrade will not find the old `"forge.tweaks"` key and will reset tweaks
473
+ to defaults. This is a one-time reset; the user re-selects density/theme/tenant
474
+ once and the new key persists.
475
+
476
+ 2. **`ForgeLocale` → `GodxLocale`:** No compile error — `ForgeLocale` still
477
+ exports. Update to `GodxLocale` at your own pace; it will be removed in v4.
478
+ Search and replace: `ForgeLocale` → `GodxLocale`.
479
+
480
+ 3. **`FORGE_LOCALE_STORAGE_KEY` → `GODX_LOCALE_STORAGE_KEY`:** Same pattern.
481
+ The old name still re-exports the same string constant.
482
+
483
+ 4. **Add `fil` locale to service `addResourceBundle` calls:** If your service
484
+ uses `i18n.addResourceBundle(locale, "my-ns", {…})` for all four locales,
485
+ add `fil`. Missing `addResourceBundle` calls for `fil` produce a silent fallback
486
+ to the base `fil` dictionary; no crash.
487
+
488
+ 5. **Zero-config toolchain (optional, strongly recommended):**
489
+ Adopt the new preset exports to reduce per-service boilerplate:
490
+
491
+ ```bash
492
+ # eslint.config.js — replace existing content with:
493
+ # export { default } from "@godxjp/ui/eslint-config"
494
+ #
495
+ # .prettierrc.json — replace with:
496
+ # "@godxjp/ui/prettier-config"
497
+ #
498
+ # tsconfig.json — extend:
499
+ # { "extends": "@godxjp/ui/tsconfig", "compilerOptions": { "paths": {...} } }
500
+ ```
501
+
502
+ 6. **`ForgeProduct.tenant` type:** If you were using the closed literal union
503
+ `"godx" | "kintai" | "tempo" | "betoya" | "restaurant"` for type narrowing,
504
+ the type is now `string`. Add your own type guard if needed:
505
+ ```ts
506
+ const KNOWN_TENANTS = ["godx", "kintai", "tempo", "betoya"] as const;
507
+ type KnownTenant = (typeof KNOWN_TENANTS)[number];
508
+ function isKnownTenant(t: string): t is KnownTenant {
509
+ return KNOWN_TENANTS.includes(t as KnownTenant);
510
+ }
511
+ ```
512
+
513
+ ## [2.4.0] — 2026-05-16
514
+
515
+ ### Added
516
+
517
+ - **Toaster** + **`toast`** — thin wrapper around `sonner` with token
518
+ class names (default `unstyled` so chrome comes from `.toast*` in
519
+ `tokens.css`). Optional **`@godxjp/ui/sonner.css`** import (after
520
+ tokens) pulls in sonner’s stacking / motion stylesheet and resets
521
+ toaster `font-family` to inherit.
522
+ - New `.combobox-*` atoms in `tokens.css` (filter list / item / empty
523
+ styles shared by `AutoComplete`, `Cascader`, `TreeSelect`).
524
+ - Dependency: **`sonner`** (`cmdk` already present).
525
+
526
+ ## [2.3.0] — 2026-05-16
527
+
528
+ ### Added
529
+
530
+ - **Dialog** family — Radix Dialog + `.dialog-*` in `tokens.css`.
531
+ - **Sheet** family (Radix Dialog; `Sheet` with `side` + `.sheet-*`
532
+ animation tokens).
533
+ - **AlertDialog** family (`AlertDialog*`, `AlertDialog` / `Cancel`
534
+ use `.btn` / `.btn-primary` / `.btn-secondary`).
535
+ - **Select** family (`Select*`, `SelectPortal`, scroll buttons, separator).
536
+ - **Switch**, **Checkbox** (Radix) with `.switch-*` / `.checkbox-*`.
537
+ - **Table** data display primitive using the `.table` atom.
538
+ - Dependencies: `@radix-ui/react-alert-dialog`, `@radix-ui/react-checkbox`.
539
+
540
+ ### Fixed
541
+
542
+ - Removed invalid `composes:` from `.popover-content` in `tokens.css`
543
+ (plain CSS does not support CSS-modules `composes`).
544
+
6
545
  ## [2.1.0] — 2026-05-13
7
546
 
8
547
  ### Added
9
- - **Popover** primitive (`Popover`, `PopoverTrigger`, `PopoverContent`,
10
- `PopoverAnchor`) wrapping `@radix-ui/react-popover`. Visual contract
548
+
549
+ - **Popover** primitive (`Popover`, `Popover`, `Popover`,
550
+ `Popover`) wrapping `@radix-ui/react-popover`. Visual contract
11
551
  in the new `.popover-content` class in `tokens.css` — brand-tokenised
12
552
  surface (`--popover`), border, and elevation.
13
- - **DropdownMenu** primitive (`DropdownMenu`, `DropdownMenuTrigger`,
14
- `DropdownMenuContent`, `DropdownMenuItem`, `DropdownMenuSeparator`,
15
- `DropdownMenuLabel`, `DropdownMenuShortcut`, `DropdownMenuGroup`,
16
- `DropdownMenuPortal`, `DropdownMenuSub`, `DropdownMenuRadioGroup`)
17
- wrapping `@radix-ui/react-dropdown-menu`. `<DropdownMenuItem>`
553
+ - **DropdownMenu** primitive (`DropdownMenu`, `DropdownMenu`,
554
+ `DropdownMenu`, `DropdownMenu`, `DropdownMenu`,
555
+ `DropdownMenu`, `DropdownMenu`, `DropdownMenu`,
556
+ `DropdownMenu`, `DropdownMenu`, `DropdownMenu`)
557
+ wrapping `@radix-ui/react-dropdown-menu`. `<DropdownMenu>`
18
558
  supports `variant="destructive"` + `inset` matching the public v0.2
19
559
  surface so call sites migrate by dep bump only.
20
560
  - **Calendar** primitive — `react-day-picker` themed via the new
@@ -29,6 +569,7 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
29
569
  - `react-day-picker` added as a dependency.
30
570
 
31
571
  ### Notes
572
+
32
573
  - This release fills the gap that blocked
33
574
  `services/forge-service/frontend/` from migrating off the public
34
575
  TempoFast `@godxjp/ui@0.2.0`. After 2.1.0 every primitive forge
@@ -57,6 +598,7 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
57
598
  ### Added
58
599
 
59
600
  ### Added
601
+
60
602
  - **BRAND.md** — the brand bible (locked 2026-05-13 from Claude Design
61
603
  handoff bundle). Spells out the 渋み / 間 / 簡素 design philosophy
62
604
  and lists the forbidden patterns reviewers reject.
@@ -65,14 +607,15 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
65
607
  - **`design/godx-admin-2026-05-13.tar.gz`** — original archive from
66
608
  `api.anthropic.com/v1/design/h/7Ya1OxEEfiaI2SWojzuP9A`. Kept so the
67
609
  brand can be re-extracted on any fresh checkout.
68
- - **Atomic primitives**: `Badge`, `Button`, `Card` (+ `CardHeader`,
69
- `CardTitle`, `CardSubtitle`, `CardContent`), `Input`, `Textarea`,
70
- `Label`, `Tabs` (+ `TabsList`, `TabsTrigger`, `TabsContent`),
610
+ - **Atomic primitives**: `Badge`, `Button`, `Card` (+ `Card header`,
611
+ `Card title`, `Card subtitle`, `Card content`), `Input`, `Textarea`,
612
+ `Label`, `Tabs` (+ `Tabs`, `Tabs`, `Tabs`),
71
613
  `Avatar`, `Separator`. Each maps onto a canonical CSS class from
72
614
  `tokens.css` — no Tailwind utility re-encoding.
73
615
  - **`./components/primitives` export path** for explicit imports.
74
616
 
75
617
  ### Changed
618
+
76
619
  - **`tokens.css` is now the single CSS entry point.** The handoff's
77
620
  `tokens.css` + `tokens-ext.css` were merged so consumers do one
78
621
  import (`@godxjp/ui/tokens`). The split is preserved verbatim under
@@ -85,6 +628,7 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
85
628
  consumers can `import { Badge, Button } from "@godxjp/ui"`.
86
629
 
87
630
  ### Removed
631
+
88
632
  - `src/tokens/tokens-ext.css` (merged into `tokens.css`).
89
633
  - `src/tokens/index.css` (no longer needed — `tokens.css` is the entry).
90
634