@vantageos/mosaic 0.1.1 → 0.1.2

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 (49) hide show
  1. package/dist/artifacts.cjs +113 -0
  2. package/dist/artifacts.cjs.map +1 -0
  3. package/dist/artifacts.d.cts +29 -0
  4. package/dist/artifacts.d.ts +29 -0
  5. package/dist/artifacts.js +105 -0
  6. package/dist/artifacts.js.map +1 -0
  7. package/dist/confirmation.cjs +180 -0
  8. package/dist/confirmation.cjs.map +1 -0
  9. package/dist/confirmation.d.cts +33 -0
  10. package/dist/confirmation.d.ts +33 -0
  11. package/dist/confirmation.js +176 -0
  12. package/dist/confirmation.js.map +1 -0
  13. package/dist/display.cjs +273 -0
  14. package/dist/display.cjs.map +1 -0
  15. package/dist/display.d.cts +94 -0
  16. package/dist/display.d.ts +94 -0
  17. package/dist/display.js +268 -0
  18. package/dist/display.js.map +1 -0
  19. package/dist/index.cjs +40 -2
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +12 -232
  22. package/dist/index.d.ts +12 -232
  23. package/dist/index.js +40 -3
  24. package/dist/index.js.map +1 -1
  25. package/dist/input.cjs +102 -0
  26. package/dist/input.cjs.map +1 -0
  27. package/dist/input.d.cts +34 -0
  28. package/dist/input.d.ts +34 -0
  29. package/dist/input.js +98 -0
  30. package/dist/input.js.map +1 -0
  31. package/dist/media.cjs +98 -0
  32. package/dist/media.cjs.map +1 -0
  33. package/dist/media.d.cts +29 -0
  34. package/dist/media.d.ts +29 -0
  35. package/dist/media.js +94 -0
  36. package/dist/media.js.map +1 -0
  37. package/dist/progress.cjs +125 -0
  38. package/dist/progress.cjs.map +1 -0
  39. package/dist/progress.d.cts +29 -0
  40. package/dist/progress.d.ts +29 -0
  41. package/dist/progress.js +121 -0
  42. package/dist/progress.js.map +1 -0
  43. package/dist/server.cjs +121 -0
  44. package/dist/server.cjs.map +1 -0
  45. package/dist/server.d.cts +33 -0
  46. package/dist/server.d.ts +33 -0
  47. package/dist/server.js +116 -0
  48. package/dist/server.js.map +1 -0
  49. package/package.json +45 -7
package/dist/input.cjs ADDED
@@ -0,0 +1,102 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+ var zod = require('zod');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+
7
+ // src/components/input/ConfirmDialog.tsx
8
+ var ConfirmDialogPropsSchema = zod.z.object({
9
+ title: zod.z.string().min(1),
10
+ message: zod.z.string().min(1),
11
+ confirmLabel: zod.z.string().min(1),
12
+ cancelLabel: zod.z.string().min(1),
13
+ variant: zod.z.enum(["default", "danger"]).default("default"),
14
+ locale: zod.z.enum(["en", "fr"]).default("en")
15
+ });
16
+ function validateConfirmDialogProps(raw) {
17
+ return ConfirmDialogPropsSchema.parse(raw);
18
+ }
19
+ function ConfirmDialogInner({
20
+ title,
21
+ message,
22
+ confirmLabel,
23
+ cancelLabel,
24
+ variant,
25
+ onConfirm,
26
+ onCancel
27
+ }) {
28
+ const dialogRef = react.useRef(null);
29
+ const titleId = react.useId();
30
+ const messageId = react.useId();
31
+ react.useEffect(() => {
32
+ const dialog = dialogRef.current;
33
+ if (!dialog) return;
34
+ dialog.showModal();
35
+ return () => {
36
+ if (dialog.open) dialog.close();
37
+ };
38
+ }, []);
39
+ function handleKeyDown(e) {
40
+ if (e.key === "Escape") {
41
+ e.preventDefault();
42
+ onCancel();
43
+ }
44
+ }
45
+ function handleBackdropClick(e) {
46
+ if (e.target === dialogRef.current) {
47
+ onCancel();
48
+ }
49
+ }
50
+ const confirmClassName = variant === "danger" ? "bg-red-600 text-white hover:bg-red-700 focus-visible:outline-red-600 px-4 py-2 rounded-md text-sm font-medium transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2" : "bg-gray-900 text-white hover:bg-gray-700 focus-visible:outline-gray-900 px-4 py-2 rounded-md text-sm font-medium transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2";
51
+ return /* @__PURE__ */ jsxRuntime.jsx(
52
+ "dialog",
53
+ {
54
+ ref: dialogRef,
55
+ "aria-modal": "true",
56
+ "aria-labelledby": titleId,
57
+ "aria-describedby": messageId,
58
+ onKeyDown: handleKeyDown,
59
+ onClick: handleBackdropClick,
60
+ className: "rounded-lg shadow-xl p-0 backdrop:bg-black/40 w-full max-w-md mx-auto",
61
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
62
+ "div",
63
+ {
64
+ className: "p-6 flex flex-col gap-4",
65
+ onClick: (e) => e.stopPropagation(),
66
+ onKeyDown: (e) => e.stopPropagation(),
67
+ children: [
68
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { id: titleId, className: "text-lg font-semibold text-gray-900", children: title }),
69
+ /* @__PURE__ */ jsxRuntime.jsx("p", { id: messageId, className: "text-sm text-gray-600", children: message }),
70
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-3 mt-2", children: [
71
+ /* @__PURE__ */ jsxRuntime.jsx(
72
+ "button",
73
+ {
74
+ type: "button",
75
+ onClick: onCancel,
76
+ className: "px-4 py-2 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-400 transition-colors",
77
+ children: cancelLabel
78
+ }
79
+ ),
80
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: onConfirm, className: confirmClassName, children: confirmLabel })
81
+ ] })
82
+ ]
83
+ }
84
+ )
85
+ }
86
+ );
87
+ }
88
+ function ConfirmDialog(raw) {
89
+ try {
90
+ const parsed = validateConfirmDialogProps(raw);
91
+ return /* @__PURE__ */ jsxRuntime.jsx(ConfirmDialogInner, { ...parsed, onConfirm: raw.onConfirm, onCancel: raw.onCancel });
92
+ } catch (err) {
93
+ console.error("[ConfirmDialog] Invalid props \u2014 component will not render.", err);
94
+ return null;
95
+ }
96
+ }
97
+
98
+ exports.ConfirmDialog = ConfirmDialog;
99
+ exports.ConfirmDialogPropsSchema = ConfirmDialogPropsSchema;
100
+ exports.validateConfirmDialogProps = validateConfirmDialogProps;
101
+ //# sourceMappingURL=input.cjs.map
102
+ //# sourceMappingURL=input.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/input/ConfirmDialog.schema.ts","../src/components/input/ConfirmDialog.tsx"],"names":["z","useRef","useId","useEffect","jsx","jsxs"],"mappings":"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","file":"input.cjs","sourcesContent":["import { z } from \"zod\";\n\n// i18nKeys: ConfirmDialog.button.confirm, ConfirmDialog.button.cancel, ConfirmDialog.aria.dialog\n\nexport const ConfirmDialogPropsSchema = z.object({\n title: z.string().min(1),\n message: z.string().min(1),\n confirmLabel: z.string().min(1),\n cancelLabel: z.string().min(1),\n variant: z.enum([\"default\", \"danger\"]).default(\"default\"),\n locale: z.enum([\"en\", \"fr\"]).default(\"en\"),\n});\n\nexport type ConfirmDialogProps = z.infer<typeof ConfirmDialogPropsSchema> & {\n onConfirm: () => void;\n onCancel: () => void;\n};\n\nexport function validateConfirmDialogProps(raw: unknown): z.infer<typeof ConfirmDialogPropsSchema> {\n return ConfirmDialogPropsSchema.parse(raw);\n}\n","\"use client\";\n\n// i18nKeys: ConfirmDialog.button.confirm, ConfirmDialog.button.cancel, ConfirmDialog.aria.dialog\n\nimport { type KeyboardEvent, type MouseEvent, useEffect, useId, useRef } from \"react\";\nimport { type ConfirmDialogProps, validateConfirmDialogProps } from \"./ConfirmDialog.schema\";\n\nfunction ConfirmDialogInner({\n title,\n message,\n confirmLabel,\n cancelLabel,\n variant,\n onConfirm,\n onCancel,\n}: ConfirmDialogProps) {\n const dialogRef = useRef<HTMLDialogElement>(null);\n const titleId = useId();\n const messageId = useId();\n\n useEffect(() => {\n const dialog = dialogRef.current;\n /* v8 ignore next 2 */\n if (!dialog) return;\n dialog.showModal();\n return () => {\n if (dialog.open) dialog.close();\n };\n }, []);\n\n function handleKeyDown(e: KeyboardEvent<HTMLDialogElement>) {\n if (e.key === \"Escape\") {\n e.preventDefault();\n onCancel();\n }\n }\n\n function handleBackdropClick(e: MouseEvent<HTMLDialogElement>) {\n if (e.target === dialogRef.current) {\n onCancel();\n }\n }\n\n const confirmClassName =\n variant === \"danger\"\n ? \"bg-red-600 text-white hover:bg-red-700 focus-visible:outline-red-600 px-4 py-2 rounded-md text-sm font-medium transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2\"\n : \"bg-gray-900 text-white hover:bg-gray-700 focus-visible:outline-gray-900 px-4 py-2 rounded-md text-sm font-medium transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2\";\n\n return (\n <dialog\n ref={dialogRef}\n aria-modal=\"true\"\n aria-labelledby={titleId}\n aria-describedby={messageId}\n onKeyDown={handleKeyDown}\n onClick={handleBackdropClick}\n className=\"rounded-lg shadow-xl p-0 backdrop:bg-black/40 w-full max-w-md mx-auto\"\n >\n {/* Inner div stops click propagation so backdrop-click only fires on <dialog> itself */}\n <div\n className=\"p-6 flex flex-col gap-4\"\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n >\n <h2 id={titleId} className=\"text-lg font-semibold text-gray-900\">\n {title}\n </h2>\n <p id={messageId} className=\"text-sm text-gray-600\">\n {message}\n </p>\n <div className=\"flex justify-end gap-3 mt-2\">\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"px-4 py-2 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-400 transition-colors\"\n >\n {cancelLabel}\n </button>\n <button type=\"button\" onClick={onConfirm} className={confirmClassName}>\n {confirmLabel}\n </button>\n </div>\n </div>\n </dialog>\n );\n}\n\nexport function ConfirmDialog(\n raw: Omit<ConfirmDialogProps, \"variant\" | \"locale\"> &\n Partial<Pick<ConfirmDialogProps, \"variant\" | \"locale\">>,\n) {\n try {\n const parsed = validateConfirmDialogProps(raw);\n return <ConfirmDialogInner {...parsed} onConfirm={raw.onConfirm} onCancel={raw.onCancel} />;\n } catch (err) {\n console.error(\"[ConfirmDialog] Invalid props — component will not render.\", err);\n return null;\n }\n}\n"]}
@@ -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, type ConfirmDialogProps, ConfirmDialogPropsSchema, validateConfirmDialogProps };
@@ -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, type ConfirmDialogProps, ConfirmDialogPropsSchema, validateConfirmDialogProps };
package/dist/input.js ADDED
@@ -0,0 +1,98 @@
1
+ import { useRef, useId, useEffect } from 'react';
2
+ import { z } from 'zod';
3
+ import { jsx, jsxs } from 'react/jsx-runtime';
4
+
5
+ // src/components/input/ConfirmDialog.tsx
6
+ var ConfirmDialogPropsSchema = z.object({
7
+ title: z.string().min(1),
8
+ message: z.string().min(1),
9
+ confirmLabel: z.string().min(1),
10
+ cancelLabel: z.string().min(1),
11
+ variant: z.enum(["default", "danger"]).default("default"),
12
+ locale: z.enum(["en", "fr"]).default("en")
13
+ });
14
+ function validateConfirmDialogProps(raw) {
15
+ return ConfirmDialogPropsSchema.parse(raw);
16
+ }
17
+ function ConfirmDialogInner({
18
+ title,
19
+ message,
20
+ confirmLabel,
21
+ cancelLabel,
22
+ variant,
23
+ onConfirm,
24
+ onCancel
25
+ }) {
26
+ const dialogRef = useRef(null);
27
+ const titleId = useId();
28
+ const messageId = useId();
29
+ useEffect(() => {
30
+ const dialog = dialogRef.current;
31
+ if (!dialog) return;
32
+ dialog.showModal();
33
+ return () => {
34
+ if (dialog.open) dialog.close();
35
+ };
36
+ }, []);
37
+ function handleKeyDown(e) {
38
+ if (e.key === "Escape") {
39
+ e.preventDefault();
40
+ onCancel();
41
+ }
42
+ }
43
+ function handleBackdropClick(e) {
44
+ if (e.target === dialogRef.current) {
45
+ onCancel();
46
+ }
47
+ }
48
+ const confirmClassName = variant === "danger" ? "bg-red-600 text-white hover:bg-red-700 focus-visible:outline-red-600 px-4 py-2 rounded-md text-sm font-medium transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2" : "bg-gray-900 text-white hover:bg-gray-700 focus-visible:outline-gray-900 px-4 py-2 rounded-md text-sm font-medium transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2";
49
+ return /* @__PURE__ */ jsx(
50
+ "dialog",
51
+ {
52
+ ref: dialogRef,
53
+ "aria-modal": "true",
54
+ "aria-labelledby": titleId,
55
+ "aria-describedby": messageId,
56
+ onKeyDown: handleKeyDown,
57
+ onClick: handleBackdropClick,
58
+ className: "rounded-lg shadow-xl p-0 backdrop:bg-black/40 w-full max-w-md mx-auto",
59
+ children: /* @__PURE__ */ jsxs(
60
+ "div",
61
+ {
62
+ className: "p-6 flex flex-col gap-4",
63
+ onClick: (e) => e.stopPropagation(),
64
+ onKeyDown: (e) => e.stopPropagation(),
65
+ children: [
66
+ /* @__PURE__ */ jsx("h2", { id: titleId, className: "text-lg font-semibold text-gray-900", children: title }),
67
+ /* @__PURE__ */ jsx("p", { id: messageId, className: "text-sm text-gray-600", children: message }),
68
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-3 mt-2", children: [
69
+ /* @__PURE__ */ jsx(
70
+ "button",
71
+ {
72
+ type: "button",
73
+ onClick: onCancel,
74
+ className: "px-4 py-2 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-400 transition-colors",
75
+ children: cancelLabel
76
+ }
77
+ ),
78
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: onConfirm, className: confirmClassName, children: confirmLabel })
79
+ ] })
80
+ ]
81
+ }
82
+ )
83
+ }
84
+ );
85
+ }
86
+ function ConfirmDialog(raw) {
87
+ try {
88
+ const parsed = validateConfirmDialogProps(raw);
89
+ return /* @__PURE__ */ jsx(ConfirmDialogInner, { ...parsed, onConfirm: raw.onConfirm, onCancel: raw.onCancel });
90
+ } catch (err) {
91
+ console.error("[ConfirmDialog] Invalid props \u2014 component will not render.", err);
92
+ return null;
93
+ }
94
+ }
95
+
96
+ export { ConfirmDialog, ConfirmDialogPropsSchema, validateConfirmDialogProps };
97
+ //# sourceMappingURL=input.js.map
98
+ //# sourceMappingURL=input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/input/ConfirmDialog.schema.ts","../src/components/input/ConfirmDialog.tsx"],"names":[],"mappings":"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","file":"input.js","sourcesContent":["import { z } from \"zod\";\n\n// i18nKeys: ConfirmDialog.button.confirm, ConfirmDialog.button.cancel, ConfirmDialog.aria.dialog\n\nexport const ConfirmDialogPropsSchema = z.object({\n title: z.string().min(1),\n message: z.string().min(1),\n confirmLabel: z.string().min(1),\n cancelLabel: z.string().min(1),\n variant: z.enum([\"default\", \"danger\"]).default(\"default\"),\n locale: z.enum([\"en\", \"fr\"]).default(\"en\"),\n});\n\nexport type ConfirmDialogProps = z.infer<typeof ConfirmDialogPropsSchema> & {\n onConfirm: () => void;\n onCancel: () => void;\n};\n\nexport function validateConfirmDialogProps(raw: unknown): z.infer<typeof ConfirmDialogPropsSchema> {\n return ConfirmDialogPropsSchema.parse(raw);\n}\n","\"use client\";\n\n// i18nKeys: ConfirmDialog.button.confirm, ConfirmDialog.button.cancel, ConfirmDialog.aria.dialog\n\nimport { type KeyboardEvent, type MouseEvent, useEffect, useId, useRef } from \"react\";\nimport { type ConfirmDialogProps, validateConfirmDialogProps } from \"./ConfirmDialog.schema\";\n\nfunction ConfirmDialogInner({\n title,\n message,\n confirmLabel,\n cancelLabel,\n variant,\n onConfirm,\n onCancel,\n}: ConfirmDialogProps) {\n const dialogRef = useRef<HTMLDialogElement>(null);\n const titleId = useId();\n const messageId = useId();\n\n useEffect(() => {\n const dialog = dialogRef.current;\n /* v8 ignore next 2 */\n if (!dialog) return;\n dialog.showModal();\n return () => {\n if (dialog.open) dialog.close();\n };\n }, []);\n\n function handleKeyDown(e: KeyboardEvent<HTMLDialogElement>) {\n if (e.key === \"Escape\") {\n e.preventDefault();\n onCancel();\n }\n }\n\n function handleBackdropClick(e: MouseEvent<HTMLDialogElement>) {\n if (e.target === dialogRef.current) {\n onCancel();\n }\n }\n\n const confirmClassName =\n variant === \"danger\"\n ? \"bg-red-600 text-white hover:bg-red-700 focus-visible:outline-red-600 px-4 py-2 rounded-md text-sm font-medium transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2\"\n : \"bg-gray-900 text-white hover:bg-gray-700 focus-visible:outline-gray-900 px-4 py-2 rounded-md text-sm font-medium transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2\";\n\n return (\n <dialog\n ref={dialogRef}\n aria-modal=\"true\"\n aria-labelledby={titleId}\n aria-describedby={messageId}\n onKeyDown={handleKeyDown}\n onClick={handleBackdropClick}\n className=\"rounded-lg shadow-xl p-0 backdrop:bg-black/40 w-full max-w-md mx-auto\"\n >\n {/* Inner div stops click propagation so backdrop-click only fires on <dialog> itself */}\n <div\n className=\"p-6 flex flex-col gap-4\"\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n >\n <h2 id={titleId} className=\"text-lg font-semibold text-gray-900\">\n {title}\n </h2>\n <p id={messageId} className=\"text-sm text-gray-600\">\n {message}\n </p>\n <div className=\"flex justify-end gap-3 mt-2\">\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"px-4 py-2 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-400 transition-colors\"\n >\n {cancelLabel}\n </button>\n <button type=\"button\" onClick={onConfirm} className={confirmClassName}>\n {confirmLabel}\n </button>\n </div>\n </div>\n </dialog>\n );\n}\n\nexport function ConfirmDialog(\n raw: Omit<ConfirmDialogProps, \"variant\" | \"locale\"> &\n Partial<Pick<ConfirmDialogProps, \"variant\" | \"locale\">>,\n) {\n try {\n const parsed = validateConfirmDialogProps(raw);\n return <ConfirmDialogInner {...parsed} onConfirm={raw.onConfirm} onCancel={raw.onCancel} />;\n } catch (err) {\n console.error(\"[ConfirmDialog] Invalid props — component will not render.\", err);\n return null;\n }\n}\n"]}
package/dist/media.cjs ADDED
@@ -0,0 +1,98 @@
1
+ 'use strict';
2
+
3
+ var zod = require('zod');
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+
6
+ // src/i18n/strings.ts
7
+ var EN = {
8
+ "ProgressBar.aria.label": "Progress",
9
+ "ProgressBar.error.invalidProps": "ProgressBar: invalid props",
10
+ "ConfirmDialog.button.confirm": "Confirm",
11
+ "ConfirmDialog.button.cancel": "Cancel",
12
+ "ConfirmDialog.aria.dialog": "Confirmation dialog",
13
+ "TableView.aria.table": "Data table",
14
+ "TableView.pagination.next": "Next page",
15
+ "TableView.pagination.prev": "Previous page",
16
+ "TableView.empty.message": "No data to display",
17
+ "TableView.error.invalidProps": "TableView: invalid props",
18
+ "MarkdownRenderer.aria.content": "Rendered Markdown content",
19
+ "MarkdownRenderer.error.invalidProps": "MarkdownRenderer: invalid props",
20
+ "MarkdownRenderer.error.tooLong": "Content exceeds maximum length",
21
+ "TokenDisplayOnceModal.button.copy": "Copy token",
22
+ "TokenDisplayOnceModal.button.close": "Close",
23
+ "TokenDisplayOnceModal.warning.once": "This token will only be shown once. Copy it now.",
24
+ "TokenDisplayOnceModal.copied": "Copied",
25
+ "StatusBadge.aria.status": "Status",
26
+ "StatusBadge.error.invalidProps": "StatusBadge: invalid props"
27
+ };
28
+ var FR = {
29
+ "ProgressBar.aria.label": "Progression",
30
+ "ProgressBar.error.invalidProps": "ProgressBar : propri\xE9t\xE9s invalides",
31
+ "ConfirmDialog.button.confirm": "Confirmer",
32
+ "ConfirmDialog.button.cancel": "Annuler",
33
+ "ConfirmDialog.aria.dialog": "Bo\xEEte de dialogue de confirmation",
34
+ "TableView.aria.table": "Tableau de donn\xE9es",
35
+ "TableView.pagination.next": "Page suivante",
36
+ "TableView.pagination.prev": "Page pr\xE9c\xE9dente",
37
+ "TableView.empty.message": "Aucune donn\xE9e \xE0 afficher",
38
+ "TableView.error.invalidProps": "TableView : propri\xE9t\xE9s invalides",
39
+ "MarkdownRenderer.aria.content": "Contenu Markdown rendu",
40
+ "MarkdownRenderer.error.invalidProps": "MarkdownRenderer : propri\xE9t\xE9s invalides",
41
+ "MarkdownRenderer.error.tooLong": "Le contenu d\xE9passe la longueur maximale",
42
+ "TokenDisplayOnceModal.button.copy": "Copier le jeton",
43
+ "TokenDisplayOnceModal.button.close": "Fermer",
44
+ "TokenDisplayOnceModal.warning.once": "Ce jeton ne sera affich\xE9 qu'une seule fois. Copiez-le maintenant.",
45
+ "TokenDisplayOnceModal.copied": "Copi\xE9",
46
+ "StatusBadge.aria.status": "Statut",
47
+ "StatusBadge.error.invalidProps": "StatusBadge : propri\xE9t\xE9s invalides"
48
+ };
49
+ var TABLE = {
50
+ en: EN,
51
+ fr: FR
52
+ };
53
+ function t(key, locale = "en") {
54
+ return TABLE[locale]?.[key] ?? TABLE.en[key];
55
+ }
56
+ var StatusBadgePropsSchema = zod.z.object({
57
+ status: zod.z.string(),
58
+ variant: zod.z.enum(["success", "warning", "danger", "info", "neutral"]).default("neutral"),
59
+ label: zod.z.string().optional(),
60
+ locale: zod.z.enum(["en", "fr"])
61
+ });
62
+ function validateProps(raw) {
63
+ return StatusBadgePropsSchema.parse(raw);
64
+ }
65
+ var variantClasses = {
66
+ success: "bg-green-100 text-green-800 ring-1 ring-green-300",
67
+ warning: "bg-amber-100 text-amber-800 ring-1 ring-amber-300",
68
+ danger: "bg-red-100 text-red-800 ring-1 ring-red-300",
69
+ info: "bg-blue-100 text-blue-800 ring-1 ring-blue-300",
70
+ neutral: "bg-slate-100 text-slate-800 ring-1 ring-slate-300"
71
+ };
72
+ function StatusBadgeInner({ status, variant, label, locale }) {
73
+ const ariaLabel = label ?? status;
74
+ return /* @__PURE__ */ jsxRuntime.jsx(
75
+ "output",
76
+ {
77
+ "aria-label": ariaLabel,
78
+ lang: locale,
79
+ className: `inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${variantClasses[variant]}`,
80
+ children: label ?? status
81
+ }
82
+ );
83
+ }
84
+ function StatusBadge(raw) {
85
+ try {
86
+ const props = validateProps(raw);
87
+ return /* @__PURE__ */ jsxRuntime.jsx(StatusBadgeInner, { ...props });
88
+ } catch {
89
+ const locale = raw.locale === "fr" ? "fr" : "en";
90
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { role: "alert", children: t("StatusBadge.error.invalidProps", locale) });
91
+ }
92
+ }
93
+
94
+ exports.StatusBadge = StatusBadge;
95
+ exports.StatusBadgePropsSchema = StatusBadgePropsSchema;
96
+ exports.validateStatusBadgeProps = validateProps;
97
+ //# sourceMappingURL=media.cjs.map
98
+ //# sourceMappingURL=media.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/i18n/strings.ts","../src/components/media/StatusBadge.schema.ts","../src/components/media/StatusBadge.tsx"],"names":["z","jsx"],"mappings":"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","file":"media.cjs","sourcesContent":["/**\n * Compile-time mirror of `@vantageos/mosaic-i18n` EN/FR locales for the 6\n * v0.1.0 components. Inlined here so that `<Comp>` renderers can resolve\n * `t(key, locale)` without dragging react-i18next into the component runtime\n * (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 */\nexport type MosaicLocale = \"en\" | \"fr\";\n\nconst EN = {\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} as const;\n\nconst FR: Record<keyof typeof EN, string> = {\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};\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 StatusBadgePropsSchema = z.object({\n status: z.string(),\n variant: z.enum([\"success\", \"warning\", \"danger\", \"info\", \"neutral\"]).default(\"neutral\"),\n label: z.string().optional(),\n locale: z.enum([\"en\", \"fr\"]),\n});\n\nexport type StatusBadgeProps = z.infer<typeof StatusBadgePropsSchema>;\n\nexport function validateProps(raw: unknown): StatusBadgeProps {\n return StatusBadgePropsSchema.parse(raw);\n}\n","// i18nKeys: StatusBadge.aria.status, StatusBadge.error.invalidProps\nimport React from \"react\";\nimport { type MosaicLocale, t } from \"../../i18n/strings.js\";\nimport { type StatusBadgeProps, validateProps } from \"./StatusBadge.schema\";\n\ntype Variant = \"success\" | \"warning\" | \"danger\" | \"info\" | \"neutral\";\n\nconst variantClasses: Record<Variant, string> = {\n success: \"bg-green-100 text-green-800 ring-1 ring-green-300\",\n warning: \"bg-amber-100 text-amber-800 ring-1 ring-amber-300\",\n danger: \"bg-red-100 text-red-800 ring-1 ring-red-300\",\n info: \"bg-blue-100 text-blue-800 ring-1 ring-blue-300\",\n neutral: \"bg-slate-100 text-slate-800 ring-1 ring-slate-300\",\n};\n\ninterface StatusBadgeInnerProps {\n status: string;\n variant: Variant;\n label?: string;\n locale: \"en\" | \"fr\";\n}\n\nfunction StatusBadgeInner({ status, variant, label, locale }: StatusBadgeInnerProps) {\n const ariaLabel = label ?? status;\n return (\n <output\n aria-label={ariaLabel}\n lang={locale}\n className={`inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${variantClasses[variant]}`}\n >\n {label ?? status}\n </output>\n );\n}\n\n/**\n * StatusBadge 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 StatusBadge(raw: Record<string, unknown>) {\n try {\n const props = validateProps(raw);\n return <StatusBadgeInner {...props} />;\n } catch {\n const locale: MosaicLocale = raw.locale === \"fr\" ? \"fr\" : \"en\";\n return <span role=\"alert\">{t(\"StatusBadge.error.invalidProps\", locale)}</span>;\n }\n}\n"]}
@@ -0,0 +1,29 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { z } from 'zod';
3
+
4
+ /**
5
+ * StatusBadge accepts any props object for JSX and MCP postMessage injection alike.
6
+ * Internal Zod validation narrows the type — invalid data renders an accessible error fallback.
7
+ */
8
+ declare function StatusBadge(raw: Record<string, unknown>): react_jsx_runtime.JSX.Element;
9
+
10
+ declare const StatusBadgePropsSchema: z.ZodObject<{
11
+ status: z.ZodString;
12
+ variant: z.ZodDefault<z.ZodEnum<["success", "warning", "danger", "info", "neutral"]>>;
13
+ label: z.ZodOptional<z.ZodString>;
14
+ locale: z.ZodEnum<["en", "fr"]>;
15
+ }, "strip", z.ZodTypeAny, {
16
+ locale: "en" | "fr";
17
+ status: string;
18
+ variant: "warning" | "danger" | "success" | "info" | "neutral";
19
+ label?: string | undefined;
20
+ }, {
21
+ locale: "en" | "fr";
22
+ status: string;
23
+ label?: string | undefined;
24
+ variant?: "warning" | "danger" | "success" | "info" | "neutral" | undefined;
25
+ }>;
26
+ type StatusBadgeProps = z.infer<typeof StatusBadgePropsSchema>;
27
+ declare function validateProps(raw: unknown): StatusBadgeProps;
28
+
29
+ export { StatusBadge, type StatusBadgeProps, StatusBadgePropsSchema, validateProps as validateStatusBadgeProps };
@@ -0,0 +1,29 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { z } from 'zod';
3
+
4
+ /**
5
+ * StatusBadge accepts any props object for JSX and MCP postMessage injection alike.
6
+ * Internal Zod validation narrows the type — invalid data renders an accessible error fallback.
7
+ */
8
+ declare function StatusBadge(raw: Record<string, unknown>): react_jsx_runtime.JSX.Element;
9
+
10
+ declare const StatusBadgePropsSchema: z.ZodObject<{
11
+ status: z.ZodString;
12
+ variant: z.ZodDefault<z.ZodEnum<["success", "warning", "danger", "info", "neutral"]>>;
13
+ label: z.ZodOptional<z.ZodString>;
14
+ locale: z.ZodEnum<["en", "fr"]>;
15
+ }, "strip", z.ZodTypeAny, {
16
+ locale: "en" | "fr";
17
+ status: string;
18
+ variant: "warning" | "danger" | "success" | "info" | "neutral";
19
+ label?: string | undefined;
20
+ }, {
21
+ locale: "en" | "fr";
22
+ status: string;
23
+ label?: string | undefined;
24
+ variant?: "warning" | "danger" | "success" | "info" | "neutral" | undefined;
25
+ }>;
26
+ type StatusBadgeProps = z.infer<typeof StatusBadgePropsSchema>;
27
+ declare function validateProps(raw: unknown): StatusBadgeProps;
28
+
29
+ export { StatusBadge, type StatusBadgeProps, StatusBadgePropsSchema, validateProps as validateStatusBadgeProps };
package/dist/media.js ADDED
@@ -0,0 +1,94 @@
1
+ import { z } from 'zod';
2
+ import { jsx } from 'react/jsx-runtime';
3
+
4
+ // src/i18n/strings.ts
5
+ var EN = {
6
+ "ProgressBar.aria.label": "Progress",
7
+ "ProgressBar.error.invalidProps": "ProgressBar: invalid props",
8
+ "ConfirmDialog.button.confirm": "Confirm",
9
+ "ConfirmDialog.button.cancel": "Cancel",
10
+ "ConfirmDialog.aria.dialog": "Confirmation dialog",
11
+ "TableView.aria.table": "Data table",
12
+ "TableView.pagination.next": "Next page",
13
+ "TableView.pagination.prev": "Previous page",
14
+ "TableView.empty.message": "No data to display",
15
+ "TableView.error.invalidProps": "TableView: invalid props",
16
+ "MarkdownRenderer.aria.content": "Rendered Markdown content",
17
+ "MarkdownRenderer.error.invalidProps": "MarkdownRenderer: invalid props",
18
+ "MarkdownRenderer.error.tooLong": "Content exceeds maximum length",
19
+ "TokenDisplayOnceModal.button.copy": "Copy token",
20
+ "TokenDisplayOnceModal.button.close": "Close",
21
+ "TokenDisplayOnceModal.warning.once": "This token will only be shown once. Copy it now.",
22
+ "TokenDisplayOnceModal.copied": "Copied",
23
+ "StatusBadge.aria.status": "Status",
24
+ "StatusBadge.error.invalidProps": "StatusBadge: invalid props"
25
+ };
26
+ var FR = {
27
+ "ProgressBar.aria.label": "Progression",
28
+ "ProgressBar.error.invalidProps": "ProgressBar : propri\xE9t\xE9s invalides",
29
+ "ConfirmDialog.button.confirm": "Confirmer",
30
+ "ConfirmDialog.button.cancel": "Annuler",
31
+ "ConfirmDialog.aria.dialog": "Bo\xEEte de dialogue de confirmation",
32
+ "TableView.aria.table": "Tableau de donn\xE9es",
33
+ "TableView.pagination.next": "Page suivante",
34
+ "TableView.pagination.prev": "Page pr\xE9c\xE9dente",
35
+ "TableView.empty.message": "Aucune donn\xE9e \xE0 afficher",
36
+ "TableView.error.invalidProps": "TableView : propri\xE9t\xE9s invalides",
37
+ "MarkdownRenderer.aria.content": "Contenu Markdown rendu",
38
+ "MarkdownRenderer.error.invalidProps": "MarkdownRenderer : propri\xE9t\xE9s invalides",
39
+ "MarkdownRenderer.error.tooLong": "Le contenu d\xE9passe la longueur maximale",
40
+ "TokenDisplayOnceModal.button.copy": "Copier le jeton",
41
+ "TokenDisplayOnceModal.button.close": "Fermer",
42
+ "TokenDisplayOnceModal.warning.once": "Ce jeton ne sera affich\xE9 qu'une seule fois. Copiez-le maintenant.",
43
+ "TokenDisplayOnceModal.copied": "Copi\xE9",
44
+ "StatusBadge.aria.status": "Statut",
45
+ "StatusBadge.error.invalidProps": "StatusBadge : propri\xE9t\xE9s invalides"
46
+ };
47
+ var TABLE = {
48
+ en: EN,
49
+ fr: FR
50
+ };
51
+ function t(key, locale = "en") {
52
+ return TABLE[locale]?.[key] ?? TABLE.en[key];
53
+ }
54
+ var StatusBadgePropsSchema = z.object({
55
+ status: z.string(),
56
+ variant: z.enum(["success", "warning", "danger", "info", "neutral"]).default("neutral"),
57
+ label: z.string().optional(),
58
+ locale: z.enum(["en", "fr"])
59
+ });
60
+ function validateProps(raw) {
61
+ return StatusBadgePropsSchema.parse(raw);
62
+ }
63
+ var variantClasses = {
64
+ success: "bg-green-100 text-green-800 ring-1 ring-green-300",
65
+ warning: "bg-amber-100 text-amber-800 ring-1 ring-amber-300",
66
+ danger: "bg-red-100 text-red-800 ring-1 ring-red-300",
67
+ info: "bg-blue-100 text-blue-800 ring-1 ring-blue-300",
68
+ neutral: "bg-slate-100 text-slate-800 ring-1 ring-slate-300"
69
+ };
70
+ function StatusBadgeInner({ status, variant, label, locale }) {
71
+ const ariaLabel = label ?? status;
72
+ return /* @__PURE__ */ jsx(
73
+ "output",
74
+ {
75
+ "aria-label": ariaLabel,
76
+ lang: locale,
77
+ className: `inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${variantClasses[variant]}`,
78
+ children: label ?? status
79
+ }
80
+ );
81
+ }
82
+ function StatusBadge(raw) {
83
+ try {
84
+ const props = validateProps(raw);
85
+ return /* @__PURE__ */ jsx(StatusBadgeInner, { ...props });
86
+ } catch {
87
+ const locale = raw.locale === "fr" ? "fr" : "en";
88
+ return /* @__PURE__ */ jsx("span", { role: "alert", children: t("StatusBadge.error.invalidProps", locale) });
89
+ }
90
+ }
91
+
92
+ export { StatusBadge, StatusBadgePropsSchema, validateProps as validateStatusBadgeProps };
93
+ //# sourceMappingURL=media.js.map
94
+ //# sourceMappingURL=media.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/i18n/strings.ts","../src/components/media/StatusBadge.schema.ts","../src/components/media/StatusBadge.tsx"],"names":[],"mappings":"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","file":"media.js","sourcesContent":["/**\n * Compile-time mirror of `@vantageos/mosaic-i18n` EN/FR locales for the 6\n * v0.1.0 components. Inlined here so that `<Comp>` renderers can resolve\n * `t(key, locale)` without dragging react-i18next into the component runtime\n * (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 */\nexport type MosaicLocale = \"en\" | \"fr\";\n\nconst EN = {\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} as const;\n\nconst FR: Record<keyof typeof EN, string> = {\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};\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 StatusBadgePropsSchema = z.object({\n status: z.string(),\n variant: z.enum([\"success\", \"warning\", \"danger\", \"info\", \"neutral\"]).default(\"neutral\"),\n label: z.string().optional(),\n locale: z.enum([\"en\", \"fr\"]),\n});\n\nexport type StatusBadgeProps = z.infer<typeof StatusBadgePropsSchema>;\n\nexport function validateProps(raw: unknown): StatusBadgeProps {\n return StatusBadgePropsSchema.parse(raw);\n}\n","// i18nKeys: StatusBadge.aria.status, StatusBadge.error.invalidProps\nimport React from \"react\";\nimport { type MosaicLocale, t } from \"../../i18n/strings.js\";\nimport { type StatusBadgeProps, validateProps } from \"./StatusBadge.schema\";\n\ntype Variant = \"success\" | \"warning\" | \"danger\" | \"info\" | \"neutral\";\n\nconst variantClasses: Record<Variant, string> = {\n success: \"bg-green-100 text-green-800 ring-1 ring-green-300\",\n warning: \"bg-amber-100 text-amber-800 ring-1 ring-amber-300\",\n danger: \"bg-red-100 text-red-800 ring-1 ring-red-300\",\n info: \"bg-blue-100 text-blue-800 ring-1 ring-blue-300\",\n neutral: \"bg-slate-100 text-slate-800 ring-1 ring-slate-300\",\n};\n\ninterface StatusBadgeInnerProps {\n status: string;\n variant: Variant;\n label?: string;\n locale: \"en\" | \"fr\";\n}\n\nfunction StatusBadgeInner({ status, variant, label, locale }: StatusBadgeInnerProps) {\n const ariaLabel = label ?? status;\n return (\n <output\n aria-label={ariaLabel}\n lang={locale}\n className={`inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${variantClasses[variant]}`}\n >\n {label ?? status}\n </output>\n );\n}\n\n/**\n * StatusBadge 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 StatusBadge(raw: Record<string, unknown>) {\n try {\n const props = validateProps(raw);\n return <StatusBadgeInner {...props} />;\n } catch {\n const locale: MosaicLocale = raw.locale === \"fr\" ? \"fr\" : \"en\";\n return <span role=\"alert\">{t(\"StatusBadge.error.invalidProps\", locale)}</span>;\n }\n}\n"]}