@vantageos/mosaic 0.3.1 → 0.4.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/CHANGELOG.md +62 -0
- package/LICENSE +110 -0
- package/README.md +84 -21
- package/dist/artifacts.cjs +4 -0
- package/dist/artifacts.cjs.map +1 -1
- package/dist/artifacts.js +4 -0
- package/dist/artifacts.js.map +1 -1
- package/dist/confirmation.cjs +4 -0
- package/dist/confirmation.cjs.map +1 -1
- package/dist/confirmation.js +4 -0
- package/dist/confirmation.js.map +1 -1
- package/dist/display.cjs +4 -0
- package/dist/display.cjs.map +1 -1
- package/dist/display.js +4 -0
- package/dist/display.js.map +1 -1
- package/dist/index.cjs +4 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/media.cjs +4 -0
- package/dist/media.cjs.map +1 -1
- package/dist/media.js +4 -0
- package/dist/media.js.map +1 -1
- package/dist/preact/artifacts.js +4 -0
- package/dist/preact/artifacts.js.map +1 -1
- package/dist/preact/confirmation.js +4 -0
- package/dist/preact/confirmation.js.map +1 -1
- package/dist/preact/display.d.ts +43 -1
- package/dist/preact/display.js +59 -1
- package/dist/preact/display.js.map +1 -1
- package/dist/preact/progress.js +4 -0
- package/dist/preact/progress.js.map +1 -1
- package/dist/progress.cjs +4 -0
- package/dist/progress.cjs.map +1 -1
- package/dist/progress.js +4 -0
- package/dist/progress.js.map +1 -1
- package/dist/react/artifacts.cjs +4 -0
- package/dist/react/artifacts.cjs.map +1 -1
- package/dist/react/artifacts.js +4 -0
- package/dist/react/artifacts.js.map +1 -1
- package/dist/react/confirmation.cjs +4 -0
- package/dist/react/confirmation.cjs.map +1 -1
- package/dist/react/confirmation.js +4 -0
- package/dist/react/confirmation.js.map +1 -1
- package/dist/react/display.cjs +61 -0
- package/dist/react/display.cjs.map +1 -1
- package/dist/react/display.d.cts +43 -1
- package/dist/react/display.d.ts +43 -1
- package/dist/react/display.js +59 -1
- package/dist/react/display.js.map +1 -1
- package/dist/react/progress.cjs +4 -0
- package/dist/react/progress.cjs.map +1 -1
- package/dist/react/progress.js +4 -0
- package/dist/react/progress.js.map +1 -1
- package/dist/tokens.cjs +73 -22
- package/dist/tokens.cjs.map +1 -1
- package/dist/tokens.d.cts +23 -3
- package/dist/tokens.d.ts +23 -3
- package/dist/tokens.js +73 -22
- package/dist/tokens.js.map +1 -1
- package/package.json +5 -3
- package/registry.yaml +7 -0
package/CHANGELOG.md
CHANGED
|
@@ -28,6 +28,68 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
28
28
|
|
|
29
29
|
---
|
|
30
30
|
|
|
31
|
+
## [0.4.0] — 2026-10-04
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
- **Badge primitive, cross-runtime.** `Badge` is exported from `./display`, `./react/display` and
|
|
35
|
+
`./preact/display`, with its schema, stories, i18n strings and a 205-line React test. Landed on
|
|
36
|
+
`main` in #61 against `target 0.3.2` and unpublished until this release, so no consumer could
|
|
37
|
+
import it.
|
|
38
|
+
- **`docs/GA-RELEASE-V0.3.1.md`** — the canonical release procedure (bilingual EN+FR): the five
|
|
39
|
+
fail-closed CI gate jobs, the `ETA_APPROVED_TASK_ID` approval hook, the
|
|
40
|
+
`prepublishOnly`/`postpublish` workspace-rewrite pattern, the 0.3.0 → 0.3.1 incident and its
|
|
41
|
+
lesson, the cross-runtime architecture and the migration guide. Written for 0.3.1 and itself
|
|
42
|
+
unpublished until now, which is why this release follows it rather than a recalled procedure.
|
|
43
|
+
|
|
44
|
+
### Documentation
|
|
45
|
+
- **The package README was frozen at 0.3.1 and is rewritten against the built artifact.**
|
|
46
|
+
It told a consumer to `npm install @vantageos/mosaic@^0.2.0 @vantageos/mosaic-tokens@^0.2.0`,
|
|
47
|
+
neither of which is what ships. Corrected to the versions actually published.
|
|
48
|
+
- **Six sentences claiming form primitives were still unshipped are deleted.** Each had
|
|
49
|
+
been appended as a primitive landed and never removed, so each sat directly above a
|
|
50
|
+
table row documenting the very primitive it called missing. All of Input, Textarea,
|
|
51
|
+
Select, Checkbox, MultiSelect, RadioGroup and FieldArray are exported — read from
|
|
52
|
+
`dist/react/forms.d.ts`, not from the prose.
|
|
53
|
+
- **A derived per-subpath export inventory replaces a partial list that read as complete.**
|
|
54
|
+
It records that `media` exports no components although it is one of the seven categories
|
|
55
|
+
gated for cross-runtime parity.
|
|
56
|
+
- **Bundle sizes are the `size-limit` output with their gates**, replacing figures for
|
|
57
|
+
surfaces the gate no longer measures.
|
|
58
|
+
- **The changelog link pointed at the repo root**, which is not the file the tarball
|
|
59
|
+
carries; it now points at this one.
|
|
60
|
+
- **The README stated MIT while `package.json` carried no `license` field** and `files`
|
|
61
|
+
shipped no LICENSE, so every version up to 0.3.1 reached consumers with no licence terms
|
|
62
|
+
at all.
|
|
63
|
+
|
|
64
|
+
### Added — licence
|
|
65
|
+
- **`FSL-1.1-Apache-2.0` is now declared and shipped.** `package.json` carries the
|
|
66
|
+
`license` field, `LICENSE` is in `files`, and the file is byte-identical to the one every
|
|
67
|
+
sibling `@vantageos` package ships
|
|
68
|
+
(sha256 `3d458972e6e84e5d2361a886ef64b07aefdc38dd8955e281ea8c2ae8849646a4`). Verified
|
|
69
|
+
against what the registry serves for `mosaic-blocks`, `mosaic-tokens` and `mcp-doctor` —
|
|
70
|
+
this package was the only one of the four publishing `license: NONE`. Nothing about the
|
|
71
|
+
terms is new; they were simply never attached to this package.
|
|
72
|
+
|
|
73
|
+
### Changed
|
|
74
|
+
- **`@vantageos/mosaic-tokens` moves from `^0.2.0` to `^0.7.0`** in the published manifest. This is
|
|
75
|
+
why the release is `0.4.0` and not the `0.3.2` the source commit targeted: `^0.2.0` does **not**
|
|
76
|
+
satisfy `0.7.0` (a caret on a `0.x` range pins the minor), so a consumer upgrading receives a
|
|
77
|
+
five-minor jump in a runtime dependency. On a `0.x` package the minor is the only available
|
|
78
|
+
signal for that, and a patch number would have understated it.
|
|
79
|
+
|
|
80
|
+
The range was never edited by hand — the manifest carries `workspace:*` and `prepublishOnly`
|
|
81
|
+
resolves it to whatever the sibling package is at, which is now `0.7.0`. That is correct
|
|
82
|
+
behaviour and it is precisely why the published version has to be derived from the packed
|
|
83
|
+
tarball rather than from the commit that said `target 0.3.2`.
|
|
84
|
+
|
|
85
|
+
### Note on this release
|
|
86
|
+
Nothing else changed in the source. `latest` served `0.3.1` from 2026-06-13 until this version, so
|
|
87
|
+
the items above are the entire delta a consumer receives — derived by locating the commit that set
|
|
88
|
+
the version to `0.3.1` and listing what touched `packages/mosaic` after it, not by reading a date
|
|
89
|
+
window (a date window includes the release commits themselves and reported 19).
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
31
93
|
## [0.3.1] — 2026-06-13 — hotfix: workspace:* leak in published 0.3.0 manifest (Path B — root-cause fix)
|
|
32
94
|
|
|
33
95
|
### Fixed
|
package/LICENSE
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
Functional Source License, Version 1.1, Apache 2.0 Future License
|
|
2
|
+
|
|
3
|
+
Abbreviation
|
|
4
|
+
|
|
5
|
+
FSL-1.1-Apache-2.0
|
|
6
|
+
|
|
7
|
+
Notice
|
|
8
|
+
|
|
9
|
+
Copyright 2026 VantageOS (ElPi Corp)
|
|
10
|
+
|
|
11
|
+
Terms and Conditions
|
|
12
|
+
|
|
13
|
+
Licensor: VantageOS (ElPi Corp)
|
|
14
|
+
|
|
15
|
+
Licensed Work: VantagePeers
|
|
16
|
+
The Licensed Work is (c) 2026 VantageOS (ElPi Corp)
|
|
17
|
+
|
|
18
|
+
Additional Use Grant: You may make production use of the Licensed Work,
|
|
19
|
+
provided Your use does not include offering the Licensed
|
|
20
|
+
Work to third parties as a hosted or managed service
|
|
21
|
+
where the service provides users with access to any
|
|
22
|
+
substantial set of the features or functionality of the
|
|
23
|
+
Licensed Work.
|
|
24
|
+
|
|
25
|
+
Change Date: 2028-04-03 (two years from publication)
|
|
26
|
+
|
|
27
|
+
Change License: Apache License, Version 2.0
|
|
28
|
+
|
|
29
|
+
For information about alternative licensing arrangements for the Licensed Work,
|
|
30
|
+
please contact: contact@vantageos.com
|
|
31
|
+
|
|
32
|
+
License text below is provided for informational purposes only.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
Functional Source License, Version 1.1, Apache 2.0 Future License
|
|
37
|
+
|
|
38
|
+
1. Purpose
|
|
39
|
+
|
|
40
|
+
This license gives you broad permission to use, modify, and share this
|
|
41
|
+
software, with one important condition: you may not use it to compete with us.
|
|
42
|
+
|
|
43
|
+
2. Acceptance
|
|
44
|
+
|
|
45
|
+
To use the software, you must agree to these terms. If you do not agree, you
|
|
46
|
+
may not use the software.
|
|
47
|
+
|
|
48
|
+
3. Copyright License
|
|
49
|
+
|
|
50
|
+
The licensor grants you a non-exclusive, royalty-free, worldwide, non-
|
|
51
|
+
sublicensable, non-transferable license to use, copy, distribute, make
|
|
52
|
+
available, and prepare derivative works of the software, in each case subject
|
|
53
|
+
to the limitations below.
|
|
54
|
+
|
|
55
|
+
4. Limitations
|
|
56
|
+
|
|
57
|
+
You may not make the functionality of the software available to third parties
|
|
58
|
+
as a service, or otherwise use the software to provide a service to third
|
|
59
|
+
parties that competes with the licensor.
|
|
60
|
+
|
|
61
|
+
5. Patents
|
|
62
|
+
|
|
63
|
+
The licensor grants you a license, under any patent claims the licensor can
|
|
64
|
+
license or becomes able to license, to make, have made, use, sell, offer for
|
|
65
|
+
sale, import, and have imported the software, in each case subject to the
|
|
66
|
+
limitations and conditions in this license.
|
|
67
|
+
|
|
68
|
+
6. Fair Use
|
|
69
|
+
|
|
70
|
+
This license is not intended to limit any rights you may have under applicable
|
|
71
|
+
fair use or other laws.
|
|
72
|
+
|
|
73
|
+
7. No Other Rights
|
|
74
|
+
|
|
75
|
+
These terms do not grant any other rights. The licensor reserves all rights not
|
|
76
|
+
expressly granted.
|
|
77
|
+
|
|
78
|
+
8. Termination
|
|
79
|
+
|
|
80
|
+
Your license is automatically terminated if you violate the terms. However, if
|
|
81
|
+
you cure the violation within 30 days of discovering it, your license is
|
|
82
|
+
reinstated retroactively.
|
|
83
|
+
|
|
84
|
+
9. Disclaimer
|
|
85
|
+
|
|
86
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
87
|
+
IMPLIED.
|
|
88
|
+
|
|
89
|
+
10. Limitation of Liability
|
|
90
|
+
|
|
91
|
+
TO THE EXTENT PERMITTED BY LAW, THE LICENSOR IS NOT LIABLE FOR ANY DAMAGES
|
|
92
|
+
ARISING FROM THE USE OF THE SOFTWARE.
|
|
93
|
+
|
|
94
|
+
11. Change Date and License
|
|
95
|
+
|
|
96
|
+
After the Change Date, the licensor grants you the rights under the Change
|
|
97
|
+
License.
|
|
98
|
+
|
|
99
|
+
12. Definitions
|
|
100
|
+
|
|
101
|
+
"Compete" means providing a product or service that is substantially similar
|
|
102
|
+
to, or a replacement for, all or a significant portion of the Licensed Work.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
Apache License, Version 2.0
|
|
107
|
+
|
|
108
|
+
After the Change Date (2028-04-03), this software will be available under the
|
|
109
|
+
Apache License, Version 2.0. See https://www.apache.org/licenses/LICENSE-2.0
|
|
110
|
+
for full text.
|
package/README.md
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# @vantageos/mosaic
|
|
2
2
|
|
|
3
|
-
Fleet-wide MCP UI design system. Zod-validated, taxonomy-organized (
|
|
3
|
+
Fleet-wide MCP UI design system. Zod-validated, taxonomy-organized (7 categories: artifacts, confirmation, display, forms, input, media, progress), streaming-ready, **cross-runtime React 19 + Preact 10**. Built for MCP Apps (SEP-1865 extension).
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
7
|
```sh
|
|
8
8
|
# React 19
|
|
9
|
-
npm install @vantageos/mosaic@^0.
|
|
9
|
+
npm install @vantageos/mosaic@^0.4.0 @vantageos/mosaic-tokens@^0.7.0 react react-dom
|
|
10
10
|
|
|
11
11
|
# Preact 10
|
|
12
|
-
npm install @vantageos/mosaic@^0.
|
|
12
|
+
npm install @vantageos/mosaic@^0.4.0 @vantageos/mosaic-tokens@^0.7.0 preact
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
All runtime peers are marked optional via `peerDependenciesMeta` — install only what your runtime needs.
|
|
@@ -32,7 +32,7 @@ This constraint is codified locally via the `build` script (the `NODE_OPTIONS` p
|
|
|
32
32
|
|---|---|---|
|
|
33
33
|
| `@vantageos/mosaic` | React 19 (back-compat) | v0.1.x consumers (Sigma VP, Theta CRM) |
|
|
34
34
|
| `@vantageos/mosaic/<cat>` | React 19 (back-compat) | Tree-shakable category imports v0.1.x style |
|
|
35
|
-
| `@vantageos/mosaic/react` | React 19 |
|
|
35
|
+
| `@vantageos/mosaic/react` | React 19 | React consumers — explicit runtime opt-in (the preferred surface since v0.2.0) |
|
|
36
36
|
| `@vantageos/mosaic/react/<cat>` | React 19 | Tree-shakable category imports under explicit react/ prefix |
|
|
37
37
|
| `@vantageos/mosaic/preact` | Preact 10 | Mu vantage-bridge iframe, Chi gptpowerups (LLM-host target) |
|
|
38
38
|
| `@vantageos/mosaic/preact/<cat>` | Preact 10 | Tree-shakable category imports under preact/ prefix |
|
|
@@ -44,7 +44,7 @@ This constraint is codified locally via the `build` script (the `NODE_OPTIONS` p
|
|
|
44
44
|
## Quick start
|
|
45
45
|
|
|
46
46
|
```tsx
|
|
47
|
-
// React 19 — preferred
|
|
47
|
+
// React 19 — the preferred runtime-explicit surface
|
|
48
48
|
import { ProgressBar } from "@vantageos/mosaic/react/progress";
|
|
49
49
|
import { ConfirmDialog } from "@vantageos/mosaic/react/confirmation";
|
|
50
50
|
import "@vantageos/mosaic-tokens/css"; // declares --mosaic-* vars on :root
|
|
@@ -64,7 +64,7 @@ export function MyComponent({ progress, label }: { progress: number; label: stri
|
|
|
64
64
|
}
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
-
## Forms
|
|
67
|
+
## Forms
|
|
68
68
|
|
|
69
69
|
`@vantageos/mosaic/{react,preact}/forms` — composite form primitives wrapping `react-hook-form` + `@hookform/resolvers/zod`. Default validation mode is `onBlur` (Chi co-validated, Day 102 DM). Cross-runtime: same imports, React 19 path or Preact 10 path.
|
|
70
70
|
|
|
@@ -130,17 +130,14 @@ export function SignupForm({ onSubmit }: { onSubmit: (data: z.infer<typeof schem
|
|
|
130
130
|
| `<SubmitButton label="..." loadingLabel="..." />` | Bound to the surrounding `FormProvider`. Disabled while invalid OR submitting. |
|
|
131
131
|
| `<Input name="..." type="text\|email\|password\|number\|url" label="..." placeholder? disabled? autoComplete? />` | Single-field `<input>` bound to the surrounding `FormProvider`. `label` is required (consumer-driven i18n). Emits `aria-invalid` + `aria-describedby` on validation error. |
|
|
132
132
|
|
|
133
|
-
Field primitives (Textarea, Select, Checkbox, MultiSelect, RadioGroup, FieldArray) land in T12-T20 — see `docs/v0.3.0-plan.md` §7.
|
|
134
133
|
| `<Textarea name="..." rows? maxLength? autoResize? placeholder? disabled? label? />` | Multi-line text input field primitive. `rows` default 3, `maxLength` enforced via shared logic gate, optional `autoResize` grows to content. `aria-invalid` + `aria-describedby` on error. |
|
|
135
134
|
|
|
136
|
-
Remaining field primitives (Input shipped T11, Select, Checkbox, MultiSelect, RadioGroup, FieldArray) land in T13-T20 — see `docs/v0.3.0-plan.md` §7.
|
|
137
135
|
| `useFieldArray({ name, control? })` | Thin wrapper around RHF's `useFieldArray`. Returns `{ fields, append, remove, move, swap }` + the rest of RHF's native return for advanced cases. Reads `control` from `FormProvider` when omitted. |
|
|
138
136
|
| `<FieldArray name="...">{({ field, index }, { append, remove, move, swap, fields }) => ...}</FieldArray>` | Render-prop wrapper around `useFieldArray`. Emits `role="list"` shell + `role="listitem"` per row, keyed by RHF's stable `field.id` (NOT array index). Powers PromptForm Add Variable, Hermes variable mappings, Demeter filter chips. |
|
|
139
137
|
|
|
140
138
|
| `<Checkbox name="..." label="..." indeterminate? description? disabled? />` | Boolean checkbox primitive. `indeterminate=true` → `aria-checked="mixed"` + DOM `.indeterminate=true` via ref. `description` wired via `aria-describedby`. `aria-invalid` + `aria-describedby` on error. |
|
|
141
139
|
| `<RadioGroup name="..." label="..." options={[...]} orientation? disabled? />` | WCAG-AA radiogroup. Roving tabIndex, Arrow key selection sync, Home/End, Space/Enter. |
|
|
142
140
|
|
|
143
|
-
Remaining field primitives (Input, Textarea, Select, MultiSelect) land in T11-T15 + T18-T20 — see `docs/v0.3.0-plan.md` §7.
|
|
144
141
|
|
|
145
142
|
### RadioGroup
|
|
146
143
|
|
|
@@ -191,13 +188,10 @@ export function PlanSelector() {
|
|
|
191
188
|
- `aria-disabled` on disabled options; disabled options skipped in arrow nav
|
|
192
189
|
- `aria-orientation` reflects `orientation` prop
|
|
193
190
|
|
|
194
|
-
Field primitives (Textarea, Select, MultiSelect, RadioGroup, FieldArray) land in T12-T20 — see `docs/v0.3.0-plan.md` §7.
|
|
195
191
|
| `<MultiSelect name="..." label="..." options={...} placeholder? disabled? searchable? maxItems? />` | Multi-value dropdown. RHF value is `string[]`. Selected items render as removable chips (Backspace/Delete on trigger removes last, per-chip × removes specific). WCAG-AA combobox (`role=combobox aria-multiselectable=true`), Arrow/Enter keyboard nav, optional case-insensitive search, optional `maxItems` cap. |
|
|
196
192
|
|
|
197
|
-
Remaining field primitives (Input + Textarea + MultiSelect shipped T11/T12/T15; Select, Checkbox, RadioGroup, FieldArray) land in T13-T20 — see `docs/v0.3.0-plan.md` §7.
|
|
198
193
|
| `<Select name="..." label="..." options={[...]} />` | Single-select dropdown (combobox+listbox APG). Optional `searchable` prop enables in-popup filter. Full keyboard nav + type-ahead. WCAG-AA strict. |
|
|
199
194
|
|
|
200
|
-
Field primitives (Input, Textarea, Checkbox, MultiSelect, RadioGroup, FieldArray) land in T11, T14-T20 — see `docs/v0.3.0-plan.md` §7.
|
|
201
195
|
|
|
202
196
|
|
|
203
197
|
|
|
@@ -216,8 +210,55 @@ const resource = createMosaicResource({
|
|
|
216
210
|
|
|
217
211
|
## Components
|
|
218
212
|
|
|
213
|
+
### What each subpath actually exports
|
|
214
|
+
|
|
215
|
+
Derived from the built type declarations, not maintained by hand:
|
|
216
|
+
|
|
217
|
+
```sh
|
|
218
|
+
# capitalised exports per subpath, excluding the
|
|
219
|
+
# Props/Schema/Validated/Option/Args/Return/Options/Shape/Mode/Type/Controls suffixes
|
|
220
|
+
node -e '...' # see the release PR for the exact script
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
| Subpath | Exports |
|
|
224
|
+
|---|---|
|
|
225
|
+
| `forms` | Checkbox, ErrorDisplay, FieldArray, FormField, FormProvider, Input, MultiSelect, RadioGroup, Select, SubmitButton, Textarea |
|
|
226
|
+
| `display` | Badge, EmptyState, Skeleton, StatusBadge, StreamingTableView, TableView, VirtualList |
|
|
227
|
+
| `progress` | ProgressBar |
|
|
228
|
+
| `input` | Tabs |
|
|
229
|
+
| `confirmation` | Alert, ConfirmDialog, ConfirmModal, TokenDisplayOnceModal |
|
|
230
|
+
| `artifacts` | MarkdownRenderer |
|
|
231
|
+
| `media` | *(none)* |
|
|
232
|
+
|
|
233
|
+
Two things this table says that prose would have hidden. **`media` exports no
|
|
234
|
+
components**, although it is one of the seven categories gated for cross-runtime
|
|
235
|
+
parity — the subpath exists and is empty of components. And the sections below
|
|
236
|
+
document only a few of these; the table is the inventory, the sections are
|
|
237
|
+
examples. Previously the sections WERE presented as the inventory, which is how
|
|
238
|
+
six separate sentences came to claim that form primitives were still unshipped
|
|
239
|
+
while a table row documenting each one sat directly beneath them.
|
|
240
|
+
|
|
241
|
+
The same list for `preact` is identical by construction — cross-runtime parity is
|
|
242
|
+
gated in CI (`scripts/verify-build-parity.sh`).
|
|
243
|
+
|
|
219
244
|
### Display
|
|
220
245
|
|
|
246
|
+
#### Badge
|
|
247
|
+
|
|
248
|
+
Static label primitive, cross-runtime. New in 0.4.0 — it was merged to `main` well
|
|
249
|
+
before and shipped in no published version until then.
|
|
250
|
+
|
|
251
|
+
```tsx
|
|
252
|
+
import { Badge } from "@vantageos/mosaic/react/display";
|
|
253
|
+
// Preact: import { Badge } from "@vantageos/mosaic/preact/display";
|
|
254
|
+
|
|
255
|
+
<Badge variant="success">Active</Badge>
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
See `src/components/display/Badge.schema.ts` for the prop contract and
|
|
259
|
+
`Badge.stories.tsx` for the rendered variants — both ship in the repo, and the
|
|
260
|
+
schema is the authority on the props rather than this snippet.
|
|
261
|
+
|
|
221
262
|
#### VirtualList
|
|
222
263
|
|
|
223
264
|
Generic virtualized list for large datasets. Uses @tanstack/react-virtual v3 (already bundled via TableView). Cross-runtime: React 19 + Preact 10.
|
|
@@ -260,7 +301,7 @@ type Task = { id: string; title: string; status: string };
|
|
|
260
301
|
## Doctrine
|
|
261
302
|
|
|
262
303
|
- **Pattern 1 (Zod runtime validation)** — every component validates props at the MCP host boundary; invalid props render an a11y fallback (`role="alert"`), never white-screen.
|
|
263
|
-
- **Pattern 2 (
|
|
304
|
+
- **Pattern 2 (category taxonomy)** — components live under exactly one category. Bilingual `category.meta.json` per category. The category list is the bare subpaths in the `exports` map, which is the authority; a count written here would be wrong at the next category added, as it was.
|
|
264
305
|
- **Pattern 3 (Registry-gated)** — `registry.yaml` declares every component; CI gate ensures parity between source and registry.
|
|
265
306
|
- **Pattern 4 (Streaming-hydration ready)** — components opt-in to MCP Apps streaming via `getStreamFor()` callbacks.
|
|
266
307
|
|
|
@@ -278,18 +319,40 @@ Consumer-driven i18n contract: components NEVER render raw alphabetic text as JS
|
|
|
278
319
|
// <ProgressBar value={50} label="Uploading…" />
|
|
279
320
|
```
|
|
280
321
|
|
|
281
|
-
## Bundle sizes
|
|
322
|
+
## Bundle sizes
|
|
282
323
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
324
|
+
Every figure below is the output of `pnpm --filter @vantageos/mosaic run size-limit`
|
|
325
|
+
against the built `dist/`, and the gates are the `limit` values in
|
|
326
|
+
`packages/mosaic/.size-limit.json`. Re-run the command rather than trusting this
|
|
327
|
+
table: a size written by hand is wrong at the next dependency bump.
|
|
328
|
+
|
|
329
|
+
| Surface | gz | gate |
|
|
330
|
+
|---|---|---|
|
|
331
|
+
| `dist/index.js` | 133.21 kB | 250 kB |
|
|
332
|
+
| `dist/react/forms.js` | 20.79 kB | 50 kB |
|
|
333
|
+
| `dist/preact/forms.js` | 20.79 kB | 50 kB |
|
|
334
|
+
|
|
335
|
+
Per-component subpaths are tree-shakeable; only the three surfaces above are gated.
|
|
288
336
|
|
|
289
337
|
## License
|
|
290
338
|
|
|
291
|
-
|
|
339
|
+
**FSL-1.1-Apache-2.0** — Functional Source License, Version 1.1, Apache 2.0 Future
|
|
340
|
+
License. © VantageOS / ElPi Corp.
|
|
341
|
+
|
|
342
|
+
The full text ships in the published tarball as [`LICENSE`](./LICENSE), and
|
|
343
|
+
`package.json` carries `"license": "FSL-1.1-Apache-2.0"`, so a consumer receives the
|
|
344
|
+
terms with the package rather than having to find them.
|
|
345
|
+
|
|
346
|
+
This is the same licence as every sibling `@vantageos` package — verified against
|
|
347
|
+
what the registry actually serves for `@vantageos/mosaic-blocks`,
|
|
348
|
+
`@vantageos/mosaic-tokens` and `@vantageos/mcp-doctor`, not against a convention
|
|
349
|
+
recalled from elsewhere, and the file is byte-identical to theirs
|
|
350
|
+
(sha256 `3d458972e6e84e5d2361a886ef64b07aefdc38dd8955e281ea8c2ae8849646a4`).
|
|
351
|
+
|
|
352
|
+
Versions up to and including 0.3.1 shipped with no licence field and no licence
|
|
353
|
+
file. From 0.4.0 they are present.
|
|
292
354
|
|
|
293
355
|
## Changelog
|
|
294
356
|
|
|
295
|
-
|
|
357
|
+
[`CHANGELOG.md`](./CHANGELOG.md), which ships inside the published tarball — the
|
|
358
|
+
repo-root file this used to point at is not what a consumer receives.
|
package/dist/artifacts.cjs
CHANGED
|
@@ -33,6 +33,8 @@ var EN = {
|
|
|
33
33
|
"TokenDisplayOnceModal.copied": "Copied",
|
|
34
34
|
"StatusBadge.aria.status": "Status",
|
|
35
35
|
"StatusBadge.error.invalidProps": "StatusBadge: invalid props",
|
|
36
|
+
"Badge.aria.label": "Badge",
|
|
37
|
+
"Badge.error.invalidProps": "Badge: invalid props",
|
|
36
38
|
"EmptyState.error.invalidProps": "EmptyState: invalid props",
|
|
37
39
|
"Toast.aria.close": "Close notification",
|
|
38
40
|
"Toast.error.invalidProps": "Toast: invalid props",
|
|
@@ -125,6 +127,8 @@ var FR = {
|
|
|
125
127
|
"TokenDisplayOnceModal.copied": "Copi\xE9",
|
|
126
128
|
"StatusBadge.aria.status": "Statut",
|
|
127
129
|
"StatusBadge.error.invalidProps": "StatusBadge : propri\xE9t\xE9s invalides",
|
|
130
|
+
"Badge.aria.label": "Badge",
|
|
131
|
+
"Badge.error.invalidProps": "Badge : propri\xE9t\xE9s invalides",
|
|
128
132
|
"EmptyState.error.invalidProps": "EmptyState : propri\xE9t\xE9s invalides",
|
|
129
133
|
"Toast.aria.close": "Fermer la notification",
|
|
130
134
|
"Toast.error.invalidProps": "Toast : propri\xE9t\xE9s invalides",
|
package/dist/artifacts.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/i18n/strings.ts","../src/components/artifacts/MarkdownRenderer.schema.ts","../src/components/artifacts/MarkdownRenderer.tsx"],"names":["z","jsx","marked","DOMPurify"],"mappings":";;;;;;;;;;;;;;AAgBA,IAAM,EAAA,GAAK;AAAA;AAAA,EAET,wBAAA,EAA0B,UAAA;AAAA,EAC1B,gCAAA,EAAkC,4BAAA;AAAA,EAClC,8BAAA,EAAgC,SAAA;AAAA,EAChC,6BAAA,EAA+B,QAAA;AAAA,EAC/B,2BAAA,EAA6B,qBAAA;AAAA,EAC7B,sBAAA,EAAwB,YAAA;AAAA,EACxB,2BAAA,EAA6B,WAAA;AAAA,EAC7B,2BAAA,EAA6B,eAAA;AAAA,EAC7B,yBAAA,EAA2B,oBAAA;AAAA,EAC3B,8BAAA,EAAgC,0BAAA;AAAA,EAChC,+BAAA,EAAiC,2BAAA;AAAA,EACjC,qCAAA,EAAuC,iCAAA;AAAA,EACvC,gCAAA,EAAkC,gCAAA;AAAA,EAClC,mCAAA,EAAqC,YAAA;AAAA,EACrC,oCAAA,EAAsC,OAAA;AAAA,EACtC,oCAAA,EAAsC,kDAAA;AAAA,EACtC,8BAAA,EAAgC,QAAA;AAAA,EAChC,yBAAA,EAA2B,QAAA;AAAA,EAC3B,gCAAA,EAAkC,4BAAA;AAAA,EAClC,+BAAA,EAAiC,2BAAA;AAAA,EACjC,kBAAA,EAAoB,oBAAA;AAAA,EACpB,0BAAA,EAA4B,sBAAA;AAAA,EAC5B,oBAAA,EAAsB,eAAA;AAAA,EACtB,0BAAA,EAA4B,sBAAA;AAAA,EAC5B,2BAAA,EAA6B,qBAAA;AAAA,EAC7B,gCAAA,EAAkC,4BAAA;AAAA,EAClC,qBAAA,EAAuB,SAAA;AAAA,EACvB,6BAAA,EAA+B,yBAAA;AAAA;AAAA,EAE/B,kCAAA,EAAoC,gCAAA;AAAA;AAAA,EAEpC,iCAAA,EAAmC,6BAAA;AAAA;AAAA,EAEnC,8BAAA,EAAgC,0BAAA;AAAA;AAAA,EAEhC,6BAAA,EAA+B,wBAAA;AAAA,EAC/B,wBAAA,EAA0B,4BAAA;AAAA,EAC1B,wBAAA,EAA0B,2BAAA;AAAA,EAC1B,8BAAA,EAAgC,oBAAA;AAAA,EAChC,8BAAA,EAAgC,mBAAA;AAAA,EAChC,4BAAA,EAA8B,gBAAA;AAAA,EAC9B,0BAAA,EAA4B,6BAAA;AAAA,EAC5B,wBAAA,EAA0B,mBAAA;AAAA,EAC1B,4BAAA,EAA8B,eAAA;AAAA;AAAA,EAE9B,0BAAA,EAA4B,aAAA;AAAA,EAC5B,4BAAA,EAA8B,kBAAA;AAAA,EAC9B,iCAAA,EAAmC,6BAAA;AAAA;AAAA,EAEnC,kBAAA,EAAoB,aAAA;AAAA,EACpB,sBAAA,EAAwB,wBAAA;AAAA,EACxB,qBAAA,EAAuB,eAAA;AAAA,EACvB,qBAAA,EAAuB,mBAAA;AAAA,EACvB,sBAAA,EAAwB,oBAAA;AAAA,EACxB,0BAAA,EAA4B,sBAAA;AAAA;AAAA,EAE5B,qBAAA,EAAuB,WAAA;AAAA,EACvB,yBAAA,EAA2B,wBAAA;AAAA,EAC3B,wBAAA,EAA0B,kBAAA;AAAA,EAC1B,4BAAA,EAA8B,sBAAA;AAAA,EAC9B,6BAAA,EAA+B,yBAAA;AAAA;AAAA,EAE/B,sBAAA,EAAwB,eAAA;AAAA,EACxB,yBAAA,EAA2B,UAAA;AAAA,EAC3B,4BAAA,EAA8B,aAAA;AAAA,EAC9B,+BAAA,EAAiC,2BAAA;AAAA;AAAA,EAEjC,qBAAA,EAAuB,UAAA;AAAA,EACvB,yBAAA,EAA2B,4BAAA;AAAA,EAC3B,6BAAA,EAA+B,yBAAA;AAAA;AAAA,EAE/B,wBAAA,EAA0B,oBAAA;AAAA,EAC1B,6BAAA,EAA+B,QAAA;AAAA,EAC/B,4BAAA,EAA8B,4BAAA;AAAA,EAC9B,4BAAA,EAA8B,sCAAA;AAAA,EAC9B,yBAAA,EAA2B,sBAAA;AAAA,EAC3B,gCAAA,EAAkC,cAAA;AAAA,EAClC,mBAAA,EAAqB,sBAAA;AAAA,EACrB,gCAAA,EAAkC,4BAAA;AAAA;AAAA,EAElC,uBAAA,EAAyB,aAAA;AAAA,EACzB,2BAAA,EAA6B,mBAAA;AAAA,EAC7B,+BAAA,EAAiC,2BAAA;AAAA;AAAA,EAEjC,oBAAA,EAAsB,wBAAA;AAAA,EACtB,2BAAA,EAA6B,cAAA;AAAA,EAC7B,cAAA,EAAgB,sBAAA;AAAA,EAChB,uBAAA,EAAyB,kBAAA;AAAA,EACzB,2BAAA,EAA6B;AAC/B,CAAA;AAEA,IAAM,EAAA,GAAsC;AAAA;AAAA,EAE1C,wBAAA,EAA0B,aAAA;AAAA,EAC1B,gCAAA,EAAkC,0CAAA;AAAA,EAClC,8BAAA,EAAgC,WAAA;AAAA,EAChC,6BAAA,EAA+B,SAAA;AAAA,EAC/B,2BAAA,EAA6B,sCAAA;AAAA,EAC7B,sBAAA,EAAwB,uBAAA;AAAA,EACxB,2BAAA,EAA6B,eAAA;AAAA,EAC7B,2BAAA,EAA6B,uBAAA;AAAA,EAC7B,yBAAA,EAA2B,gCAAA;AAAA,EAC3B,8BAAA,EAAgC,wCAAA;AAAA,EAChC,+BAAA,EAAiC,wBAAA;AAAA,EACjC,qCAAA,EAAuC,+CAAA;AAAA,EACvC,gCAAA,EAAkC,4CAAA;AAAA,EAClC,mCAAA,EAAqC,iBAAA;AAAA,EACrC,oCAAA,EAAsC,QAAA;AAAA,EACtC,oCAAA,EACE,sEAAA;AAAA,EACF,8BAAA,EAAgC,UAAA;AAAA,EAChC,yBAAA,EAA2B,QAAA;AAAA,EAC3B,gCAAA,EAAkC,0CAAA;AAAA,EAClC,+BAAA,EAAiC,yCAAA;AAAA,EACjC,kBAAA,EAAoB,wBAAA;AAAA,EACpB,0BAAA,EAA4B,oCAAA;AAAA,EAC5B,oBAAA,EAAsB,iBAAA;AAAA,EACtB,0BAAA,EAA4B,oCAAA;AAAA,EAC5B,2BAAA,EAA6B,mCAAA;AAAA,EAC7B,gCAAA,EAAkC,0CAAA;AAAA,EAClC,qBAAA,EAAuB,YAAA;AAAA,EACvB,6BAAA,EAA+B,uCAAA;AAAA;AAAA,EAE/B,kCAAA,EAAoC,mCAAA;AAAA;AAAA,EAEpC,iCAAA,EAAmC,2CAAA;AAAA;AAAA,EAEnC,8BAAA,EAAgC,wCAAA;AAAA;AAAA,EAEhC,6BAAA,EAA+B,0BAAA;AAAA,EAC/B,wBAAA,EAA0B,wCAAA;AAAA,EAC1B,wBAAA,EAA0B,iCAAA;AAAA,EAC1B,8BAAA,EAAgC,2BAAA;AAAA,EAChC,8BAAA,EAAgC,2BAAA;AAAA,EAChC,4BAAA,EAA8B,iBAAA;AAAA,EAC9B,0BAAA,EAA4B,qCAAA;AAAA,EAC5B,wBAAA,EAA0B,0BAAA;AAAA,EAC1B,4BAAA,EAA8B,iBAAA;AAAA;AAAA,EAE9B,0BAAA,EAA4B,yBAAA;AAAA,EAC5B,4BAAA,EAA8B,sBAAA;AAAA,EAC9B,iCAAA,EAAmC,2CAAA;AAAA;AAAA,EAEnC,kBAAA,EAAoB,iBAAA;AAAA,EACpB,sBAAA,EAAwB,0BAAA;AAAA,EACxB,qBAAA,EAAuB,iBAAA;AAAA,EACvB,qBAAA,EAAuB,2BAAA;AAAA,EACvB,sBAAA,EAAwB,2BAAA;AAAA,EACxB,0BAAA,EAA4B,oCAAA;AAAA;AAAA,EAE5B,qBAAA,EAAuB,eAAA;AAAA,EACvB,yBAAA,EAA2B,0BAAA;AAAA,EAC3B,wBAAA,EAA0B,wBAAA;AAAA,EAC1B,4BAAA,EAA8B,wBAAA;AAAA,EAC9B,6BAAA,EAA+B,uCAAA;AAAA;AAAA,EAE/B,sBAAA,EAAwB,wBAAA;AAAA,EACxB,yBAAA,EAA2B,0BAAA;AAAA,EAC3B,4BAAA,EAA8B,2BAAA;AAAA,EAC9B,+BAAA,EAAiC,yCAAA;AAAA;AAAA,EAEjC,qBAAA,EAAuB,kBAAA;AAAA,EACvB,yBAAA,EAA2B,gCAAA;AAAA,EAC3B,6BAAA,EAA+B,uCAAA;AAAA;AAAA,EAE/B,wBAAA,EAA0B,gCAAA;AAAA,EAC1B,6BAAA,EAA+B,SAAA;AAAA,EAC/B,4BAAA,EAA8B,qCAAA;AAAA,EAC9B,4BAAA,EAA8B,yCAAA;AAAA,EAC9B,yBAAA,EAA2B,mCAAA;AAAA,EAC3B,gCAAA,EAAkC,kBAAA;AAAA,EAClC,mBAAA,EAAqB,0BAAA;AAAA,EACrB,gCAAA,EAAkC,0CAAA;AAAA;AAAA,EAElC,uBAAA,EAAyB,yBAAA;AAAA,EACzB,2BAAA,EAA6B,4BAAA;AAAA,EAC7B,+BAAA,EAAiC,yCAAA;AAAA;AAAA,EAEjC,oBAAA,EAAsB,kCAAA;AAAA,EACtB,2BAAA,EAA6B,kBAAA;AAAA,EAC7B,cAAA,EAAgB,0BAAA;AAAA,EAChB,uBAAA,EAAyB,4BAAA;AAAA,EACzB,2BAAA,EAA6B;AAC/B,CAAA;AAIA,IAAM,KAAA,GAA6D;AAAA,EACjE,EAAA,EAAI,EAAA;AAAA,EACJ,EAAA,EAAI;AACN,CAAA;AAGO,SAAS,CAAA,CAAE,GAAA,EAAoB,MAAA,GAAuB,IAAA,EAAc;AACzE,EAAA,OAAO,MAAM,MAAM,CAAA,GAAI,GAAG,CAAA,IAAK,KAAA,CAAM,GAAG,GAAG,CAAA;AAC7C;ACnNO,IAAM,2BAAA,GAA8BA,MAAE,MAAA,CAAO;AAAA,EAClD,OAAA,EAASA,MAAE,MAAA,EAAO;AAAA,EAClB,QAAQA,KAAA,CAAE,IAAA,CAAK,CAAC,IAAA,EAAM,IAAI,CAAC,CAAA;AAAA,EAC3B,WAAWA,KAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,QAAQ,GAAK,CAAA;AAAA,EAC9C,SAAA,EAAWA,KAAA,CAAE,OAAA,EAAQ,CAAE,QAAQ,KAAK;AACtC,CAAC;AAIM,SAAS,cAAc,GAAA,EAAqC;AACjE,EAAA,OAAO,2BAAA,CAA4B,MAAM,GAAG,CAAA;AAC9C;ACCA,IAAM,eAAA,GAA+C;AAAA,EACnD,EAAA,EAAI,iCAAA;AAAA,EACJ,EAAA,EAAI;AACN,CAAA;AAEA,SAAS,qBAAA,CAAsB;AAAA,EAC7B,OAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA,EAA+B;AAC7B,EAAA,IAAI,OAAA,CAAQ,SAAS,SAAA,EAAW;AAC9B,IAAA,uBACEC,cAAA,CAAC,SAAI,IAAA,EAAK,OAAA,EAAQ,MAAM,MAAA,EACrB,QAAA,EAAA,eAAA,CAAgB,MAAM,CAAA,EACzB,CAAA;AAAA,EAEJ;AAIA,EAAA,MAAM,SAAS,SAAA,GAAY,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,YAAY,EAAE,CAAA;AACnE,EAAA,MAAM,UAAUC,aAAA,CAAO,KAAA,CAAM,QAAQ,EAAE,KAAA,EAAO,OAAO,CAAA;AAErD,EAAA,MAAM,SAAA,GAAYC,0BAAA,CAAU,QAAA,CAAS,OAAO,CAAA;AAE5C,EAAA,MAAM,SAAA,GAAY,MAAA,KAAW,IAAA,GAAO,oBAAA,GAAoB,mBAAA;AAExD,EAAA,uBACEF,cAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,YAAA,EAAY,SAAA;AAAA,MACZ,IAAA,EAAM,MAAA;AAAA,MAEN,uBAAA,EAAyB,EAAE,MAAA,EAAQ,SAAA;AAAU;AAAA,GAC/C;AAEJ;AAMO,SAAS,iBAAiB,GAAA,EAA8B;AAC7D,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,GAAQ,cAAc,GAAG,CAAA;AAC/B,IAAA,uBAAOA,cAAA,CAAC,qBAAA,EAAA,EAAuB,GAAG,KAAA,EAAO,CAAA;AAAA,EAC3C,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,MAAA,GAAuB,GAAA,CAAI,MAAA,KAAW,IAAA,GAAO,IAAA,GAAO,IAAA;AAC1D,IAAA,sCAAQ,KAAA,EAAA,EAAI,IAAA,EAAK,SAAS,QAAA,EAAA,CAAA,CAAE,qCAAA,EAAuC,MAAM,CAAA,EAAE,CAAA;AAAA,EAC7E;AACF","file":"artifacts.cjs","sourcesContent":["/**\n * Compile-time mirror of `@vantageos/mosaic-i18n` EN/FR locales for all\n * Mosaic components (v0.3.0). Inlined here so that `<Comp>` renderers can\n * resolve `t(key, locale)` without dragging react-i18next into the component\n * runtime (keeps bundle small and tests provider-free). Drift is gated by\n * `mosaic-registry-drift-check.mjs` which validates the canonical\n * `packages/mosaic-i18n/src/locales/{en,fr}.json` against `registry.yaml`.\n *\n * Mosaic standard §8: production JSX MUST resolve user-facing strings via\n * `t()` — no hardcoded English literals.\n *\n * Forms keys added — v0.3.0-C-PR1 (Axis 5/6 i18n pass).\n * Convention: Forms.<Component>.<context>.<id>\n */\nexport type MosaicLocale = \"en\" | \"fr\";\n\nconst EN = {\n // ─── Non-forms components ──────────────────────────────────────────────────\n \"ProgressBar.aria.label\": \"Progress\",\n \"ProgressBar.error.invalidProps\": \"ProgressBar: invalid props\",\n \"ConfirmDialog.button.confirm\": \"Confirm\",\n \"ConfirmDialog.button.cancel\": \"Cancel\",\n \"ConfirmDialog.aria.dialog\": \"Confirmation dialog\",\n \"TableView.aria.table\": \"Data table\",\n \"TableView.pagination.next\": \"Next page\",\n \"TableView.pagination.prev\": \"Previous page\",\n \"TableView.empty.message\": \"No data to display\",\n \"TableView.error.invalidProps\": \"TableView: invalid props\",\n \"MarkdownRenderer.aria.content\": \"Rendered Markdown content\",\n \"MarkdownRenderer.error.invalidProps\": \"MarkdownRenderer: invalid props\",\n \"MarkdownRenderer.error.tooLong\": \"Content exceeds maximum length\",\n \"TokenDisplayOnceModal.button.copy\": \"Copy token\",\n \"TokenDisplayOnceModal.button.close\": \"Close\",\n \"TokenDisplayOnceModal.warning.once\": \"This token will only be shown once. Copy it now.\",\n \"TokenDisplayOnceModal.copied\": \"Copied\",\n \"StatusBadge.aria.status\": \"Status\",\n \"StatusBadge.error.invalidProps\": \"StatusBadge: invalid props\",\n \"EmptyState.error.invalidProps\": \"EmptyState: invalid props\",\n \"Toast.aria.close\": \"Close notification\",\n \"Toast.error.invalidProps\": \"Toast: invalid props\",\n \"Alert.aria.dismiss\": \"Dismiss alert\",\n \"Alert.error.invalidProps\": \"Alert: invalid props\",\n \"VirtualList.empty.message\": \"No items to display\",\n \"VirtualList.error.invalidProps\": \"VirtualList: invalid props\",\n \"Skeleton.aria.label\": \"Loading\",\n \"Skeleton.error.invalidProps\": \"Skeleton: invalid props\",\n // ─── Forms — useMosaicForm ─────────────────────────────────────────────────\n \"useMosaicForm.error.invalidProps\": \"useMosaicForm: invalid options\",\n // ─── Forms — FormProvider ──────────────────────────────────────────────────\n \"FormProvider.error.invalidProps\": \"FormProvider: invalid props\",\n // ─── Forms — FormField ────────────────────────────────────────────────────\n \"FormField.error.invalidProps\": \"FormField: invalid props\",\n // ─── Forms — ErrorDisplay ─────────────────────────────────────────────────\n \"ErrorDisplay.error.required\": \"This field is required\",\n \"ErrorDisplay.error.min\": \"Value is below the minimum\",\n \"ErrorDisplay.error.max\": \"Value exceeds the maximum\",\n \"ErrorDisplay.error.minLength\": \"Input is too short\",\n \"ErrorDisplay.error.maxLength\": \"Input is too long\",\n \"ErrorDisplay.error.pattern\": \"Invalid format\",\n \"ErrorDisplay.error.email\": \"Enter a valid email address\",\n \"ErrorDisplay.error.url\": \"Enter a valid URL\",\n \"ErrorDisplay.error.generic\": \"Invalid value\",\n // ─── Forms — SubmitButton ─────────────────────────────────────────────────\n \"SubmitButton.aria.submit\": \"Submit form\",\n \"SubmitButton.state.loading\": \"Submitting…\",\n \"SubmitButton.error.invalidProps\": \"SubmitButton: invalid props\",\n // ─── Forms — Input ────────────────────────────────────────────────────────\n \"Input.aria.label\": \"Input field\",\n \"Input.error.required\": \"This field is required\",\n \"Input.error.invalid\": \"Invalid value\",\n \"Input.error.tooLong\": \"Input is too long\",\n \"Input.error.tooShort\": \"Input is too short\",\n \"Input.error.invalidProps\": \"Input: invalid props\",\n // ─── Forms — Textarea ─────────────────────────────────────────────────────\n \"Textarea.aria.label\": \"Text area\",\n \"Textarea.error.required\": \"This field is required\",\n \"Textarea.error.tooLong\": \"Text is too long\",\n \"Textarea.counter.remaining\": \"characters remaining\",\n \"Textarea.error.invalidProps\": \"Textarea: invalid props\",\n // ─── Forms — FieldArray ───────────────────────────────────────────────────\n \"FieldArray.aria.list\": \"List of items\",\n \"FieldArray.aria.addItem\": \"Add item\",\n \"FieldArray.aria.removeItem\": \"Remove item\",\n \"FieldArray.error.invalidProps\": \"FieldArray: invalid props\",\n // ─── Forms — Checkbox ─────────────────────────────────────────────────────\n \"Checkbox.aria.label\": \"Checkbox\",\n \"Checkbox.error.required\": \"This field must be checked\",\n \"Checkbox.error.invalidProps\": \"Checkbox: invalid props\",\n // ─── Forms — MultiSelect ──────────────────────────────────────────────────\n \"MultiSelect.aria.label\": \"Multi-select field\",\n \"MultiSelect.aria.removeChip\": \"Remove\",\n \"MultiSelect.error.required\": \"Select at least one option\",\n \"MultiSelect.error.maxItems\": \"Maximum number of selections reached\",\n \"MultiSelect.placeholder\": \"Select options…\",\n \"MultiSelect.search.placeholder\": \"Search…\",\n \"MultiSelect.empty\": \"No options available\",\n \"MultiSelect.error.invalidProps\": \"MultiSelect: invalid props\",\n // ─── Forms — RadioGroup ───────────────────────────────────────────────────\n \"RadioGroup.aria.label\": \"Radio group\",\n \"RadioGroup.error.required\": \"Select one option\",\n \"RadioGroup.error.invalidProps\": \"RadioGroup: invalid props\",\n // ─── Forms — Select ───────────────────────────────────────────────────────\n \"Select.placeholder\": \"Select an option…\",\n \"Select.search.placeholder\": \"Search…\",\n \"Select.empty\": \"No options available\",\n \"Select.error.required\": \"Select an option\",\n \"Select.error.invalidProps\": \"Select: invalid props\",\n} as const;\n\nconst FR: Record<keyof typeof EN, string> = {\n // ─── Non-forms components ──────────────────────────────────────────────────\n \"ProgressBar.aria.label\": \"Progression\",\n \"ProgressBar.error.invalidProps\": \"ProgressBar : propriétés invalides\",\n \"ConfirmDialog.button.confirm\": \"Confirmer\",\n \"ConfirmDialog.button.cancel\": \"Annuler\",\n \"ConfirmDialog.aria.dialog\": \"Boîte de dialogue de confirmation\",\n \"TableView.aria.table\": \"Tableau de données\",\n \"TableView.pagination.next\": \"Page suivante\",\n \"TableView.pagination.prev\": \"Page précédente\",\n \"TableView.empty.message\": \"Aucune donnée à afficher\",\n \"TableView.error.invalidProps\": \"TableView : propriétés invalides\",\n \"MarkdownRenderer.aria.content\": \"Contenu Markdown rendu\",\n \"MarkdownRenderer.error.invalidProps\": \"MarkdownRenderer : propriétés invalides\",\n \"MarkdownRenderer.error.tooLong\": \"Le contenu dépasse la longueur maximale\",\n \"TokenDisplayOnceModal.button.copy\": \"Copier le jeton\",\n \"TokenDisplayOnceModal.button.close\": \"Fermer\",\n \"TokenDisplayOnceModal.warning.once\":\n \"Ce jeton ne sera affiché qu'une seule fois. Copiez-le maintenant.\",\n \"TokenDisplayOnceModal.copied\": \"Copié\",\n \"StatusBadge.aria.status\": \"Statut\",\n \"StatusBadge.error.invalidProps\": \"StatusBadge : propriétés invalides\",\n \"EmptyState.error.invalidProps\": \"EmptyState : propriétés invalides\",\n \"Toast.aria.close\": \"Fermer la notification\",\n \"Toast.error.invalidProps\": \"Toast : propriétés invalides\",\n \"Alert.aria.dismiss\": \"Fermer l'alerte\",\n \"Alert.error.invalidProps\": \"Alert : propriétés invalides\",\n \"VirtualList.empty.message\": \"Aucun élément à afficher\",\n \"VirtualList.error.invalidProps\": \"VirtualList : propriétés invalides\",\n \"Skeleton.aria.label\": \"Chargement\",\n \"Skeleton.error.invalidProps\": \"Skeleton : propriétés invalides\",\n // ─── Forms — useMosaicForm ─────────────────────────────────────────────────\n \"useMosaicForm.error.invalidProps\": \"useMosaicForm : options invalides\",\n // ─── Forms — FormProvider ──────────────────────────────────────────────────\n \"FormProvider.error.invalidProps\": \"FormProvider : propriétés invalides\",\n // ─── Forms — FormField ────────────────────────────────────────────────────\n \"FormField.error.invalidProps\": \"FormField : propriétés invalides\",\n // ─── Forms — ErrorDisplay ─────────────────────────────────────────────────\n \"ErrorDisplay.error.required\": \"Ce champ est obligatoire\",\n \"ErrorDisplay.error.min\": \"La valeur est inférieure au minimum\",\n \"ErrorDisplay.error.max\": \"La valeur dépasse le maximum\",\n \"ErrorDisplay.error.minLength\": \"La saisie est trop courte\",\n \"ErrorDisplay.error.maxLength\": \"La saisie est trop longue\",\n \"ErrorDisplay.error.pattern\": \"Format invalide\",\n \"ErrorDisplay.error.email\": \"Saisissez une adresse e-mail valide\",\n \"ErrorDisplay.error.url\": \"Saisissez une URL valide\",\n \"ErrorDisplay.error.generic\": \"Valeur invalide\",\n // ─── Forms — SubmitButton ─────────────────────────────────────────────────\n \"SubmitButton.aria.submit\": \"Soumettre le formulaire\",\n \"SubmitButton.state.loading\": \"Envoi en cours…\",\n \"SubmitButton.error.invalidProps\": \"SubmitButton : propriétés invalides\",\n // ─── Forms — Input ────────────────────────────────────────────────────────\n \"Input.aria.label\": \"Champ de saisie\",\n \"Input.error.required\": \"Ce champ est obligatoire\",\n \"Input.error.invalid\": \"Valeur invalide\",\n \"Input.error.tooLong\": \"La saisie est trop longue\",\n \"Input.error.tooShort\": \"La saisie est trop courte\",\n \"Input.error.invalidProps\": \"Input : propriétés invalides\",\n // ─── Forms — Textarea ─────────────────────────────────────────────────────\n \"Textarea.aria.label\": \"Zone de texte\",\n \"Textarea.error.required\": \"Ce champ est obligatoire\",\n \"Textarea.error.tooLong\": \"Le texte est trop long\",\n \"Textarea.counter.remaining\": \"caractères restants\",\n \"Textarea.error.invalidProps\": \"Textarea : propriétés invalides\",\n // ─── Forms — FieldArray ───────────────────────────────────────────────────\n \"FieldArray.aria.list\": \"Liste d'éléments\",\n \"FieldArray.aria.addItem\": \"Ajouter un élément\",\n \"FieldArray.aria.removeItem\": \"Supprimer l'élément\",\n \"FieldArray.error.invalidProps\": \"FieldArray : propriétés invalides\",\n // ─── Forms — Checkbox ─────────────────────────────────────────────────────\n \"Checkbox.aria.label\": \"Case à cocher\",\n \"Checkbox.error.required\": \"Ce champ doit être coché\",\n \"Checkbox.error.invalidProps\": \"Checkbox : propriétés invalides\",\n // ─── Forms — MultiSelect ──────────────────────────────────────────────────\n \"MultiSelect.aria.label\": \"Champ de sélection multiple\",\n \"MultiSelect.aria.removeChip\": \"Retirer\",\n \"MultiSelect.error.required\": \"Sélectionnez au moins une option\",\n \"MultiSelect.error.maxItems\": \"Nombre maximum de sélections atteint\",\n \"MultiSelect.placeholder\": \"Sélectionner des options…\",\n \"MultiSelect.search.placeholder\": \"Rechercher…\",\n \"MultiSelect.empty\": \"Aucune option disponible\",\n \"MultiSelect.error.invalidProps\": \"MultiSelect : propriétés invalides\",\n // ─── Forms — RadioGroup ───────────────────────────────────────────────────\n \"RadioGroup.aria.label\": \"Groupe de boutons radio\",\n \"RadioGroup.error.required\": \"Sélectionnez une option\",\n \"RadioGroup.error.invalidProps\": \"RadioGroup : propriétés invalides\",\n // ─── Forms — Select ───────────────────────────────────────────────────────\n \"Select.placeholder\": \"Sélectionner une option…\",\n \"Select.search.placeholder\": \"Rechercher…\",\n \"Select.empty\": \"Aucune option disponible\",\n \"Select.error.required\": \"Sélectionnez une option\",\n \"Select.error.invalidProps\": \"Select : propriétés invalides\",\n};\n\nexport type MosaicI18nKey = keyof typeof EN;\n\nconst TABLE: Record<MosaicLocale, Record<MosaicI18nKey, string>> = {\n en: EN,\n fr: FR,\n};\n\n/** Resolves a Mosaic i18n key for the given locale, falling back to EN. */\nexport function t(key: MosaicI18nKey, locale: MosaicLocale = \"en\"): string {\n return TABLE[locale]?.[key] ?? TABLE.en[key];\n}\n","import { z } from \"zod\";\n\nexport const MarkdownRendererPropsSchema = z.object({\n content: z.string(),\n locale: z.enum([\"en\", \"fr\"]),\n maxLength: z.number().positive().default(50000),\n allowHtml: z.boolean().default(false),\n});\n\nexport type MarkdownRendererProps = z.infer<typeof MarkdownRendererPropsSchema>;\n\nexport function validateProps(raw: unknown): MarkdownRendererProps {\n return MarkdownRendererPropsSchema.parse(raw);\n}\n","import DOMPurify from \"dompurify\";\nimport { marked } from \"marked\";\n// i18nKeys: MarkdownRenderer.aria.content, MarkdownRenderer.error.invalidProps, MarkdownRenderer.error.tooLong\nimport React from \"react\";\nimport { type MosaicLocale, t } from \"../../i18n/strings.js\";\nimport { type MarkdownRendererProps, validateProps } from \"./MarkdownRenderer.schema\";\n\ninterface MarkdownRendererInnerProps {\n content: string;\n locale: \"en\" | \"fr\";\n maxLength: number;\n allowHtml: boolean;\n}\n\nconst tooLongMessages: Record<\"en\" | \"fr\", string> = {\n en: \"Content exceeds maximum length.\",\n fr: \"Le contenu dépasse la longueur maximale.\",\n};\n\nfunction MarkdownRendererInner({\n content,\n locale,\n maxLength,\n allowHtml,\n}: MarkdownRendererInnerProps) {\n if (content.length > maxLength) {\n return (\n <div role=\"alert\" lang={locale}>\n {tooLongMessages[locale]}\n </div>\n );\n }\n\n // When allowHtml=false, strip raw HTML tags from source before parsing,\n // so user-supplied HTML is neutralised before marked converts markdown to HTML.\n const source = allowHtml ? content : content.replace(/<[^>]*>/g, \"\");\n const rawHtml = marked.parse(source, { async: false }) as string;\n // Always sanitize the marked output to prevent XSS from markdown-injected HTML.\n const cleanHtml = DOMPurify.sanitize(rawHtml);\n\n const ariaLabel = locale === \"fr\" ? \"Contenu formaté\" : \"Formatted content\";\n\n return (\n <article\n aria-label={ariaLabel}\n lang={locale}\n // biome-ignore lint/security/noDangerouslySetInnerHtml: sanitized by DOMPurify\n dangerouslySetInnerHTML={{ __html: cleanHtml }}\n />\n );\n}\n\n/**\n * MarkdownRenderer accepts any props object for JSX and MCP postMessage injection alike.\n * Internal Zod validation narrows the type — invalid data renders an accessible error fallback.\n */\nexport function MarkdownRenderer(raw: Record<string, unknown>) {\n try {\n const props = validateProps(raw);\n return <MarkdownRendererInner {...props} />;\n } catch {\n const locale: MosaicLocale = raw.locale === \"fr\" ? \"fr\" : \"en\";\n return <div role=\"alert\">{t(\"MarkdownRenderer.error.invalidProps\", locale)}</div>;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/i18n/strings.ts","../src/components/artifacts/MarkdownRenderer.schema.ts","../src/components/artifacts/MarkdownRenderer.tsx"],"names":["z","jsx","marked","DOMPurify"],"mappings":"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","file":"artifacts.cjs","sourcesContent":["/**\n * Compile-time mirror of `@vantageos/mosaic-i18n` EN/FR locales for all\n * Mosaic components (v0.3.0). Inlined here so that `<Comp>` renderers can\n * resolve `t(key, locale)` without dragging react-i18next into the component\n * runtime (keeps bundle small and tests provider-free). Drift is gated by\n * `mosaic-registry-drift-check.mjs` which validates the canonical\n * `packages/mosaic-i18n/src/locales/{en,fr}.json` against `registry.yaml`.\n *\n * Mosaic standard §8: production JSX MUST resolve user-facing strings via\n * `t()` — no hardcoded English literals.\n *\n * Forms keys added — v0.3.0-C-PR1 (Axis 5/6 i18n pass).\n * Convention: Forms.<Component>.<context>.<id>\n */\nexport type MosaicLocale = \"en\" | \"fr\";\n\nconst EN = {\n // ─── Non-forms components ──────────────────────────────────────────────────\n \"ProgressBar.aria.label\": \"Progress\",\n \"ProgressBar.error.invalidProps\": \"ProgressBar: invalid props\",\n \"ConfirmDialog.button.confirm\": \"Confirm\",\n \"ConfirmDialog.button.cancel\": \"Cancel\",\n \"ConfirmDialog.aria.dialog\": \"Confirmation dialog\",\n \"TableView.aria.table\": \"Data table\",\n \"TableView.pagination.next\": \"Next page\",\n \"TableView.pagination.prev\": \"Previous page\",\n \"TableView.empty.message\": \"No data to display\",\n \"TableView.error.invalidProps\": \"TableView: invalid props\",\n \"MarkdownRenderer.aria.content\": \"Rendered Markdown content\",\n \"MarkdownRenderer.error.invalidProps\": \"MarkdownRenderer: invalid props\",\n \"MarkdownRenderer.error.tooLong\": \"Content exceeds maximum length\",\n \"TokenDisplayOnceModal.button.copy\": \"Copy token\",\n \"TokenDisplayOnceModal.button.close\": \"Close\",\n \"TokenDisplayOnceModal.warning.once\": \"This token will only be shown once. Copy it now.\",\n \"TokenDisplayOnceModal.copied\": \"Copied\",\n \"StatusBadge.aria.status\": \"Status\",\n \"StatusBadge.error.invalidProps\": \"StatusBadge: invalid props\",\n \"Badge.aria.label\": \"Badge\",\n \"Badge.error.invalidProps\": \"Badge: invalid props\",\n \"EmptyState.error.invalidProps\": \"EmptyState: invalid props\",\n \"Toast.aria.close\": \"Close notification\",\n \"Toast.error.invalidProps\": \"Toast: invalid props\",\n \"Alert.aria.dismiss\": \"Dismiss alert\",\n \"Alert.error.invalidProps\": \"Alert: invalid props\",\n \"VirtualList.empty.message\": \"No items to display\",\n \"VirtualList.error.invalidProps\": \"VirtualList: invalid props\",\n \"Skeleton.aria.label\": \"Loading\",\n \"Skeleton.error.invalidProps\": \"Skeleton: invalid props\",\n // ─── Forms — useMosaicForm ─────────────────────────────────────────────────\n \"useMosaicForm.error.invalidProps\": \"useMosaicForm: invalid options\",\n // ─── Forms — FormProvider ──────────────────────────────────────────────────\n \"FormProvider.error.invalidProps\": \"FormProvider: invalid props\",\n // ─── Forms — FormField ────────────────────────────────────────────────────\n \"FormField.error.invalidProps\": \"FormField: invalid props\",\n // ─── Forms — ErrorDisplay ─────────────────────────────────────────────────\n \"ErrorDisplay.error.required\": \"This field is required\",\n \"ErrorDisplay.error.min\": \"Value is below the minimum\",\n \"ErrorDisplay.error.max\": \"Value exceeds the maximum\",\n \"ErrorDisplay.error.minLength\": \"Input is too short\",\n \"ErrorDisplay.error.maxLength\": \"Input is too long\",\n \"ErrorDisplay.error.pattern\": \"Invalid format\",\n \"ErrorDisplay.error.email\": \"Enter a valid email address\",\n \"ErrorDisplay.error.url\": \"Enter a valid URL\",\n \"ErrorDisplay.error.generic\": \"Invalid value\",\n // ─── Forms — SubmitButton ─────────────────────────────────────────────────\n \"SubmitButton.aria.submit\": \"Submit form\",\n \"SubmitButton.state.loading\": \"Submitting…\",\n \"SubmitButton.error.invalidProps\": \"SubmitButton: invalid props\",\n // ─── Forms — Input ────────────────────────────────────────────────────────\n \"Input.aria.label\": \"Input field\",\n \"Input.error.required\": \"This field is required\",\n \"Input.error.invalid\": \"Invalid value\",\n \"Input.error.tooLong\": \"Input is too long\",\n \"Input.error.tooShort\": \"Input is too short\",\n \"Input.error.invalidProps\": \"Input: invalid props\",\n // ─── Forms — Textarea ─────────────────────────────────────────────────────\n \"Textarea.aria.label\": \"Text area\",\n \"Textarea.error.required\": \"This field is required\",\n \"Textarea.error.tooLong\": \"Text is too long\",\n \"Textarea.counter.remaining\": \"characters remaining\",\n \"Textarea.error.invalidProps\": \"Textarea: invalid props\",\n // ─── Forms — FieldArray ───────────────────────────────────────────────────\n \"FieldArray.aria.list\": \"List of items\",\n \"FieldArray.aria.addItem\": \"Add item\",\n \"FieldArray.aria.removeItem\": \"Remove item\",\n \"FieldArray.error.invalidProps\": \"FieldArray: invalid props\",\n // ─── Forms — Checkbox ─────────────────────────────────────────────────────\n \"Checkbox.aria.label\": \"Checkbox\",\n \"Checkbox.error.required\": \"This field must be checked\",\n \"Checkbox.error.invalidProps\": \"Checkbox: invalid props\",\n // ─── Forms — MultiSelect ──────────────────────────────────────────────────\n \"MultiSelect.aria.label\": \"Multi-select field\",\n \"MultiSelect.aria.removeChip\": \"Remove\",\n \"MultiSelect.error.required\": \"Select at least one option\",\n \"MultiSelect.error.maxItems\": \"Maximum number of selections reached\",\n \"MultiSelect.placeholder\": \"Select options…\",\n \"MultiSelect.search.placeholder\": \"Search…\",\n \"MultiSelect.empty\": \"No options available\",\n \"MultiSelect.error.invalidProps\": \"MultiSelect: invalid props\",\n // ─── Forms — RadioGroup ───────────────────────────────────────────────────\n \"RadioGroup.aria.label\": \"Radio group\",\n \"RadioGroup.error.required\": \"Select one option\",\n \"RadioGroup.error.invalidProps\": \"RadioGroup: invalid props\",\n // ─── Forms — Select ───────────────────────────────────────────────────────\n \"Select.placeholder\": \"Select an option…\",\n \"Select.search.placeholder\": \"Search…\",\n \"Select.empty\": \"No options available\",\n \"Select.error.required\": \"Select an option\",\n \"Select.error.invalidProps\": \"Select: invalid props\",\n} as const;\n\nconst FR: Record<keyof typeof EN, string> = {\n // ─── Non-forms components ──────────────────────────────────────────────────\n \"ProgressBar.aria.label\": \"Progression\",\n \"ProgressBar.error.invalidProps\": \"ProgressBar : propriétés invalides\",\n \"ConfirmDialog.button.confirm\": \"Confirmer\",\n \"ConfirmDialog.button.cancel\": \"Annuler\",\n \"ConfirmDialog.aria.dialog\": \"Boîte de dialogue de confirmation\",\n \"TableView.aria.table\": \"Tableau de données\",\n \"TableView.pagination.next\": \"Page suivante\",\n \"TableView.pagination.prev\": \"Page précédente\",\n \"TableView.empty.message\": \"Aucune donnée à afficher\",\n \"TableView.error.invalidProps\": \"TableView : propriétés invalides\",\n \"MarkdownRenderer.aria.content\": \"Contenu Markdown rendu\",\n \"MarkdownRenderer.error.invalidProps\": \"MarkdownRenderer : propriétés invalides\",\n \"MarkdownRenderer.error.tooLong\": \"Le contenu dépasse la longueur maximale\",\n \"TokenDisplayOnceModal.button.copy\": \"Copier le jeton\",\n \"TokenDisplayOnceModal.button.close\": \"Fermer\",\n \"TokenDisplayOnceModal.warning.once\":\n \"Ce jeton ne sera affiché qu'une seule fois. Copiez-le maintenant.\",\n \"TokenDisplayOnceModal.copied\": \"Copié\",\n \"StatusBadge.aria.status\": \"Statut\",\n \"StatusBadge.error.invalidProps\": \"StatusBadge : propriétés invalides\",\n \"Badge.aria.label\": \"Badge\",\n \"Badge.error.invalidProps\": \"Badge : propriétés invalides\",\n \"EmptyState.error.invalidProps\": \"EmptyState : propriétés invalides\",\n \"Toast.aria.close\": \"Fermer la notification\",\n \"Toast.error.invalidProps\": \"Toast : propriétés invalides\",\n \"Alert.aria.dismiss\": \"Fermer l'alerte\",\n \"Alert.error.invalidProps\": \"Alert : propriétés invalides\",\n \"VirtualList.empty.message\": \"Aucun élément à afficher\",\n \"VirtualList.error.invalidProps\": \"VirtualList : propriétés invalides\",\n \"Skeleton.aria.label\": \"Chargement\",\n \"Skeleton.error.invalidProps\": \"Skeleton : propriétés invalides\",\n // ─── Forms — useMosaicForm ─────────────────────────────────────────────────\n \"useMosaicForm.error.invalidProps\": \"useMosaicForm : options invalides\",\n // ─── Forms — FormProvider ──────────────────────────────────────────────────\n \"FormProvider.error.invalidProps\": \"FormProvider : propriétés invalides\",\n // ─── Forms — FormField ────────────────────────────────────────────────────\n \"FormField.error.invalidProps\": \"FormField : propriétés invalides\",\n // ─── Forms — ErrorDisplay ─────────────────────────────────────────────────\n \"ErrorDisplay.error.required\": \"Ce champ est obligatoire\",\n \"ErrorDisplay.error.min\": \"La valeur est inférieure au minimum\",\n \"ErrorDisplay.error.max\": \"La valeur dépasse le maximum\",\n \"ErrorDisplay.error.minLength\": \"La saisie est trop courte\",\n \"ErrorDisplay.error.maxLength\": \"La saisie est trop longue\",\n \"ErrorDisplay.error.pattern\": \"Format invalide\",\n \"ErrorDisplay.error.email\": \"Saisissez une adresse e-mail valide\",\n \"ErrorDisplay.error.url\": \"Saisissez une URL valide\",\n \"ErrorDisplay.error.generic\": \"Valeur invalide\",\n // ─── Forms — SubmitButton ─────────────────────────────────────────────────\n \"SubmitButton.aria.submit\": \"Soumettre le formulaire\",\n \"SubmitButton.state.loading\": \"Envoi en cours…\",\n \"SubmitButton.error.invalidProps\": \"SubmitButton : propriétés invalides\",\n // ─── Forms — Input ────────────────────────────────────────────────────────\n \"Input.aria.label\": \"Champ de saisie\",\n \"Input.error.required\": \"Ce champ est obligatoire\",\n \"Input.error.invalid\": \"Valeur invalide\",\n \"Input.error.tooLong\": \"La saisie est trop longue\",\n \"Input.error.tooShort\": \"La saisie est trop courte\",\n \"Input.error.invalidProps\": \"Input : propriétés invalides\",\n // ─── Forms — Textarea ─────────────────────────────────────────────────────\n \"Textarea.aria.label\": \"Zone de texte\",\n \"Textarea.error.required\": \"Ce champ est obligatoire\",\n \"Textarea.error.tooLong\": \"Le texte est trop long\",\n \"Textarea.counter.remaining\": \"caractères restants\",\n \"Textarea.error.invalidProps\": \"Textarea : propriétés invalides\",\n // ─── Forms — FieldArray ───────────────────────────────────────────────────\n \"FieldArray.aria.list\": \"Liste d'éléments\",\n \"FieldArray.aria.addItem\": \"Ajouter un élément\",\n \"FieldArray.aria.removeItem\": \"Supprimer l'élément\",\n \"FieldArray.error.invalidProps\": \"FieldArray : propriétés invalides\",\n // ─── Forms — Checkbox ─────────────────────────────────────────────────────\n \"Checkbox.aria.label\": \"Case à cocher\",\n \"Checkbox.error.required\": \"Ce champ doit être coché\",\n \"Checkbox.error.invalidProps\": \"Checkbox : propriétés invalides\",\n // ─── Forms — MultiSelect ──────────────────────────────────────────────────\n \"MultiSelect.aria.label\": \"Champ de sélection multiple\",\n \"MultiSelect.aria.removeChip\": \"Retirer\",\n \"MultiSelect.error.required\": \"Sélectionnez au moins une option\",\n \"MultiSelect.error.maxItems\": \"Nombre maximum de sélections atteint\",\n \"MultiSelect.placeholder\": \"Sélectionner des options…\",\n \"MultiSelect.search.placeholder\": \"Rechercher…\",\n \"MultiSelect.empty\": \"Aucune option disponible\",\n \"MultiSelect.error.invalidProps\": \"MultiSelect : propriétés invalides\",\n // ─── Forms — RadioGroup ───────────────────────────────────────────────────\n \"RadioGroup.aria.label\": \"Groupe de boutons radio\",\n \"RadioGroup.error.required\": \"Sélectionnez une option\",\n \"RadioGroup.error.invalidProps\": \"RadioGroup : propriétés invalides\",\n // ─── Forms — Select ───────────────────────────────────────────────────────\n \"Select.placeholder\": \"Sélectionner une option…\",\n \"Select.search.placeholder\": \"Rechercher…\",\n \"Select.empty\": \"Aucune option disponible\",\n \"Select.error.required\": \"Sélectionnez une option\",\n \"Select.error.invalidProps\": \"Select : propriétés invalides\",\n};\n\nexport type MosaicI18nKey = keyof typeof EN;\n\nconst TABLE: Record<MosaicLocale, Record<MosaicI18nKey, string>> = {\n en: EN,\n fr: FR,\n};\n\n/** Resolves a Mosaic i18n key for the given locale, falling back to EN. */\nexport function t(key: MosaicI18nKey, locale: MosaicLocale = \"en\"): string {\n return TABLE[locale]?.[key] ?? TABLE.en[key];\n}\n","import { z } from \"zod\";\n\nexport const MarkdownRendererPropsSchema = z.object({\n content: z.string(),\n locale: z.enum([\"en\", \"fr\"]),\n maxLength: z.number().positive().default(50000),\n allowHtml: z.boolean().default(false),\n});\n\nexport type MarkdownRendererProps = z.infer<typeof MarkdownRendererPropsSchema>;\n\nexport function validateProps(raw: unknown): MarkdownRendererProps {\n return MarkdownRendererPropsSchema.parse(raw);\n}\n","import DOMPurify from \"dompurify\";\nimport { marked } from \"marked\";\n// i18nKeys: MarkdownRenderer.aria.content, MarkdownRenderer.error.invalidProps, MarkdownRenderer.error.tooLong\nimport React from \"react\";\nimport { type MosaicLocale, t } from \"../../i18n/strings.js\";\nimport { type MarkdownRendererProps, validateProps } from \"./MarkdownRenderer.schema\";\n\ninterface MarkdownRendererInnerProps {\n content: string;\n locale: \"en\" | \"fr\";\n maxLength: number;\n allowHtml: boolean;\n}\n\nconst tooLongMessages: Record<\"en\" | \"fr\", string> = {\n en: \"Content exceeds maximum length.\",\n fr: \"Le contenu dépasse la longueur maximale.\",\n};\n\nfunction MarkdownRendererInner({\n content,\n locale,\n maxLength,\n allowHtml,\n}: MarkdownRendererInnerProps) {\n if (content.length > maxLength) {\n return (\n <div role=\"alert\" lang={locale}>\n {tooLongMessages[locale]}\n </div>\n );\n }\n\n // When allowHtml=false, strip raw HTML tags from source before parsing,\n // so user-supplied HTML is neutralised before marked converts markdown to HTML.\n const source = allowHtml ? content : content.replace(/<[^>]*>/g, \"\");\n const rawHtml = marked.parse(source, { async: false }) as string;\n // Always sanitize the marked output to prevent XSS from markdown-injected HTML.\n const cleanHtml = DOMPurify.sanitize(rawHtml);\n\n const ariaLabel = locale === \"fr\" ? \"Contenu formaté\" : \"Formatted content\";\n\n return (\n <article\n aria-label={ariaLabel}\n lang={locale}\n // biome-ignore lint/security/noDangerouslySetInnerHtml: sanitized by DOMPurify\n dangerouslySetInnerHTML={{ __html: cleanHtml }}\n />\n );\n}\n\n/**\n * MarkdownRenderer accepts any props object for JSX and MCP postMessage injection alike.\n * Internal Zod validation narrows the type — invalid data renders an accessible error fallback.\n */\nexport function MarkdownRenderer(raw: Record<string, unknown>) {\n try {\n const props = validateProps(raw);\n return <MarkdownRendererInner {...props} />;\n } catch {\n const locale: MosaicLocale = raw.locale === \"fr\" ? \"fr\" : \"en\";\n return <div role=\"alert\">{t(\"MarkdownRenderer.error.invalidProps\", locale)}</div>;\n }\n}\n"]}
|
package/dist/artifacts.js
CHANGED
|
@@ -27,6 +27,8 @@ var EN = {
|
|
|
27
27
|
"TokenDisplayOnceModal.copied": "Copied",
|
|
28
28
|
"StatusBadge.aria.status": "Status",
|
|
29
29
|
"StatusBadge.error.invalidProps": "StatusBadge: invalid props",
|
|
30
|
+
"Badge.aria.label": "Badge",
|
|
31
|
+
"Badge.error.invalidProps": "Badge: invalid props",
|
|
30
32
|
"EmptyState.error.invalidProps": "EmptyState: invalid props",
|
|
31
33
|
"Toast.aria.close": "Close notification",
|
|
32
34
|
"Toast.error.invalidProps": "Toast: invalid props",
|
|
@@ -119,6 +121,8 @@ var FR = {
|
|
|
119
121
|
"TokenDisplayOnceModal.copied": "Copi\xE9",
|
|
120
122
|
"StatusBadge.aria.status": "Statut",
|
|
121
123
|
"StatusBadge.error.invalidProps": "StatusBadge : propri\xE9t\xE9s invalides",
|
|
124
|
+
"Badge.aria.label": "Badge",
|
|
125
|
+
"Badge.error.invalidProps": "Badge : propri\xE9t\xE9s invalides",
|
|
122
126
|
"EmptyState.error.invalidProps": "EmptyState : propri\xE9t\xE9s invalides",
|
|
123
127
|
"Toast.aria.close": "Fermer la notification",
|
|
124
128
|
"Toast.error.invalidProps": "Toast : propri\xE9t\xE9s invalides",
|