@aotter/mantle-ui 0.2.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 (184) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +163 -0
  3. package/dist/admin/assets/developer-workspace-D6ZBl-hH.js +27 -0
  4. package/dist/admin/assets/developer-workspace-DLioOiRN.css +1 -0
  5. package/dist/admin/assets/html-editor-aFwAzRmq.js +129 -0
  6. package/dist/admin/assets/index-C0Ini5Qc.css +2 -0
  7. package/dist/admin/assets/index-DQemY7Xp.js +71 -0
  8. package/dist/admin/assets/markdown-editor-rSCtXCtH.js +29 -0
  9. package/dist/admin/assets/with-selector-BnwVHY9y.js +1 -0
  10. package/dist/admin/favicon.png +0 -0
  11. package/dist/admin/favicon.svg +20 -0
  12. package/dist/admin/index.html +18 -0
  13. package/dist/admin/preview.html +18 -0
  14. package/dist/admin/theme.js +64 -0
  15. package/dist/app/bridge.d.ts +75 -0
  16. package/dist/app/bridge.d.ts.map +1 -0
  17. package/dist/app/bridge.js +96 -0
  18. package/dist/app/bridge.js.map +1 -0
  19. package/dist/controller/index.d.ts +142 -0
  20. package/dist/controller/index.d.ts.map +1 -0
  21. package/dist/controller/index.js +279 -0
  22. package/dist/controller/index.js.map +1 -0
  23. package/dist/index.d.ts +8 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +8 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/kit/components/auth-card.d.ts +15 -0
  28. package/dist/kit/components/auth-card.d.ts.map +1 -0
  29. package/dist/kit/components/auth-card.js +12 -0
  30. package/dist/kit/components/auth-card.js.map +1 -0
  31. package/dist/kit/components/one-time-code-input.d.ts +4 -0
  32. package/dist/kit/components/one-time-code-input.d.ts.map +1 -0
  33. package/dist/kit/components/one-time-code-input.js +7 -0
  34. package/dist/kit/components/one-time-code-input.js.map +1 -0
  35. package/dist/kit/components/sign-in-flow.d.ts +94 -0
  36. package/dist/kit/components/sign-in-flow.d.ts.map +1 -0
  37. package/dist/kit/components/sign-in-flow.js +108 -0
  38. package/dist/kit/components/sign-in-flow.js.map +1 -0
  39. package/dist/kit/components/ui/alert-dialog.d.ts +19 -0
  40. package/dist/kit/components/ui/alert-dialog.d.ts.map +1 -0
  41. package/dist/kit/components/ui/alert-dialog.js +43 -0
  42. package/dist/kit/components/ui/alert-dialog.js.map +1 -0
  43. package/dist/kit/components/ui/avatar.d.ts +12 -0
  44. package/dist/kit/components/ui/avatar.d.ts.map +1 -0
  45. package/dist/kit/components/ui/avatar.js +24 -0
  46. package/dist/kit/components/ui/avatar.js.map +1 -0
  47. package/dist/kit/components/ui/badge.d.ts +10 -0
  48. package/dist/kit/components/ui/badge.d.ts.map +1 -0
  49. package/dist/kit/components/ui/badge.js +25 -0
  50. package/dist/kit/components/ui/badge.js.map +1 -0
  51. package/dist/kit/components/ui/breadcrumb.d.ts +13 -0
  52. package/dist/kit/components/ui/breadcrumb.d.ts.map +1 -0
  53. package/dist/kit/components/ui/breadcrumb.js +25 -0
  54. package/dist/kit/components/ui/breadcrumb.js.map +1 -0
  55. package/dist/kit/components/ui/button.d.ts +11 -0
  56. package/dist/kit/components/ui/button.d.ts.map +1 -0
  57. package/dist/kit/components/ui/button.js +36 -0
  58. package/dist/kit/components/ui/button.js.map +1 -0
  59. package/dist/kit/components/ui/calendar.d.ts +11 -0
  60. package/dist/kit/components/ui/calendar.d.ts.map +1 -0
  61. package/dist/kit/components/ui/calendar.js +77 -0
  62. package/dist/kit/components/ui/calendar.js.map +1 -0
  63. package/dist/kit/components/ui/card.d.ts +12 -0
  64. package/dist/kit/components/ui/card.d.ts.map +1 -0
  65. package/dist/kit/components/ui/card.js +25 -0
  66. package/dist/kit/components/ui/card.js.map +1 -0
  67. package/dist/kit/components/ui/checkbox.d.ts +5 -0
  68. package/dist/kit/components/ui/checkbox.d.ts.map +1 -0
  69. package/dist/kit/components/ui/checkbox.js +9 -0
  70. package/dist/kit/components/ui/checkbox.js.map +1 -0
  71. package/dist/kit/components/ui/collapsible.d.ts +6 -0
  72. package/dist/kit/components/ui/collapsible.d.ts.map +1 -0
  73. package/dist/kit/components/ui/collapsible.js +14 -0
  74. package/dist/kit/components/ui/collapsible.js.map +1 -0
  75. package/dist/kit/components/ui/dialog.d.ts +17 -0
  76. package/dist/kit/components/ui/dialog.d.ts.map +1 -0
  77. package/dist/kit/components/ui/dialog.js +37 -0
  78. package/dist/kit/components/ui/dialog.js.map +1 -0
  79. package/dist/kit/components/ui/dropdown-menu.d.ts +30 -0
  80. package/dist/kit/components/ui/dropdown-menu.d.ts.map +1 -0
  81. package/dist/kit/components/ui/dropdown-menu.js +51 -0
  82. package/dist/kit/components/ui/dropdown-menu.js.map +1 -0
  83. package/dist/kit/components/ui/input-otp.d.ts +11 -0
  84. package/dist/kit/components/ui/input-otp.d.ts.map +1 -0
  85. package/dist/kit/components/ui/input-otp.js +17 -0
  86. package/dist/kit/components/ui/input-otp.js.map +1 -0
  87. package/dist/kit/components/ui/input.d.ts +4 -0
  88. package/dist/kit/components/ui/input.d.ts.map +1 -0
  89. package/dist/kit/components/ui/input.js +7 -0
  90. package/dist/kit/components/ui/input.js.map +1 -0
  91. package/dist/kit/components/ui/label.d.ts +5 -0
  92. package/dist/kit/components/ui/label.d.ts.map +1 -0
  93. package/dist/kit/components/ui/label.js +8 -0
  94. package/dist/kit/components/ui/label.js.map +1 -0
  95. package/dist/kit/components/ui/pagination.d.ts +19 -0
  96. package/dist/kit/components/ui/pagination.d.ts.map +1 -0
  97. package/dist/kit/components/ui/pagination.js +24 -0
  98. package/dist/kit/components/ui/pagination.js.map +1 -0
  99. package/dist/kit/components/ui/popover.d.ts +11 -0
  100. package/dist/kit/components/ui/popover.d.ts.map +1 -0
  101. package/dist/kit/components/ui/popover.js +26 -0
  102. package/dist/kit/components/ui/popover.js.map +1 -0
  103. package/dist/kit/components/ui/select.d.ts +16 -0
  104. package/dist/kit/components/ui/select.d.ts.map +1 -0
  105. package/dist/kit/components/ui/select.js +37 -0
  106. package/dist/kit/components/ui/select.js.map +1 -0
  107. package/dist/kit/components/ui/separator.d.ts +5 -0
  108. package/dist/kit/components/ui/separator.d.ts.map +1 -0
  109. package/dist/kit/components/ui/separator.js +8 -0
  110. package/dist/kit/components/ui/separator.js.map +1 -0
  111. package/dist/kit/components/ui/sheet.d.ts +16 -0
  112. package/dist/kit/components/ui/sheet.d.ts.map +1 -0
  113. package/dist/kit/components/ui/sheet.js +37 -0
  114. package/dist/kit/components/ui/sheet.js.map +1 -0
  115. package/dist/kit/components/ui/sidebar.d.ts +77 -0
  116. package/dist/kit/components/ui/sidebar.d.ts.map +1 -0
  117. package/dist/kit/components/ui/sidebar.js +207 -0
  118. package/dist/kit/components/ui/sidebar.js.map +1 -0
  119. package/dist/kit/components/ui/skeleton.d.ts +3 -0
  120. package/dist/kit/components/ui/skeleton.d.ts.map +1 -0
  121. package/dist/kit/components/ui/skeleton.js +7 -0
  122. package/dist/kit/components/ui/skeleton.js.map +1 -0
  123. package/dist/kit/components/ui/sonner.d.ts +4 -0
  124. package/dist/kit/components/ui/sonner.d.ts.map +1 -0
  125. package/dist/kit/components/ui/sonner.js +23 -0
  126. package/dist/kit/components/ui/sonner.js.map +1 -0
  127. package/dist/kit/components/ui/table.d.ts +11 -0
  128. package/dist/kit/components/ui/table.d.ts.map +1 -0
  129. package/dist/kit/components/ui/table.js +28 -0
  130. package/dist/kit/components/ui/table.js.map +1 -0
  131. package/dist/kit/components/ui/tabs.d.ts +12 -0
  132. package/dist/kit/components/ui/tabs.d.ts.map +1 -0
  133. package/dist/kit/components/ui/tabs.js +28 -0
  134. package/dist/kit/components/ui/tabs.js.map +1 -0
  135. package/dist/kit/components/ui/textarea.d.ts +4 -0
  136. package/dist/kit/components/ui/textarea.d.ts.map +1 -0
  137. package/dist/kit/components/ui/textarea.js +7 -0
  138. package/dist/kit/components/ui/textarea.js.map +1 -0
  139. package/dist/kit/components/ui/tooltip.d.ts +8 -0
  140. package/dist/kit/components/ui/tooltip.d.ts.map +1 -0
  141. package/dist/kit/components/ui/tooltip.js +18 -0
  142. package/dist/kit/components/ui/tooltip.js.map +1 -0
  143. package/dist/kit/hooks/use-mobile.d.ts +2 -0
  144. package/dist/kit/hooks/use-mobile.d.ts.map +1 -0
  145. package/dist/kit/hooks/use-mobile.js +16 -0
  146. package/dist/kit/hooks/use-mobile.js.map +1 -0
  147. package/dist/kit/index.d.ts +37 -0
  148. package/dist/kit/index.d.ts.map +1 -0
  149. package/dist/kit/index.js +37 -0
  150. package/dist/kit/index.js.map +1 -0
  151. package/dist/kit/kit.css +2 -0
  152. package/dist/kit/lib/utils.d.ts +3 -0
  153. package/dist/kit/lib/utils.d.ts.map +1 -0
  154. package/dist/kit/lib/utils.js +6 -0
  155. package/dist/kit/lib/utils.js.map +1 -0
  156. package/dist/kit/tokens.css +88 -0
  157. package/dist/mcp-app/index.d.ts +6 -0
  158. package/dist/mcp-app/index.js +6 -0
  159. package/dist/mcp-app/interaction.html +183 -0
  160. package/dist/react/components.d.ts +59 -0
  161. package/dist/react/components.d.ts.map +1 -0
  162. package/dist/react/components.js +102 -0
  163. package/dist/react/components.js.map +1 -0
  164. package/dist/react/fields.d.ts +62 -0
  165. package/dist/react/fields.d.ts.map +1 -0
  166. package/dist/react/fields.js +225 -0
  167. package/dist/react/fields.js.map +1 -0
  168. package/dist/react/labels.d.ts +33 -0
  169. package/dist/react/labels.d.ts.map +1 -0
  170. package/dist/react/labels.js +30 -0
  171. package/dist/react/labels.js.map +1 -0
  172. package/dist/react/schema-form.d.ts +34 -0
  173. package/dist/react/schema-form.d.ts.map +1 -0
  174. package/dist/react/schema-form.js +79 -0
  175. package/dist/react/schema-form.js.map +1 -0
  176. package/dist/react/use-interaction.d.ts +4 -0
  177. package/dist/react/use-interaction.d.ts.map +1 -0
  178. package/dist/react/use-interaction.js +6 -0
  179. package/dist/react/use-interaction.js.map +1 -0
  180. package/dist/react/values.d.ts +64 -0
  181. package/dist/react/values.d.ts.map +1 -0
  182. package/dist/react/values.js +123 -0
  183. package/dist/react/values.js.map +1 -0
  184. package/package.json +130 -0
@@ -0,0 +1,34 @@
1
+ import type { ReactNode } from "react";
2
+ import type { InteractionController, InteractionState } from "../controller/index.js";
3
+ /** The JSON Schema subset the generic form renders. */
4
+ export interface FormSchema {
5
+ readonly type?: string | readonly string[];
6
+ readonly title?: string | Readonly<Record<string, string>>;
7
+ readonly description?: string | Readonly<Record<string, string>>;
8
+ readonly properties?: Readonly<Record<string, FormSchema>>;
9
+ readonly required?: readonly string[];
10
+ readonly enum?: readonly unknown[];
11
+ readonly maxLength?: number;
12
+ readonly readOnly?: boolean;
13
+ readonly [keyword: string]: unknown;
14
+ }
15
+ /**
16
+ * A plain form for an operation's editable inputs, for hosts without their
17
+ * own field renderer (an MCP App, a small application). Strings, numbers,
18
+ * booleans and enums get native controls; anything richer is edited as JSON.
19
+ * Fields listed in `hidden` (row bindings, the version, idempotency keys)
20
+ * are not rendered.
21
+ */
22
+ export declare function SchemaForm(props: {
23
+ readonly schema: FormSchema;
24
+ readonly controller: InteractionController;
25
+ readonly state: InteractionState;
26
+ readonly hidden?: readonly string[];
27
+ readonly language?: string;
28
+ }): ReactNode;
29
+ /**
30
+ * A schema `title` or `description` in the language: an exact tag, then the
31
+ * same tag in any case, then the same primary language, then English.
32
+ */
33
+ export declare function schemaText(value: FormSchema["title"], language: string | undefined): string | undefined;
34
+ //# sourceMappingURL=schema-form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-form.d.ts","sourceRoot":"","sources":["../../src/react/schema-form.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAEtF,uDAAuD;AACvD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3D,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACjE,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IAC3D,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;CACrC;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAChC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAC;IAC3C,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,GAAG,SAAS,CAyBZ;AA+DD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAUvG"}
@@ -0,0 +1,79 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * A plain form for an operation's editable inputs, for hosts without their
4
+ * own field renderer (an MCP App, a small application). Strings, numbers,
5
+ * booleans and enums get native controls; anything richer is edited as JSON.
6
+ * Fields listed in `hidden` (row bindings, the version, idempotency keys)
7
+ * are not rendered.
8
+ */
9
+ export function SchemaForm(props) {
10
+ const hidden = new Set(props.hidden ?? []);
11
+ const required = new Set(props.schema.required ?? []);
12
+ const fields = Object.entries(props.schema.properties ?? {})
13
+ .filter(([name, field]) => !hidden.has(name) && field.readOnly !== true);
14
+ if (fields.length === 0)
15
+ return null;
16
+ return (_jsx("div", { "data-slot": "schema-form", className: "grid gap-3", children: fields.map(([name, field]) => {
17
+ const id = `mantle-field-${name}`;
18
+ const label = schemaText(field.title, props.language) ?? name;
19
+ const hint = schemaText(field.description, props.language);
20
+ const value = props.state.draft[name];
21
+ return (_jsxs("div", { className: "grid gap-1 text-sm", children: [_jsxs("label", { htmlFor: id, className: "font-medium", children: [label, required.has(name) ? _jsx("span", { "aria-hidden": "true", children: " *" }) : null] }), control(id, name, field, value, required.has(name), props.controller, hint ? `${id}-hint` : undefined), hint ? _jsx("p", { id: `${id}-hint`, className: "text-muted-foreground", children: hint }) : null] }, name));
22
+ }) }));
23
+ }
24
+ function control(id, name, field, value, required, controller, describedBy) {
25
+ const common = { id, name, required, "aria-describedby": describedBy, className: "rounded-md border bg-background px-2 py-1" };
26
+ const type = Array.isArray(field.type) ? field.type.find((item) => item !== "null") : field.type;
27
+ if (field.enum) {
28
+ return (_jsxs("select", { ...common, value: value === undefined ? "" : String(value), onChange: (event) => {
29
+ const picked = field.enum.find((option) => String(option) === event.target.value);
30
+ controller.edit(name, picked);
31
+ }, children: [_jsx("option", { value: "", disabled: required, children: "\u2014" }), field.enum.map((option) => _jsx("option", { value: String(option), children: String(option) }, String(option)))] }));
32
+ }
33
+ if (type === "boolean") {
34
+ return _jsx("input", { ...common, type: "checkbox", className: "h-4 w-4", checked: value === true, onChange: (event) => controller.edit(name, event.target.checked) });
35
+ }
36
+ if (type === "number" || type === "integer") {
37
+ return (_jsx("input", { ...common, type: "number", step: type === "integer" ? 1 : "any", value: typeof value === "number" ? value : "", onChange: (event) => controller.edit(name, event.target.value === "" ? undefined : Number(event.target.value)) }));
38
+ }
39
+ if (type === "string") {
40
+ const long = (field.maxLength ?? 0) > 200;
41
+ return long
42
+ ? _jsx("textarea", { ...common, rows: 4, value: typeof value === "string" ? value : "", onChange: (event) => controller.edit(name, event.target.value) })
43
+ : _jsx("input", { ...common, type: "text", value: typeof value === "string" ? value : "", onChange: (event) => controller.edit(name, event.target.value) });
44
+ }
45
+ return _jsx(JsonField, { common: common, name: name, value: value, controller: controller });
46
+ }
47
+ function JsonField(props) {
48
+ return (_jsx("textarea", { ...props.common, rows: 4, defaultValue: props.value === undefined ? "" : JSON.stringify(props.value, null, 2), onBlur: (event) => {
49
+ const raw = event.target.value.trim();
50
+ event.target.setCustomValidity("");
51
+ if (raw === "")
52
+ return props.controller.edit(props.name, undefined);
53
+ try {
54
+ props.controller.edit(props.name, JSON.parse(raw));
55
+ }
56
+ catch {
57
+ event.target.setCustomValidity("Enter valid JSON.");
58
+ event.target.reportValidity();
59
+ }
60
+ } }));
61
+ }
62
+ /**
63
+ * A schema `title` or `description` in the language: an exact tag, then the
64
+ * same tag in any case, then the same primary language, then English.
65
+ */
66
+ export function schemaText(value, language) {
67
+ if (typeof value === "string")
68
+ return value;
69
+ if (!value)
70
+ return undefined;
71
+ const tags = Object.keys(value);
72
+ const wanted = language?.toLowerCase();
73
+ const primary = wanted?.split("-")[0];
74
+ const tag = (language && language in value ? language : undefined)
75
+ ?? tags.find((item) => item.toLowerCase() === wanted)
76
+ ?? tags.find((item) => item.toLowerCase().split("-")[0] === primary);
77
+ return (tag ? value[tag] : undefined) ?? value["en"] ?? Object.values(value)[0];
78
+ }
79
+ //# sourceMappingURL=schema-form.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-form.js","sourceRoot":"","sources":["../../src/react/schema-form.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { InteractionController, InteractionState } from "../controller/index.js";
2
+ /** The controller's snapshot as React state. */
3
+ export declare function useInteraction(controller: InteractionController): InteractionState;
4
+ //# sourceMappingURL=use-interaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-interaction.d.ts","sourceRoot":"","sources":["../../src/react/use-interaction.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAEtF,gDAAgD;AAChD,wBAAgB,cAAc,CAAC,UAAU,EAAE,qBAAqB,GAAG,gBAAgB,CAElF"}
@@ -0,0 +1,6 @@
1
+ import { useSyncExternalStore } from "react";
2
+ /** The controller's snapshot as React state. */
3
+ export function useInteraction(controller) {
4
+ return useSyncExternalStore(controller.subscribe, controller.getSnapshot, controller.getSnapshot);
5
+ }
6
+ //# sourceMappingURL=use-interaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-interaction.js","sourceRoot":"","sources":["../../src/react/use-interaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAG7C,gDAAgD;AAChD,MAAM,UAAU,cAAc,CAAC,UAAiC;IAC9D,OAAO,oBAAoB,CAAC,UAAU,CAAC,SAAS,EAAE,UAAU,CAAC,WAAW,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;AACpG,CAAC"}
@@ -0,0 +1,64 @@
1
+ import type { ReactNode } from "react";
2
+ /**
3
+ * How a Mantle value reads: labels, option titles, money, dates. Pure functions over the JSON Schema a field
4
+ * declares, shared by Admin and MCP Apps so a value looks the same wherever it is shown.
5
+ */
6
+ /** A string, or one per language (`{ en, "zh-TW" }`). */
7
+ export type LocalizedText = string | Readonly<Record<string, string>>;
8
+ /** The JSON Schema keywords the field and value renderers read; anything else passes through. */
9
+ export interface FieldSchema {
10
+ readonly type?: string | readonly string[];
11
+ readonly title?: LocalizedText;
12
+ readonly description?: LocalizedText;
13
+ readonly properties?: Readonly<Record<string, FieldSchema>>;
14
+ readonly required?: readonly string[];
15
+ readonly items?: FieldSchema;
16
+ readonly enum?: readonly unknown[];
17
+ readonly oneOf?: readonly FieldSchema[];
18
+ readonly const?: unknown;
19
+ readonly format?: string;
20
+ readonly minimum?: number;
21
+ readonly maximum?: number;
22
+ readonly maxLength?: number;
23
+ readonly default?: unknown;
24
+ readonly nullable?: boolean;
25
+ readonly readOnly?: boolean;
26
+ readonly [keyword: string]: unknown;
27
+ }
28
+ /**
29
+ * The preferred language (`en-US` also finds `en`, and case does not matter), then the site's canonical one, then English,
30
+ * then the first given.
31
+ */
32
+ export declare function resolveLocalizedText(value: LocalizedText | null | undefined, preferred: string, canonical?: string | null): string | null;
33
+ /** Kebab/snake/camelCase identifier to a human-readable label. */
34
+ export declare function fieldLabel(name: string): string;
35
+ /** A field's `title` in the language, else its name humanized. */
36
+ export declare function propertyLabel(name: string, schema: FieldSchema | undefined, language: string, canonical?: string | null): string;
37
+ /** A field's `description` in the language, if it has one. */
38
+ export declare function propertyDescription(schema: FieldSchema | undefined, language: string, canonical?: string | null): string | undefined;
39
+ /** A property's string options: its `enum`, or a `oneOf` of string `const`s, each with its `title`. */
40
+ export declare function enumOptions(schema: FieldSchema | undefined): {
41
+ value: string;
42
+ title?: LocalizedText;
43
+ }[] | undefined;
44
+ /** How an option reads: its `title` in the language, else the value humanized. */
45
+ export declare function optionLabel(schema: FieldSchema | undefined, value: string, language: string, canonical?: string | null): string;
46
+ /** An integer of minor units (`x-mcp-hint: money-minor`). */
47
+ export declare function moneyMinorHint(schema: FieldSchema | undefined): boolean;
48
+ /** An integer of epoch milliseconds (`x-mcp-hint: timestamp-ms`). */
49
+ export declare function timestampHint(schema: FieldSchema | undefined): boolean;
50
+ /** Minor units → a localized amount, in `currency` when it is an ISO 4217 code. */
51
+ export declare function formatMoneyMinor(value: unknown, currency?: unknown): string | null;
52
+ /** Epoch milliseconds → a localized date and time. */
53
+ export declare function formatTimestampMs(value: unknown): string | null;
54
+ /** A field value (epoch milliseconds or an ISO string) as a Date. */
55
+ export declare function dateFromFieldValue(value: unknown): Date | undefined;
56
+ /** Which of the entry's own timestamps a column is, by its name; none of them has a Schema title. */
57
+ export declare function nativeTimestamp(name: string): "created" | "updated" | undefined;
58
+ /** The entry's own timestamps are date-times on the wire, like a `format: date-time` field. */
59
+ export declare const NATIVE_TIMESTAMP: FieldSchema;
60
+ /** A column's schema: the property, or for a native timestamp column the date-time it is. */
61
+ export declare function withNativeSchema<S extends FieldSchema>(name: string, property: S | undefined): S | undefined;
62
+ /** One value as a cell shows it: money, dates and option titles formatted, anything structured as JSON. */
63
+ export declare function renderDataValue(schema: FieldSchema | undefined, value: unknown, language?: string, canonical?: string | null): ReactNode;
64
+ //# sourceMappingURL=values.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"values.d.ts","sourceRoot":"","sources":["../../src/react/values.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,123 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * The preferred language (`en-US` also finds `en`, and case does not matter), then the site's canonical one, then English,
4
+ * then the first given.
5
+ */
6
+ export function resolveLocalizedText(value, preferred, canonical) {
7
+ if (value == null)
8
+ return null;
9
+ if (typeof value === "string")
10
+ return value;
11
+ const keys = Object.keys(value);
12
+ const find = (tag) => (tag ? keys.find((k) => k.toLowerCase() === tag.toLowerCase()) : undefined);
13
+ const key = find(preferred) ?? find(preferred.split("-")[0]) ?? find(canonical) ?? find("en") ?? keys[0];
14
+ return key !== undefined ? value[key] : null;
15
+ }
16
+ /** Kebab/snake/camelCase identifier to a human-readable label. */
17
+ export function fieldLabel(name) {
18
+ return name
19
+ .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
20
+ .replace(/[_-]+/g, " ")
21
+ .replace(/\b\w/g, (char) => char.toUpperCase());
22
+ }
23
+ /** A field's `title` in the language, else its name humanized. */
24
+ export function propertyLabel(name, schema, language, canonical = null) {
25
+ return resolveLocalizedText(schema?.title, language, canonical) ?? fieldLabel(name);
26
+ }
27
+ /** A field's `description` in the language, if it has one. */
28
+ export function propertyDescription(schema, language, canonical = null) {
29
+ return resolveLocalizedText(schema?.description, language, canonical) ?? undefined;
30
+ }
31
+ /** A property's string options: its `enum`, or a `oneOf` of string `const`s, each with its `title`. */
32
+ export function enumOptions(schema) {
33
+ if (schema?.enum?.length && schema.enum.every((v) => typeof v === "string"))
34
+ return schema.enum.map((value) => ({ value }));
35
+ const branches = schema?.oneOf;
36
+ if (!branches?.length || !branches.every((b) => typeof b.const === "string"))
37
+ return undefined;
38
+ return branches.map((b) => ({ value: b.const, ...(b.title !== undefined ? { title: b.title } : {}) }));
39
+ }
40
+ /** How an option reads: its `title` in the language, else the value humanized. */
41
+ export function optionLabel(schema, value, language, canonical) {
42
+ const title = enumOptions(schema)?.find((o) => o.value === value)?.title;
43
+ return resolveLocalizedText(title, language, canonical) ?? fieldLabel(value);
44
+ }
45
+ /** An integer of minor units (`x-mcp-hint: money-minor`). */
46
+ export function moneyMinorHint(schema) {
47
+ return schema?.["x-mcp-hint"] === "money-minor";
48
+ }
49
+ /** An integer of epoch milliseconds (`x-mcp-hint: timestamp-ms`). */
50
+ export function timestampHint(schema) {
51
+ return schema?.["x-mcp-hint"] === "timestamp-ms";
52
+ }
53
+ /** Minor units → a localized amount, in `currency` when it is an ISO 4217 code. */
54
+ export function formatMoneyMinor(value, currency) {
55
+ if (typeof value !== "number" || !Number.isFinite(value))
56
+ return null;
57
+ const major = value / 100;
58
+ if (typeof currency === "string" && currency) {
59
+ try {
60
+ return new Intl.NumberFormat(undefined, { style: "currency", currency }).format(major);
61
+ }
62
+ catch {
63
+ // not a currency code: a plain grouped number
64
+ }
65
+ }
66
+ return new Intl.NumberFormat().format(major);
67
+ }
68
+ const TIMESTAMP_FMT = new Intl.DateTimeFormat(undefined, { dateStyle: "short", timeStyle: "short" });
69
+ /** Epoch milliseconds → a localized date and time. */
70
+ export function formatTimestampMs(value) {
71
+ if (typeof value !== "number" || !Number.isFinite(value))
72
+ return null;
73
+ try {
74
+ return TIMESTAMP_FMT.format(new Date(value));
75
+ }
76
+ catch {
77
+ return null;
78
+ }
79
+ }
80
+ /** A field value (epoch milliseconds or an ISO string) as a Date. */
81
+ export function dateFromFieldValue(value) {
82
+ if (typeof value !== "number" && typeof value !== "string")
83
+ return undefined;
84
+ const date = new Date(value);
85
+ return Number.isNaN(date.getTime()) ? undefined : date;
86
+ }
87
+ /** Which of the entry's own timestamps a column is, by its name; none of them has a Schema title. */
88
+ export function nativeTimestamp(name) {
89
+ return name === "createdAt" || name === "created_at" ? "created" : name === "updatedAt" || name === "updated_at" ? "updated" : undefined;
90
+ }
91
+ /** The entry's own timestamps are date-times on the wire, like a `format: date-time` field. */
92
+ export const NATIVE_TIMESTAMP = { type: "string", format: "date-time" };
93
+ const NATIVE = { createdAt: NATIVE_TIMESTAMP, updatedAt: NATIVE_TIMESTAMP, created_at: NATIVE_TIMESTAMP, updated_at: NATIVE_TIMESTAMP };
94
+ /** A column's schema: the property, or for a native timestamp column the date-time it is. */
95
+ export function withNativeSchema(name, property) {
96
+ return property ?? (Object.prototype.hasOwnProperty.call(NATIVE, name) ? NATIVE[name] : undefined);
97
+ }
98
+ /** One value as a cell shows it: money, dates and option titles formatted, anything structured as JSON. */
99
+ export function renderDataValue(schema, value, language = "en", canonical = null) {
100
+ if (moneyMinorHint(schema)) {
101
+ const formatted = formatMoneyMinor(value, undefined);
102
+ if (formatted)
103
+ return formatted;
104
+ }
105
+ if (timestampHint(schema)) {
106
+ const formatted = formatTimestampMs(value);
107
+ if (formatted)
108
+ return formatted;
109
+ }
110
+ if (schema?.format === "date-time" && typeof value === "string") {
111
+ const formatted = formatTimestampMs(Date.parse(value));
112
+ if (formatted)
113
+ return _jsx("time", { dateTime: value, children: formatted });
114
+ }
115
+ if (value == null || value === "")
116
+ return _jsx("span", { className: "text-muted-foreground", children: "-" });
117
+ if (typeof value === "string" && enumOptions(schema))
118
+ return optionLabel(schema, value, language, canonical);
119
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean")
120
+ return String(value);
121
+ return _jsx("span", { className: "font-mono text-xs", children: JSON.stringify(value) });
122
+ }
123
+ //# sourceMappingURL=values.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"values.js","sourceRoot":"","sources":["../../src/react/values.tsx"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,130 @@
1
+ {
2
+ "name": "@aotter/mantle-ui",
3
+ "version": "0.2.0-alpha.1",
4
+ "description": "Shared interaction UI for Mantle Admin and MCP Apps: a framework-free controller (/controller), React components on top of it, the UI kit (/kit) and the MCP App (/mcp-app).",
5
+ "license": "Apache-2.0",
6
+ "homepage": "https://mantle.tools/",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/aotter/mantle.git",
10
+ "directory": "packages/mantle-ui"
11
+ },
12
+ "type": "module",
13
+ "sideEffects": [
14
+ "*.css"
15
+ ],
16
+ "publishConfig": {
17
+ "access": "public",
18
+ "tag": "alpha",
19
+ "registry": "https://registry.npmjs.org"
20
+ },
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/index.d.ts",
24
+ "import": "./dist/index.js"
25
+ },
26
+ "./controller": {
27
+ "types": "./dist/controller/index.d.ts",
28
+ "import": "./dist/controller/index.js"
29
+ },
30
+ "./kit": {
31
+ "types": "./dist/kit/index.d.ts",
32
+ "import": "./dist/kit/index.js"
33
+ },
34
+ "./kit.css": "./dist/kit/kit.css",
35
+ "./tokens.css": "./dist/kit/tokens.css",
36
+ "./package.json": "./package.json",
37
+ "./mcp-app/interaction.html": "./dist/mcp-app/interaction.html",
38
+ "./mcp-app": {
39
+ "types": "./dist/mcp-app/index.d.ts",
40
+ "import": "./dist/mcp-app/index.js"
41
+ },
42
+ "./admin/index.html": "./dist/admin/index.html"
43
+ },
44
+ "files": [
45
+ "dist",
46
+ "README.md"
47
+ ],
48
+ "peerDependencies": {
49
+ "class-variance-authority": "^0.7.1",
50
+ "clsx": "^2.1.1",
51
+ "input-otp": "^1.5.0",
52
+ "lucide-react": "^1.41.0",
53
+ "radix-ui": "^1.6.7",
54
+ "react": "^19.0.0",
55
+ "react-day-picker": "^10.0.1",
56
+ "sonner": "^2.0.8",
57
+ "tailwind-merge": "^3.6.0"
58
+ },
59
+ "peerDependenciesMeta": {
60
+ "class-variance-authority": {
61
+ "optional": true
62
+ },
63
+ "clsx": {
64
+ "optional": true
65
+ },
66
+ "input-otp": {
67
+ "optional": true
68
+ },
69
+ "lucide-react": {
70
+ "optional": true
71
+ },
72
+ "radix-ui": {
73
+ "optional": true
74
+ },
75
+ "react": {
76
+ "optional": true
77
+ },
78
+ "react-day-picker": {
79
+ "optional": true
80
+ },
81
+ "sonner": {
82
+ "optional": true
83
+ },
84
+ "tailwind-merge": {
85
+ "optional": true
86
+ }
87
+ },
88
+ "devDependencies": {
89
+ "@dagrejs/dagre": "^3.1.1",
90
+ "@modelcontextprotocol/ext-apps": "2.0.0",
91
+ "@tailwindcss/vite": "^4.3.3",
92
+ "@tanstack/react-query": "^5.102.8",
93
+ "@tiptap/react": "^3.31.3",
94
+ "@tiptap/starter-kit": "^3.31.3",
95
+ "@types/node": "^26",
96
+ "@types/react": "^19.2.18",
97
+ "@types/react-dom": "^19.2.7",
98
+ "@vitejs/plugin-react": "^6.1.1",
99
+ "@xyflow/react": "^12.11.6",
100
+ "class-variance-authority": "^0.7.1",
101
+ "clsx": "^2.1.1",
102
+ "date-fns": "^4.4.0",
103
+ "input-otp": "^1.5.0",
104
+ "lucide-react": "^1.41.0",
105
+ "playwright": "^1.62.1",
106
+ "radix-ui": "^1.6.7",
107
+ "react": "^19.2.8",
108
+ "react-day-picker": "^10.0.1",
109
+ "react-dom": "^19.2.8",
110
+ "react-markdown": "^10.1.0",
111
+ "rehype-sanitize": "^6.0.0",
112
+ "remark-gfm": "^4.0.1",
113
+ "shadcn": "^4.19.1",
114
+ "sonner": "^2.0.8",
115
+ "tailwind-merge": "^3.6.0",
116
+ "tailwindcss": "^4.3.3",
117
+ "tw-animate-css": "^1.4.0",
118
+ "typescript": "^6.0.3",
119
+ "vite": "^8.2.2",
120
+ "vite-plugin-singlefile": "^2.3.0",
121
+ "vitest": "^4.1.11",
122
+ "@aotter/mantle": "0.2.0-alpha.1"
123
+ },
124
+ "scripts": {
125
+ "prebuild": "rm -rf dist .tsbuildinfo",
126
+ "build": "tsc -b tsconfig.lib.json && vite build --config vite.kit.config.ts && node scripts/emit-kit-styles.mjs && vite build --config vite.mcp-app.config.ts && node scripts/emit-mcp-app-module.mjs && vite build --config admin/vite.config.ts",
127
+ "typecheck": "tsc --noEmit -p tsconfig.lib.json && tsc -p tsconfig.mcp-app.json && tsc --noEmit -p admin/tsconfig.json",
128
+ "test": "vitest run"
129
+ }
130
+ }