@json-render/svelte 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/CatalogRenderer.svelte +5 -1
- package/dist/CatalogRenderer.svelte.d.ts +3 -1
- package/dist/CatalogRenderer.svelte.d.ts.map +1 -1
- package/dist/ElementRenderer.svelte +5 -2
- package/dist/ElementRenderer.svelte.d.ts.map +1 -1
- package/dist/JsonUIProvider.svelte +9 -3
- package/dist/JsonUIProvider.svelte.d.ts +3 -1
- package/dist/JsonUIProvider.svelte.d.ts.map +1 -1
- package/dist/RepeatChildren.svelte +26 -7
- package/dist/RepeatChildren.svelte.d.ts.map +1 -1
- package/dist/contexts/ActionProvider.svelte +4 -6
- package/dist/contexts/ActionProvider.svelte.d.ts.map +1 -1
- package/dist/contexts/DirectivesContextProvider.svelte +46 -0
- package/dist/contexts/DirectivesContextProvider.svelte.d.ts +21 -0
- package/dist/contexts/DirectivesContextProvider.svelte.d.ts.map +1 -0
- package/dist/contexts/actions.test.js +32 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/renderer.d.ts +3 -1
- package/dist/renderer.d.ts.map +1 -1
- package/dist/renderer.js +3 -0
- package/dist/renderer.test.js +32 -0
- package/dist/schema.d.ts +11 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +5 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -148,6 +148,8 @@ const chat = createChatUI({ endpoint: "/api/chat" });
|
|
|
148
148
|
|
|
149
149
|
## Documentation
|
|
150
150
|
|
|
151
|
+
Nested lists can set `repeat.statePath` to `{ "$item": "field" }` to iterate an array on the enclosing repeat item.
|
|
152
|
+
|
|
151
153
|
Full API reference: [json-render.dev/docs/api/svelte](https://json-render.dev/docs/api/svelte).
|
|
152
154
|
|
|
153
155
|
## License
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
|
-
import type { ComputedFunction, Spec, StateStore } from "@json-render/core";
|
|
2
|
+
import type { ComputedFunction, DirectiveDefinition, Spec, StateStore } from "@json-render/core";
|
|
3
3
|
import type { ComponentRenderer, ComponentRegistry } from "./renderer.js";
|
|
4
4
|
|
|
5
5
|
export interface CatalogRendererProps {
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
onAction?: (actionName: string, params?: Record<string, unknown>) => void;
|
|
11
11
|
onStateChange?: (changes: Array<{ path: string; value: unknown }>) => void;
|
|
12
12
|
functions?: Record<string, ComputedFunction>;
|
|
13
|
+
/** Custom directives for user-defined `$`-prefixed dynamic values */
|
|
14
|
+
directives?: DirectiveDefinition[];
|
|
13
15
|
loading?: boolean;
|
|
14
16
|
fallback?: ComponentRenderer;
|
|
15
17
|
}
|
|
@@ -28,6 +30,7 @@
|
|
|
28
30
|
onAction,
|
|
29
31
|
onStateChange,
|
|
30
32
|
functions,
|
|
33
|
+
directives,
|
|
31
34
|
loading = false,
|
|
32
35
|
fallback,
|
|
33
36
|
}: CatalogRendererProps = $props();
|
|
@@ -50,6 +53,7 @@
|
|
|
50
53
|
initialState={state}
|
|
51
54
|
handlers={actionHandlers}
|
|
52
55
|
{functions}
|
|
56
|
+
{directives}
|
|
53
57
|
{onStateChange}>
|
|
54
58
|
<Renderer {spec} {registry} {loading} {fallback} />
|
|
55
59
|
</JsonUIProvider>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ComputedFunction, Spec, StateStore } from "@json-render/core";
|
|
1
|
+
import type { ComputedFunction, DirectiveDefinition, Spec, StateStore } from "@json-render/core";
|
|
2
2
|
import type { ComponentRenderer, ComponentRegistry } from "./renderer.js";
|
|
3
3
|
export interface CatalogRendererProps {
|
|
4
4
|
spec: Spec | null;
|
|
@@ -11,6 +11,8 @@ export interface CatalogRendererProps {
|
|
|
11
11
|
value: unknown;
|
|
12
12
|
}>) => void;
|
|
13
13
|
functions?: Record<string, ComputedFunction>;
|
|
14
|
+
/** Custom directives for user-defined `$`-prefixed dynamic values */
|
|
15
|
+
directives?: DirectiveDefinition[];
|
|
14
16
|
loading?: boolean;
|
|
15
17
|
fallback?: ComponentRenderer;
|
|
16
18
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CatalogRenderer.svelte.d.ts","sourceRoot":"","sources":["../src/CatalogRenderer.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"CatalogRenderer.svelte.d.ts","sourceRoot":"","sources":["../src/CatalogRenderer.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACjG,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE1E,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAC1E,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,KAAK,IAAI,CAAC;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC7C,qEAAqE;IACrE,UAAU,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B;AA6CH,QAAA,MAAM,eAAe,0DAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import { getActionContext } from "./contexts/ActionProvider.svelte";
|
|
17
17
|
import { getRepeatScope } from "./contexts/RepeatScopeProvider.svelte";
|
|
18
18
|
import { getFunctions } from "./contexts/FunctionsContextProvider.svelte";
|
|
19
|
+
import { getDirectives } from "./contexts/DirectivesContextProvider.svelte";
|
|
19
20
|
import RepeatChildren from "./RepeatChildren.svelte";
|
|
20
21
|
import Self from "./ElementRenderer.svelte";
|
|
21
22
|
|
|
@@ -49,8 +50,9 @@
|
|
|
49
50
|
const actionCtx = getActionContext();
|
|
50
51
|
const repeatScope = getRepeatScope();
|
|
51
52
|
const functions = getFunctions();
|
|
53
|
+
const directives = getDirectives();
|
|
52
54
|
|
|
53
|
-
// Build context with repeat scope
|
|
55
|
+
// Build context with repeat scope, $computed functions, and custom directives
|
|
54
56
|
let fullCtx = $derived<PropResolutionContext>(
|
|
55
57
|
repeatScope
|
|
56
58
|
? {
|
|
@@ -59,8 +61,9 @@
|
|
|
59
61
|
repeatIndex: repeatScope.index,
|
|
60
62
|
repeatBasePath: repeatScope.basePath,
|
|
61
63
|
functions,
|
|
64
|
+
directives,
|
|
62
65
|
}
|
|
63
|
-
: { stateModel: stateCtx.state, functions },
|
|
66
|
+
: { stateModel: stateCtx.state, functions, directives },
|
|
64
67
|
);
|
|
65
68
|
|
|
66
69
|
// Evaluate visibility
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElementRenderer.svelte.d.ts","sourceRoot":"","sources":["../src/ElementRenderer.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAWzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"ElementRenderer.svelte.d.ts","sourceRoot":"","sources":["../src/ElementRenderer.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAWzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAWxE,UAAU,KAAK;IACb,OAAO,EAAE,SAAS,CAAC;IACnB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B;AA+JH,QAAA,MAAM,eAAe,2CAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
|
-
import type { ComputedFunction } from "@json-render/core";
|
|
2
|
+
import type { ComputedFunction, DirectiveDefinition } from "@json-render/core";
|
|
3
3
|
/**
|
|
4
4
|
* Props for JSONUIProvider
|
|
5
5
|
*/
|
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
>;
|
|
25
25
|
/** Named functions for `$computed` expressions in props */
|
|
26
26
|
functions?: Record<string, ComputedFunction>;
|
|
27
|
+
/** Custom directives for user-defined `$`-prefixed dynamic values */
|
|
28
|
+
directives?: DirectiveDefinition[];
|
|
27
29
|
/** Callback when state changes (uncontrolled mode) */
|
|
28
30
|
onStateChange?: (changes: Array<{ path: string; value: unknown }>) => void;
|
|
29
31
|
/** Children snippet */
|
|
@@ -39,6 +41,7 @@
|
|
|
39
41
|
import ValidationProvider from "./contexts/ValidationProvider.svelte";
|
|
40
42
|
import ActionProvider from "./contexts/ActionProvider.svelte";
|
|
41
43
|
import FunctionsContextProvider from "./contexts/FunctionsContextProvider.svelte";
|
|
44
|
+
import DirectivesContextProvider from "./contexts/DirectivesContextProvider.svelte";
|
|
42
45
|
import ConfirmDialogManager from "./ConfirmDialogManager.svelte";
|
|
43
46
|
import type { ComponentRegistry } from "./renderer.js";
|
|
44
47
|
|
|
@@ -49,6 +52,7 @@
|
|
|
49
52
|
navigate,
|
|
50
53
|
validationFunctions = {},
|
|
51
54
|
functions,
|
|
55
|
+
directives,
|
|
52
56
|
onStateChange,
|
|
53
57
|
children,
|
|
54
58
|
}: JSONUIProviderProps = $props();
|
|
@@ -59,8 +63,10 @@
|
|
|
59
63
|
<ValidationProvider customFunctions={validationFunctions}>
|
|
60
64
|
<ActionProvider {handlers} {navigate}>
|
|
61
65
|
<FunctionsContextProvider {functions}>
|
|
62
|
-
{
|
|
63
|
-
|
|
66
|
+
<DirectivesContextProvider {directives}>
|
|
67
|
+
{@render children()}
|
|
68
|
+
<ConfirmDialogManager />
|
|
69
|
+
</DirectivesContextProvider>
|
|
64
70
|
</FunctionsContextProvider>
|
|
65
71
|
</ActionProvider>
|
|
66
72
|
</ValidationProvider>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ComputedFunction } from "@json-render/core";
|
|
1
|
+
import type { ComputedFunction, DirectiveDefinition } from "@json-render/core";
|
|
2
2
|
/**
|
|
3
3
|
* Props for JSONUIProvider
|
|
4
4
|
*/
|
|
@@ -20,6 +20,8 @@ export interface JSONUIProviderProps {
|
|
|
20
20
|
validationFunctions?: Record<string, (value: unknown, args?: Record<string, unknown>) => boolean>;
|
|
21
21
|
/** Named functions for `$computed` expressions in props */
|
|
22
22
|
functions?: Record<string, ComputedFunction>;
|
|
23
|
+
/** Custom directives for user-defined `$`-prefixed dynamic values */
|
|
24
|
+
directives?: DirectiveDefinition[];
|
|
23
25
|
/** Callback when state changes (uncontrolled mode) */
|
|
24
26
|
onStateChange?: (changes: Array<{
|
|
25
27
|
path: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JsonUIProvider.svelte.d.ts","sourceRoot":"","sources":["../src/JsonUIProvider.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"JsonUIProvider.svelte.d.ts","sourceRoot":"","sources":["../src/JsonUIProvider.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC/E;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B;;;OAGG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,0BAA0B;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,sBAAsB;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACzC,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,kCAAkC;IAClC,mBAAmB,CAAC,EAAE,MAAM,CAC1B,MAAM,EACN,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAC5D,CAAC;IACF,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC7C,qEAAqE;IACrE,UAAU,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACnC,sDAAsD;IACtD,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,KAAK,IAAI,CAAC;IAC3E,uBAAuB;IACvB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAQnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AA8CvD,QAAA,MAAM,cAAc,yDAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Spec, UIElement } from "@json-render/core";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
getByPath,
|
|
5
|
+
resolveRepeatItemStatePath,
|
|
6
|
+
resolveRepeatStatePath,
|
|
7
|
+
} from "@json-render/core";
|
|
4
8
|
import type { ComponentRegistry, ComponentRenderer } from "./renderer.js";
|
|
5
9
|
import { getStateContext } from "./contexts/StateProvider.svelte";
|
|
6
|
-
import RepeatScopeProvider
|
|
10
|
+
import RepeatScopeProvider, {
|
|
11
|
+
getRepeatScope,
|
|
12
|
+
} from "./contexts/RepeatScopeProvider.svelte";
|
|
7
13
|
import ElementRenderer from "./ElementRenderer.svelte";
|
|
8
14
|
|
|
9
15
|
interface Props {
|
|
@@ -17,17 +23,30 @@
|
|
|
17
23
|
let { element, spec, registry, loading = false, fallback }: Props = $props();
|
|
18
24
|
|
|
19
25
|
const stateCtx = getStateContext();
|
|
26
|
+
const parentScope = getRepeatScope();
|
|
27
|
+
|
|
28
|
+
let statePath = $derived.by(() => {
|
|
29
|
+
const resolved = resolveRepeatStatePath(
|
|
30
|
+
element.repeat!.statePath,
|
|
31
|
+
parentScope?.basePath,
|
|
32
|
+
);
|
|
33
|
+
if (resolved === undefined) {
|
|
34
|
+
console.warn(
|
|
35
|
+
"[json-render/svelte] $item in repeat.statePath used outside of a repeat scope",
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
return resolved;
|
|
39
|
+
});
|
|
20
40
|
|
|
21
|
-
// Get items from state
|
|
22
41
|
let items = $derived(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
| undefined) ?? [],
|
|
42
|
+
statePath === undefined
|
|
43
|
+
? []
|
|
44
|
+
: ((getByPath(stateCtx.state, statePath) as unknown[] | undefined) ?? []),
|
|
26
45
|
);
|
|
27
46
|
</script>
|
|
28
47
|
|
|
29
48
|
{#each items as itemValue, index (element.repeat?.key && typeof itemValue === "object" && itemValue !== null ? String((itemValue as any)[element.repeat.key] ?? index) : String(index))}
|
|
30
|
-
{@const basePath =
|
|
49
|
+
{@const basePath = resolveRepeatItemStatePath(statePath!, index)}
|
|
31
50
|
|
|
32
51
|
{#if element.children}
|
|
33
52
|
<RepeatScopeProvider item={itemValue} {index} {basePath}>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RepeatChildren.svelte.d.ts","sourceRoot":"","sources":["../src/RepeatChildren.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"RepeatChildren.svelte.d.ts","sourceRoot":"","sources":["../src/RepeatChildren.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAMzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAQxE,UAAU,KAAK;IACb,OAAO,EAAE,SAAS,CAAC;IACnB,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B;AAuDH,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
|
|
@@ -304,9 +304,8 @@
|
|
|
304
304
|
handler,
|
|
305
305
|
setState: stateCtx.set,
|
|
306
306
|
navigate,
|
|
307
|
-
executeAction: async (
|
|
308
|
-
|
|
309
|
-
await execute(subBinding);
|
|
307
|
+
executeAction: async (binding) => {
|
|
308
|
+
await execute(binding);
|
|
310
309
|
},
|
|
311
310
|
});
|
|
312
311
|
} finally {
|
|
@@ -322,9 +321,8 @@
|
|
|
322
321
|
handler,
|
|
323
322
|
setState: stateCtx.set,
|
|
324
323
|
navigate,
|
|
325
|
-
executeAction: async (
|
|
326
|
-
|
|
327
|
-
await execute(subBinding);
|
|
324
|
+
executeAction: async (binding) => {
|
|
325
|
+
await execute(binding);
|
|
328
326
|
},
|
|
329
327
|
});
|
|
330
328
|
} finally {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionProvider.svelte.d.ts","sourceRoot":"","sources":["../../src/contexts/ActionProvider.svelte.ts"],"names":[],"mappings":"AAIE,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACb,cAAc,EACf,MAAM,mBAAmB,CAAC;AAI3B;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACxC,qCAAqC;IACrC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B,kCAAkC;IAClC,mBAAmB,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAChD,gCAAgC;IAChC,OAAO,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,iCAAiC;IACjC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gCAAgC;IAChC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,iCAAiC;IACjC,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;CACjE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAQhD;AAED;;GAEG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,GACX,YAAY,CAAC,aAAa,GAAG,SAAS,CAAC,CAOzC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,8BAA8B;IAC9B,OAAO,EAAE,aAAa,CAAC;IACvB,4BAA4B;IAC5B,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAuDH,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAOH,KAAK,aAAa,IAAI,iBAAiB,EACxC,MAAM,mBAAmB,CAAC;AAM3B,UAAU,KAAK;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC7C,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"ActionProvider.svelte.d.ts","sourceRoot":"","sources":["../../src/contexts/ActionProvider.svelte.ts"],"names":[],"mappings":"AAIE,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACb,cAAc,EACf,MAAM,mBAAmB,CAAC;AAI3B;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACxC,qCAAqC;IACrC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B,kCAAkC;IAClC,mBAAmB,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAChD,gCAAgC;IAChC,OAAO,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,iCAAiC;IACjC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gCAAgC;IAChC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,iCAAiC;IACjC,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;CACjE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAQhD;AAED;;GAEG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,GACX,YAAY,CAAC,aAAa,GAAG,SAAS,CAAC,CAOzC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,8BAA8B;IAC9B,OAAO,EAAE,aAAa,CAAC;IACvB,4BAA4B;IAC5B,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAuDH,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAOH,KAAK,aAAa,IAAI,iBAAiB,EACxC,MAAM,mBAAmB,CAAC;AAM3B,UAAU,KAAK;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC7C,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAqOH,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import { getContext } from "svelte";
|
|
3
|
+
import type { DirectiveDefinition, DirectiveRegistry } from "@json-render/core";
|
|
4
|
+
import { createDirectiveRegistry } from "@json-render/core";
|
|
5
|
+
|
|
6
|
+
const DIRECTIVES_KEY = Symbol.for("json-render-directives");
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Directives context value
|
|
10
|
+
*/
|
|
11
|
+
export interface DirectivesContext {
|
|
12
|
+
/** Custom directive registry */
|
|
13
|
+
registry: DirectiveRegistry | undefined;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Get the directives registry from component tree
|
|
18
|
+
*/
|
|
19
|
+
export function getDirectives(): DirectiveRegistry | undefined {
|
|
20
|
+
const ctx = getContext<DirectivesContext>(DIRECTIVES_KEY);
|
|
21
|
+
return ctx?.registry;
|
|
22
|
+
}
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<script lang="ts">
|
|
26
|
+
import { setContext, type Snippet } from "svelte";
|
|
27
|
+
|
|
28
|
+
interface Props {
|
|
29
|
+
directives?: DirectiveDefinition[];
|
|
30
|
+
children?: Snippet;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let { directives, children }: Props = $props();
|
|
34
|
+
|
|
35
|
+
let registry = $derived(
|
|
36
|
+
directives ? createDirectiveRegistry(directives) : undefined,
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
setContext(DIRECTIVES_KEY, {
|
|
40
|
+
get registry() {
|
|
41
|
+
return registry;
|
|
42
|
+
},
|
|
43
|
+
} satisfies DirectivesContext);
|
|
44
|
+
</script>
|
|
45
|
+
|
|
46
|
+
{@render children?.()}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { DirectiveDefinition, DirectiveRegistry } from "@json-render/core";
|
|
2
|
+
/**
|
|
3
|
+
* Directives context value
|
|
4
|
+
*/
|
|
5
|
+
export interface DirectivesContext {
|
|
6
|
+
/** Custom directive registry */
|
|
7
|
+
registry: DirectiveRegistry | undefined;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Get the directives registry from component tree
|
|
11
|
+
*/
|
|
12
|
+
export declare function getDirectives(): DirectiveRegistry | undefined;
|
|
13
|
+
import { type Snippet } from "svelte";
|
|
14
|
+
interface Props {
|
|
15
|
+
directives?: DirectiveDefinition[];
|
|
16
|
+
children?: Snippet;
|
|
17
|
+
}
|
|
18
|
+
declare const DirectivesContextProvider: import("svelte").Component<Props, {}, "">;
|
|
19
|
+
type DirectivesContextProvider = ReturnType<typeof DirectivesContextProvider>;
|
|
20
|
+
export default DirectivesContextProvider;
|
|
21
|
+
//# sourceMappingURL=DirectivesContextProvider.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DirectivesContextProvider.svelte.d.ts","sourceRoot":"","sources":["../../src/contexts/DirectivesContextProvider.svelte.ts"],"names":[],"mappings":"AAIE,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAKhF;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,gCAAgC;IAChC,QAAQ,EAAE,iBAAiB,GAAG,SAAS,CAAC;CACzC;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,iBAAiB,GAAG,SAAS,CAG7D;AAGH,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGhD,UAAU,KAAK;IACb,UAAU,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAwBH,QAAA,MAAM,yBAAyB,2CAAwC,CAAC;AACxE,KAAK,yBAAyB,GAAG,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAC9E,eAAe,yBAAyB,CAAC"}
|
|
@@ -101,6 +101,38 @@ describe("createActionContext", () => {
|
|
|
101
101
|
expect(customHandler).toHaveBeenCalledWith({ foo: "bar" });
|
|
102
102
|
}, { handlers: { myAction: customHandler } });
|
|
103
103
|
})());
|
|
104
|
+
it("forwards params to a named onSuccess action (#301)", (() => {
|
|
105
|
+
const toast = vi.fn().mockResolvedValue(undefined);
|
|
106
|
+
return component(async () => {
|
|
107
|
+
const actionCtx = getActionContext();
|
|
108
|
+
await actionCtx.execute({
|
|
109
|
+
action: "save",
|
|
110
|
+
onSuccess: { action: "toast", params: { message: "Saved" } },
|
|
111
|
+
});
|
|
112
|
+
expect(toast).toHaveBeenCalledWith({ message: "Saved" });
|
|
113
|
+
}, {
|
|
114
|
+
handlers: {
|
|
115
|
+
save: vi.fn().mockResolvedValue(undefined),
|
|
116
|
+
toast,
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
})());
|
|
120
|
+
it("forwards params to a named onError action (#301)", (() => {
|
|
121
|
+
const toast = vi.fn().mockResolvedValue(undefined);
|
|
122
|
+
return component(async () => {
|
|
123
|
+
const actionCtx = getActionContext();
|
|
124
|
+
await actionCtx.execute({
|
|
125
|
+
action: "save",
|
|
126
|
+
onError: { action: "toast", params: { message: "Failed" } },
|
|
127
|
+
});
|
|
128
|
+
expect(toast).toHaveBeenCalledWith({ message: "Failed" });
|
|
129
|
+
}, {
|
|
130
|
+
handlers: {
|
|
131
|
+
save: vi.fn().mockRejectedValue(new Error("boom")),
|
|
132
|
+
toast,
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
})());
|
|
104
136
|
it("warns when no handler registered", component(async () => {
|
|
105
137
|
const actionCtx = getActionContext();
|
|
106
138
|
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => { });
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export { default as ActionProvider, getActionContext, getAction, type ActionCont
|
|
|
4
4
|
export { default as ValidationProvider, getValidationContext, getOptionalValidationContext, getFieldValidation, type ValidationContext, type FieldValidationState, } from "./contexts/ValidationProvider.svelte";
|
|
5
5
|
export { default as RepeatScopeProvider, getRepeatScope, type RepeatScopeValue, } from "./contexts/RepeatScopeProvider.svelte";
|
|
6
6
|
export { default as FunctionsContextProvider, getFunctions, type FunctionsContext, } from "./contexts/FunctionsContextProvider.svelte";
|
|
7
|
+
export { default as DirectivesContextProvider, getDirectives, type DirectivesContext, } from "./contexts/DirectivesContextProvider.svelte";
|
|
7
8
|
export { schema, type SvelteSchema, type SvelteSpec } from "./schema.js";
|
|
8
9
|
export type { EventHandle, BaseComponentProps, SetState, StateModel, ComponentContext, ComponentFn, Components, ActionFn, Actions, } from "./catalog-types.js";
|
|
9
10
|
export { flatToTree, buildSpecFromParts, getTextFromParts, type DataPart, } from "./utils.svelte.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,OAAO,IAAI,aAAa,EACxB,eAAe,EACf,aAAa,EACb,YAAY,EACZ,KAAK,YAAY,GAClB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EACL,OAAO,IAAI,kBAAkB,EAC7B,oBAAoB,EACpB,SAAS,EACT,KAAK,iBAAiB,GACvB,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EACL,OAAO,IAAI,cAAc,EACzB,gBAAgB,EAChB,SAAS,EACT,KAAK,aAAa,EAClB,KAAK,mBAAmB,GACzB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EACL,OAAO,IAAI,kBAAkB,EAC7B,oBAAoB,EACpB,4BAA4B,EAC5B,kBAAkB,EAClB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,GAC1B,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EACL,OAAO,IAAI,mBAAmB,EAC9B,cAAc,EACd,KAAK,gBAAgB,GACtB,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EACL,OAAO,IAAI,wBAAwB,EACnC,YAAY,EACZ,KAAK,gBAAgB,GACtB,MAAM,4CAA4C,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,OAAO,IAAI,aAAa,EACxB,eAAe,EACf,aAAa,EACb,YAAY,EACZ,KAAK,YAAY,GAClB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EACL,OAAO,IAAI,kBAAkB,EAC7B,oBAAoB,EACpB,SAAS,EACT,KAAK,iBAAiB,GACvB,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EACL,OAAO,IAAI,cAAc,EACzB,gBAAgB,EAChB,SAAS,EACT,KAAK,aAAa,EAClB,KAAK,mBAAmB,GACzB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EACL,OAAO,IAAI,kBAAkB,EAC7B,oBAAoB,EACpB,4BAA4B,EAC5B,kBAAkB,EAClB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,GAC1B,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EACL,OAAO,IAAI,mBAAmB,EAC9B,cAAc,EACd,KAAK,gBAAgB,GACtB,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EACL,OAAO,IAAI,wBAAwB,EACnC,YAAY,EACZ,KAAK,gBAAgB,GACtB,MAAM,4CAA4C,CAAC;AAEpD,OAAO,EACL,OAAO,IAAI,yBAAyB,EACpC,aAAa,EACb,KAAK,iBAAiB,GACvB,MAAM,6CAA6C,CAAC;AAMrD,OAAO,EAAE,MAAM,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAMzE,YAAY,EACV,WAAW,EACX,kBAAkB,EAClB,QAAQ,EACR,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,QAAQ,EACR,OAAO,GACR,MAAM,oBAAoB,CAAC;AAM5B,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,gBAAgB,EAChB,KAAK,QAAQ,GACd,MAAM,mBAAmB,CAAC;AAM3B,OAAO,EACL,cAAc,EACd,YAAY,EACZ,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,UAAU,GAChB,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EACL,cAAc,EACd,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,GACvB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EACL,OAAO,IAAI,eAAe,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,OAAO,IAAI,cAAc,EACzB,KAAK,mBAAmB,GACzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAMhF,YAAY,EACV,IAAI,EACJ,SAAS,EACT,aAAa,EACb,aAAa,GACd,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@ export { default as ActionProvider, getActionContext, getAction, } from "./conte
|
|
|
7
7
|
export { default as ValidationProvider, getValidationContext, getOptionalValidationContext, getFieldValidation, } from "./contexts/ValidationProvider.svelte";
|
|
8
8
|
export { default as RepeatScopeProvider, getRepeatScope, } from "./contexts/RepeatScopeProvider.svelte";
|
|
9
9
|
export { default as FunctionsContextProvider, getFunctions, } from "./contexts/FunctionsContextProvider.svelte";
|
|
10
|
+
export { default as DirectivesContextProvider, getDirectives, } from "./contexts/DirectivesContextProvider.svelte";
|
|
10
11
|
// =============================================================================
|
|
11
12
|
// Schema
|
|
12
13
|
// =============================================================================
|
package/dist/renderer.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Catalog, ComputedFunction, SchemaDefinition, Spec, StateStore, UIElement } from "@json-render/core";
|
|
1
|
+
import type { Catalog, ComputedFunction, DirectiveDefinition, SchemaDefinition, Spec, StateStore, UIElement } from "@json-render/core";
|
|
2
2
|
import type { Component, Snippet } from "svelte";
|
|
3
3
|
import type { BaseComponentProps, EventHandle, SetState, StateModel } from "./catalog-types.js";
|
|
4
4
|
/**
|
|
@@ -94,6 +94,8 @@ export interface CreateRendererProps {
|
|
|
94
94
|
}>) => void;
|
|
95
95
|
/** Named functions for `$computed` expressions in props */
|
|
96
96
|
functions?: Record<string, ComputedFunction>;
|
|
97
|
+
/** Custom directives for user-defined `$`-prefixed dynamic values */
|
|
98
|
+
directives?: DirectiveDefinition[];
|
|
97
99
|
loading?: boolean;
|
|
98
100
|
fallback?: Component;
|
|
99
101
|
}
|
package/dist/renderer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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"}
|
package/dist/renderer.js
CHANGED
package/dist/renderer.test.js
CHANGED
|
@@ -165,4 +165,36 @@ describe("Renderer", () => {
|
|
|
165
165
|
expect(texts).toHaveLength(1);
|
|
166
166
|
expect(texts[0]?.textContent).toBe("I exist");
|
|
167
167
|
});
|
|
168
|
+
it("renders nested repeats from the enclosing item", () => {
|
|
169
|
+
const spec = {
|
|
170
|
+
root: "groups",
|
|
171
|
+
state: {
|
|
172
|
+
groups: [
|
|
173
|
+
{ subitems: [{ label: "a1" }, { label: "a2" }] },
|
|
174
|
+
{ subitems: [{ label: "b1" }] },
|
|
175
|
+
],
|
|
176
|
+
},
|
|
177
|
+
elements: {
|
|
178
|
+
groups: {
|
|
179
|
+
type: "Container",
|
|
180
|
+
props: {},
|
|
181
|
+
repeat: { statePath: "/groups" },
|
|
182
|
+
children: ["subitems"],
|
|
183
|
+
},
|
|
184
|
+
subitems: {
|
|
185
|
+
type: "Container",
|
|
186
|
+
props: {},
|
|
187
|
+
repeat: { statePath: { $item: "/subitems" } },
|
|
188
|
+
children: ["label"],
|
|
189
|
+
},
|
|
190
|
+
label: {
|
|
191
|
+
type: "Text",
|
|
192
|
+
props: { text: { $item: "label" } },
|
|
193
|
+
children: [],
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
const { container } = mountRenderer(spec);
|
|
198
|
+
expect(Array.from(container.querySelectorAll(".test-text")).map((element) => element.textContent)).toEqual(["a1", "a2", "b1"]);
|
|
199
|
+
});
|
|
168
200
|
});
|
package/dist/schema.d.ts
CHANGED
|
@@ -18,7 +18,17 @@ export declare const schema: import("@json-render/core").Schema<{
|
|
|
18
18
|
/** Child element keys (flat reference) */
|
|
19
19
|
children: import("@json-render/core").SchemaType<"array", import("@json-render/core").SchemaType<"string", unknown>>;
|
|
20
20
|
/** Visibility condition */
|
|
21
|
-
visible:
|
|
21
|
+
visible: {
|
|
22
|
+
optional: true;
|
|
23
|
+
kind: "any";
|
|
24
|
+
inner?: unknown;
|
|
25
|
+
};
|
|
26
|
+
/** Repeat children from a state array */
|
|
27
|
+
repeat: {
|
|
28
|
+
optional: true;
|
|
29
|
+
kind: "any";
|
|
30
|
+
inner?: unknown;
|
|
31
|
+
};
|
|
22
32
|
}>>;
|
|
23
33
|
}>;
|
|
24
34
|
catalog: import("@json-render/core").SchemaType<"object", {
|
package/dist/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,eAAO,MAAM,MAAM;;QAIb,uBAAuB;;QAEvB,kCAAkC;;YAG9B,kCAAkC;;YAElC,sBAAsB;;YAEtB,0CAA0C;;YAE1C,2BAA2B
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,eAAO,MAAM,MAAM;;QAIb,uBAAuB;;QAEvB,kCAAkC;;YAG9B,kCAAkC;;YAElC,sBAAsB;;YAEtB,0CAA0C;;YAE1C,2BAA2B;;;;;;YAE3B,yCAAyC;;;;;;;;;QAQ7C,4BAA4B;;YAE1B,qCAAqC;;YAErC,uGAAuG;;YAEvG,0CAA0C;;YAE1C,8FAA8F;;;QAGhG,oCAAoC;;YAElC,mCAAmC;;YAEnC,0CAA0C;;;;EAgDjD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,MAAM,CAAC;AAEzC;;GAEG;AACH,MAAM,MAAM,UAAU,CAAC,QAAQ,IAAI,OAAO,MAAM,SAAS;IACvD,aAAa,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK;QAAE,SAAS,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC;CAC9D,GACG,CAAC,GACD,KAAK,CAAC"}
|
package/dist/schema.js
CHANGED
|
@@ -20,7 +20,9 @@ export const schema = defineSchema((s) => ({
|
|
|
20
20
|
/** Child element keys (flat reference) */
|
|
21
21
|
children: s.array(s.string()),
|
|
22
22
|
/** Visibility condition */
|
|
23
|
-
visible: s.any(),
|
|
23
|
+
visible: { ...s.any(), ...s.optional() },
|
|
24
|
+
/** Repeat children from a state array */
|
|
25
|
+
repeat: { ...s.any(), ...s.optional() },
|
|
24
26
|
})),
|
|
25
27
|
}),
|
|
26
28
|
// What the CATALOG must provide
|
|
@@ -67,12 +69,13 @@ export const schema = defineSchema((s) => ({
|
|
|
67
69
|
// Element integrity
|
|
68
70
|
"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.",
|
|
69
71
|
"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.",
|
|
72
|
+
'REQUIRED FIELDS: Every element MUST include a "children" array. Leaf elements (text, badges, inputs, images) use an empty array: "children": []. Omitting "children" fails validation.',
|
|
70
73
|
// Field placement
|
|
71
74
|
'CRITICAL: The "visible" field goes on the ELEMENT object, NOT inside "props". Correct: {"type":"<ComponentName>","props":{},"visible":{"$state":"/tab","eq":"home"},"children":[...]}.',
|
|
72
75
|
'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.',
|
|
73
76
|
// State and data
|
|
74
77
|
"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).",
|
|
75
|
-
'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.',
|
|
78
|
+
'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.',
|
|
76
79
|
// Design quality
|
|
77
80
|
"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.",
|
|
78
81
|
"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.",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@json-render/svelte",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Svelte 5 renderer for @json-render/core. JSON becomes Svelte components.",
|
|
6
6
|
"keywords": [
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"dist"
|
|
50
50
|
],
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@json-render/core": "0.
|
|
52
|
+
"@json-render/core": "0.20.0"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@sveltejs/package": "^2.3.0",
|