@vantageos/mosaic 0.2.2 → 0.3.0-alpha.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 (91) hide show
  1. package/README.md +181 -0
  2. package/dist/Alert.schema-BQsZGG6P.d.cts +41 -0
  3. package/dist/Alert.schema-BQsZGG6P.d.ts +41 -0
  4. package/dist/ConfirmDialog-B3CQQGmJ.d.cts +34 -0
  5. package/dist/ConfirmDialog-B3CQQGmJ.d.ts +34 -0
  6. package/dist/Skeleton.schema-BO0ca2UX.d.cts +135 -0
  7. package/dist/Skeleton.schema-BO0ca2UX.d.ts +135 -0
  8. package/dist/Tabs.schema-BzcEyeq8.d.cts +79 -0
  9. package/dist/Tabs.schema-BzcEyeq8.d.ts +79 -0
  10. package/dist/artifacts.cjs +20 -2
  11. package/dist/artifacts.cjs.map +1 -1
  12. package/dist/artifacts.js +20 -2
  13. package/dist/artifacts.js.map +1 -1
  14. package/dist/confirmation.cjs +44 -2
  15. package/dist/confirmation.cjs.map +1 -1
  16. package/dist/confirmation.d.cts +34 -1
  17. package/dist/confirmation.d.ts +34 -1
  18. package/dist/confirmation.js +41 -3
  19. package/dist/confirmation.js.map +1 -1
  20. package/dist/display.cjs +145 -2
  21. package/dist/display.cjs.map +1 -1
  22. package/dist/display.d.cts +1 -0
  23. package/dist/display.d.ts +1 -0
  24. package/dist/display.js +140 -3
  25. package/dist/display.js.map +1 -1
  26. package/dist/forms.cjs +1412 -0
  27. package/dist/forms.cjs.map +1 -0
  28. package/dist/forms.d.cts +159 -0
  29. package/dist/forms.d.ts +159 -0
  30. package/dist/forms.js +1331 -0
  31. package/dist/forms.js.map +1 -0
  32. package/dist/index-CwXVgtGb.d.cts +917 -0
  33. package/dist/index-CwXVgtGb.d.ts +917 -0
  34. package/dist/index.cjs +188 -2
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.d.cts +5 -2
  37. package/dist/index.d.ts +5 -2
  38. package/dist/index.js +177 -3
  39. package/dist/index.js.map +1 -1
  40. package/dist/input.cjs +19 -0
  41. package/dist/input.cjs.map +1 -1
  42. package/dist/input.d.cts +4 -34
  43. package/dist/input.d.ts +4 -34
  44. package/dist/input.js +18 -1
  45. package/dist/input.js.map +1 -1
  46. package/dist/media.cjs +20 -2
  47. package/dist/media.cjs.map +1 -1
  48. package/dist/media.js +20 -2
  49. package/dist/media.js.map +1 -1
  50. package/dist/preact/confirmation.d.ts +85 -1
  51. package/dist/preact/confirmation.js +263 -0
  52. package/dist/preact/confirmation.js.map +1 -1
  53. package/dist/preact/display.d.ts +240 -1
  54. package/dist/preact/display.js +366 -0
  55. package/dist/preact/display.js.map +1 -1
  56. package/dist/preact/forms.d.ts +875 -0
  57. package/dist/preact/forms.js +1323 -0
  58. package/dist/preact/forms.js.map +1 -0
  59. package/dist/preact/input.d.ts +88 -1
  60. package/dist/preact/input.js +194 -0
  61. package/dist/preact/input.js.map +1 -1
  62. package/dist/progress.cjs +20 -2
  63. package/dist/progress.cjs.map +1 -1
  64. package/dist/progress.js +20 -2
  65. package/dist/progress.js.map +1 -1
  66. package/dist/react/confirmation.cjs +267 -0
  67. package/dist/react/confirmation.cjs.map +1 -1
  68. package/dist/react/confirmation.d.cts +21 -1
  69. package/dist/react/confirmation.d.ts +21 -1
  70. package/dist/react/confirmation.js +263 -0
  71. package/dist/react/confirmation.js.map +1 -1
  72. package/dist/react/display.cjs +372 -0
  73. package/dist/react/display.cjs.map +1 -1
  74. package/dist/react/display.d.cts +112 -1
  75. package/dist/react/display.d.ts +112 -1
  76. package/dist/react/display.js +362 -0
  77. package/dist/react/display.js.map +1 -1
  78. package/dist/react/forms.cjs +1384 -0
  79. package/dist/react/forms.cjs.map +1 -0
  80. package/dist/react/forms.d.cts +5 -0
  81. package/dist/react/forms.d.ts +5 -0
  82. package/dist/react/forms.js +1323 -0
  83. package/dist/react/forms.js.map +1 -0
  84. package/dist/react/input.cjs +197 -0
  85. package/dist/react/input.cjs.map +1 -1
  86. package/dist/react/input.d.cts +13 -1
  87. package/dist/react/input.d.ts +13 -1
  88. package/dist/react/input.js +194 -0
  89. package/dist/react/input.js.map +1 -1
  90. package/package.json +73 -49
  91. package/registry.yaml +154 -1
package/README.md CHANGED
@@ -52,6 +52,143 @@ export function MyComponent({ progress, label }: { progress: number; label: stri
52
52
  }
53
53
  ```
54
54
 
55
+ ## Forms (v0.3.0-alpha.1)
56
+
57
+ `@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.
58
+
59
+ ### Install peers
60
+
61
+ ```sh
62
+ npm install react-hook-form@^7.54.0 @hookform/resolvers@^3.10.0
63
+ ```
64
+
65
+ Both peers are declared optional in `peerDependenciesMeta` — only install them if you use the forms surface.
66
+
67
+ ### Quick start
68
+
69
+ ```tsx
70
+ import { z } from "zod";
71
+ import {
72
+ useMosaicForm,
73
+ FormProvider,
74
+ FormField,
75
+ ErrorDisplay,
76
+ SubmitButton,
77
+ } from "@vantageos/mosaic/react/forms";
78
+
79
+ const schema = z.object({
80
+ email: z.string().email("Invalid email"),
81
+ age: z.number().min(18, "Must be 18+"),
82
+ });
83
+
84
+ export function SignupForm({ onSubmit }: { onSubmit: (data: z.infer<typeof schema>) => void }) {
85
+ const form = useMosaicForm({
86
+ schema,
87
+ defaultValues: { email: "", age: 0 },
88
+ // mode defaults to "onBlur" — Mosaic doctrine
89
+ });
90
+
91
+ return (
92
+ <FormProvider form={form}>
93
+ <form onSubmit={form.handleSubmit(onSubmit)}>
94
+ <FormField name="email">
95
+ {({ field, fieldState }) => (
96
+ <label>
97
+ Email
98
+ <input {...field} value={(field.value as string) ?? ""} />
99
+ <ErrorDisplay error={fieldState.error} />
100
+ </label>
101
+ )}
102
+ </FormField>
103
+ <SubmitButton label="Sign up" />
104
+ </form>
105
+ </FormProvider>
106
+ );
107
+ }
108
+ ```
109
+
110
+ ### Surface
111
+
112
+ | Export | Purpose |
113
+ |---|---|
114
+ | `useMosaicForm({ schema, defaultValues, mode? })` | Wrapper around `useForm` + `zodResolver`. Returns RHF's `UseFormReturn` extended with `mosaicSchema` + `mosaicMode`. |
115
+ | `<FormProvider form={...}>` | Wraps RHF's `FormProvider` AND a Mosaic-specific context. Use `useMosaicFormContext()` inside descendants. |
116
+ | `<FormField name="...">{({ field, fieldState, formState }) => ...}</FormField>` | Render-prop wrapper around RHF's `Controller`. |
117
+ | `<ErrorDisplay error={...} messageMap={...} />` | Single-field error formatter. Renders nothing when no error. Priority: `error.message` → `messageMap[type]` → generic fallback. |
118
+ | `<SubmitButton label="..." loadingLabel="..." />` | Bound to the surrounding `FormProvider`. Disabled while invalid OR submitting. |
119
+ | `<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. |
120
+
121
+ Field primitives (Textarea, Select, Checkbox, MultiSelect, RadioGroup, FieldArray) land in T12-T20 — see `docs/v0.3.0-plan.md` §7.
122
+ | `<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. |
123
+
124
+ Remaining field primitives (Input shipped T11, Select, Checkbox, MultiSelect, RadioGroup, FieldArray) land in T13-T20 — see `docs/v0.3.0-plan.md` §7.
125
+ | `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. |
126
+ | `<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. |
127
+
128
+ | `<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. |
129
+ | `<RadioGroup name="..." label="..." options={[...]} orientation? disabled? />` | WCAG-AA radiogroup. Roving tabIndex, Arrow key selection sync, Home/End, Space/Enter. |
130
+
131
+ Remaining field primitives (Input, Textarea, Select, MultiSelect) land in T11-T15 + T18-T20 — see `docs/v0.3.0-plan.md` §7.
132
+
133
+ ### RadioGroup
134
+
135
+ Mutually exclusive single-choice field. Keyboard navigation follows WAI-ARIA radiogroup pattern (§3.10): Arrow keys move focus AND select simultaneously (roving tabindex). Disabled options are skipped during navigation.
136
+
137
+ ```tsx
138
+ import { z } from "zod";
139
+ import {
140
+ useMosaicForm,
141
+ FormProvider,
142
+ RadioGroup,
143
+ } from "@vantageos/mosaic/react/forms";
144
+
145
+ const schema = z.object({
146
+ plan: z.string().min(1, "Please select a plan"),
147
+ });
148
+
149
+ export function PlanSelector() {
150
+ const form = useMosaicForm({
151
+ schema,
152
+ defaultValues: { plan: "" },
153
+ });
154
+
155
+ return (
156
+ <FormProvider form={form}>
157
+ <form onSubmit={form.handleSubmit(console.log)}>
158
+ <RadioGroup
159
+ name="plan"
160
+ label="Select a plan"
161
+ options={[
162
+ { value: "free", label: "Free", description: "Up to 3 projects" },
163
+ { value: "pro", label: "Pro", description: "Unlimited projects" },
164
+ { value: "team", label: "Team", description: "Multi-user", disabled: false },
165
+ ]}
166
+ orientation="vertical"
167
+ />
168
+ </form>
169
+ </FormProvider>
170
+ );
171
+ }
172
+ ```
173
+
174
+ **WCAG-AA contract:**
175
+ - `role="radiogroup"` + `aria-labelledby` on container
176
+ - `role="radio"` + `aria-checked` + roving `tabIndex` per option
177
+ - `aria-labelledby` per option → its visible label span
178
+ - `aria-describedby` per option → its description span (when present)
179
+ - `aria-disabled` on disabled options; disabled options skipped in arrow nav
180
+ - `aria-orientation` reflects `orientation` prop
181
+
182
+ Field primitives (Textarea, Select, MultiSelect, RadioGroup, FieldArray) land in T12-T20 — see `docs/v0.3.0-plan.md` §7.
183
+ | `<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. |
184
+
185
+ 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.
186
+ | `<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. |
187
+
188
+ Field primitives (Input, Textarea, Checkbox, MultiSelect, RadioGroup, FieldArray) land in T11, T14-T20 — see `docs/v0.3.0-plan.md` §7.
189
+
190
+
191
+
55
192
  ## Server (MCP UI)
56
193
 
57
194
  ```ts
@@ -64,6 +201,50 @@ const resource = createMosaicResource({
64
201
  // returns a SEP-1865-compliant MCP UI resource with text/html;profile=mcp-app MIME
65
202
  ```
66
203
 
204
+
205
+ ## Components
206
+
207
+ ### Display
208
+
209
+ #### VirtualList
210
+
211
+ Generic virtualized list for large datasets. Uses @tanstack/react-virtual v3 (already bundled via TableView). Cross-runtime: React 19 + Preact 10.
212
+
213
+ ```tsx
214
+ import { VirtualList } from "@vantageos/mosaic/react/display";
215
+ // Preact: import { VirtualList } from "@vantageos/mosaic/preact/display";
216
+
217
+ type Task = { id: string; title: string; status: string };
218
+
219
+ <VirtualList<Task>
220
+ items={tasks}
221
+ itemHeight={56} // fixed px height
222
+ renderItem={(task, index) => (
223
+ <div key={task.id}>
224
+ <span>{task.title}</span>
225
+ <span>{task.status}</span>
226
+ </div>
227
+ )}
228
+ onRowClick={(task, index) => router.push('/tasks/' + task.id)}
229
+ overscan={5} // rows outside viewport (default 5)
230
+ className="task-list"
231
+ locale="en" // "en" | "fr"
232
+ />
233
+ ```
234
+
235
+ **Props**
236
+
237
+ | Prop | Type | Default | Description |
238
+ |---|---|---|---|
239
+ | `items` | `T[]` | required | Items to render |
240
+ | `itemHeight` | `number` | -- | Fixed row height px (mutually exclusive with `estimateSize`) |
241
+ | `estimateSize` | `(index) => number` | -- | Variable height estimator |
242
+ | `renderItem` | `(item: T, index: number) => ReactNode` | required | Row renderer |
243
+ | `onRowClick` | `(item: T, index: number) => void` | `undefined` | Click handler — triggers WCAG-AA a11y (role=button + tabIndex=0 + Enter/Space) |
244
+ | `overscan` | `number` | `5` | Rows outside visible area |
245
+ | `className` | `string` | `undefined` | CSS class on scroll container |
246
+ | `locale` | `"en" or "fr"` | `"en"` | Built-in string locale |
247
+
67
248
  ## Doctrine
68
249
 
69
250
  - **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.
@@ -0,0 +1,41 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * Alert component props schema.
5
+ *
6
+ * Persistent inline banner (vs Toast which is ephemeral + auto-dismissing).
7
+ *
8
+ * variant — controls visual style + ARIA role auto-assignment:
9
+ * "error" → role="alert" (assertive, interrupts screen reader)
10
+ * all others → role="status" (polite, non-intrusive)
11
+ * title — consumer-driven; caller passes already-localized string
12
+ * description — optional supporting text beneath the title
13
+ * dismissible — when true, renders a dismiss button (default: false)
14
+ * onDismiss — callback fired when dismiss button is clicked
15
+ * locale — controls dismiss button aria-label language
16
+ */
17
+ declare const AlertPropsSchema: z.ZodObject<{
18
+ variant: z.ZodEnum<["success", "error", "info", "warning"]>;
19
+ title: z.ZodString;
20
+ description: z.ZodOptional<z.ZodString>;
21
+ dismissible: z.ZodDefault<z.ZodBoolean>;
22
+ locale: z.ZodDefault<z.ZodEnum<["en", "fr"]>>;
23
+ }, "strip", z.ZodTypeAny, {
24
+ locale: "en" | "fr";
25
+ title: string;
26
+ variant: "warning" | "error" | "success" | "info";
27
+ dismissible: boolean;
28
+ description?: string | undefined;
29
+ }, {
30
+ title: string;
31
+ variant: "warning" | "error" | "success" | "info";
32
+ locale?: "en" | "fr" | undefined;
33
+ description?: string | undefined;
34
+ dismissible?: boolean | undefined;
35
+ }>;
36
+ type AlertProps = z.infer<typeof AlertPropsSchema> & {
37
+ onDismiss?: () => void;
38
+ };
39
+ declare function validateAlertProps(raw: unknown): z.infer<typeof AlertPropsSchema>;
40
+
41
+ export { type AlertProps as A, AlertPropsSchema as a, validateAlertProps as v };
@@ -0,0 +1,41 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * Alert component props schema.
5
+ *
6
+ * Persistent inline banner (vs Toast which is ephemeral + auto-dismissing).
7
+ *
8
+ * variant — controls visual style + ARIA role auto-assignment:
9
+ * "error" → role="alert" (assertive, interrupts screen reader)
10
+ * all others → role="status" (polite, non-intrusive)
11
+ * title — consumer-driven; caller passes already-localized string
12
+ * description — optional supporting text beneath the title
13
+ * dismissible — when true, renders a dismiss button (default: false)
14
+ * onDismiss — callback fired when dismiss button is clicked
15
+ * locale — controls dismiss button aria-label language
16
+ */
17
+ declare const AlertPropsSchema: z.ZodObject<{
18
+ variant: z.ZodEnum<["success", "error", "info", "warning"]>;
19
+ title: z.ZodString;
20
+ description: z.ZodOptional<z.ZodString>;
21
+ dismissible: z.ZodDefault<z.ZodBoolean>;
22
+ locale: z.ZodDefault<z.ZodEnum<["en", "fr"]>>;
23
+ }, "strip", z.ZodTypeAny, {
24
+ locale: "en" | "fr";
25
+ title: string;
26
+ variant: "warning" | "error" | "success" | "info";
27
+ dismissible: boolean;
28
+ description?: string | undefined;
29
+ }, {
30
+ title: string;
31
+ variant: "warning" | "error" | "success" | "info";
32
+ locale?: "en" | "fr" | undefined;
33
+ description?: string | undefined;
34
+ dismissible?: boolean | undefined;
35
+ }>;
36
+ type AlertProps = z.infer<typeof AlertPropsSchema> & {
37
+ onDismiss?: () => void;
38
+ };
39
+ declare function validateAlertProps(raw: unknown): z.infer<typeof AlertPropsSchema>;
40
+
41
+ export { type AlertProps as A, AlertPropsSchema as a, validateAlertProps as v };
@@ -0,0 +1,34 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { z } from 'zod';
3
+
4
+ declare const ConfirmDialogPropsSchema: z.ZodObject<{
5
+ title: z.ZodString;
6
+ message: z.ZodString;
7
+ confirmLabel: z.ZodString;
8
+ cancelLabel: z.ZodString;
9
+ variant: z.ZodDefault<z.ZodEnum<["default", "danger"]>>;
10
+ locale: z.ZodDefault<z.ZodEnum<["en", "fr"]>>;
11
+ }, "strip", z.ZodTypeAny, {
12
+ locale: "en" | "fr";
13
+ message: string;
14
+ title: string;
15
+ confirmLabel: string;
16
+ cancelLabel: string;
17
+ variant: "default" | "danger";
18
+ }, {
19
+ message: string;
20
+ title: string;
21
+ confirmLabel: string;
22
+ cancelLabel: string;
23
+ locale?: "en" | "fr" | undefined;
24
+ variant?: "default" | "danger" | undefined;
25
+ }>;
26
+ type ConfirmDialogProps = z.infer<typeof ConfirmDialogPropsSchema> & {
27
+ onConfirm: () => void;
28
+ onCancel: () => void;
29
+ };
30
+ declare function validateConfirmDialogProps(raw: unknown): z.infer<typeof ConfirmDialogPropsSchema>;
31
+
32
+ declare function ConfirmDialog(raw: Omit<ConfirmDialogProps, "variant" | "locale"> & Partial<Pick<ConfirmDialogProps, "variant" | "locale">>): react_jsx_runtime.JSX.Element | null;
33
+
34
+ export { ConfirmDialog as C, type ConfirmDialogProps as a, ConfirmDialogPropsSchema as b, validateConfirmDialogProps as v };
@@ -0,0 +1,34 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { z } from 'zod';
3
+
4
+ declare const ConfirmDialogPropsSchema: z.ZodObject<{
5
+ title: z.ZodString;
6
+ message: z.ZodString;
7
+ confirmLabel: z.ZodString;
8
+ cancelLabel: z.ZodString;
9
+ variant: z.ZodDefault<z.ZodEnum<["default", "danger"]>>;
10
+ locale: z.ZodDefault<z.ZodEnum<["en", "fr"]>>;
11
+ }, "strip", z.ZodTypeAny, {
12
+ locale: "en" | "fr";
13
+ message: string;
14
+ title: string;
15
+ confirmLabel: string;
16
+ cancelLabel: string;
17
+ variant: "default" | "danger";
18
+ }, {
19
+ message: string;
20
+ title: string;
21
+ confirmLabel: string;
22
+ cancelLabel: string;
23
+ locale?: "en" | "fr" | undefined;
24
+ variant?: "default" | "danger" | undefined;
25
+ }>;
26
+ type ConfirmDialogProps = z.infer<typeof ConfirmDialogPropsSchema> & {
27
+ onConfirm: () => void;
28
+ onCancel: () => void;
29
+ };
30
+ declare function validateConfirmDialogProps(raw: unknown): z.infer<typeof ConfirmDialogPropsSchema>;
31
+
32
+ declare function ConfirmDialog(raw: Omit<ConfirmDialogProps, "variant" | "locale"> & Partial<Pick<ConfirmDialogProps, "variant" | "locale">>): react_jsx_runtime.JSX.Element | null;
33
+
34
+ export { ConfirmDialog as C, type ConfirmDialogProps as a, ConfirmDialogPropsSchema as b, validateConfirmDialogProps as v };
@@ -0,0 +1,135 @@
1
+ import { z } from 'zod';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+
4
+ /**
5
+ * EmptyState component props schema.
6
+ *
7
+ * Empty-set illustration + title + description + optional CTA.
8
+ * Consumer-driven i18n: caller passes already-localized strings.
9
+ *
10
+ * icon — optional ReactNode / PreactNode passed by the caller
11
+ * title — required heading (h2, consumer-driven i18n)
12
+ * description — optional supporting text
13
+ * action — optional CTA: { label, onClick, variant? }
14
+ */
15
+ declare const EmptyStatePropsSchema: z.ZodObject<{
16
+ title: z.ZodString;
17
+ description: z.ZodOptional<z.ZodString>;
18
+ action: z.ZodOptional<z.ZodObject<{
19
+ label: z.ZodString;
20
+ variant: z.ZodDefault<z.ZodEnum<["primary", "secondary"]>>;
21
+ }, "strip", z.ZodTypeAny, {
22
+ label: string;
23
+ variant: "primary" | "secondary";
24
+ }, {
25
+ label: string;
26
+ variant?: "primary" | "secondary" | undefined;
27
+ }>>;
28
+ locale: z.ZodDefault<z.ZodEnum<["en", "fr"]>>;
29
+ }, "strip", z.ZodTypeAny, {
30
+ locale: "en" | "fr";
31
+ title: string;
32
+ description?: string | undefined;
33
+ action?: {
34
+ label: string;
35
+ variant: "primary" | "secondary";
36
+ } | undefined;
37
+ }, {
38
+ title: string;
39
+ locale?: "en" | "fr" | undefined;
40
+ description?: string | undefined;
41
+ action?: {
42
+ label: string;
43
+ variant?: "primary" | "secondary" | undefined;
44
+ } | undefined;
45
+ }>;
46
+ type EmptyStatePropsSchemaInput = z.input<typeof EmptyStatePropsSchema>;
47
+ type EmptyStatePropsSchemaOutput = z.output<typeof EmptyStatePropsSchema>;
48
+ /**
49
+ * Full EmptyState props including framework-specific node types and callback.
50
+ * `icon` and `action.onClick` are excluded from Zod (functions/nodes are not serializable).
51
+ *
52
+ * Note: action.variant is optional for callers — Zod applies "primary" default at parse time.
53
+ */
54
+ type EmptyStateProps = Omit<EmptyStatePropsSchemaOutput, "action"> & {
55
+ icon?: any;
56
+ action?: {
57
+ label: string;
58
+ variant?: "primary" | "secondary";
59
+ onClick: () => void;
60
+ };
61
+ };
62
+ declare function validateEmptyStateProps(raw: unknown): EmptyStatePropsSchemaOutput;
63
+
64
+ /**
65
+ * Skeleton — cross-runtime loading placeholder (React 19 implementation).
66
+ *
67
+ * Accepts `Record<string, unknown>` for MCP postMessage injection safety.
68
+ * Zod validation narrows before render. Invalid props → accessible error span.
69
+ *
70
+ * Animation "none" is auto-applied when prefers-reduced-motion is set (via
71
+ * Tailwind's animate-pulse which respects the media query natively), or by
72
+ * passing animation="none" explicitly.
73
+ *
74
+ * WCAG-AA:
75
+ * - role="status" + aria-busy="true" on the container
76
+ * - aria-label resolves via t() in EN/FR
77
+ * - aria-hidden="true" on individual line spans (status role covers the group)
78
+ */
79
+ declare function Skeleton(raw: Record<string, unknown>): react_jsx_runtime.JSX.Element;
80
+
81
+ /**
82
+ * Skeleton component props schema.
83
+ *
84
+ * variant — shape of the placeholder:
85
+ * "rect" → rectangular block (default)
86
+ * "circle" → circular avatar / icon placeholder
87
+ * "text" → single or multi-line text placeholder
88
+ *
89
+ * width / height — CSS values (string) or pixels (number).
90
+ * "rect" defaults: width="100%", height=100
91
+ * "circle" defaults: width=height (equal, square rendered as circle)
92
+ * "text" defaults: width="100%", height=16
93
+ *
94
+ * count — number of text line spans (only meaningful for variant="text").
95
+ * Default 1. Ignored for rect/circle.
96
+ *
97
+ * animation — shimmer style:
98
+ * "pulse" → opacity pulse (default)
99
+ * "wave" → left-to-right gradient sweep
100
+ * "none" → static placeholder (auto-selected when prefers-reduced-motion)
101
+ */
102
+ declare const SkeletonPropsSchema: z.ZodObject<{
103
+ variant: z.ZodDefault<z.ZodEnum<["rect", "circle", "text"]>>;
104
+ width: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
105
+ height: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
106
+ count: z.ZodDefault<z.ZodNumber>;
107
+ animation: z.ZodDefault<z.ZodEnum<["pulse", "wave", "none"]>>;
108
+ locale: z.ZodDefault<z.ZodEnum<["en", "fr"]>>;
109
+ }, "strip", z.ZodTypeAny, {
110
+ locale: "en" | "fr";
111
+ variant: "text" | "rect" | "circle";
112
+ count: number;
113
+ animation: "none" | "pulse" | "wave";
114
+ width?: string | number | undefined;
115
+ height?: string | number | undefined;
116
+ }, {
117
+ locale?: "en" | "fr" | undefined;
118
+ width?: string | number | undefined;
119
+ variant?: "text" | "rect" | "circle" | undefined;
120
+ count?: number | undefined;
121
+ height?: string | number | undefined;
122
+ animation?: "none" | "pulse" | "wave" | undefined;
123
+ }>;
124
+ type SkeletonProps = z.infer<typeof SkeletonPropsSchema>;
125
+ declare function validateSkeletonProps(raw: unknown): SkeletonProps;
126
+ /**
127
+ * Resolve final width/height CSS values given the variant and raw props.
128
+ * Centralised here so React + Preact runtimes share identical defaults.
129
+ */
130
+ declare function resolveSkeletonDimensions(variant: SkeletonProps["variant"], width: SkeletonProps["width"], height: SkeletonProps["height"]): {
131
+ widthCss: string;
132
+ heightCss: string;
133
+ };
134
+
135
+ export { type EmptyStateProps as E, Skeleton as S, EmptyStatePropsSchema as a, type EmptyStatePropsSchemaInput as b, type EmptyStatePropsSchemaOutput as c, type SkeletonProps as d, SkeletonPropsSchema as e, validateSkeletonProps as f, resolveSkeletonDimensions as r, validateEmptyStateProps as v };
@@ -0,0 +1,135 @@
1
+ import { z } from 'zod';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+
4
+ /**
5
+ * EmptyState component props schema.
6
+ *
7
+ * Empty-set illustration + title + description + optional CTA.
8
+ * Consumer-driven i18n: caller passes already-localized strings.
9
+ *
10
+ * icon — optional ReactNode / PreactNode passed by the caller
11
+ * title — required heading (h2, consumer-driven i18n)
12
+ * description — optional supporting text
13
+ * action — optional CTA: { label, onClick, variant? }
14
+ */
15
+ declare const EmptyStatePropsSchema: z.ZodObject<{
16
+ title: z.ZodString;
17
+ description: z.ZodOptional<z.ZodString>;
18
+ action: z.ZodOptional<z.ZodObject<{
19
+ label: z.ZodString;
20
+ variant: z.ZodDefault<z.ZodEnum<["primary", "secondary"]>>;
21
+ }, "strip", z.ZodTypeAny, {
22
+ label: string;
23
+ variant: "primary" | "secondary";
24
+ }, {
25
+ label: string;
26
+ variant?: "primary" | "secondary" | undefined;
27
+ }>>;
28
+ locale: z.ZodDefault<z.ZodEnum<["en", "fr"]>>;
29
+ }, "strip", z.ZodTypeAny, {
30
+ locale: "en" | "fr";
31
+ title: string;
32
+ description?: string | undefined;
33
+ action?: {
34
+ label: string;
35
+ variant: "primary" | "secondary";
36
+ } | undefined;
37
+ }, {
38
+ title: string;
39
+ locale?: "en" | "fr" | undefined;
40
+ description?: string | undefined;
41
+ action?: {
42
+ label: string;
43
+ variant?: "primary" | "secondary" | undefined;
44
+ } | undefined;
45
+ }>;
46
+ type EmptyStatePropsSchemaInput = z.input<typeof EmptyStatePropsSchema>;
47
+ type EmptyStatePropsSchemaOutput = z.output<typeof EmptyStatePropsSchema>;
48
+ /**
49
+ * Full EmptyState props including framework-specific node types and callback.
50
+ * `icon` and `action.onClick` are excluded from Zod (functions/nodes are not serializable).
51
+ *
52
+ * Note: action.variant is optional for callers — Zod applies "primary" default at parse time.
53
+ */
54
+ type EmptyStateProps = Omit<EmptyStatePropsSchemaOutput, "action"> & {
55
+ icon?: any;
56
+ action?: {
57
+ label: string;
58
+ variant?: "primary" | "secondary";
59
+ onClick: () => void;
60
+ };
61
+ };
62
+ declare function validateEmptyStateProps(raw: unknown): EmptyStatePropsSchemaOutput;
63
+
64
+ /**
65
+ * Skeleton — cross-runtime loading placeholder (React 19 implementation).
66
+ *
67
+ * Accepts `Record<string, unknown>` for MCP postMessage injection safety.
68
+ * Zod validation narrows before render. Invalid props → accessible error span.
69
+ *
70
+ * Animation "none" is auto-applied when prefers-reduced-motion is set (via
71
+ * Tailwind's animate-pulse which respects the media query natively), or by
72
+ * passing animation="none" explicitly.
73
+ *
74
+ * WCAG-AA:
75
+ * - role="status" + aria-busy="true" on the container
76
+ * - aria-label resolves via t() in EN/FR
77
+ * - aria-hidden="true" on individual line spans (status role covers the group)
78
+ */
79
+ declare function Skeleton(raw: Record<string, unknown>): react_jsx_runtime.JSX.Element;
80
+
81
+ /**
82
+ * Skeleton component props schema.
83
+ *
84
+ * variant — shape of the placeholder:
85
+ * "rect" → rectangular block (default)
86
+ * "circle" → circular avatar / icon placeholder
87
+ * "text" → single or multi-line text placeholder
88
+ *
89
+ * width / height — CSS values (string) or pixels (number).
90
+ * "rect" defaults: width="100%", height=100
91
+ * "circle" defaults: width=height (equal, square rendered as circle)
92
+ * "text" defaults: width="100%", height=16
93
+ *
94
+ * count — number of text line spans (only meaningful for variant="text").
95
+ * Default 1. Ignored for rect/circle.
96
+ *
97
+ * animation — shimmer style:
98
+ * "pulse" → opacity pulse (default)
99
+ * "wave" → left-to-right gradient sweep
100
+ * "none" → static placeholder (auto-selected when prefers-reduced-motion)
101
+ */
102
+ declare const SkeletonPropsSchema: z.ZodObject<{
103
+ variant: z.ZodDefault<z.ZodEnum<["rect", "circle", "text"]>>;
104
+ width: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
105
+ height: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
106
+ count: z.ZodDefault<z.ZodNumber>;
107
+ animation: z.ZodDefault<z.ZodEnum<["pulse", "wave", "none"]>>;
108
+ locale: z.ZodDefault<z.ZodEnum<["en", "fr"]>>;
109
+ }, "strip", z.ZodTypeAny, {
110
+ locale: "en" | "fr";
111
+ variant: "text" | "rect" | "circle";
112
+ count: number;
113
+ animation: "none" | "pulse" | "wave";
114
+ width?: string | number | undefined;
115
+ height?: string | number | undefined;
116
+ }, {
117
+ locale?: "en" | "fr" | undefined;
118
+ width?: string | number | undefined;
119
+ variant?: "text" | "rect" | "circle" | undefined;
120
+ count?: number | undefined;
121
+ height?: string | number | undefined;
122
+ animation?: "none" | "pulse" | "wave" | undefined;
123
+ }>;
124
+ type SkeletonProps = z.infer<typeof SkeletonPropsSchema>;
125
+ declare function validateSkeletonProps(raw: unknown): SkeletonProps;
126
+ /**
127
+ * Resolve final width/height CSS values given the variant and raw props.
128
+ * Centralised here so React + Preact runtimes share identical defaults.
129
+ */
130
+ declare function resolveSkeletonDimensions(variant: SkeletonProps["variant"], width: SkeletonProps["width"], height: SkeletonProps["height"]): {
131
+ widthCss: string;
132
+ heightCss: string;
133
+ };
134
+
135
+ export { type EmptyStateProps as E, Skeleton as S, EmptyStatePropsSchema as a, type EmptyStatePropsSchemaInput as b, type EmptyStatePropsSchemaOutput as c, type SkeletonProps as d, SkeletonPropsSchema as e, validateSkeletonProps as f, resolveSkeletonDimensions as r, validateEmptyStateProps as v };