@mobile-reality/mdma-renderer-vue 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +117 -0
  3. package/dist/components/ApprovalGateRenderer.d.ts +40 -0
  4. package/dist/components/ApprovalGateRenderer.d.ts.map +1 -0
  5. package/dist/components/ApprovalGateRenderer.js +48 -0
  6. package/dist/components/ApprovalGateRenderer.js.map +1 -0
  7. package/dist/components/ButtonRenderer.d.ts +40 -0
  8. package/dist/components/ButtonRenderer.d.ts.map +1 -0
  9. package/dist/components/ButtonRenderer.js +28 -0
  10. package/dist/components/ButtonRenderer.js.map +1 -0
  11. package/dist/components/CalloutRenderer.d.ts +40 -0
  12. package/dist/components/CalloutRenderer.d.ts.map +1 -0
  13. package/dist/components/CalloutRenderer.js +39 -0
  14. package/dist/components/CalloutRenderer.js.map +1 -0
  15. package/dist/components/ChartRenderer.d.ts +45 -0
  16. package/dist/components/ChartRenderer.d.ts.map +1 -0
  17. package/dist/components/ChartRenderer.js +66 -0
  18. package/dist/components/ChartRenderer.js.map +1 -0
  19. package/dist/components/CustomRenderer.d.ts +45 -0
  20. package/dist/components/CustomRenderer.d.ts.map +1 -0
  21. package/dist/components/CustomRenderer.js +32 -0
  22. package/dist/components/CustomRenderer.js.map +1 -0
  23. package/dist/components/FormRenderer.d.ts +41 -0
  24. package/dist/components/FormRenderer.d.ts.map +1 -0
  25. package/dist/components/FormRenderer.js +291 -0
  26. package/dist/components/FormRenderer.js.map +1 -0
  27. package/dist/components/MdastRenderer.d.ts +37 -0
  28. package/dist/components/MdastRenderer.d.ts.map +1 -0
  29. package/dist/components/MdastRenderer.js +102 -0
  30. package/dist/components/MdastRenderer.js.map +1 -0
  31. package/dist/components/MdmaBlock.d.ts +36 -0
  32. package/dist/components/MdmaBlock.d.ts.map +1 -0
  33. package/dist/components/MdmaBlock.js +40 -0
  34. package/dist/components/MdmaBlock.js.map +1 -0
  35. package/dist/components/MdmaBlockLoading.d.ts +29 -0
  36. package/dist/components/MdmaBlockLoading.d.ts.map +1 -0
  37. package/dist/components/MdmaBlockLoading.js +30 -0
  38. package/dist/components/MdmaBlockLoading.js.map +1 -0
  39. package/dist/components/MdmaDocument.d.ts +109 -0
  40. package/dist/components/MdmaDocument.d.ts.map +1 -0
  41. package/dist/components/MdmaDocument.js +190 -0
  42. package/dist/components/MdmaDocument.js.map +1 -0
  43. package/dist/components/TableRenderer.d.ts +40 -0
  44. package/dist/components/TableRenderer.d.ts.map +1 -0
  45. package/dist/components/TableRenderer.js +65 -0
  46. package/dist/components/TableRenderer.js.map +1 -0
  47. package/dist/components/TasklistRenderer.d.ts +40 -0
  48. package/dist/components/TasklistRenderer.d.ts.map +1 -0
  49. package/dist/components/TasklistRenderer.js +49 -0
  50. package/dist/components/TasklistRenderer.js.map +1 -0
  51. package/dist/components/ThinkingRenderer.d.ts +45 -0
  52. package/dist/components/ThinkingRenderer.d.ts.map +1 -0
  53. package/dist/components/ThinkingRenderer.js +48 -0
  54. package/dist/components/ThinkingRenderer.js.map +1 -0
  55. package/dist/components/WebhookRenderer.d.ts +40 -0
  56. package/dist/components/WebhookRenderer.d.ts.map +1 -0
  57. package/dist/components/WebhookRenderer.js +41 -0
  58. package/dist/components/WebhookRenderer.js.map +1 -0
  59. package/dist/composables/use-document-store.d.ts +22 -0
  60. package/dist/composables/use-document-store.d.ts.map +1 -0
  61. package/dist/composables/use-document-store.js +84 -0
  62. package/dist/composables/use-document-store.js.map +1 -0
  63. package/dist/context/CustomVariantContext.d.ts +41 -0
  64. package/dist/context/CustomVariantContext.d.ts.map +1 -0
  65. package/dist/context/CustomVariantContext.js +17 -0
  66. package/dist/context/CustomVariantContext.js.map +1 -0
  67. package/dist/context/ElementOverridesContext.d.ts +111 -0
  68. package/dist/context/ElementOverridesContext.d.ts.map +1 -0
  69. package/dist/context/ElementOverridesContext.js +31 -0
  70. package/dist/context/ElementOverridesContext.js.map +1 -0
  71. package/dist/context/MdmaProvider.d.ts +50 -0
  72. package/dist/context/MdmaProvider.d.ts.map +1 -0
  73. package/dist/context/MdmaProvider.js +35 -0
  74. package/dist/context/MdmaProvider.js.map +1 -0
  75. package/dist/index.d.ts +21 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +21 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/renderers/renderer-props.d.ts +51 -0
  80. package/dist/renderers/renderer-props.d.ts.map +1 -0
  81. package/dist/renderers/renderer-props.js +30 -0
  82. package/dist/renderers/renderer-props.js.map +1 -0
  83. package/dist/renderers/renderer-registry.d.ts +18 -0
  84. package/dist/renderers/renderer-registry.d.ts.map +1 -0
  85. package/dist/renderers/renderer-registry.js +52 -0
  86. package/dist/renderers/renderer-registry.js.map +1 -0
  87. package/dist/theme/MdmaThemeProvider.d.ts +152 -0
  88. package/dist/theme/MdmaThemeProvider.d.ts.map +1 -0
  89. package/dist/theme/MdmaThemeProvider.js +169 -0
  90. package/dist/theme/MdmaThemeProvider.js.map +1 -0
  91. package/package.json +60 -0
  92. package/styles.css +1045 -0
@@ -0,0 +1,30 @@
1
+ import { computed, defineComponent, h } from 'vue';
2
+ /** Try to extract a component type hint from partial YAML (e.g. "type: form"). */
3
+ function extractTypeHint(yaml) {
4
+ if (!yaml)
5
+ return null;
6
+ const match = yaml.match(/^\s*type:\s*(\S+)/m);
7
+ return match ? match[1] : null;
8
+ }
9
+ /**
10
+ * Skeleton shown for an `mdma` fence that hasn't finished streaming (or failed
11
+ * validation). The type hint comes from the partial YAML so the placeholder can
12
+ * name what is arriving instead of showing a generic spinner.
13
+ */
14
+ export const MdmaBlockLoading = defineComponent({
15
+ name: 'MdmaBlockLoading',
16
+ props: {
17
+ node: { type: Object, required: true },
18
+ },
19
+ setup(props) {
20
+ const typeHint = computed(() => extractTypeHint(props.node.value));
21
+ return () => h('div', { class: 'mdma-block-loading' }, [
22
+ h('div', { class: 'mdma-block-loading-shimmer' }),
23
+ h('div', { class: 'mdma-block-loading-content' }, [
24
+ h('span', { class: 'mdma-block-loading-icon' }),
25
+ h('span', { class: 'mdma-block-loading-text' }, typeHint.value ? `Loading ${typeHint.value} component...` : 'Loading component...'),
26
+ ]),
27
+ ]);
28
+ },
29
+ });
30
+ //# sourceMappingURL=MdmaBlockLoading.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MdmaBlockLoading.js","sourceRoot":"","sources":["../../src/components/MdmaBlockLoading.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC,EAAiB,MAAM,KAAK,CAAC;AAMlE,kFAAkF;AAClF,SAAS,eAAe,CAAC,IAAa;IACpC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAC/C,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,eAAe,CAAC;IAC9C,IAAI,EAAE,kBAAkB;IACxB,KAAK,EAAE;QACL,IAAI,EAAE,EAAE,IAAI,EAAE,MAAsC,EAAE,QAAQ,EAAE,IAAI,EAAE;KACvE;IACD,KAAK,CAAC,KAAK;QACT,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAEnE,OAAO,GAAG,EAAE,CACV,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAAE;YACxC,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC;YACjD,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,4BAA4B,EAAE,EAAE;gBAChD,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC;gBAC/C,CAAC,CACC,MAAM,EACN,EAAE,KAAK,EAAE,yBAAyB,EAAE,EACpC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,QAAQ,CAAC,KAAK,eAAe,CAAC,CAAC,CAAC,sBAAsB,CACnF;aACF,CAAC;SACH,CAAC,CAAC;IACP,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,109 @@
1
+ import { type PropType } from 'vue';
2
+ import type { MdmaRoot } from '@mobile-reality/mdma-spec';
3
+ import type { DocumentStore } from '@mobile-reality/mdma-runtime';
4
+ import { type DataSources } from '../context/MdmaProvider.js';
5
+ import { type CustomVariants } from '../context/CustomVariantContext.js';
6
+ import { type MdmaThemeInput } from '../theme/MdmaThemeProvider.js';
7
+ import type { MdmaBlockRenderer } from '../renderers/renderer-props.js';
8
+ /**
9
+ * A component entry can be either:
10
+ * - A Vue component — shorthand for a full renderer override.
11
+ * - A config object — with an optional `renderer` and/or `elements`
12
+ * for sub-element overrides (e.g. form inputs, checkboxes).
13
+ */
14
+ export type ComponentEntry = MdmaBlockRenderer | {
15
+ renderer?: MdmaBlockRenderer;
16
+ elements?: Record<string, MdmaBlockRenderer>;
17
+ };
18
+ /** Rendering customizations — a single map keyed by component type. */
19
+ export interface MdmaRenderCustomizations {
20
+ /**
21
+ * Component-level overrides keyed by MDMA component type name.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * components: {
26
+ * button: CustomButtonRenderer, // full renderer
27
+ * form: { elements: { input: GlassInput } }, // sub-element overrides
28
+ * }
29
+ * ```
30
+ */
31
+ components?: Record<string, ComponentEntry>;
32
+ /**
33
+ * Variant renderers for `custom` components, keyed by the component's `name`.
34
+ * Rendering is host/framework-specific, so it is registered here rather than
35
+ * in the spec. Register a variant's schema + behavior with the runtime's
36
+ * `registerCustomComponent`.
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * customVariants: { 'signature-pad': SignaturePadRenderer }
41
+ * ```
42
+ */
43
+ customVariants?: CustomVariants;
44
+ /** Named option lists that form select fields can reference by string (e.g. `options: countries`). */
45
+ dataSources?: DataSources;
46
+ }
47
+ export type MdmaDocumentProps = {
48
+ ast: MdmaRoot;
49
+ store: DocumentStore;
50
+ /** Rendering customizations (component renderers + element overrides). */
51
+ customizations?: MdmaRenderCustomizations;
52
+ /**
53
+ * Theme applied to the document root: `'light'` | `'dark'` | `'auto'`
54
+ * (follows the OS preference), or a full `MdmaTheme` for custom tokens.
55
+ * Omit to use the stylesheet's default (light) look.
56
+ */
57
+ theme?: MdmaThemeInput;
58
+ class?: string;
59
+ };
60
+ export declare const MdmaDocument: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
61
+ ast: {
62
+ type: PropType<MdmaRoot>;
63
+ required: true;
64
+ };
65
+ store: {
66
+ type: PropType<DocumentStore>;
67
+ required: true;
68
+ };
69
+ customizations: {
70
+ type: PropType<MdmaRenderCustomizations>;
71
+ default: undefined;
72
+ };
73
+ theme: {
74
+ type: PropType<MdmaThemeInput>;
75
+ default: undefined;
76
+ };
77
+ class: {
78
+ type: StringConstructor;
79
+ default: undefined;
80
+ };
81
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
82
+ [key: string]: any;
83
+ }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
84
+ ast: {
85
+ type: PropType<MdmaRoot>;
86
+ required: true;
87
+ };
88
+ store: {
89
+ type: PropType<DocumentStore>;
90
+ required: true;
91
+ };
92
+ customizations: {
93
+ type: PropType<MdmaRenderCustomizations>;
94
+ default: undefined;
95
+ };
96
+ theme: {
97
+ type: PropType<MdmaThemeInput>;
98
+ default: undefined;
99
+ };
100
+ class: {
101
+ type: StringConstructor;
102
+ default: undefined;
103
+ };
104
+ }>> & Readonly<{}>, {
105
+ theme: MdmaThemeInput;
106
+ class: string;
107
+ customizations: MdmaRenderCustomizations;
108
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
109
+ //# sourceMappingURL=MdmaDocument.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MdmaDocument.d.ts","sourceRoot":"","sources":["../../src/components/MdmaDocument.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6D,KAAK,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC/F,OAAO,KAAK,EAAE,QAAQ,EAA8B,MAAM,2BAA2B,CAAC;AAEtF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAK5E,OAAO,EAAyB,KAAK,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAChG,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,+BAA+B,CAAC;AAIvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAExE;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GACtB,iBAAiB,GACjB;IACE,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CAC9C,CAAC;AAEN,uEAAuE;AACvE,MAAM,WAAW,wBAAwB;IACvC;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC5C;;;;;;;;;;OAUG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,sGAAsG;IACtG,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,QAAQ,CAAC;IACd,KAAK,EAAE,aAAa,CAAC;IACrB,0EAA0E;IAC1E,cAAc,CAAC,EAAE,wBAAwB,CAAC;IAC1C;;;;OAIG;IACH,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAwHF,eAAO,MAAM,YAAY;;cAGE,QAAQ,CAAC,QAAQ,CAAC;;;;cAChB,QAAQ,CAAC,aAAa,CAAC;;;;cAE9B,QAAQ,CAAC,wBAAwB,CAAC;;;;cAGjB,QAAQ,CAAC,cAAc,CAAC;;;;;;;;;;;cANpC,QAAQ,CAAC,QAAQ,CAAC;;;;cAChB,QAAQ,CAAC,aAAa,CAAC;;;;cAE9B,QAAQ,CAAC,wBAAwB,CAAC;;;;cAGjB,QAAQ,CAAC,cAAc,CAAC;;;;;;;;;;;4EAiG7D,CAAC"}
@@ -0,0 +1,190 @@
1
+ import { computed, defineComponent, h, provide } from 'vue';
2
+ import { MDMA_LANG_TAG } from '@mobile-reality/mdma-spec';
3
+ import { MdmaProvider } from '../context/MdmaProvider.js';
4
+ import { ElementOverridesProvider, } from '../context/ElementOverridesContext.js';
5
+ import { CustomVariantProvider } from '../context/CustomVariantContext.js';
6
+ import { MdmaThemeKey, resolveThemeProps, useResolvedTheme, } from '../theme/MdmaThemeProvider.js';
7
+ import { MdmaBlock } from './MdmaBlock.js';
8
+ import { MdmaBlockLoading } from './MdmaBlockLoading.js';
9
+ import { MdastRenderer } from './MdastRenderer.js';
10
+ /** Check if an entry is a config object (has `renderer` or `elements`) rather than a component. */
11
+ function isComponentConfig(entry) {
12
+ return (typeof entry === 'object' && entry !== null && ('renderer' in entry || 'elements' in entry));
13
+ }
14
+ /** Split a unified `components` map into the internal renderer + elementOverrides formats. */
15
+ function splitComponents(components) {
16
+ if (!components)
17
+ return { renderers: undefined, elementOverrides: undefined };
18
+ const renderers = {};
19
+ const elementOverrides = {};
20
+ for (const [key, entry] of Object.entries(components)) {
21
+ if (isComponentConfig(entry)) {
22
+ if (entry.renderer)
23
+ renderers[key] = entry.renderer;
24
+ if (entry.elements)
25
+ elementOverrides[key] = entry.elements;
26
+ }
27
+ else {
28
+ renderers[key] = entry;
29
+ }
30
+ }
31
+ return {
32
+ renderers: Object.keys(renderers).length > 0 ? renderers : undefined,
33
+ elementOverrides: Object.keys(elementOverrides).length > 0 ? elementOverrides : undefined,
34
+ };
35
+ }
36
+ /** Extract the `id` field from partial YAML content. */
37
+ function extractIdFromYaml(yaml) {
38
+ if (!yaml)
39
+ return null;
40
+ const match = yaml.match(/^\s*id:\s*(\S+)/m);
41
+ return match ? match[1] : null;
42
+ }
43
+ /** Extract the `type` field from partial YAML content. */
44
+ function extractTypeFromYaml(yaml) {
45
+ if (!yaml)
46
+ return null;
47
+ const match = yaml.match(/^\s*type:\s*(\S+)/m);
48
+ return match ? match[1] : null;
49
+ }
50
+ /**
51
+ * Build a synthetic MdmaBlock for a thinking component from partial YAML.
52
+ * This allows the thinking block to render streamed content instead of
53
+ * showing a loading skeleton.
54
+ */
55
+ function buildPartialThinkingBlock(yaml) {
56
+ const id = extractIdFromYaml(yaml);
57
+ if (!id)
58
+ return null;
59
+ // Extract label (single-line value after "label:")
60
+ const labelMatch = yaml.match(/^\s*label:\s*(.+)$/m);
61
+ const label = labelMatch ? labelMatch[1].trim() : undefined;
62
+ // Extract content — handles both YAML block scalar (|) and inline string
63
+ let content = '';
64
+ const contentBlockMatch = yaml.match(/^\s*content:\s*\|\s*\n([\s\S]*)$/m);
65
+ if (contentBlockMatch) {
66
+ // Block scalar: grab everything after "content: |" up to the next
67
+ // top-level YAML key or end of string. Lines are indented by ≥2 spaces.
68
+ const rawBlock = contentBlockMatch[1];
69
+ const lines = [];
70
+ for (const line of rawBlock.split('\n')) {
71
+ // A non-indented non-empty line means a new YAML key — stop.
72
+ if (line.length > 0 && !line.startsWith(' ') && !line.startsWith('\t'))
73
+ break;
74
+ // Strip the common 2-space indent used by YAML block scalars
75
+ lines.push(line.replace(/^ {1,2}/, ''));
76
+ }
77
+ content = lines.join('\n').trimEnd();
78
+ }
79
+ else {
80
+ // Inline string: content: "some text" or content: some text
81
+ const inlineMatch = yaml.match(/^\s*content:\s*(?:"([^"]*)"|'([^']*)'|(.+))$/m);
82
+ if (inlineMatch) {
83
+ content = (inlineMatch[1] ?? inlineMatch[2] ?? inlineMatch[3] ?? '').trim();
84
+ }
85
+ }
86
+ return {
87
+ type: 'mdmaBlock',
88
+ rawYaml: yaml,
89
+ component: {
90
+ type: 'thinking',
91
+ id,
92
+ content: content || '...',
93
+ status: 'thinking',
94
+ collapsed: false,
95
+ ...(label ? { label } : {}),
96
+ },
97
+ };
98
+ }
99
+ function isMdmaBlock(node) {
100
+ return (typeof node === 'object' &&
101
+ node !== null &&
102
+ 'type' in node &&
103
+ node.type === 'mdmaBlock');
104
+ }
105
+ /** Detect code blocks with lang="mdma" that weren't converted to MdmaBlock
106
+ * (incomplete YAML during streaming or validation failure). */
107
+ function isPendingMdmaBlock(node) {
108
+ return (typeof node === 'object' &&
109
+ node !== null &&
110
+ 'type' in node &&
111
+ node.type === 'code' &&
112
+ 'lang' in node &&
113
+ node.lang === MDMA_LANG_TAG);
114
+ }
115
+ export const MdmaDocument = defineComponent({
116
+ name: 'MdmaDocument',
117
+ props: {
118
+ ast: { type: Object, required: true },
119
+ store: { type: Object, required: true },
120
+ customizations: {
121
+ type: Object,
122
+ default: undefined,
123
+ },
124
+ theme: { type: [String, Object], default: undefined },
125
+ class: { type: String, default: undefined },
126
+ },
127
+ setup(props) {
128
+ const split = computed(() => splitComponents(props.customizations?.components));
129
+ // Resolve our own `theme` prop, or inherit an ancestor `MdmaThemeProvider`'s
130
+ // theme when none is given (so a single provider can theme a whole app).
131
+ const inheritedTheme = useResolvedTheme();
132
+ const themeProps = computed(() => props.theme !== undefined ? resolveThemeProps(props.theme) : inheritedTheme.value);
133
+ provide(MdmaThemeKey, themeProps);
134
+ // Cache of successfully parsed blocks by component ID. Prevents flickering
135
+ // during streaming when a block alternates between parsed and pending states
136
+ // as incomplete YAML temporarily fails to validate.
137
+ const renderedBlocks = new Map();
138
+ const renderChild = (child, index) => {
139
+ const renderers = split.value.renderers;
140
+ if (isMdmaBlock(child)) {
141
+ // Cache this successfully parsed block
142
+ renderedBlocks.set(child.component.id, child);
143
+ return h(MdmaBlock, { key: child.component.id, block: child, renderers });
144
+ }
145
+ // Incomplete MDMA blocks (still streaming or failed validation)
146
+ if (isPendingMdmaBlock(child)) {
147
+ const pendingYaml = child.value;
148
+ const pendingId = extractIdFromYaml(pendingYaml);
149
+ // If this block was previously rendered, keep showing the rendered
150
+ // version instead of flickering back to the loading skeleton.
151
+ const cachedBlock = pendingId ? renderedBlocks.get(pendingId) : null;
152
+ if (cachedBlock) {
153
+ return h(MdmaBlock, {
154
+ key: cachedBlock.component.id,
155
+ block: cachedBlock,
156
+ renderers,
157
+ });
158
+ }
159
+ // Thinking blocks stream their content live instead of showing
160
+ // a loading skeleton — build a synthetic block from partial YAML.
161
+ const pendingType = extractTypeFromYaml(pendingYaml);
162
+ if (pendingType === 'thinking' && pendingYaml) {
163
+ const partialBlock = buildPartialThinkingBlock(pendingYaml);
164
+ if (partialBlock) {
165
+ return h(MdmaBlock, {
166
+ key: partialBlock.component.id,
167
+ block: partialBlock,
168
+ renderers,
169
+ });
170
+ }
171
+ }
172
+ return h(MdmaBlockLoading, { key: index, node: child });
173
+ }
174
+ // Render standard Markdown nodes (headings, paragraphs, lists, etc.)
175
+ return h(MdastRenderer, { key: index, node: child });
176
+ };
177
+ return () => h(MdmaProvider, { store: props.store, dataSources: props.customizations?.dataSources }, {
178
+ default: () => h(CustomVariantProvider, { value: props.customizations?.customVariants }, {
179
+ default: () => h(ElementOverridesProvider, { value: split.value.elementOverrides }, {
180
+ default: () => h('div', {
181
+ class: `mdma-document ${props.class ?? ''}`,
182
+ 'data-theme': themeProps.value.dataTheme,
183
+ style: themeProps.value.style,
184
+ }, props.ast.children.map(renderChild)),
185
+ }),
186
+ }),
187
+ });
188
+ },
189
+ });
190
+ //# sourceMappingURL=MdmaDocument.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MdmaDocument.js","sourceRoot":"","sources":["../../src/components/MdmaDocument.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ export declare const TableRenderer: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
2
+ component: {
3
+ type: import("vue").PropType<import("@mobile-reality/mdma-spec").MdmaComponent>;
4
+ required: true;
5
+ };
6
+ componentState: {
7
+ type: import("vue").PropType<import("@mobile-reality/mdma-runtime").ComponentState>;
8
+ default: undefined;
9
+ };
10
+ dispatch: {
11
+ type: import("vue").PropType<(action: import("@mobile-reality/mdma-spec").StoreAction) => void>;
12
+ required: true;
13
+ };
14
+ resolveBinding: {
15
+ type: import("vue").PropType<(expr: string) => unknown>;
16
+ required: true;
17
+ };
18
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
19
+ [key: string]: any;
20
+ }> | null, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
21
+ component: {
22
+ type: import("vue").PropType<import("@mobile-reality/mdma-spec").MdmaComponent>;
23
+ required: true;
24
+ };
25
+ componentState: {
26
+ type: import("vue").PropType<import("@mobile-reality/mdma-runtime").ComponentState>;
27
+ default: undefined;
28
+ };
29
+ dispatch: {
30
+ type: import("vue").PropType<(action: import("@mobile-reality/mdma-spec").StoreAction) => void>;
31
+ required: true;
32
+ };
33
+ resolveBinding: {
34
+ type: import("vue").PropType<(expr: string) => unknown>;
35
+ required: true;
36
+ };
37
+ }>> & Readonly<{}>, {
38
+ componentState: import("@mobile-reality/mdma-runtime").ComponentState;
39
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
40
+ //# sourceMappingURL=TableRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TableRenderer.d.ts","sourceRoot":"","sources":["../../src/components/TableRenderer.ts"],"names":[],"mappings":"AA0BA,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4EAyExB,CAAC"}
@@ -0,0 +1,65 @@
1
+ import { defineComponent, h, ref } from 'vue';
2
+ import { blockRendererProps } from '../renderers/renderer-props.js';
3
+ /** A PII cell, masked until the reader clicks to reveal it. */
4
+ const MaskedCell = defineComponent({
5
+ name: 'MdmaMaskedCell',
6
+ props: {
7
+ value: { type: String, required: true },
8
+ },
9
+ setup(props) {
10
+ const revealed = ref(false);
11
+ return () => h('span', {
12
+ class: 'mdma-table-cell--sensitive',
13
+ title: revealed.value ? 'Click to mask' : 'Click to reveal',
14
+ onClick: () => {
15
+ revealed.value = !revealed.value;
16
+ },
17
+ }, revealed.value ? props.value : '•••••');
18
+ },
19
+ });
20
+ export const TableRenderer = defineComponent({
21
+ name: 'TableRenderer',
22
+ props: blockRendererProps,
23
+ setup(props) {
24
+ return () => {
25
+ const component = props.component;
26
+ if (component.type !== 'table')
27
+ return null;
28
+ const rawData = typeof component.data === 'string' ? props.resolveBinding(component.data) : component.data;
29
+ const data = Array.isArray(rawData) ? rawData : [];
30
+ const sensitiveKeys = new Set(component.columns.filter((col) => col.sensitive).map((col) => col.key));
31
+ return h('div', { class: 'mdma-table', 'data-component-id': component.id }, [
32
+ component.label ? h('h3', { class: 'mdma-table-label' }, component.label) : null,
33
+ h('table', [
34
+ h('thead', [
35
+ h('tr', component.columns.map((col) => h('th', { key: col.key, style: col.width ? { width: col.width } : undefined }, [
36
+ col.header,
37
+ col.sensitive
38
+ ? h('span', { class: 'mdma-sensitive-badge', title: 'Sensitive column (PII)' }, '\u{1F512}')
39
+ : null,
40
+ ]))),
41
+ ]),
42
+ h('tbody', [
43
+ ...data.map((row, i) => h('tr', { key: i }, component.columns.map((col) => {
44
+ const raw = row[col.key] ?? '';
45
+ // A cell may itself hold a binding expression, e.g. "{{user.name}}".
46
+ const resolved = typeof raw === 'string' && /^\{\{.+\}\}$/.test(raw)
47
+ ? props.resolveBinding(raw)
48
+ : raw;
49
+ const cellValue = String(resolved ?? '');
50
+ return h('td', { key: col.key }, sensitiveKeys.has(col.key) && cellValue
51
+ ? h(MaskedCell, { value: cellValue })
52
+ : cellValue);
53
+ }))),
54
+ data.length === 0
55
+ ? h('tr', [
56
+ h('td', { colspan: component.columns.length, class: 'mdma-table-empty' }, 'No data'),
57
+ ])
58
+ : null,
59
+ ]),
60
+ ]),
61
+ ]);
62
+ };
63
+ },
64
+ });
65
+ //# sourceMappingURL=TableRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TableRenderer.js","sourceRoot":"","sources":["../../src/components/TableRenderer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ export declare const TasklistRenderer: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
2
+ component: {
3
+ type: import("vue").PropType<import("@mobile-reality/mdma-spec").MdmaComponent>;
4
+ required: true;
5
+ };
6
+ componentState: {
7
+ type: import("vue").PropType<import("@mobile-reality/mdma-runtime").ComponentState>;
8
+ default: undefined;
9
+ };
10
+ dispatch: {
11
+ type: import("vue").PropType<(action: import("@mobile-reality/mdma-spec").StoreAction) => void>;
12
+ required: true;
13
+ };
14
+ resolveBinding: {
15
+ type: import("vue").PropType<(expr: string) => unknown>;
16
+ required: true;
17
+ };
18
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
19
+ [key: string]: any;
20
+ }> | null, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
21
+ component: {
22
+ type: import("vue").PropType<import("@mobile-reality/mdma-spec").MdmaComponent>;
23
+ required: true;
24
+ };
25
+ componentState: {
26
+ type: import("vue").PropType<import("@mobile-reality/mdma-runtime").ComponentState>;
27
+ default: undefined;
28
+ };
29
+ dispatch: {
30
+ type: import("vue").PropType<(action: import("@mobile-reality/mdma-spec").StoreAction) => void>;
31
+ required: true;
32
+ };
33
+ resolveBinding: {
34
+ type: import("vue").PropType<(expr: string) => unknown>;
35
+ required: true;
36
+ };
37
+ }>> & Readonly<{}>, {
38
+ componentState: import("@mobile-reality/mdma-runtime").ComponentState;
39
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
40
+ //# sourceMappingURL=TasklistRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TasklistRenderer.d.ts","sourceRoot":"","sources":["../../src/components/TasklistRenderer.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4EAsD3B,CAAC"}
@@ -0,0 +1,49 @@
1
+ import { defineComponent, h } from 'vue';
2
+ import { blockRendererProps } from '../renderers/renderer-props.js';
3
+ export const TasklistRenderer = defineComponent({
4
+ name: 'TasklistRenderer',
5
+ props: blockRendererProps,
6
+ setup(props) {
7
+ return () => {
8
+ const component = props.component;
9
+ if (component.type !== 'tasklist')
10
+ return null;
11
+ const values = props.componentState?.values ?? {};
12
+ return h('div', { class: 'mdma-tasklist', 'data-component-id': component.id }, [
13
+ component.label ? h('h3', { class: 'mdma-tasklist-label' }, component.label) : null,
14
+ h('ul', { class: 'mdma-tasklist-items' }, component.items.map((item) => h('li', { key: item.id, class: 'mdma-tasklist-item' }, [
15
+ h('label', [
16
+ h('input', {
17
+ type: 'checkbox',
18
+ checked: Boolean(values[item.id]),
19
+ onChange: (e) => {
20
+ const checked = e.target.checked;
21
+ props.dispatch({
22
+ type: 'FIELD_CHANGED',
23
+ componentId: component.id,
24
+ field: item.id,
25
+ value: checked,
26
+ });
27
+ // Fire onComplete only on the transition into all-items-checked, mirroring
28
+ // how FormRenderer emits ACTION_TRIGGERED on submit.
29
+ if (component.onComplete) {
30
+ const wasComplete = component.items.every((it) => Boolean(values[it.id]));
31
+ const isComplete = component.items.every((it) => it.id === item.id ? checked : Boolean(values[it.id]));
32
+ if (!wasComplete && isComplete) {
33
+ props.dispatch({
34
+ type: 'ACTION_TRIGGERED',
35
+ componentId: component.id,
36
+ actionId: component.onComplete,
37
+ });
38
+ }
39
+ }
40
+ },
41
+ }),
42
+ h('span', item.text),
43
+ ]),
44
+ ]))),
45
+ ]);
46
+ };
47
+ },
48
+ });
49
+ //# sourceMappingURL=TasklistRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TasklistRenderer.js","sourceRoot":"","sources":["../../src/components/TasklistRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEpE,MAAM,CAAC,MAAM,gBAAgB,GAAG,eAAe,CAAC;IAC9C,IAAI,EAAE,kBAAkB;IACxB,KAAK,EAAE,kBAAkB;IACzB,KAAK,CAAC,KAAK;QACT,OAAO,GAAG,EAAE;YACV,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;YAClC,IAAI,SAAS,CAAC,IAAI,KAAK,UAAU;gBAAE,OAAO,IAAI,CAAC;YAE/C,MAAM,MAAM,GAAG,KAAK,CAAC,cAAc,EAAE,MAAM,IAAI,EAAE,CAAC;YAElD,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,SAAS,CAAC,EAAE,EAAE,EAAE;gBAC7E,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,qBAAqB,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI;gBACnF,CAAC,CACC,IAAI,EACJ,EAAE,KAAK,EAAE,qBAAqB,EAAE,EAChC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAC3B,CAAC,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAAE;oBACrD,CAAC,CAAC,OAAO,EAAE;wBACT,CAAC,CAAC,OAAO,EAAE;4BACT,IAAI,EAAE,UAAU;4BAChB,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;4BACjC,QAAQ,EAAE,CAAC,CAAQ,EAAE,EAAE;gCACrB,MAAM,OAAO,GAAI,CAAC,CAAC,MAA2B,CAAC,OAAO,CAAC;gCACvD,KAAK,CAAC,QAAQ,CAAC;oCACb,IAAI,EAAE,eAAe;oCACrB,WAAW,EAAE,SAAS,CAAC,EAAE;oCACzB,KAAK,EAAE,IAAI,CAAC,EAAE;oCACd,KAAK,EAAE,OAAO;iCACf,CAAC,CAAC;gCACH,2EAA2E;gCAC3E,qDAAqD;gCACrD,IAAI,SAAS,CAAC,UAAU,EAAE,CAAC;oCACzB,MAAM,WAAW,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;oCAC1E,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAC9C,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CACrD,CAAC;oCACF,IAAI,CAAC,WAAW,IAAI,UAAU,EAAE,CAAC;wCAC/B,KAAK,CAAC,QAAQ,CAAC;4CACb,IAAI,EAAE,kBAAkB;4CACxB,WAAW,EAAE,SAAS,CAAC,EAAE;4CACzB,QAAQ,EAAE,SAAS,CAAC,UAAU;yCAC/B,CAAC,CAAC;oCACL,CAAC;gCACH,CAAC;4BACH,CAAC;yBACF,CAAC;wBACF,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC;qBACrB,CAAC;iBACH,CAAC,CACH,CACF;aACF,CAAC,CAAC;QACL,CAAC,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Basic built-in thinking renderer.
3
+ * Uses native <details>/<summary> for a zero-dependency collapsible.
4
+ * Override with a richer renderer via customizations.
5
+ */
6
+ export declare const ThinkingRenderer: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
7
+ component: {
8
+ type: import("vue").PropType<import("@mobile-reality/mdma-spec").MdmaComponent>;
9
+ required: true;
10
+ };
11
+ componentState: {
12
+ type: import("vue").PropType<import("@mobile-reality/mdma-runtime").ComponentState>;
13
+ default: undefined;
14
+ };
15
+ dispatch: {
16
+ type: import("vue").PropType<(action: import("@mobile-reality/mdma-spec").StoreAction) => void>;
17
+ required: true;
18
+ };
19
+ resolveBinding: {
20
+ type: import("vue").PropType<(expr: string) => unknown>;
21
+ required: true;
22
+ };
23
+ }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
24
+ [key: string]: any;
25
+ }> | null, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
26
+ component: {
27
+ type: import("vue").PropType<import("@mobile-reality/mdma-spec").MdmaComponent>;
28
+ required: true;
29
+ };
30
+ componentState: {
31
+ type: import("vue").PropType<import("@mobile-reality/mdma-runtime").ComponentState>;
32
+ default: undefined;
33
+ };
34
+ dispatch: {
35
+ type: import("vue").PropType<(action: import("@mobile-reality/mdma-spec").StoreAction) => void>;
36
+ required: true;
37
+ };
38
+ resolveBinding: {
39
+ type: import("vue").PropType<(expr: string) => unknown>;
40
+ required: true;
41
+ };
42
+ }>> & Readonly<{}>, {
43
+ componentState: import("@mobile-reality/mdma-runtime").ComponentState;
44
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
45
+ //# sourceMappingURL=ThinkingRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThinkingRenderer.d.ts","sourceRoot":"","sources":["../../src/components/ThinkingRenderer.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4EAiD3B,CAAC"}