@selvajs/ui 4.10.0 → 4.11.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/dist/components/compute/ComputeApp.svelte +1 -1
- package/dist/components/preview/InputControl.svelte +29 -14
- package/dist/contexts/clientSlotContext.svelte.d.ts +0 -2
- package/package.json +3 -3
- package/src/lib/components/compute/ComputeApp.svelte +1 -1
- package/src/lib/components/preview/InputControl.svelte +29 -14
- package/src/lib/contexts/clientSlotContext.svelte.ts +3 -5
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
header?: Snippet;
|
|
55
55
|
// Scopes sessionStorage for external-input values; falls back to definitionKey then schema.id.
|
|
56
56
|
externalScopeKey?: string;
|
|
57
|
-
// Renders client-sourced inputs with presentation === 'slot'; receives { inputId, displayName,
|
|
57
|
+
// Renders client-sourced inputs with presentation === 'slot'; receives { inputId, displayName, value, onValueChange }.
|
|
58
58
|
clientSlot?: ClientSlot;
|
|
59
59
|
/**
|
|
60
60
|
* UI language for the app's own chrome (viewer, panels, status text).
|
|
@@ -59,12 +59,10 @@
|
|
|
59
59
|
// Client-sourced input set to render a host element in its place. The 'hidden'
|
|
60
60
|
// presentation never reaches here (visible:false filters it out upstream), so a
|
|
61
61
|
// client slot source means presentation === 'slot'.
|
|
62
|
-
const
|
|
63
|
-
const source = (
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (source?.kind !== 'client' || source.client?.presentation !== 'slot') return null;
|
|
67
|
-
return { slotLabel: source.client.slotLabel };
|
|
62
|
+
const isClientSlot = $derived.by(() => {
|
|
63
|
+
const source = (item as { source?: { kind?: string; client?: { presentation?: string } } })
|
|
64
|
+
.source;
|
|
65
|
+
return source?.kind === 'client' && source.client?.presentation === 'slot';
|
|
68
66
|
});
|
|
69
67
|
const clientSlot = getClientSlot();
|
|
70
68
|
|
|
@@ -144,15 +142,32 @@
|
|
|
144
142
|
}
|
|
145
143
|
</script>
|
|
146
144
|
|
|
147
|
-
{#if
|
|
145
|
+
{#if isClientSlot}
|
|
148
146
|
{#if clientSlot}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
147
|
+
<Field.Field>
|
|
148
|
+
<Field.Label class="gap-2 flex items-center">
|
|
149
|
+
{label}
|
|
150
|
+
{#if item.description}
|
|
151
|
+
<Dialog.Root>
|
|
152
|
+
<Dialog.Trigger class="p-1 cursor-help opacity-60 transition-opacity hover:opacity-100">
|
|
153
|
+
<HelpCircle size={16} />
|
|
154
|
+
</Dialog.Trigger>
|
|
155
|
+
<Dialog.Content class="sm:max-w-md">
|
|
156
|
+
<Dialog.Header>
|
|
157
|
+
<Dialog.Title>{label}</Dialog.Title>
|
|
158
|
+
<Dialog.Description>{item.description}</Dialog.Description>
|
|
159
|
+
</Dialog.Header>
|
|
160
|
+
</Dialog.Content>
|
|
161
|
+
</Dialog.Root>
|
|
162
|
+
{/if}
|
|
163
|
+
</Field.Label>
|
|
164
|
+
{@render clientSlot({
|
|
165
|
+
inputId: item.paramId,
|
|
166
|
+
displayName: label,
|
|
167
|
+
value,
|
|
168
|
+
onValueChange: commit
|
|
169
|
+
})}
|
|
170
|
+
</Field.Field>
|
|
156
171
|
{/if}
|
|
157
172
|
{:else if !hideDynamicListWhenEmpty}
|
|
158
173
|
<Field.Field>
|
|
@@ -4,8 +4,6 @@ export interface ClientSlotArgs {
|
|
|
4
4
|
/** Grasshopper parameter instance GUID (LayoutItem.paramId / SchemaInput.id). */
|
|
5
5
|
inputId: string;
|
|
6
6
|
displayName: string;
|
|
7
|
-
/** Author-set label from the schema, passed through untouched. May be undefined. */
|
|
8
|
-
slotLabel?: string;
|
|
9
7
|
/** The current value held for this input (e.g. the prefilled JSON), if any. */
|
|
10
8
|
value: unknown;
|
|
11
9
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@selvajs/ui",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.11.0",
|
|
4
4
|
"description": "Shared UI components and utilities for Selva applications",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"svelte": "^5",
|
|
44
44
|
"tailwind-variants": "^3.2.2",
|
|
45
45
|
"three": "^0.184.0",
|
|
46
|
-
"@selvajs/schemas": "^4.
|
|
46
|
+
"@selvajs/schemas": "^4.6.0"
|
|
47
47
|
},
|
|
48
48
|
"peerDependenciesMeta": {
|
|
49
49
|
"three": {
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"tailwind-variants": "^3.2.2",
|
|
74
74
|
"vitest": "^3.2.6",
|
|
75
75
|
"@selvajs/config": "0.0.1",
|
|
76
|
-
"@selvajs/schemas": "4.
|
|
76
|
+
"@selvajs/schemas": "4.6.0"
|
|
77
77
|
},
|
|
78
78
|
"scripts": {
|
|
79
79
|
"dev": "vite dev",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
header?: Snippet;
|
|
55
55
|
// Scopes sessionStorage for external-input values; falls back to definitionKey then schema.id.
|
|
56
56
|
externalScopeKey?: string;
|
|
57
|
-
// Renders client-sourced inputs with presentation === 'slot'; receives { inputId, displayName,
|
|
57
|
+
// Renders client-sourced inputs with presentation === 'slot'; receives { inputId, displayName, value, onValueChange }.
|
|
58
58
|
clientSlot?: ClientSlot;
|
|
59
59
|
/**
|
|
60
60
|
* UI language for the app's own chrome (viewer, panels, status text).
|
|
@@ -59,12 +59,10 @@
|
|
|
59
59
|
// Client-sourced input set to render a host element in its place. The 'hidden'
|
|
60
60
|
// presentation never reaches here (visible:false filters it out upstream), so a
|
|
61
61
|
// client slot source means presentation === 'slot'.
|
|
62
|
-
const
|
|
63
|
-
const source = (
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (source?.kind !== 'client' || source.client?.presentation !== 'slot') return null;
|
|
67
|
-
return { slotLabel: source.client.slotLabel };
|
|
62
|
+
const isClientSlot = $derived.by(() => {
|
|
63
|
+
const source = (item as { source?: { kind?: string; client?: { presentation?: string } } })
|
|
64
|
+
.source;
|
|
65
|
+
return source?.kind === 'client' && source.client?.presentation === 'slot';
|
|
68
66
|
});
|
|
69
67
|
const clientSlot = getClientSlot();
|
|
70
68
|
|
|
@@ -144,15 +142,32 @@
|
|
|
144
142
|
}
|
|
145
143
|
</script>
|
|
146
144
|
|
|
147
|
-
{#if
|
|
145
|
+
{#if isClientSlot}
|
|
148
146
|
{#if clientSlot}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
147
|
+
<Field.Field>
|
|
148
|
+
<Field.Label class="gap-2 flex items-center">
|
|
149
|
+
{label}
|
|
150
|
+
{#if item.description}
|
|
151
|
+
<Dialog.Root>
|
|
152
|
+
<Dialog.Trigger class="p-1 cursor-help opacity-60 transition-opacity hover:opacity-100">
|
|
153
|
+
<HelpCircle size={16} />
|
|
154
|
+
</Dialog.Trigger>
|
|
155
|
+
<Dialog.Content class="sm:max-w-md">
|
|
156
|
+
<Dialog.Header>
|
|
157
|
+
<Dialog.Title>{label}</Dialog.Title>
|
|
158
|
+
<Dialog.Description>{item.description}</Dialog.Description>
|
|
159
|
+
</Dialog.Header>
|
|
160
|
+
</Dialog.Content>
|
|
161
|
+
</Dialog.Root>
|
|
162
|
+
{/if}
|
|
163
|
+
</Field.Label>
|
|
164
|
+
{@render clientSlot({
|
|
165
|
+
inputId: item.paramId,
|
|
166
|
+
displayName: label,
|
|
167
|
+
value,
|
|
168
|
+
onValueChange: commit
|
|
169
|
+
})}
|
|
170
|
+
</Field.Field>
|
|
156
171
|
{/if}
|
|
157
172
|
{:else if !hideDynamicListWhenEmpty}
|
|
158
173
|
<Field.Field>
|
|
@@ -9,16 +9,14 @@ import type { SupportedTypes } from '@selvajs/schemas';
|
|
|
9
9
|
// An input with source.kind === 'client' and source.client.presentation === 'slot'
|
|
10
10
|
// reserves its cell but renders nothing itself. Instead Selva invokes this snippet
|
|
11
11
|
// so the host can render its own element (e.g. an "Edit JSON" button, or a custom
|
|
12
|
-
// picker). Selva never interprets what the host renders
|
|
13
|
-
//
|
|
14
|
-
//
|
|
12
|
+
// picker). Selva never interprets what the host renders. The host may COMMIT a value
|
|
13
|
+
// back via `onValueChange`, which flows into the solve exactly like any built-in
|
|
14
|
+
// widget's change.
|
|
15
15
|
|
|
16
16
|
export interface ClientSlotArgs {
|
|
17
17
|
/** Grasshopper parameter instance GUID (LayoutItem.paramId / SchemaInput.id). */
|
|
18
18
|
inputId: string;
|
|
19
19
|
displayName: string;
|
|
20
|
-
/** Author-set label from the schema, passed through untouched. May be undefined. */
|
|
21
|
-
slotLabel?: string;
|
|
22
20
|
/** The current value held for this input (e.g. the prefilled JSON), if any. */
|
|
23
21
|
value: unknown;
|
|
24
22
|
/**
|