@json-render/solid 0.18.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/{chunk-XTSB6FIM.mjs → chunk-ZTWTJIEL.mjs} +6 -3
- package/dist/chunk-ZTWTJIEL.mjs.map +1 -0
- package/dist/index.d.mts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +53 -27
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +50 -27
- package/dist/index.mjs.map +1 -1
- package/dist/schema.d.mts +22 -2
- package/dist/schema.d.ts +22 -2
- package/dist/schema.js +5 -2
- package/dist/schema.js.map +1 -1
- package/dist/schema.mjs +1 -1
- package/package.json +2 -2
- package/dist/chunk-XTSB6FIM.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -227,6 +227,8 @@ await stream.send("Build me a dashboard");
|
|
|
227
227
|
|
|
228
228
|
## Differences from `@json-render/react`
|
|
229
229
|
|
|
230
|
+
Nested lists can set `repeat.statePath` to `{ "$item": "field" }` to iterate an array on the enclosing repeat item.
|
|
231
|
+
|
|
230
232
|
Most APIs are intentionally aligned, but there are runtime behavior differences due to Solid:
|
|
231
233
|
|
|
232
234
|
- Solid components run once, then update via signals.
|
|
@@ -16,7 +16,9 @@ var schema = defineSchema(
|
|
|
16
16
|
/** Child element keys (flat reference) */
|
|
17
17
|
children: s.array(s.string()),
|
|
18
18
|
/** Visibility condition */
|
|
19
|
-
visible: s.any()
|
|
19
|
+
visible: { ...s.any(), ...s.optional() },
|
|
20
|
+
/** Repeat children from a state array */
|
|
21
|
+
repeat: { ...s.any(), ...s.optional() }
|
|
20
22
|
})
|
|
21
23
|
)
|
|
22
24
|
}),
|
|
@@ -65,12 +67,13 @@ var schema = defineSchema(
|
|
|
65
67
|
// Element integrity
|
|
66
68
|
"CRITICAL INTEGRITY CHECK: Before outputting ANY element that references children, you MUST have already output (or will output) each child as its own element. If an element has children: ['a', 'b'], then elements 'a' and 'b' MUST exist. A missing child element causes that entire branch of the UI to be invisible.",
|
|
67
69
|
"SELF-CHECK: After generating all elements, mentally walk the tree from root. Every key in every children array must resolve to a defined element. If you find a gap, output the missing element immediately.",
|
|
70
|
+
'REQUIRED FIELDS: Every element MUST include a "children" array. Leaf elements (text, badges, inputs, images) use an empty array: "children": []. Omitting "children" fails validation.',
|
|
68
71
|
// Field placement
|
|
69
72
|
'CRITICAL: The "visible" field goes on the ELEMENT object, NOT inside "props". Correct: {"type":"<ComponentName>","props":{},"visible":{"$state":"/tab","eq":"home"},"children":[...]}.',
|
|
70
73
|
'CRITICAL: The "on" field goes on the ELEMENT object, NOT inside "props". Use on.press, on.change, on.submit etc. NEVER put action/actionParams inside props.',
|
|
71
74
|
// State and data
|
|
72
75
|
"When the user asks for a UI that displays data (e.g. blog posts, products, users), ALWAYS include a state field with realistic sample data. The state field is a top-level field on the spec (sibling of root/elements).",
|
|
73
|
-
'When building repeating content backed by a state array (e.g. posts, products, items), use the "repeat" field on a container element. Example: { "type": "<ContainerComponent>", "props": {}, "repeat": { "statePath": "/posts", "key": "id" }, "children": ["post-card"] }. Replace <ContainerComponent> with an appropriate component from the AVAILABLE COMPONENTS list. Inside repeated children, use { "$item": "field" } to read a field from the current item, and { "$index": true } for the current array index. For two-way binding to an item field use { "$bindItem": "completed" }. Do NOT hardcode individual elements for each array item.',
|
|
76
|
+
'When building repeating content backed by a state array (e.g. posts, products, items), use the "repeat" field on a container element. Example: { "type": "<ContainerComponent>", "props": {}, "repeat": { "statePath": "/posts", "key": "id" }, "children": ["post-card"] }. For a nested list stored on the enclosing item, use "repeat": { "statePath": { "$item": "comments" }, "key": "id" }. The $item statePath form is valid only inside another repeat. Replace <ContainerComponent> with an appropriate component from the AVAILABLE COMPONENTS list. Inside repeated children, use { "$item": "field" } to read a field from the current item, and { "$index": true } for the current array index. For two-way binding to an item field use { "$bindItem": "completed" }. Do NOT hardcode individual elements for each array item.',
|
|
74
77
|
// Design quality
|
|
75
78
|
"Design with visual hierarchy: use container components to group content, heading components for section titles, proper spacing, and status indicators. ONLY use components from the AVAILABLE COMPONENTS list.",
|
|
76
79
|
"For data-rich UIs, use multi-column layout components if available. For forms and single-column content, use vertical layout components. ONLY use components from the AVAILABLE COMPONENTS list.",
|
|
@@ -84,4 +87,4 @@ export {
|
|
|
84
87
|
schema,
|
|
85
88
|
elementTreeSchema
|
|
86
89
|
};
|
|
87
|
-
//# sourceMappingURL=chunk-
|
|
90
|
+
//# sourceMappingURL=chunk-ZTWTJIEL.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schema.ts"],"sourcesContent":["import { defineSchema } from \"@json-render/core\";\n\n/**\n * The schema for @json-render/solid\n *\n * Defines:\n * - Spec: A flat tree of elements with keys, types, props, and children references\n * - Catalog: Components with props schemas, and optional actions\n */\nexport const schema = defineSchema(\n (s) => ({\n // What the AI-generated SPEC looks like\n spec: s.object({\n /** Root element key */\n root: s.string(),\n /** Flat map of elements by key */\n elements: s.record(\n s.object({\n /** Component type from catalog */\n type: s.ref(\"catalog.components\"),\n /** Component props */\n props: s.propsOf(\"catalog.components\"),\n /** Child element keys (flat reference) */\n children: s.array(s.string()),\n /** Visibility condition */\n visible: { ...s.any(), ...s.optional() },\n /** Repeat children from a state array */\n repeat: { ...s.any(), ...s.optional() },\n }),\n ),\n }),\n\n // What the CATALOG must provide\n catalog: s.object({\n /** Component definitions */\n components: s.map({\n /** Zod schema for component props */\n props: s.zod(),\n /** Slots for this component. Use ['default'] for children, or named slots like ['header', 'footer'] */\n slots: s.array(s.string()),\n /** Description for AI generation hints */\n description: s.string(),\n /** Example prop values used in prompt examples (auto-generated from Zod schema if omitted) */\n example: s.any(),\n }),\n /** Action definitions (optional) */\n actions: s.map({\n /** Zod schema for action params */\n params: s.zod(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n }),\n }),\n {\n builtInActions: [\n {\n name: \"setState\",\n description:\n \"Update a value in the state model at the given statePath. Params: { statePath: string, value: any }\",\n },\n {\n name: \"pushState\",\n description:\n 'Append an item to an array in state. Params: { statePath: string, value: any, clearStatePath?: string }. Value can contain {\"$state\":\"/path\"} refs and \"$id\" for auto IDs.',\n },\n {\n name: \"removeState\",\n description:\n \"Remove an item from an array in state by index. Params: { statePath: string, index: number }\",\n },\n {\n name: \"validateForm\",\n description:\n \"Validate all registered form fields and write the result to state. Params: { statePath?: string }. Defaults to /formValidation. Result: { valid: boolean, errors: Record<string, string[]> }.\",\n },\n ],\n defaultRules: [\n // Element integrity\n \"CRITICAL INTEGRITY CHECK: Before outputting ANY element that references children, you MUST have already output (or will output) each child as its own element. If an element has children: ['a', 'b'], then elements 'a' and 'b' MUST exist. A missing child element causes that entire branch of the UI to be invisible.\",\n \"SELF-CHECK: After generating all elements, mentally walk the tree from root. Every key in every children array must resolve to a defined element. If you find a gap, output the missing element immediately.\",\n 'REQUIRED FIELDS: Every element MUST include a \"children\" array. Leaf elements (text, badges, inputs, images) use an empty array: \"children\": []. Omitting \"children\" fails validation.',\n\n // Field placement\n 'CRITICAL: The \"visible\" field goes on the ELEMENT object, NOT inside \"props\". Correct: {\"type\":\"<ComponentName>\",\"props\":{},\"visible\":{\"$state\":\"/tab\",\"eq\":\"home\"},\"children\":[...]}.',\n 'CRITICAL: The \"on\" field goes on the ELEMENT object, NOT inside \"props\". Use on.press, on.change, on.submit etc. NEVER put action/actionParams inside props.',\n\n // State and data\n \"When the user asks for a UI that displays data (e.g. blog posts, products, users), ALWAYS include a state field with realistic sample data. The state field is a top-level field on the spec (sibling of root/elements).\",\n 'When building repeating content backed by a state array (e.g. posts, products, items), use the \"repeat\" field on a container element. Example: { \"type\": \"<ContainerComponent>\", \"props\": {}, \"repeat\": { \"statePath\": \"/posts\", \"key\": \"id\" }, \"children\": [\"post-card\"] }. For a nested list stored on the enclosing item, use \"repeat\": { \"statePath\": { \"$item\": \"comments\" }, \"key\": \"id\" }. The $item statePath form is valid only inside another repeat. Replace <ContainerComponent> with an appropriate component from the AVAILABLE COMPONENTS list. Inside repeated children, use { \"$item\": \"field\" } to read a field from the current item, and { \"$index\": true } for the current array index. For two-way binding to an item field use { \"$bindItem\": \"completed\" }. Do NOT hardcode individual elements for each array item.',\n\n // Design quality\n \"Design with visual hierarchy: use container components to group content, heading components for section titles, proper spacing, and status indicators. ONLY use components from the AVAILABLE COMPONENTS list.\",\n \"For data-rich UIs, use multi-column layout components if available. For forms and single-column content, use vertical layout components. ONLY use components from the AVAILABLE COMPONENTS list.\",\n \"Always include realistic, professional-looking sample data. For blogs include 3-4 posts with varied titles, authors, dates, categories. For products include names, prices, images. Never leave data empty.\",\n ],\n },\n);\n\n/**\n * Type for the Solid schema\n */\nexport type SolidSchema = typeof schema;\n\n/**\n * Infer the spec type from a catalog\n */\nexport type SolidSpec<TCatalog> = typeof schema extends {\n createCatalog: (catalog: TCatalog) => { _specType: infer S };\n}\n ? S\n : never;\n\n// Backward compatibility aliases\n/** @deprecated Use `schema` instead */\nexport const elementTreeSchema = schema;\n/** @deprecated Use `SolidSchema` instead */\nexport type ElementTreeSchema = SolidSchema;\n/** @deprecated Use `SolidSpec` instead */\nexport type ElementTreeSpec<T> = SolidSpec<T>;\n"],"mappings":";AAAA,SAAS,oBAAoB;AAStB,IAAM,SAAS;AAAA,EACpB,CAAC,OAAO;AAAA;AAAA,IAEN,MAAM,EAAE,OAAO;AAAA;AAAA,MAEb,MAAM,EAAE,OAAO;AAAA;AAAA,MAEf,UAAU,EAAE;AAAA,QACV,EAAE,OAAO;AAAA;AAAA,UAEP,MAAM,EAAE,IAAI,oBAAoB;AAAA;AAAA,UAEhC,OAAO,EAAE,QAAQ,oBAAoB;AAAA;AAAA,UAErC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA;AAAA,UAE5B,SAAS,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA;AAAA,UAEvC,QAAQ,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,SAAS,EAAE;AAAA,QACxC,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA;AAAA,IAGD,SAAS,EAAE,OAAO;AAAA;AAAA,MAEhB,YAAY,EAAE,IAAI;AAAA;AAAA,QAEhB,OAAO,EAAE,IAAI;AAAA;AAAA,QAEb,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA;AAAA,QAEzB,aAAa,EAAE,OAAO;AAAA;AAAA,QAEtB,SAAS,EAAE,IAAI;AAAA,MACjB,CAAC;AAAA;AAAA,MAED,SAAS,EAAE,IAAI;AAAA;AAAA,QAEb,QAAQ,EAAE,IAAI;AAAA;AAAA,QAEd,aAAa,EAAE,OAAO;AAAA,MACxB,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EACA;AAAA,IACE,gBAAgB;AAAA,MACd;AAAA,QACE,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,aACE;AAAA,MACJ;AAAA,IACF;AAAA,IACA,cAAc;AAAA;AAAA,MAEZ;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAGA;AAAA,MACA;AAAA;AAAA,MAGA;AAAA,MACA;AAAA;AAAA,MAGA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAkBO,IAAM,oBAAoB;","names":[]}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as solid_js from 'solid-js';
|
|
2
2
|
import { ParentProps, Accessor, JSX, Component } from 'solid-js';
|
|
3
|
-
import { StateStore, StateModel, VisibilityCondition, VisibilityContext, ActionHandler, ResolvedAction, ActionBinding, ActionConfirm, ValidationFunction, ValidationResult, ValidationConfig, Catalog, InferCatalogComponents, InferComponentProps, InferCatalogActions, InferActionParams, UIElement, SchemaDefinition, Spec, ComputedFunction, FlatElement } from '@json-render/core';
|
|
3
|
+
import { StateStore, StateModel, VisibilityCondition, VisibilityContext, ActionHandler, ResolvedAction, ActionBinding, ActionConfirm, ValidationFunction, ValidationResult, ValidationConfig, Catalog, InferCatalogComponents, InferComponentProps, InferCatalogActions, InferActionParams, UIElement, SchemaDefinition, Spec, ComputedFunction, DirectiveDefinition, FlatElement } from '@json-render/core';
|
|
4
4
|
export { Spec, StateModel, StateStore, createStateStore } from '@json-render/core';
|
|
5
5
|
export { ElementTreeSchema, ElementTreeSpec, SolidSchema, SolidSpec, elementTreeSchema, schema } from './schema.mjs';
|
|
6
6
|
|
|
@@ -278,6 +278,8 @@ interface JSONUIProviderProps {
|
|
|
278
278
|
validationFunctions?: Record<string, (value: unknown, args?: Record<string, unknown>) => boolean>;
|
|
279
279
|
/** Named functions for `$computed` expressions in props */
|
|
280
280
|
functions?: Record<string, ComputedFunction>;
|
|
281
|
+
/** Custom directives for user-defined `$`-prefixed dynamic values */
|
|
282
|
+
directives?: DirectiveDefinition[];
|
|
281
283
|
/** Callback when state changes (uncontrolled mode) */
|
|
282
284
|
onStateChange?: (changes: Array<{
|
|
283
285
|
path: string;
|
|
@@ -366,6 +368,8 @@ interface CreateRendererProps {
|
|
|
366
368
|
}>) => void;
|
|
367
369
|
/** Named functions for `$computed` expressions in props */
|
|
368
370
|
functions?: Record<string, ComputedFunction>;
|
|
371
|
+
/** Custom directives for user-defined `$`-prefixed dynamic values */
|
|
372
|
+
directives?: DirectiveDefinition[];
|
|
369
373
|
/** Whether the spec is currently loading/streaming */
|
|
370
374
|
loading?: boolean;
|
|
371
375
|
/** Fallback component for unknown types */
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as solid_js from 'solid-js';
|
|
2
2
|
import { ParentProps, Accessor, JSX, Component } from 'solid-js';
|
|
3
|
-
import { StateStore, StateModel, VisibilityCondition, VisibilityContext, ActionHandler, ResolvedAction, ActionBinding, ActionConfirm, ValidationFunction, ValidationResult, ValidationConfig, Catalog, InferCatalogComponents, InferComponentProps, InferCatalogActions, InferActionParams, UIElement, SchemaDefinition, Spec, ComputedFunction, FlatElement } from '@json-render/core';
|
|
3
|
+
import { StateStore, StateModel, VisibilityCondition, VisibilityContext, ActionHandler, ResolvedAction, ActionBinding, ActionConfirm, ValidationFunction, ValidationResult, ValidationConfig, Catalog, InferCatalogComponents, InferComponentProps, InferCatalogActions, InferActionParams, UIElement, SchemaDefinition, Spec, ComputedFunction, DirectiveDefinition, FlatElement } from '@json-render/core';
|
|
4
4
|
export { Spec, StateModel, StateStore, createStateStore } from '@json-render/core';
|
|
5
5
|
export { ElementTreeSchema, ElementTreeSpec, SolidSchema, SolidSpec, elementTreeSchema, schema } from './schema.js';
|
|
6
6
|
|
|
@@ -278,6 +278,8 @@ interface JSONUIProviderProps {
|
|
|
278
278
|
validationFunctions?: Record<string, (value: unknown, args?: Record<string, unknown>) => boolean>;
|
|
279
279
|
/** Named functions for `$computed` expressions in props */
|
|
280
280
|
functions?: Record<string, ComputedFunction>;
|
|
281
|
+
/** Custom directives for user-defined `$`-prefixed dynamic values */
|
|
282
|
+
directives?: DirectiveDefinition[];
|
|
281
283
|
/** Callback when state changes (uncontrolled mode) */
|
|
282
284
|
onStateChange?: (changes: Array<{
|
|
283
285
|
path: string;
|
|
@@ -366,6 +368,8 @@ interface CreateRendererProps {
|
|
|
366
368
|
}>) => void;
|
|
367
369
|
/** Named functions for `$computed` expressions in props */
|
|
368
370
|
functions?: Record<string, ComputedFunction>;
|
|
371
|
+
/** Custom directives for user-defined `$`-prefixed dynamic values */
|
|
372
|
+
directives?: DirectiveDefinition[];
|
|
369
373
|
/** Whether the spec is currently loading/streaming */
|
|
370
374
|
loading?: boolean;
|
|
371
375
|
/** Fallback component for unknown types */
|
package/dist/index.js
CHANGED
|
@@ -598,11 +598,8 @@ function ActionProvider(props) {
|
|
|
598
598
|
handler,
|
|
599
599
|
setState: set,
|
|
600
600
|
navigate: props.navigate,
|
|
601
|
-
executeAction: async (
|
|
602
|
-
|
|
603
|
-
action: name
|
|
604
|
-
};
|
|
605
|
-
await execute(subBinding);
|
|
601
|
+
executeAction: async (binding2) => {
|
|
602
|
+
await execute(binding2);
|
|
606
603
|
}
|
|
607
604
|
});
|
|
608
605
|
} finally {
|
|
@@ -621,11 +618,8 @@ function ActionProvider(props) {
|
|
|
621
618
|
handler,
|
|
622
619
|
setState: set,
|
|
623
620
|
navigate: props.navigate,
|
|
624
|
-
executeAction: async (
|
|
625
|
-
|
|
626
|
-
action: name
|
|
627
|
-
};
|
|
628
|
-
await execute(subBinding);
|
|
621
|
+
executeAction: async (binding2) => {
|
|
622
|
+
await execute(binding2);
|
|
629
623
|
}
|
|
630
624
|
});
|
|
631
625
|
} finally {
|
|
@@ -753,7 +747,9 @@ var schema = (0, import_core5.defineSchema)(
|
|
|
753
747
|
/** Child element keys (flat reference) */
|
|
754
748
|
children: s.array(s.string()),
|
|
755
749
|
/** Visibility condition */
|
|
756
|
-
visible: s.any()
|
|
750
|
+
visible: { ...s.any(), ...s.optional() },
|
|
751
|
+
/** Repeat children from a state array */
|
|
752
|
+
repeat: { ...s.any(), ...s.optional() }
|
|
757
753
|
})
|
|
758
754
|
)
|
|
759
755
|
}),
|
|
@@ -802,12 +798,13 @@ var schema = (0, import_core5.defineSchema)(
|
|
|
802
798
|
// Element integrity
|
|
803
799
|
"CRITICAL INTEGRITY CHECK: Before outputting ANY element that references children, you MUST have already output (or will output) each child as its own element. If an element has children: ['a', 'b'], then elements 'a' and 'b' MUST exist. A missing child element causes that entire branch of the UI to be invisible.",
|
|
804
800
|
"SELF-CHECK: After generating all elements, mentally walk the tree from root. Every key in every children array must resolve to a defined element. If you find a gap, output the missing element immediately.",
|
|
801
|
+
'REQUIRED FIELDS: Every element MUST include a "children" array. Leaf elements (text, badges, inputs, images) use an empty array: "children": []. Omitting "children" fails validation.',
|
|
805
802
|
// Field placement
|
|
806
803
|
'CRITICAL: The "visible" field goes on the ELEMENT object, NOT inside "props". Correct: {"type":"<ComponentName>","props":{},"visible":{"$state":"/tab","eq":"home"},"children":[...]}.',
|
|
807
804
|
'CRITICAL: The "on" field goes on the ELEMENT object, NOT inside "props". Use on.press, on.change, on.submit etc. NEVER put action/actionParams inside props.',
|
|
808
805
|
// State and data
|
|
809
806
|
"When the user asks for a UI that displays data (e.g. blog posts, products, users), ALWAYS include a state field with realistic sample data. The state field is a top-level field on the spec (sibling of root/elements).",
|
|
810
|
-
'When building repeating content backed by a state array (e.g. posts, products, items), use the "repeat" field on a container element. Example: { "type": "<ContainerComponent>", "props": {}, "repeat": { "statePath": "/posts", "key": "id" }, "children": ["post-card"] }. Replace <ContainerComponent> with an appropriate component from the AVAILABLE COMPONENTS list. Inside repeated children, use { "$item": "field" } to read a field from the current item, and { "$index": true } for the current array index. For two-way binding to an item field use { "$bindItem": "completed" }. Do NOT hardcode individual elements for each array item.',
|
|
807
|
+
'When building repeating content backed by a state array (e.g. posts, products, items), use the "repeat" field on a container element. Example: { "type": "<ContainerComponent>", "props": {}, "repeat": { "statePath": "/posts", "key": "id" }, "children": ["post-card"] }. For a nested list stored on the enclosing item, use "repeat": { "statePath": { "$item": "comments" }, "key": "id" }. The $item statePath form is valid only inside another repeat. Replace <ContainerComponent> with an appropriate component from the AVAILABLE COMPONENTS list. Inside repeated children, use { "$item": "field" } to read a field from the current item, and { "$index": true } for the current array index. For two-way binding to an item field use { "$bindItem": "completed" }. Do NOT hardcode individual elements for each array item.',
|
|
811
808
|
// Design quality
|
|
812
809
|
"Design with visual hierarchy: use container components to group content, heading components for section titles, proper spacing, and status indicators. ONLY use components from the AVAILABLE COMPONENTS list.",
|
|
813
810
|
"For data-rich UIs, use multi-column layout components if available. For forms and single-column content, use vertical layout components. ONLY use components from the AVAILABLE COMPONENTS list.",
|
|
@@ -835,6 +832,10 @@ var FunctionsContext = (0, import_solid_js6.createContext)(EMPTY_FUNCTIONS);
|
|
|
835
832
|
function useFunctions() {
|
|
836
833
|
return (0, import_solid_js6.useContext)(FunctionsContext) ?? EMPTY_FUNCTIONS;
|
|
837
834
|
}
|
|
835
|
+
var DirectivesContext = (0, import_solid_js6.createContext)(void 0);
|
|
836
|
+
function useDirectives() {
|
|
837
|
+
return (0, import_solid_js6.useContext)(DirectivesContext);
|
|
838
|
+
}
|
|
838
839
|
function useDevtoolsActive() {
|
|
839
840
|
const [active, setActive] = (0, import_solid_js6.createSignal)((0, import_core6.isDevtoolsActive)());
|
|
840
841
|
const unsub = (0, import_core6.subscribeDevtoolsActive)(() => setActive((0, import_core6.isDevtoolsActive)()));
|
|
@@ -852,6 +853,7 @@ function ElementRenderer(props) {
|
|
|
852
853
|
const stateStore = useStateStore();
|
|
853
854
|
const getSnapshot = () => stateStore.getSnapshot();
|
|
854
855
|
const functions = useFunctions();
|
|
856
|
+
const directives = useDirectives();
|
|
855
857
|
const fullCtx = (0, import_solid_js6.createMemo)(() => {
|
|
856
858
|
const repeatItem = repeatScope?.item;
|
|
857
859
|
const repeatIndex = repeatScope?.index;
|
|
@@ -869,7 +871,8 @@ function ElementRenderer(props) {
|
|
|
869
871
|
...repeatBasePath !== void 0 ? {
|
|
870
872
|
repeatBasePath
|
|
871
873
|
} : {},
|
|
872
|
-
functions
|
|
874
|
+
functions,
|
|
875
|
+
directives
|
|
873
876
|
};
|
|
874
877
|
});
|
|
875
878
|
const isVisible = (0, import_solid_js6.createMemo)(() => props.element.visible === void 0 ? true : (0, import_core6.evaluateVisibility)(props.element.visible, fullCtx()));
|
|
@@ -1111,8 +1114,15 @@ function ElementRendererContent(props) {
|
|
|
1111
1114
|
function RepeatChildren(props) {
|
|
1112
1115
|
const stateStore = useStateStore();
|
|
1113
1116
|
const repeat = () => props.element.repeat;
|
|
1114
|
-
const
|
|
1115
|
-
const
|
|
1117
|
+
const parentScope = useRepeatScope();
|
|
1118
|
+
const statePath = () => {
|
|
1119
|
+
const resolved = (0, import_core6.resolveRepeatStatePath)(repeat().statePath, parentScope?.basePath);
|
|
1120
|
+
if (resolved === void 0) {
|
|
1121
|
+
console.warn("[json-render/solid] $item in repeat.statePath used outside of a repeat scope");
|
|
1122
|
+
}
|
|
1123
|
+
return resolved;
|
|
1124
|
+
};
|
|
1125
|
+
const items = () => statePath() === void 0 ? [] : (0, import_core6.getByPath)(stateStore.state, statePath()) ?? [];
|
|
1116
1126
|
return (0, import_web18.createComponent)(import_solid_js6.For, {
|
|
1117
1127
|
get each() {
|
|
1118
1128
|
return items();
|
|
@@ -1128,7 +1138,7 @@ function RepeatChildren(props) {
|
|
|
1128
1138
|
return index();
|
|
1129
1139
|
},
|
|
1130
1140
|
get basePath() {
|
|
1131
|
-
return
|
|
1141
|
+
return (0, import_core6.resolveRepeatItemStatePath)(statePath(), index());
|
|
1132
1142
|
},
|
|
1133
1143
|
get children() {
|
|
1134
1144
|
return (0, import_web18.createComponent)(import_solid_js6.For, {
|
|
@@ -1205,6 +1215,7 @@ function Renderer(props) {
|
|
|
1205
1215
|
});
|
|
1206
1216
|
}
|
|
1207
1217
|
function JSONUIProvider(props) {
|
|
1218
|
+
const directiveRegistry = (0, import_solid_js6.createMemo)(() => props.directives ? (0, import_core6.createDirectiveRegistry)(props.directives) : void 0);
|
|
1208
1219
|
return (0, import_web18.createComponent)(StateProvider, {
|
|
1209
1220
|
get store() {
|
|
1210
1221
|
return props.store;
|
|
@@ -1236,7 +1247,14 @@ function JSONUIProvider(props) {
|
|
|
1236
1247
|
return props.functions ?? EMPTY_FUNCTIONS;
|
|
1237
1248
|
},
|
|
1238
1249
|
get children() {
|
|
1239
|
-
return
|
|
1250
|
+
return (0, import_web18.createComponent)(DirectivesContext.Provider, {
|
|
1251
|
+
get value() {
|
|
1252
|
+
return directiveRegistry();
|
|
1253
|
+
},
|
|
1254
|
+
get children() {
|
|
1255
|
+
return [(0, import_web17.memo)(() => props.children), (0, import_web18.createComponent)(ConfirmationDialogManager, {})];
|
|
1256
|
+
}
|
|
1257
|
+
});
|
|
1240
1258
|
}
|
|
1241
1259
|
});
|
|
1242
1260
|
}
|
|
@@ -1322,6 +1340,7 @@ function defineRegistry(_catalog, options) {
|
|
|
1322
1340
|
function createRenderer(catalog, components) {
|
|
1323
1341
|
const registry = components;
|
|
1324
1342
|
return function CatalogRenderer(props) {
|
|
1343
|
+
const directiveRegistry = (0, import_solid_js6.createMemo)(() => props.directives ? (0, import_core6.createDirectiveRegistry)(props.directives) : void 0);
|
|
1325
1344
|
const actionHandlers = () => props.onAction ? new Proxy({}, {
|
|
1326
1345
|
get: (_target, prop) => {
|
|
1327
1346
|
return (params) => props.onAction(prop, params);
|
|
@@ -1353,18 +1372,25 @@ function createRenderer(catalog, components) {
|
|
|
1353
1372
|
return props.functions ?? EMPTY_FUNCTIONS;
|
|
1354
1373
|
},
|
|
1355
1374
|
get children() {
|
|
1356
|
-
return
|
|
1357
|
-
get
|
|
1358
|
-
return
|
|
1359
|
-
},
|
|
1360
|
-
registry,
|
|
1361
|
-
get loading() {
|
|
1362
|
-
return props.loading;
|
|
1375
|
+
return (0, import_web18.createComponent)(DirectivesContext.Provider, {
|
|
1376
|
+
get value() {
|
|
1377
|
+
return directiveRegistry();
|
|
1363
1378
|
},
|
|
1364
|
-
get
|
|
1365
|
-
return
|
|
1379
|
+
get children() {
|
|
1380
|
+
return [(0, import_web18.createComponent)(Renderer, {
|
|
1381
|
+
get spec() {
|
|
1382
|
+
return props.spec;
|
|
1383
|
+
},
|
|
1384
|
+
registry,
|
|
1385
|
+
get loading() {
|
|
1386
|
+
return props.loading;
|
|
1387
|
+
},
|
|
1388
|
+
get fallback() {
|
|
1389
|
+
return props.fallback;
|
|
1390
|
+
}
|
|
1391
|
+
}), (0, import_web18.createComponent)(ConfirmationDialogManager, {})];
|
|
1366
1392
|
}
|
|
1367
|
-
})
|
|
1393
|
+
});
|
|
1368
1394
|
}
|
|
1369
1395
|
});
|
|
1370
1396
|
}
|