@vantageos/mosaic 0.3.0-alpha.1 → 0.3.1

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 (97) hide show
  1. package/CHANGELOG.md +175 -0
  2. package/README.md +12 -0
  3. package/dist/{Alert.schema-BQsZGG6P.d.cts → Alert.schema-LPJE5gFP.d.cts} +31 -1
  4. package/dist/{Alert.schema-BQsZGG6P.d.ts → Alert.schema-LPJE5gFP.d.ts} +31 -1
  5. package/dist/MarkdownRenderer.schema-Rx7kIeVA.d.cts +22 -0
  6. package/dist/MarkdownRenderer.schema-Rx7kIeVA.d.ts +22 -0
  7. package/dist/ProgressBar.schema-CdVYx0Wq.d.cts +22 -0
  8. package/dist/ProgressBar.schema-CdVYx0Wq.d.ts +22 -0
  9. package/dist/StatusBadge.schema-1tOjB4Ir.d.cts +22 -0
  10. package/dist/StatusBadge.schema-1tOjB4Ir.d.ts +22 -0
  11. package/dist/artifacts.cjs +126 -2
  12. package/dist/artifacts.cjs.map +1 -1
  13. package/dist/artifacts.d.cts +3 -21
  14. package/dist/artifacts.d.ts +3 -21
  15. package/dist/artifacts.js +126 -2
  16. package/dist/artifacts.js.map +1 -1
  17. package/dist/confirmation.cjs +126 -2
  18. package/dist/confirmation.cjs.map +1 -1
  19. package/dist/confirmation.d.cts +3 -32
  20. package/dist/confirmation.d.ts +3 -32
  21. package/dist/confirmation.js +126 -2
  22. package/dist/confirmation.js.map +1 -1
  23. package/dist/display.cjs +129 -2
  24. package/dist/display.cjs.map +1 -1
  25. package/dist/display.d.cts +132 -2
  26. package/dist/display.d.ts +132 -2
  27. package/dist/display.js +129 -2
  28. package/dist/display.js.map +1 -1
  29. package/dist/forms.cjs +20 -17
  30. package/dist/forms.cjs.map +1 -1
  31. package/dist/forms.js +20 -17
  32. package/dist/forms.js.map +1 -1
  33. package/dist/index.cjs +129 -2
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +9 -7
  36. package/dist/index.d.ts +9 -7
  37. package/dist/index.js +129 -2
  38. package/dist/index.js.map +1 -1
  39. package/dist/media.cjs +126 -2
  40. package/dist/media.cjs.map +1 -1
  41. package/dist/media.d.cts +3 -21
  42. package/dist/media.d.ts +3 -21
  43. package/dist/media.js +126 -2
  44. package/dist/media.js.map +1 -1
  45. package/dist/preact/artifacts.d.ts +39 -1
  46. package/dist/preact/artifacts.js +234 -0
  47. package/dist/preact/artifacts.js.map +1 -1
  48. package/dist/preact/confirmation.d.ts +31 -1
  49. package/dist/preact/confirmation.js +245 -5
  50. package/dist/preact/confirmation.js.map +1 -1
  51. package/dist/preact/display.d.ts +127 -1
  52. package/dist/preact/display.js +419 -11
  53. package/dist/preact/display.js.map +1 -1
  54. package/dist/preact/forms.js +22 -19
  55. package/dist/preact/forms.js.map +1 -1
  56. package/dist/preact/input.js +2 -2
  57. package/dist/preact/progress.d.ts +35 -1
  58. package/dist/preact/progress.js +263 -0
  59. package/dist/preact/progress.js.map +1 -1
  60. package/dist/progress.cjs +126 -2
  61. package/dist/progress.cjs.map +1 -1
  62. package/dist/progress.d.cts +3 -21
  63. package/dist/progress.d.ts +3 -21
  64. package/dist/progress.js +126 -2
  65. package/dist/progress.js.map +1 -1
  66. package/dist/react/artifacts.cjs +241 -0
  67. package/dist/react/artifacts.cjs.map +1 -1
  68. package/dist/react/artifacts.d.cts +20 -1
  69. package/dist/react/artifacts.d.ts +20 -1
  70. package/dist/react/artifacts.js +234 -0
  71. package/dist/react/artifacts.js.map +1 -1
  72. package/dist/react/confirmation.cjs +248 -2
  73. package/dist/react/confirmation.cjs.map +1 -1
  74. package/dist/react/confirmation.d.cts +3 -3
  75. package/dist/react/confirmation.d.ts +3 -3
  76. package/dist/react/confirmation.js +244 -4
  77. package/dist/react/confirmation.js.map +1 -1
  78. package/dist/react/display.cjs +418 -2
  79. package/dist/react/display.cjs.map +1 -1
  80. package/dist/react/display.d.cts +20 -3
  81. package/dist/react/display.d.ts +20 -3
  82. package/dist/react/display.js +413 -4
  83. package/dist/react/display.js.map +1 -1
  84. package/dist/react/forms.cjs +20 -17
  85. package/dist/react/forms.cjs.map +1 -1
  86. package/dist/react/forms.js +20 -17
  87. package/dist/react/forms.js.map +1 -1
  88. package/dist/react/progress.cjs +266 -0
  89. package/dist/react/progress.cjs.map +1 -1
  90. package/dist/react/progress.d.cts +17 -1
  91. package/dist/react/progress.d.ts +17 -1
  92. package/dist/react/progress.js +263 -0
  93. package/dist/react/progress.js.map +1 -1
  94. package/package.json +231 -228
  95. package/registry.yaml +34 -21
  96. package/dist/Skeleton.schema-BO0ca2UX.d.cts +0 -135
  97. package/dist/Skeleton.schema-BO0ca2UX.d.ts +0 -135
package/CHANGELOG.md ADDED
@@ -0,0 +1,175 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@vantageos/mosaic` are documented in this file.
4
+
5
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
+ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ---
9
+
10
+ ## [Unreleased]
11
+
12
+ ### Added
13
+ - **D-PR1 — Pre-publish dry-run evidence for v0.3.0 GA.** New doc `docs/D-PR1-PRE-PUBLISH-DRY-RUN-V0.3.0.md` (bilingual EN+FR) capturing the hard-evidence pre-publish gate run in a fresh sandbox worktree off `origin/main` @ `7ae5450`: sandbox build-pass (RULE #19, `SANDBOX_BUILD_PASS_ID=7ae5450`, build exit 0), Gate 1 build-parity (exit 0), `npm pack --dry-run` (150 files / 511.8 kB / unpacked 3.0 MB / version 0.3.0 / sha `31caed2f`, CHANGELOG + README + package.json + registry.yaml + full `dist/` surface present — **no real publish**), corrected vendored cross-runtime subpath coverage gate (`--ga-mode`, exit 0, 0 missing), and the full gate set re-run green (tsc, biome, vitest 854, playwright-axe 29, size-limit, registry-drift, storybook-test 103, Gate 2 peer-resolution, Gate 3 coherence 10). Documents the **D-T1 blocker**: the canonical B-PR1 skill / B-PR2 publish hook carry a category-prefixed layout defect (`./forms/react`) vs Mosaic's runtime-prefixed layout (`./react/forms`) and **false-block** the real publish — must be fixed before `tag v0.3.0` (Sigma task `k176e5rpz`); plus `ETA_APPROVED_TASK_ID` must be set after Eta approval. Mission `k57b6d1b` · task `k177e1wr`. No source/build/gate code changed — docs-only.
14
+ - **CI Gate 4 — Cross-runtime subpath coverage (B-PR3).** New fail-fast CI gate asserting that **every bare component category** in `packages/mosaic/package.json` `exports` (`./forms`, `./progress`, `./display`, `./artifacts`, `./confirmation`, `./media`, `./input`) also exports a **non-empty** `dist` artifact under **both** `./react/<cat>` and `./preact/<cat>`. This is the gate that would have caught the original v0.3.0 GA blocker (foundation components present as bare exports but missing/empty under `/react` + `/preact`).
15
+ - New vendored script `packages/mosaic/scripts/cross-runtime-subpath-coverage-check.py` — vendored from the canonical B-PR1 skill `mosaic-cross-runtime-subpath-coverage-check` (VantageRegistry; PR #20). Stdlib-only, with an optional PyYAML registry cross-check that degrades gracefully when PyYAML is absent (no Python dependency added to CI). Carries one documented deviation: a `RUNTIME_PREFIXED` toggle adapting the canonical category-prefixed layout (`./forms/react`) to this repo's runtime-prefixed layout (`./react/forms`).
16
+ - New job `cross-runtime-subpath-coverage` (`needs: build-parity-cross-runtime`) builds tokens + mosaic so `dist/` exists, then runs `python3 .../cross-runtime-subpath-coverage-check.py --package-root packages/mosaic --ga-mode` (exit 1 fails CI with a `component × runtime` diagnostic). CI-side equivalent of the B-PR2 npm-publish hook.
17
+ - New doc `docs/CROSS-RUNTIME-GATE.md` (bilingual EN+FR). Additive change — no existing gate (Gate 1 build-parity, Gate 2 peerDeps smoke, Gate 3 coherence, `ci` job) weakened or replaced. Mission `k57b6d1b` · task `k176pzsszyy4v3f505khwg33gx88j36n`.
18
+ - Wave 3 components TBD (DatePicker, Avatar, FilterChip, Pagination — demand-driven T21+).
19
+
20
+ ### Fixed
21
+ - CI Gate 2 (PeerDeps optionality smoke) now runs GREEN (unblocks v0.3.0 GA publish gate). Two layered bugs, both packaging-scope:
22
+ - **Build (tsup):** the preact runtime bundles that re-export the shared React implementation (`preact/progress`, `preact/input`, `preact/confirmation`, `preact/forms`) shipped `import … from "react/jsx-runtime"` and `import … from "react"`. `esbuildOptions.alias` (`react → preact/compat`) never fired because tsup auto-externalises peerDeps (`react`, `react/jsx-runtime`) *before* alias resolution, so the alias was a no-op for those specifiers. A react-only consumer (which has react) could therefore resolve `@vantageos/mosaic/preact/*` even with preact absent — optionality broken in both directions. Fix: replaced the alias with an esbuild `onResolve` plugin (`mosaic-react-to-preact`) that deterministically rewrites the whole react family (`react`, `react-dom`, `react-dom/client`, `react/jsx-runtime`, `react/jsx-dev-runtime`) to their preact equivalents and marks them external; paired with `noExternal: [/^react…/]` on the preact pass so tsup's own external plugin returns undefined for the react family and lets the rewrite run. Added `preact/jsx-runtime` to `PREACT_EXTERNAL`. Preact bundles now import only preact specifiers; react bundles unchanged.
23
+ - **Smoke fixture (run-smoke.sh):** the fixtures installed mosaic via `npm install file:../../../packages/mosaic`, which npm symlinks into the monorepo source tree; Node then resolved the bundle's runtime imports by climbing out of the fixture into the monorepo root `node_modules` (where both react and preact are hoisted devDeps), producing a false PASS. Rewrote the driver to model a real npm consumer faithfully: `pnpm pack` both packages (rewriting the `workspace:*` tokens dep to a concrete version) and install the tarballs into an isolated `mktemp -d` consumer outside the repo tree, with `--legacy-peer-deps` so npm does not auto-install the *transitive* peer react pulled by `@tanstack/react-virtual` into a preact-only consumer. Fixture assertions (`index.mjs`) untouched. Smoke now PASSES: react-only resolves `react/*` and fails `preact/*`; preact-only resolves `preact/*` and fails `react/*`.
24
+ - CI `biome check --error-on-warnings` now exits 0 on `main` (unblocks v0.3.0 GA publish gate): suppressed 6 `noNonNullAssertion` lint errors in VirtualList tests (React + Preact) with justified `biome-ignore` comments matching repo convention, plus format/organizeImports auto-fixes across 7 files.
25
+ - `forms/Select.tsx` (React + Preact) biome a11y gate: replaced the blanket `biome.json` per-file rule override with scoped, justified `biome-ignore` comments on exactly the 6 flagged ARIA roles per runtime (`useSemanticElements` on the `combobox`/`listbox`/`option` roles, `noNoninteractiveElementToInteractiveRole` on `ul`→`listbox` + `li`→`option`, `useFocusableInteractive` on the `li`). These are biome heuristic false-positives on the WAI-ARIA APG combobox + listbox pattern (options managed via `aria-activedescendant`, intentionally not in the tab order). Comments mirror the existing `noAutofocus` APG-pattern suppression; no JSX/logic changed. Added `tests/a11y/Select.spec.ts` (axe-core) proving 0 violations on the pattern.
26
+ - CI `playwright-axe` step now runs GREEN (unblocks v0.3.0 GA `npm-publish` gate, which is `needs: ci`). Root cause from real CI logs: the runner ships no browsers, so every a11y spec died at `browserType.launch` ("Executable doesn't exist"). Fixes: (1) added a `playwright install --with-deps chromium` step before `playwright-axe` in `.github/workflows/ci.yml`; (2) normalized the stale `/storybook/?story=` spec URLs (StatusBadge, MarkdownRenderer, ConfirmDialog, TokenDisplayOnceModal, ProgressBar) to the working `/iframe.html?id=` convention used by `Select.spec.ts`, corrected three wrong story-id slugs (`media-statusbadge--error-state`, `artifacts-markdownrenderer--error-state`, `progress-progressbar--default`), and scoped axe to `#storybook-root` so the Storybook iframe shell's page-level best-practice rules no longer mask component results; (3) `TableView.spec.ts` now waits via `getByRole("table")` (matches the native `<table>` implicit role; the CSS `[role="table"]` selector never matched) and scopes axe to `#storybook-root`.
27
+ - `display/TableView.tsx`: fixed a real axe violation (`scrollable-region-focusable`, WCAG 2.1.1 / 2.1.3, serious) — the virtualized scroll viewport is scrollable but was not keyboard-operable. Added `tabIndex={0}` + `role="region"` + `aria-label` (justified `biome-ignore` comments matching repo convention). Full `tests/a11y/` suite now passes 29/29 with axe 0 violations under `CI=true` against the Playwright `webServer`.
28
+
29
+ ---
30
+
31
+ ## [0.3.1] — 2026-06-13 — hotfix: workspace:* leak in published 0.3.0 manifest (Path B — root-cause fix)
32
+
33
+ ### Fixed
34
+ - **External npm install of `@vantageos/mosaic@0.3.0` was broken**: the published manifest carried `"@vantageos/mosaic-tokens": "workspace:*"` as a runtime dependency. The `workspace:*` protocol is a bun/pnpm/yarn monorepo specifier that the npm registry cannot resolve to a real version, so any external `npm install @vantageos/mosaic` failed with `ETARGET No matching version found for @vantageos/mosaic-tokens@workspace:*`. Gamma flag via Pi msg `jn77k1v2414far8z5b7abxgjqn88jq9b`. Task `k1769bhq5f7z56yyfs143jsw5588k7j6` (mission `k57b6d1bzc318pc4gqmhe4tapx88jqbd`).
35
+
36
+ ### Path B — root-cause fix (Gamma defect-owner recommendation, msg `jn7fjf62mnzrwfhe2p9vfwymxn88ks67`)
37
+
38
+ The first iteration of this PR rewrote `packages/mosaic/package.json` source from `workspace:*` → `^0.2.0`, but this approach:
39
+ - broke CI (`ERR_PNPM_OUTDATED_LOCKFILE` — pnpm frozen-lockfile no longer matched the manifest), AND
40
+ - severed the monorepo workspace link (sibling `mosaic-tokens` would resolve from npm, not the local package), AND
41
+ - re-leaks on every future release unless the spec is permanently pinned (which breaks dev linking).
42
+
43
+ Path B keeps the source `workspace:*` reference (lockfile stays valid → CI green) and **rewrites at publish-time only**:
44
+
45
+ - **NEW** `packages/mosaic/scripts/rewrite-workspace-deps.mjs` — Node stdlib-only script. Walks `dependencies` / `peerDependencies` / `devDependencies` / `optionalDependencies`; for every `workspace:*` (or `workspace:^` / `workspace:~`) ref, reads the sibling package's `package.json` `version` field from `packages/<bare-name>/package.json` and rewrites the spec to `^<version>`. Mutates `packages/mosaic/package.json` in place for the duration of the publish step.
46
+ - **MODIFIED** `prepublishOnly` script now runs the rewrite FIRST: `node scripts/rewrite-workspace-deps.mjs && pnpm run build && pnpm run test && pnpm run size-limit && node scripts/check-eta-gate.js`.
47
+ - **NEW** `postpublish` script reverts the mutation via `git checkout HEAD -- package.json`, leaving the source repo in its workspace-linked state for monorepo dev.
48
+
49
+ This preserves monorepo dev (`workspace:*` resolves to the local sibling) AND ships a registry-resolvable manifest (`^<version>` in the published tarball). The rewrite happens during `npm publish` (which invokes `prepublishOnly` automatically), and the postpublish revert ensures no source drift.
50
+
51
+ ### Verify post-publish
52
+ - `npm view @vantageos/mosaic@0.3.1 dependencies` — `@vantageos/mosaic-tokens` shows `^0.2.0`, no `workspace:*` anywhere.
53
+ - Clean install: `mkdir /tmp/smoke && cd /tmp/smoke && npm init -y && npm install @vantageos/mosaic@0.3.1` — exits 0, pulls `@vantageos/mosaic-tokens@0.2.0` from registry.
54
+ - `git diff HEAD -- packages/mosaic/package.json` post-publish — clean (postpublish reverted).
55
+
56
+ ### F-list track
57
+ - Tracked in F-list `k173e0bwvfpmngwrrtcqh3zzj988fnaq` priority MAX. The rewrite script is fleet-wide reusable for any other `@vantageos/*` monorepo package that publishes via `npm publish` (vs `pnpm publish` which auto-rewrites).
58
+
59
+ ---
60
+
61
+ ## [0.3.0] — GA — 2026-06-13
62
+
63
+ ### Added
64
+ - All Wave 1 + Wave 2 components promoted from `0.3.0-alpha.1` with no breaking API changes.
65
+ - `forms` category becomes stable (7th top-level taxonomy bucket).
66
+
67
+ ---
68
+
69
+ ## [0.3.0-alpha.1] — 2026-06-11
70
+
71
+ ### Added
72
+ - **`RadioGroup`** (Wave 2 T17) — WCAG-AA mutually exclusive single-choice form primitive. Cross-runtime: `@vantageos/mosaic/react/forms` + `@vantageos/mosaic/preact/forms`. Roving tabindex (WAI-ARIA §3.10), Arrow/Home/End keyboard navigation, `aria-orientation`, group-level and per-option disabled.
73
+ - **`Select`** (Wave 2 T13) — single-select dropdown implementing the ARIA combobox+listbox pattern (APG 2024). Optional in-popup search. ArrowUp/Down/Home/End/Enter/Escape/type-ahead keyboard navigation. Shared pure logic (`Select.logic.ts`) referenced by both runtimes.
74
+ - **`MultiSelect`** (Wave 2 T15) — multi-value dropdown with removable chips. `aria-multiselectable`, per-chip `aria-label="Remove {label}"`, `maxItems` gate, searchable filter, Backspace removes last chip.
75
+ - **`Textarea`** (Wave 2 T12) — multi-line text input with optional `autoResize` (grow-to-fit) and `maxLength` clamping enforced at the `onChange` boundary before RHF receives the value.
76
+ - **`Input`** (Wave 2 T11) — first field primitive of the `forms` category. Five HTML input types (`text | email | password | number | url`). `aria-invalid` + `aria-describedby` wired automatically.
77
+ - **`Checkbox`** (Wave 2 T14) — boolean checkbox with `indeterminate` state (DOM `.indeterminate = true` + `aria-checked="mixed"`), optional `description` wired to `aria-describedby`.
78
+ - **`FieldArray`** (Wave 2 T16) — render-prop wrapper around RHF `useFieldArray`. Keys rows by stable `field.id` (not array index). Provides `append / remove / move / swap / insert / prepend / replace / update`. WCAG-AA `role="list"` + `role="listitem"` container.
79
+ - **`ConfirmModal`** alias (Wave 1 T9-v2) — thin re-export of `ConfirmDialog` on `@vantageos/mosaic/react/confirmation` and `@vantageos/mosaic/preact/confirmation`. Referential identity invariant (`ConfirmModal === ConfirmDialog`) enforced by tests.
80
+ - **`VirtualList<T>`** (Wave 1 T2) — generic virtualized list using `@tanstack/react-virtual` v3. API: `items`, `itemHeight`, `estimateSize`, `renderItem`, `onRowClick`, `overscan`, `className`, `locale`. WCAG-AA when `onRowClick` present (`role="button"`, `tabIndex={0}`, Enter/Space handlers). Bilingual empty state (EN/FR).
81
+ - **`forms` category** (Wave 2 T10 scaffold) — 7th top-level taxonomy bucket. Five scaffold primitives: `useMosaicForm`, `FormProvider`, `FormField`, `ErrorDisplay`, `SubmitButton`. Default validation mode `"onBlur"`. Subpaths: `@vantageos/mosaic/react/forms`, `@vantageos/mosaic/preact/forms`, `@vantageos/mosaic/forms` (back-compat root).
82
+ - `react-hook-form ^7.54.0` and `@hookform/resolvers ^3.10.0` added as optional peer dependencies.
83
+ - `./forms`, `./react/forms`, `./preact/forms` subpath exports added.
84
+
85
+ ### Fixed
86
+ - Cascade-merge build break (hotfix 2026-06-11): restored JSDoc openers, deduped barrel re-exports, dropped phantom `Badge` refs, added missing `Skeleton` i18n strings.
87
+
88
+ ### Wave 1 additions (also shipping in 0.3.0-alpha.1 codebase)
89
+ - **`Tabs`** (T5) — cross-runtime React 19 + Preact 10, WCAG-AA.
90
+ - **`Alert`** (T8) — persistent inline banner (React 19 + Preact 10).
91
+ - **`Toast`** (T3) — ephemeral notification (confirmation category, Chi+Hermes convergence).
92
+ - **`Skeleton`** (T6) — loading placeholder (React 19 + Preact 10).
93
+ - **`EmptyState`** (T7) — empty list / zero-data state (display category, Hermes+Chi convergence).
94
+ - Three new CI gate jobs wired into `ci.yml` per Standard v1.2 §20.
95
+
96
+ ---
97
+
98
+ ## [0.2.2] — 2026-06-11
99
+
100
+ ### Fixed
101
+ - **Critical — §18.5 type surface contract**: `tsup.config.ts` react pass changed from `clean: true` to `clean: false`. The three sibling tsup configs (react / preact / tokens re-export) ran their DTS phases in parallel; the react DTS pass finished last and previously wiped `dist/preact/*.d.ts` and `dist/tokens.d.ts` written by the sibling passes. All DTS files now persist on disk.
102
+ - Added `prebuild` script (`node -e "fs.rmSync('dist',{recursive:true,force:true})"`) to guarantee a clean `dist` before tsup runs, replacing the racy in-pass `clean: true`.
103
+
104
+ ---
105
+
106
+ ## [0.2.1] — 2026-06-11 (YANKED — superseded by 0.2.2)
107
+
108
+ ### Added
109
+ - `TableView.onRowClick(row, index)` and `StreamingTableView.onRowClick` — when provided, rows render with `role="button"`, `tabIndex={0}`, and Enter/Space keyboard handlers. Fixes 5-BU ABSOLUTE blocker (Phi + Chi + Theta + Hermes + Demeter).
110
+
111
+ ### Notes
112
+ - 100% back-compat with v0.2.0: when `onRowClick` is undefined, row rendering is byte-identical to v0.2.0.
113
+
114
+ ---
115
+
116
+ ## [0.2.0] — 2026-06-02
117
+
118
+ ### Added
119
+ - **Cross-runtime subpaths** — `@vantageos/mosaic/react/<cat>` (React 19) and `@vantageos/mosaic/preact/<cat>` (Preact 10) for all 6 categories (`progress`, `input`, `display`, `artifacts`, `confirmation`, `media`). Path A architecture (single package, multi-runtime subpaths) replaces forked maintenance.
120
+ - **`@vantageos/mosaic/tokens` subpath** — convenience re-export of `@vantageos/mosaic-tokens`.
121
+ - **tsup three sibling configs** — react pass (legacy v0.1.2 entries + new `react/<cat>`), preact pass (`preact/<cat>` ESM-only with esbuild `alias` mapping `react` → `preact/compat`), tokens re-export shim.
122
+ - **`preact ^10.25.0`** added to peerDependencies. All peer deps (`react`, `react-dom`, `preact`, `react-i18next`, `@mcp-ui/client`, `rxjs`) marked optional via `peerDependenciesMeta`.
123
+ - **`@vantageos/mosaic-tokens`** (new sibling package) — 58 framework-free design tokens across 6 categories: 15 colors (OKLCH × 3 shades × 5 statuses), 8 spacing values, 14 typography vars, 6 shadows, 7 radii, 8 motion. Three surfaces: CSS custom properties, typed JS exports, Tailwind v4 plugin.
124
+
125
+ ### Changed
126
+ - Standard §18 "Cross-Runtime Support (v0.2.0 amendment)" published to `mosaic-architecture-standard-v1.md` documenting the A1 architecture, exports surface table, peerDependenciesMeta model, bundle targets, new CI gates, compatibility commitments, and per-BU migration guide.
127
+
128
+ ---
129
+
130
+ ## [0.1.2] — 2026-06-02
131
+
132
+ ### Added
133
+ - Per-component subpath exports: `@vantageos/mosaic/progress`, `/input`, `/display`, `/artifacts`, `/confirmation`, `/media`, `/server`.
134
+ - `TableView` static rows array overload — accepts `rows: Row[]` for already-fetched data. Streaming variant renamed to `StreamingTableView` with `rows$: Observable`.
135
+
136
+ ### Fixed
137
+ - Removed `recharts` from dependencies (unused in v0.1.0 — will re-add as optional peer when Chart component lands).
138
+ - Moved `rxjs` from dependencies → optional peerDependencies.
139
+
140
+ ### Migration from 0.1.1
141
+ - Root imports (`import { Foo } from '@vantageos/mosaic'`) still work — root export preserved.
142
+ - For optimal tree-shaking, switch to subpath: `import { ProgressBar } from '@vantageos/mosaic/progress'`.
143
+ - Streaming usage: rename `<TableView rows$={obs}>` to `<StreamingTableView rows$={obs}>` and ensure `rxjs` is in your project deps.
144
+
145
+ ---
146
+
147
+ ## [0.1.1] — 2026-06-02
148
+
149
+ ### Added
150
+ - `no-hardcode-strings.test.ts` — vitest AST scan enforcing zero raw JSX text children with alphabetic content (Eta axis 6 CONDITION fix path).
151
+ - Whitelist mechanisms: same-line `// allow-hardcode-i18n: <reason>` comment and file-level `// allow-hardcode-i18n-file: <reason>` comment.
152
+ - Auto-exempt: `.test.tsx`, `.spec.tsx`, `.stories.tsx` files.
153
+
154
+ ---
155
+
156
+ ## [0.1.0] — 2026-05-28
157
+
158
+ ### Added
159
+ - Initial release — 6 consumer-driven MCP UI components: `MarkdownRenderer`, `TokenDisplayOnceModal`, `TableView`, `ConfirmDialog`, `StatusBadge`, `ProgressBar`.
160
+ - Monorepo scaffold: pnpm + turbo + 4 pattern infrastructure + CI gate.
161
+ - Zod runtime validation on all component props.
162
+ - `registry.yaml` with component catalogue.
163
+ - i18n consumer-driven model (zero hardcoded JSX text).
164
+
165
+ ---
166
+
167
+ [Unreleased]: https://github.com/elpiarthera/vantageos-mosaic/compare/v0.3.0...HEAD
168
+ [0.3.0]: https://github.com/elpiarthera/vantageos-mosaic/compare/v0.2.2...v0.3.0
169
+ [0.3.0-alpha.1]: https://github.com/elpiarthera/vantageos-mosaic/compare/v0.2.2...v0.3.0-alpha.1
170
+ [0.2.2]: https://github.com/elpiarthera/vantageos-mosaic/compare/v0.2.1...v0.2.2
171
+ [0.2.1]: https://github.com/elpiarthera/vantageos-mosaic/compare/v0.2.0...v0.2.1
172
+ [0.2.0]: https://github.com/elpiarthera/vantageos-mosaic/compare/v0.1.2...v0.2.0
173
+ [0.1.2]: https://github.com/elpiarthera/vantageos-mosaic/compare/v0.1.1...v0.1.2
174
+ [0.1.1]: https://github.com/elpiarthera/vantageos-mosaic/compare/v0.1.0...v0.1.1
175
+ [0.1.0]: https://github.com/elpiarthera/vantageos-mosaic/releases/tag/v0.1.0
package/README.md CHANGED
@@ -14,6 +14,18 @@ npm install @vantageos/mosaic@^0.2.0 @vantageos/mosaic-tokens@^0.2.0 preact
14
14
 
15
15
  All runtime peers are marked optional via `peerDependenciesMeta` — install only what your runtime needs.
16
16
 
17
+ ## Build
18
+
19
+ ```sh
20
+ pnpm --filter @vantageos/mosaic build
21
+ ```
22
+
23
+ The `build` script prefixes `NODE_OPTIONS=--max-old-space-size=8192` automatically — no manual env export required.
24
+
25
+ **Why 8 GB heap?** tsup runs multiple parallel DTS (declaration emit) configs for cross-runtime outputs (React 19, Preact 10, server, tokens). Each TypeScript compiler worker holds the full type graph in memory. The combined peak exceeds Node's default 2 GB V8 limit, causing OOM crashes (`FATAL ERROR: Reached heap limit Allocation failed`). 8 GB gives adequate headroom on a standard CI runner (ubuntu-latest provides 16 GB RAM).
26
+
27
+ This constraint is codified locally via the `build` script (the `NODE_OPTIONS` prefix above), so it applies anywhere the script runs — including CI. Wiring it as an explicit job-level `env: NODE_OPTIONS` in `.github/workflows/ci.yml` for the build-bearing jobs (`build-parity-cross-runtime`, `peer-resolution-smoke`, `npm-publish`) is planned but not yet present.
28
+
17
29
  ## Surface
18
30
 
19
31
  | Subpath | Runtime | Use case |
@@ -1,5 +1,35 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
1
2
  import { z } from 'zod';
2
3
 
4
+ declare const TokenDisplayOnceModalPropsSchema: z.ZodObject<{
5
+ token: z.ZodString;
6
+ title: z.ZodString;
7
+ warningMessage: z.ZodString;
8
+ copyLabel: z.ZodString;
9
+ closeLabel: z.ZodString;
10
+ locale: z.ZodDefault<z.ZodEnum<["en", "fr"]>>;
11
+ }, "strip", z.ZodTypeAny, {
12
+ locale: "en" | "fr";
13
+ title: string;
14
+ token: string;
15
+ warningMessage: string;
16
+ copyLabel: string;
17
+ closeLabel: string;
18
+ }, {
19
+ title: string;
20
+ token: string;
21
+ warningMessage: string;
22
+ copyLabel: string;
23
+ closeLabel: string;
24
+ locale?: "en" | "fr" | undefined;
25
+ }>;
26
+ type TokenDisplayOnceModalProps = z.infer<typeof TokenDisplayOnceModalPropsSchema> & {
27
+ onClose: () => void;
28
+ };
29
+ declare function validateTokenDisplayOnceModalProps(raw: unknown): z.infer<typeof TokenDisplayOnceModalPropsSchema>;
30
+
31
+ declare function TokenDisplayOnceModal(raw: Omit<TokenDisplayOnceModalProps, "locale"> & Partial<Pick<TokenDisplayOnceModalProps, "locale">>): react_jsx_runtime.JSX.Element | null;
32
+
3
33
  /**
4
34
  * Alert component props schema.
5
35
  *
@@ -38,4 +68,4 @@ type AlertProps = z.infer<typeof AlertPropsSchema> & {
38
68
  };
39
69
  declare function validateAlertProps(raw: unknown): z.infer<typeof AlertPropsSchema>;
40
70
 
41
- export { type AlertProps as A, AlertPropsSchema as a, validateAlertProps as v };
71
+ export { type AlertProps as A, TokenDisplayOnceModal as T, AlertPropsSchema as a, type TokenDisplayOnceModalProps as b, TokenDisplayOnceModalPropsSchema as c, validateTokenDisplayOnceModalProps as d, validateAlertProps as v };
@@ -1,5 +1,35 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
1
2
  import { z } from 'zod';
2
3
 
4
+ declare const TokenDisplayOnceModalPropsSchema: z.ZodObject<{
5
+ token: z.ZodString;
6
+ title: z.ZodString;
7
+ warningMessage: z.ZodString;
8
+ copyLabel: z.ZodString;
9
+ closeLabel: z.ZodString;
10
+ locale: z.ZodDefault<z.ZodEnum<["en", "fr"]>>;
11
+ }, "strip", z.ZodTypeAny, {
12
+ locale: "en" | "fr";
13
+ title: string;
14
+ token: string;
15
+ warningMessage: string;
16
+ copyLabel: string;
17
+ closeLabel: string;
18
+ }, {
19
+ title: string;
20
+ token: string;
21
+ warningMessage: string;
22
+ copyLabel: string;
23
+ closeLabel: string;
24
+ locale?: "en" | "fr" | undefined;
25
+ }>;
26
+ type TokenDisplayOnceModalProps = z.infer<typeof TokenDisplayOnceModalPropsSchema> & {
27
+ onClose: () => void;
28
+ };
29
+ declare function validateTokenDisplayOnceModalProps(raw: unknown): z.infer<typeof TokenDisplayOnceModalPropsSchema>;
30
+
31
+ declare function TokenDisplayOnceModal(raw: Omit<TokenDisplayOnceModalProps, "locale"> & Partial<Pick<TokenDisplayOnceModalProps, "locale">>): react_jsx_runtime.JSX.Element | null;
32
+
3
33
  /**
4
34
  * Alert component props schema.
5
35
  *
@@ -38,4 +68,4 @@ type AlertProps = z.infer<typeof AlertPropsSchema> & {
38
68
  };
39
69
  declare function validateAlertProps(raw: unknown): z.infer<typeof AlertPropsSchema>;
40
70
 
41
- export { type AlertProps as A, AlertPropsSchema as a, validateAlertProps as v };
71
+ export { type AlertProps as A, TokenDisplayOnceModal as T, AlertPropsSchema as a, type TokenDisplayOnceModalProps as b, TokenDisplayOnceModalPropsSchema as c, validateTokenDisplayOnceModalProps as d, validateAlertProps as v };
@@ -0,0 +1,22 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const MarkdownRendererPropsSchema: z.ZodObject<{
4
+ content: z.ZodString;
5
+ locale: z.ZodEnum<["en", "fr"]>;
6
+ maxLength: z.ZodDefault<z.ZodNumber>;
7
+ allowHtml: z.ZodDefault<z.ZodBoolean>;
8
+ }, "strip", z.ZodTypeAny, {
9
+ locale: "en" | "fr";
10
+ content: string;
11
+ maxLength: number;
12
+ allowHtml: boolean;
13
+ }, {
14
+ locale: "en" | "fr";
15
+ content: string;
16
+ maxLength?: number | undefined;
17
+ allowHtml?: boolean | undefined;
18
+ }>;
19
+ type MarkdownRendererProps = z.infer<typeof MarkdownRendererPropsSchema>;
20
+ declare function validateProps(raw: unknown): MarkdownRendererProps;
21
+
22
+ export { type MarkdownRendererProps as M, MarkdownRendererPropsSchema as a, validateProps as v };
@@ -0,0 +1,22 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const MarkdownRendererPropsSchema: z.ZodObject<{
4
+ content: z.ZodString;
5
+ locale: z.ZodEnum<["en", "fr"]>;
6
+ maxLength: z.ZodDefault<z.ZodNumber>;
7
+ allowHtml: z.ZodDefault<z.ZodBoolean>;
8
+ }, "strip", z.ZodTypeAny, {
9
+ locale: "en" | "fr";
10
+ content: string;
11
+ maxLength: number;
12
+ allowHtml: boolean;
13
+ }, {
14
+ locale: "en" | "fr";
15
+ content: string;
16
+ maxLength?: number | undefined;
17
+ allowHtml?: boolean | undefined;
18
+ }>;
19
+ type MarkdownRendererProps = z.infer<typeof MarkdownRendererPropsSchema>;
20
+ declare function validateProps(raw: unknown): MarkdownRendererProps;
21
+
22
+ export { type MarkdownRendererProps as M, MarkdownRendererPropsSchema as a, validateProps as v };
@@ -0,0 +1,22 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const ProgressBarPropsSchema: z.ZodObject<{
4
+ value: z.ZodNumber;
5
+ label: z.ZodString;
6
+ locale: z.ZodDefault<z.ZodEnum<["en", "fr"]>>;
7
+ colorVariant: z.ZodDefault<z.ZodEnum<["default", "warning", "danger"]>>;
8
+ }, "strip", z.ZodTypeAny, {
9
+ value: number;
10
+ label: string;
11
+ locale: "en" | "fr";
12
+ colorVariant: "default" | "warning" | "danger";
13
+ }, {
14
+ value: number;
15
+ label: string;
16
+ locale?: "en" | "fr" | undefined;
17
+ colorVariant?: "default" | "warning" | "danger" | undefined;
18
+ }>;
19
+ type ProgressBarProps = z.infer<typeof ProgressBarPropsSchema>;
20
+ declare function validateProps(raw: unknown): ProgressBarProps;
21
+
22
+ export { type ProgressBarProps as P, ProgressBarPropsSchema as a, validateProps as v };
@@ -0,0 +1,22 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const ProgressBarPropsSchema: z.ZodObject<{
4
+ value: z.ZodNumber;
5
+ label: z.ZodString;
6
+ locale: z.ZodDefault<z.ZodEnum<["en", "fr"]>>;
7
+ colorVariant: z.ZodDefault<z.ZodEnum<["default", "warning", "danger"]>>;
8
+ }, "strip", z.ZodTypeAny, {
9
+ value: number;
10
+ label: string;
11
+ locale: "en" | "fr";
12
+ colorVariant: "default" | "warning" | "danger";
13
+ }, {
14
+ value: number;
15
+ label: string;
16
+ locale?: "en" | "fr" | undefined;
17
+ colorVariant?: "default" | "warning" | "danger" | undefined;
18
+ }>;
19
+ type ProgressBarProps = z.infer<typeof ProgressBarPropsSchema>;
20
+ declare function validateProps(raw: unknown): ProgressBarProps;
21
+
22
+ export { type ProgressBarProps as P, ProgressBarPropsSchema as a, validateProps as v };
@@ -0,0 +1,22 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const StatusBadgePropsSchema: z.ZodObject<{
4
+ status: z.ZodString;
5
+ variant: z.ZodDefault<z.ZodEnum<["success", "warning", "danger", "info", "neutral"]>>;
6
+ label: z.ZodOptional<z.ZodString>;
7
+ locale: z.ZodEnum<["en", "fr"]>;
8
+ }, "strip", z.ZodTypeAny, {
9
+ locale: "en" | "fr";
10
+ status: string;
11
+ variant: "warning" | "danger" | "success" | "info" | "neutral";
12
+ label?: string | undefined;
13
+ }, {
14
+ locale: "en" | "fr";
15
+ status: string;
16
+ label?: string | undefined;
17
+ variant?: "warning" | "danger" | "success" | "info" | "neutral" | undefined;
18
+ }>;
19
+ type StatusBadgeProps = z.infer<typeof StatusBadgePropsSchema>;
20
+ declare function validateProps(raw: unknown): StatusBadgeProps;
21
+
22
+ export { type StatusBadgeProps as S, StatusBadgePropsSchema as a, validateProps as v };
@@ -0,0 +1,22 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const StatusBadgePropsSchema: z.ZodObject<{
4
+ status: z.ZodString;
5
+ variant: z.ZodDefault<z.ZodEnum<["success", "warning", "danger", "info", "neutral"]>>;
6
+ label: z.ZodOptional<z.ZodString>;
7
+ locale: z.ZodEnum<["en", "fr"]>;
8
+ }, "strip", z.ZodTypeAny, {
9
+ locale: "en" | "fr";
10
+ status: string;
11
+ variant: "warning" | "danger" | "success" | "info" | "neutral";
12
+ label?: string | undefined;
13
+ }, {
14
+ locale: "en" | "fr";
15
+ status: string;
16
+ label?: string | undefined;
17
+ variant?: "warning" | "danger" | "success" | "info" | "neutral" | undefined;
18
+ }>;
19
+ type StatusBadgeProps = z.infer<typeof StatusBadgePropsSchema>;
20
+ declare function validateProps(raw: unknown): StatusBadgeProps;
21
+
22
+ export { type StatusBadgeProps as S, StatusBadgePropsSchema as a, validateProps as v };
@@ -13,6 +13,7 @@ var DOMPurify__default = /*#__PURE__*/_interopDefault(DOMPurify);
13
13
 
14
14
  // src/i18n/strings.ts
15
15
  var EN = {
16
+ // ─── Non-forms components ──────────────────────────────────────────────────
16
17
  "ProgressBar.aria.label": "Progress",
17
18
  "ProgressBar.error.invalidProps": "ProgressBar: invalid props",
18
19
  "ConfirmDialog.button.confirm": "Confirm",
@@ -40,9 +41,71 @@ var EN = {
40
41
  "VirtualList.empty.message": "No items to display",
41
42
  "VirtualList.error.invalidProps": "VirtualList: invalid props",
42
43
  "Skeleton.aria.label": "Loading",
43
- "Skeleton.error.invalidProps": "Skeleton: invalid props"
44
+ "Skeleton.error.invalidProps": "Skeleton: invalid props",
45
+ // ─── Forms — useMosaicForm ─────────────────────────────────────────────────
46
+ "useMosaicForm.error.invalidProps": "useMosaicForm: invalid options",
47
+ // ─── Forms — FormProvider ──────────────────────────────────────────────────
48
+ "FormProvider.error.invalidProps": "FormProvider: invalid props",
49
+ // ─── Forms — FormField ────────────────────────────────────────────────────
50
+ "FormField.error.invalidProps": "FormField: invalid props",
51
+ // ─── Forms — ErrorDisplay ─────────────────────────────────────────────────
52
+ "ErrorDisplay.error.required": "This field is required",
53
+ "ErrorDisplay.error.min": "Value is below the minimum",
54
+ "ErrorDisplay.error.max": "Value exceeds the maximum",
55
+ "ErrorDisplay.error.minLength": "Input is too short",
56
+ "ErrorDisplay.error.maxLength": "Input is too long",
57
+ "ErrorDisplay.error.pattern": "Invalid format",
58
+ "ErrorDisplay.error.email": "Enter a valid email address",
59
+ "ErrorDisplay.error.url": "Enter a valid URL",
60
+ "ErrorDisplay.error.generic": "Invalid value",
61
+ // ─── Forms — SubmitButton ─────────────────────────────────────────────────
62
+ "SubmitButton.aria.submit": "Submit form",
63
+ "SubmitButton.state.loading": "Submitting\u2026",
64
+ "SubmitButton.error.invalidProps": "SubmitButton: invalid props",
65
+ // ─── Forms — Input ────────────────────────────────────────────────────────
66
+ "Input.aria.label": "Input field",
67
+ "Input.error.required": "This field is required",
68
+ "Input.error.invalid": "Invalid value",
69
+ "Input.error.tooLong": "Input is too long",
70
+ "Input.error.tooShort": "Input is too short",
71
+ "Input.error.invalidProps": "Input: invalid props",
72
+ // ─── Forms — Textarea ─────────────────────────────────────────────────────
73
+ "Textarea.aria.label": "Text area",
74
+ "Textarea.error.required": "This field is required",
75
+ "Textarea.error.tooLong": "Text is too long",
76
+ "Textarea.counter.remaining": "characters remaining",
77
+ "Textarea.error.invalidProps": "Textarea: invalid props",
78
+ // ─── Forms — FieldArray ───────────────────────────────────────────────────
79
+ "FieldArray.aria.list": "List of items",
80
+ "FieldArray.aria.addItem": "Add item",
81
+ "FieldArray.aria.removeItem": "Remove item",
82
+ "FieldArray.error.invalidProps": "FieldArray: invalid props",
83
+ // ─── Forms — Checkbox ─────────────────────────────────────────────────────
84
+ "Checkbox.aria.label": "Checkbox",
85
+ "Checkbox.error.required": "This field must be checked",
86
+ "Checkbox.error.invalidProps": "Checkbox: invalid props",
87
+ // ─── Forms — MultiSelect ──────────────────────────────────────────────────
88
+ "MultiSelect.aria.label": "Multi-select field",
89
+ "MultiSelect.aria.removeChip": "Remove",
90
+ "MultiSelect.error.required": "Select at least one option",
91
+ "MultiSelect.error.maxItems": "Maximum number of selections reached",
92
+ "MultiSelect.placeholder": "Select options\u2026",
93
+ "MultiSelect.search.placeholder": "Search\u2026",
94
+ "MultiSelect.empty": "No options available",
95
+ "MultiSelect.error.invalidProps": "MultiSelect: invalid props",
96
+ // ─── Forms — RadioGroup ───────────────────────────────────────────────────
97
+ "RadioGroup.aria.label": "Radio group",
98
+ "RadioGroup.error.required": "Select one option",
99
+ "RadioGroup.error.invalidProps": "RadioGroup: invalid props",
100
+ // ─── Forms — Select ───────────────────────────────────────────────────────
101
+ "Select.placeholder": "Select an option\u2026",
102
+ "Select.search.placeholder": "Search\u2026",
103
+ "Select.empty": "No options available",
104
+ "Select.error.required": "Select an option",
105
+ "Select.error.invalidProps": "Select: invalid props"
44
106
  };
45
107
  var FR = {
108
+ // ─── Non-forms components ──────────────────────────────────────────────────
46
109
  "ProgressBar.aria.label": "Progression",
47
110
  "ProgressBar.error.invalidProps": "ProgressBar : propri\xE9t\xE9s invalides",
48
111
  "ConfirmDialog.button.confirm": "Confirmer",
@@ -70,7 +133,68 @@ var FR = {
70
133
  "VirtualList.empty.message": "Aucun \xE9l\xE9ment \xE0 afficher",
71
134
  "VirtualList.error.invalidProps": "VirtualList : propri\xE9t\xE9s invalides",
72
135
  "Skeleton.aria.label": "Chargement",
73
- "Skeleton.error.invalidProps": "Skeleton : propri\xE9t\xE9s invalides"
136
+ "Skeleton.error.invalidProps": "Skeleton : propri\xE9t\xE9s invalides",
137
+ // ─── Forms — useMosaicForm ─────────────────────────────────────────────────
138
+ "useMosaicForm.error.invalidProps": "useMosaicForm : options invalides",
139
+ // ─── Forms — FormProvider ──────────────────────────────────────────────────
140
+ "FormProvider.error.invalidProps": "FormProvider : propri\xE9t\xE9s invalides",
141
+ // ─── Forms — FormField ────────────────────────────────────────────────────
142
+ "FormField.error.invalidProps": "FormField : propri\xE9t\xE9s invalides",
143
+ // ─── Forms — ErrorDisplay ─────────────────────────────────────────────────
144
+ "ErrorDisplay.error.required": "Ce champ est obligatoire",
145
+ "ErrorDisplay.error.min": "La valeur est inf\xE9rieure au minimum",
146
+ "ErrorDisplay.error.max": "La valeur d\xE9passe le maximum",
147
+ "ErrorDisplay.error.minLength": "La saisie est trop courte",
148
+ "ErrorDisplay.error.maxLength": "La saisie est trop longue",
149
+ "ErrorDisplay.error.pattern": "Format invalide",
150
+ "ErrorDisplay.error.email": "Saisissez une adresse e-mail valide",
151
+ "ErrorDisplay.error.url": "Saisissez une URL valide",
152
+ "ErrorDisplay.error.generic": "Valeur invalide",
153
+ // ─── Forms — SubmitButton ─────────────────────────────────────────────────
154
+ "SubmitButton.aria.submit": "Soumettre le formulaire",
155
+ "SubmitButton.state.loading": "Envoi en cours\u2026",
156
+ "SubmitButton.error.invalidProps": "SubmitButton : propri\xE9t\xE9s invalides",
157
+ // ─── Forms — Input ────────────────────────────────────────────────────────
158
+ "Input.aria.label": "Champ de saisie",
159
+ "Input.error.required": "Ce champ est obligatoire",
160
+ "Input.error.invalid": "Valeur invalide",
161
+ "Input.error.tooLong": "La saisie est trop longue",
162
+ "Input.error.tooShort": "La saisie est trop courte",
163
+ "Input.error.invalidProps": "Input : propri\xE9t\xE9s invalides",
164
+ // ─── Forms — Textarea ─────────────────────────────────────────────────────
165
+ "Textarea.aria.label": "Zone de texte",
166
+ "Textarea.error.required": "Ce champ est obligatoire",
167
+ "Textarea.error.tooLong": "Le texte est trop long",
168
+ "Textarea.counter.remaining": "caract\xE8res restants",
169
+ "Textarea.error.invalidProps": "Textarea : propri\xE9t\xE9s invalides",
170
+ // ─── Forms — FieldArray ───────────────────────────────────────────────────
171
+ "FieldArray.aria.list": "Liste d'\xE9l\xE9ments",
172
+ "FieldArray.aria.addItem": "Ajouter un \xE9l\xE9ment",
173
+ "FieldArray.aria.removeItem": "Supprimer l'\xE9l\xE9ment",
174
+ "FieldArray.error.invalidProps": "FieldArray : propri\xE9t\xE9s invalides",
175
+ // ─── Forms — Checkbox ─────────────────────────────────────────────────────
176
+ "Checkbox.aria.label": "Case \xE0 cocher",
177
+ "Checkbox.error.required": "Ce champ doit \xEAtre coch\xE9",
178
+ "Checkbox.error.invalidProps": "Checkbox : propri\xE9t\xE9s invalides",
179
+ // ─── Forms — MultiSelect ──────────────────────────────────────────────────
180
+ "MultiSelect.aria.label": "Champ de s\xE9lection multiple",
181
+ "MultiSelect.aria.removeChip": "Retirer",
182
+ "MultiSelect.error.required": "S\xE9lectionnez au moins une option",
183
+ "MultiSelect.error.maxItems": "Nombre maximum de s\xE9lections atteint",
184
+ "MultiSelect.placeholder": "S\xE9lectionner des options\u2026",
185
+ "MultiSelect.search.placeholder": "Rechercher\u2026",
186
+ "MultiSelect.empty": "Aucune option disponible",
187
+ "MultiSelect.error.invalidProps": "MultiSelect : propri\xE9t\xE9s invalides",
188
+ // ─── Forms — RadioGroup ───────────────────────────────────────────────────
189
+ "RadioGroup.aria.label": "Groupe de boutons radio",
190
+ "RadioGroup.error.required": "S\xE9lectionnez une option",
191
+ "RadioGroup.error.invalidProps": "RadioGroup : propri\xE9t\xE9s invalides",
192
+ // ─── Forms — Select ───────────────────────────────────────────────────────
193
+ "Select.placeholder": "S\xE9lectionner une option\u2026",
194
+ "Select.search.placeholder": "Rechercher\u2026",
195
+ "Select.empty": "Aucune option disponible",
196
+ "Select.error.required": "S\xE9lectionnez une option",
197
+ "Select.error.invalidProps": "Select : propri\xE9t\xE9s invalides"
74
198
  };
75
199
  var TABLE = {
76
200
  en: EN,