@selvajs/ui 6.6.0-beta.16 → 6.6.0-beta.17

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.
@@ -55,7 +55,7 @@
55
55
  {#if Icon}
56
56
  <Icon class={cn('mt-0.5 h-4 w-4 shrink-0', accent)} />
57
57
  {/if}
58
- <div class="min-w-0 space-y-1">
58
+ <div class="min-w-0 space-y-1 wrap-anywhere">
59
59
  {#if title}
60
60
  <p class={cn('leading-tight font-medium', accent)}>{title}</p>
61
61
  {/if}
@@ -68,7 +68,7 @@ get along, so we shut typescript up by casting `value` to `never`.
68
68
  data-spacing={spacing}
69
69
  style="--gap: calc(var(--spacing) * {spacing})"
70
70
  class={cn(
71
- 'group/toggle-group data-[variant=segmented]:p-0.5 flex w-fit flex-row items-center gap-(--gap) rounded-md data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch data-[variant=segmented]:border data-[variant=segmented]:border-input data-[variant=segmented]:bg-muted',
71
+ 'group/toggle-group data-[variant=segmented]:p-0.5 flex w-fit flex-row items-center gap-(--gap) rounded-md data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch data-[variant=segmented]:rounded-lg data-[variant=segmented]:border data-[variant=segmented]:border-input data-[variant=segmented]:bg-muted',
72
72
  className
73
73
  )}
74
74
  {...restProps}
package/dist/index.d.ts CHANGED
@@ -9,6 +9,7 @@ export { default as Viewer } from './components/viewer/Viewer.svelte';
9
9
  export * from './schema/defaults';
10
10
  export * from './schema/dynamic-value-list';
11
11
  export * from './schema/traversal';
12
+ export { visibleInputItems } from './schema/visibility-rules';
12
13
  export { type UIHost, type ElementKind, HOST_LABELS, isGeometryParamType, layoutItemKind, hostsFor, isSupportedOn, valuelessInputIds, unsupportedItems } from './schema/host-support';
13
14
  export * from './compute/solving.svelte';
14
15
  export { useSolveSession } from './compute/useSolveSession.svelte';
package/dist/index.js CHANGED
@@ -13,6 +13,7 @@ export { default as Viewer } from './components/viewer/Viewer.svelte';
13
13
  export * from './schema/defaults';
14
14
  export * from './schema/dynamic-value-list';
15
15
  export * from './schema/traversal';
16
+ export { visibleInputItems } from './schema/visibility-rules';
16
17
  export { HOST_LABELS, isGeometryParamType, layoutItemKind, hostsFor, isSupportedOn, valuelessInputIds, unsupportedItems } from './schema/host-support';
17
18
  export * from './compute/solving.svelte';
18
19
  // Solve Session seam. Re-exported so transports outside this package — e.g.
package/dist/public.d.ts CHANGED
@@ -14,6 +14,7 @@ export { writeExternalValue, readExternalValue, clearExternalValue, getExternalI
14
14
  export * from './schema/defaults';
15
15
  export * from './schema/traversal';
16
16
  export * from './schema/dynamic-value-list';
17
+ export { visibleInputItems } from './schema/visibility-rules';
17
18
  export type { ActionButton } from './types/actionButton';
18
19
  export type { SolveFn, SolveResult, SolveDiagnostic } from '@selvajs/solve/shared';
19
20
  export { DEFAULT_PRESET_LABELS, type PresetLabels } from './types/presetLabels';
package/dist/public.js CHANGED
@@ -28,4 +28,5 @@ export { writeExternalValue, readExternalValue, clearExternalValue, getExternalI
28
28
  export * from './schema/defaults';
29
29
  export * from './schema/traversal';
30
30
  export * from './schema/dynamic-value-list';
31
+ export { visibleInputItems } from './schema/visibility-rules';
31
32
  export { DEFAULT_PRESET_LABELS } from './types/presetLabels';
@@ -1,4 +1,4 @@
1
- import type { LayoutItem, VisibilityRule, VisibilityCondition, GroupVisibilityCondition, TabConfig } from '@selvajs/schemas';
1
+ import type { InputLayoutItem, LayoutItem, VisibilityRule, VisibilityCondition, GroupVisibilityCondition, TabConfig, UISchema } from '@selvajs/schemas';
2
2
  export interface VisibilityResult {
3
3
  visible: boolean;
4
4
  disabled: boolean;
@@ -20,6 +20,12 @@ export declare function evaluateGroupVisibility(group: {
20
20
  items?: LayoutItem[];
21
21
  }, values: Record<string, unknown>): boolean;
22
22
  export declare function isTabVisible(tab: TabConfig, values: Record<string, unknown>): boolean;
23
+ /**
24
+ * The input items the form shows for these values: each passes its own condition, inside a
25
+ * shown group and, when tabbed, a shown tab. For a host that repeats the form back, such as a
26
+ * summary before a commit, without re-deriving the renderer's rules.
27
+ */
28
+ export declare function visibleInputItems(schema: UISchema, values: Record<string, unknown>): InputLayoutItem[];
23
29
  /**
24
30
  * A linebreak is always "visible" but renders as a divider only, so a group left with
25
31
  * nothing but separators counts as empty.
@@ -106,6 +106,23 @@ export function evaluateGroupVisibility(group, values) {
106
106
  export function isTabVisible(tab, values) {
107
107
  return (tab.visible !== false && tab.groups.some((group) => evaluateGroupVisibility(group, values)));
108
108
  }
109
+ /**
110
+ * The input items the form shows for these values: each passes its own condition, inside a
111
+ * shown group and, when tabbed, a shown tab. For a host that repeats the form back, such as a
112
+ * summary before a commit, without re-deriving the renderer's rules.
113
+ */
114
+ export function visibleInputItems(schema, values) {
115
+ const layout = schema?.layout;
116
+ const groups = layout?.type === 'tabbed'
117
+ ? (layout.tabs ?? []).filter((t) => isTabVisible(t, values)).flatMap((t) => t.groups ?? [])
118
+ : layout?.type === 'flat'
119
+ ? (layout.groups ?? [])
120
+ : [];
121
+ return groups
122
+ .filter((g) => evaluateGroupVisibility(g, values))
123
+ .flatMap((g) => g.items ?? [])
124
+ .filter((i) => i.type === 'input' && evaluateVisibility(i, values).visible);
125
+ }
109
126
  /**
110
127
  * A linebreak is always "visible" but renders as a divider only, so a group left with
111
128
  * nothing but separators counts as empty.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@selvajs/ui",
3
- "version": "6.6.0-beta.16",
3
+ "version": "6.6.0-beta.17",
4
4
  "description": "Shared UI components and utilities for Selva applications",
5
5
  "license": "MIT",
6
6
  "author": "VektorNode",
@@ -63,9 +63,9 @@
63
63
  "tailwind-variants": "^3.3.1",
64
64
  "three": "^0.187.0",
65
65
  "@selvajs/compute": "^5.0.0-beta.9",
66
- "@selvajs/solve": "^2.0.0-beta.12",
67
- "@selvajs/schemas": "^5.3.0-beta.2",
68
- "@selvajs/visualization": "^1.6.0-beta.9"
66
+ "@selvajs/visualization": "^1.6.0-beta.9",
67
+ "@selvajs/schemas": "^5.3.0-beta.3",
68
+ "@selvajs/solve": "^2.0.0-beta.12"
69
69
  },
70
70
  "peerDependenciesMeta": {
71
71
  "three": {
@@ -96,7 +96,7 @@
96
96
  "@selvajs/compute": "5.0.0-beta.9",
97
97
  "@selvajs/config": "0.0.4",
98
98
  "@selvajs/visualization": "1.6.0-beta.9",
99
- "@selvajs/schemas": "5.3.0-beta.2",
99
+ "@selvajs/schemas": "5.3.0-beta.3",
100
100
  "@selvajs/solve": "2.0.0-beta.12"
101
101
  },
102
102
  "scripts": {
@@ -55,7 +55,7 @@
55
55
  {#if Icon}
56
56
  <Icon class={cn('mt-0.5 h-4 w-4 shrink-0', accent)} />
57
57
  {/if}
58
- <div class="min-w-0 space-y-1">
58
+ <div class="min-w-0 space-y-1 wrap-anywhere">
59
59
  {#if title}
60
60
  <p class={cn('leading-tight font-medium', accent)}>{title}</p>
61
61
  {/if}
@@ -68,7 +68,7 @@ get along, so we shut typescript up by casting `value` to `never`.
68
68
  data-spacing={spacing}
69
69
  style="--gap: calc(var(--spacing) * {spacing})"
70
70
  class={cn(
71
- 'group/toggle-group data-[variant=segmented]:p-0.5 flex w-fit flex-row items-center gap-(--gap) rounded-md data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch data-[variant=segmented]:border data-[variant=segmented]:border-input data-[variant=segmented]:bg-muted',
71
+ 'group/toggle-group data-[variant=segmented]:p-0.5 flex w-fit flex-row items-center gap-(--gap) rounded-md data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch data-[variant=segmented]:rounded-lg data-[variant=segmented]:border data-[variant=segmented]:border-input data-[variant=segmented]:bg-muted',
72
72
  className
73
73
  )}
74
74
  {...restProps}
package/src/lib/index.ts CHANGED
@@ -19,6 +19,7 @@ export { default as Viewer } from './components/viewer/Viewer.svelte';
19
19
  export * from './schema/defaults';
20
20
  export * from './schema/dynamic-value-list';
21
21
  export * from './schema/traversal';
22
+ export { visibleInputItems } from './schema/visibility-rules';
22
23
  export {
23
24
  type UIHost,
24
25
  type ElementKind,
package/src/lib/public.ts CHANGED
@@ -80,6 +80,7 @@ export {
80
80
  export * from './schema/defaults';
81
81
  export * from './schema/traversal';
82
82
  export * from './schema/dynamic-value-list';
83
+ export { visibleInputItems } from './schema/visibility-rules';
83
84
 
84
85
  // UI-facing runtime types (not from schema)
85
86
  export type { ActionButton } from './types/actionButton';
@@ -1,10 +1,12 @@
1
1
  import type {
2
+ InputLayoutItem,
2
3
  LayoutItem,
3
4
  OutputLayoutItem,
4
5
  VisibilityRule,
5
6
  VisibilityCondition,
6
7
  GroupVisibilityCondition,
7
- TabConfig
8
+ TabConfig,
9
+ UISchema
8
10
  } from '@selvajs/schemas';
9
11
  import { isFileData } from '../utils/file-download';
10
12
 
@@ -148,6 +150,30 @@ export function isTabVisible(tab: TabConfig, values: Record<string, unknown>): b
148
150
  );
149
151
  }
150
152
 
153
+ /**
154
+ * The input items the form shows for these values: each passes its own condition, inside a
155
+ * shown group and, when tabbed, a shown tab. For a host that repeats the form back, such as a
156
+ * summary before a commit, without re-deriving the renderer's rules.
157
+ */
158
+ export function visibleInputItems(
159
+ schema: UISchema,
160
+ values: Record<string, unknown>
161
+ ): InputLayoutItem[] {
162
+ const layout = schema?.layout;
163
+ const groups =
164
+ layout?.type === 'tabbed'
165
+ ? (layout.tabs ?? []).filter((t) => isTabVisible(t, values)).flatMap((t) => t.groups ?? [])
166
+ : layout?.type === 'flat'
167
+ ? (layout.groups ?? [])
168
+ : [];
169
+ return groups
170
+ .filter((g) => evaluateGroupVisibility(g, values))
171
+ .flatMap((g) => g.items ?? [])
172
+ .filter(
173
+ (i): i is InputLayoutItem => i.type === 'input' && evaluateVisibility(i, values).visible
174
+ );
175
+ }
176
+
151
177
  /**
152
178
  * A linebreak is always "visible" but renders as a divider only, so a group left with
153
179
  * nothing but separators counts as empty.