@selvajs/ui 6.6.0-beta.15 → 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.
- package/README.md +0 -3
- package/dist/components/compute/AppLayout.svelte +5 -3
- package/dist/components/compute/CollapsedPanelStrip.svelte +1 -1
- package/dist/components/compute/ParameterPresetManager.svelte +1 -1
- package/dist/components/compute/SolveMessages.svelte +2 -2
- package/dist/components/layout/FooterItemRenderer.svelte +1 -1
- package/dist/components/layout/PageFooter.svelte +2 -2
- package/dist/components/layout/PageHeader.svelte +1 -1
- package/dist/components/layout/SideNav.svelte +3 -3
- package/dist/components/layout/SubNav.svelte +2 -2
- package/dist/components/preview/ChartOutput.svelte +3 -3
- package/dist/components/preview/Group.svelte +7 -7
- package/dist/components/preview/ImageOutput.svelte +6 -6
- package/dist/components/preview/InputControl.svelte +1 -0
- package/dist/components/preview/OutputDisplay.svelte +8 -6
- package/dist/components/preview/TabBar.svelte +6 -4
- package/dist/components/preview/TabBar.svelte.d.ts +2 -0
- package/dist/components/preview/TabContent.svelte +1 -1
- package/dist/components/preview/TabLayout.svelte +3 -4
- package/dist/components/preview/inputs/ChecklistInput.svelte +3 -3
- package/dist/components/preview/inputs/ColorInput.svelte +356 -14
- package/dist/components/preview/inputs/ColorInput.svelte.d.ts +1 -0
- package/dist/components/preview/inputs/FileInput.svelte +3 -3
- package/dist/components/preview/inputs/SegmentedInput.svelte +2 -1
- package/dist/components/preview/inputs/TileInput.svelte +1 -1
- package/dist/components/primitives/CalculateButton.svelte +2 -2
- package/dist/components/primitives/Callout.svelte +8 -6
- package/dist/components/primitives/Callout.svelte.d.ts +4 -4
- package/dist/components/primitives/DataTable.svelte +1 -1
- package/dist/components/primitives/ImageUploadField.svelte +1 -1
- package/dist/components/primitives/alert-dialog/alert-dialog-content.svelte +1 -1
- package/dist/components/primitives/badge/badge.svelte +2 -2
- package/dist/components/primitives/badge/badge.svelte.d.ts +6 -6
- package/dist/components/primitives/button/button.svelte +6 -7
- package/dist/components/primitives/button/button.svelte.d.ts +18 -18
- package/dist/components/primitives/card/card.svelte +1 -1
- package/dist/components/primitives/card/card.svelte.d.ts +1 -1
- package/dist/components/primitives/checkbox/checkbox.svelte +1 -1
- package/dist/components/primitives/command/command-input.svelte +1 -1
- package/dist/components/primitives/command/command-item.svelte +1 -1
- package/dist/components/primitives/command/command-link-item.svelte +1 -1
- package/dist/components/primitives/command/command.svelte +1 -1
- package/dist/components/primitives/context-menu/context-menu-checkbox-item.svelte +1 -1
- package/dist/components/primitives/context-menu/context-menu-content.svelte +1 -1
- package/dist/components/primitives/context-menu/context-menu-item.svelte +1 -1
- package/dist/components/primitives/context-menu/context-menu-radio-item.svelte +1 -1
- package/dist/components/primitives/context-menu/context-menu-sub-content.svelte +1 -1
- package/dist/components/primitives/context-menu/context-menu-sub-trigger.svelte +1 -1
- package/dist/components/primitives/dialog/dialog-content.svelte +2 -2
- package/dist/components/primitives/drawer/Drawer.svelte +1 -1
- package/dist/components/primitives/dropdown-menu/dropdown-menu-checkbox-item.svelte +31 -11
- package/dist/components/primitives/dropdown-menu/dropdown-menu-checkbox-item.svelte.d.ts +2 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-content.svelte +5 -1
- package/dist/components/primitives/dropdown-menu/dropdown-menu-content.svelte.d.ts +2 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu-item.svelte +4 -2
- package/dist/components/primitives/dropdown-menu/dropdown-menu-item.svelte.d.ts +2 -1
- package/dist/components/primitives/dropdown-menu/dropdown-menu-radio-item.svelte +1 -1
- package/dist/components/primitives/dropdown-menu/dropdown-menu-shortcut.svelte +1 -1
- package/dist/components/primitives/dropdown-menu/dropdown-menu-sub-content.svelte +1 -1
- package/dist/components/primitives/dropdown-menu/dropdown-menu-sub-trigger.svelte +1 -1
- package/dist/components/primitives/index.d.ts +1 -1
- package/dist/components/primitives/index.js +1 -1
- package/dist/components/primitives/input/input.svelte +2 -2
- package/dist/components/primitives/input-group/input-group.svelte +1 -1
- package/dist/components/primitives/popover/popover-content.svelte +1 -1
- package/dist/components/primitives/resizable/resizable-handle.svelte +2 -2
- package/dist/components/primitives/search/search.svelte +1 -1
- package/dist/components/primitives/select/select-content.svelte +1 -1
- package/dist/components/primitives/select/select-item.svelte +1 -1
- package/dist/components/primitives/select/select-trigger.svelte +1 -1
- package/dist/components/primitives/slider/slider.svelte +1 -1
- package/dist/components/primitives/switch/switch.svelte +1 -1
- package/dist/components/primitives/tabs/tabs-list.svelte +1 -1
- package/dist/components/primitives/tabs/tabs-list.svelte.d.ts +3 -3
- package/dist/components/primitives/tabs/tabs-trigger.svelte +1 -1
- package/dist/components/primitives/tabs/tabs-trigger.svelte.d.ts +3 -3
- package/dist/components/primitives/textarea/textarea.svelte +1 -1
- package/dist/components/primitives/toggle/toggle.svelte +6 -3
- package/dist/components/primitives/toggle/toggle.svelte.d.ts +10 -7
- package/dist/components/primitives/toggle-group/toggle-group-item.svelte +1 -1
- package/dist/components/primitives/toggle-group/toggle-group.svelte +1 -1
- package/dist/components/primitives/tooltip/index.d.ts +6 -0
- package/dist/components/primitives/tooltip/index.js +8 -0
- package/dist/components/primitives/tooltip/tooltip-content.svelte +34 -0
- package/dist/components/primitives/tooltip/tooltip-content.svelte.d.ts +10 -0
- package/dist/components/primitives/tooltip/tooltip-portal.svelte +7 -0
- package/dist/components/primitives/tooltip/tooltip-portal.svelte.d.ts +4 -0
- package/dist/components/primitives/tooltip/tooltip-provider.svelte +7 -0
- package/dist/components/primitives/tooltip/tooltip-provider.svelte.d.ts +4 -0
- package/dist/components/primitives/tooltip/tooltip-trigger.svelte +7 -0
- package/dist/components/primitives/tooltip/tooltip-trigger.svelte.d.ts +4 -0
- package/dist/components/primitives/tooltip/tooltip.svelte +7 -0
- package/dist/components/primitives/tooltip/tooltip.svelte.d.ts +4 -0
- package/dist/components/viewer/MeshMetadataPanel.svelte +1 -1
- package/dist/components/viewer/SceneManager.svelte +19 -19
- package/dist/components/viewer/Viewer.svelte +68 -157
- package/dist/components/viewer/ViewerDock.svelte +404 -0
- package/dist/components/viewer/ViewerDock.svelte.d.ts +42 -0
- package/dist/i18n/messages.d.ts +11 -0
- package/dist/i18n/messages.js +18 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/public.d.ts +1 -0
- package/dist/public.js +1 -0
- package/dist/schema/visibility-rules.d.ts +7 -1
- package/dist/schema/visibility-rules.js +17 -0
- package/dist/styles/base.css +81 -80
- package/dist/utils/color-space.d.ts +21 -0
- package/dist/utils/color-space.js +90 -0
- package/package.json +8 -9
- package/src/lib/components/compute/AppLayout.svelte +5 -3
- package/src/lib/components/compute/CollapsedPanelStrip.svelte +1 -1
- package/src/lib/components/compute/ParameterPresetManager.svelte +1 -1
- package/src/lib/components/compute/SolveMessages.svelte +2 -2
- package/src/lib/components/layout/FooterItemRenderer.svelte +1 -1
- package/src/lib/components/layout/PageFooter.svelte +2 -2
- package/src/lib/components/layout/PageHeader.svelte +1 -1
- package/src/lib/components/layout/SideNav.svelte +3 -3
- package/src/lib/components/layout/SubNav.svelte +2 -2
- package/src/lib/components/preview/ChartOutput.svelte +3 -3
- package/src/lib/components/preview/Group.svelte +7 -7
- package/src/lib/components/preview/ImageOutput.svelte +6 -6
- package/src/lib/components/preview/InputControl.svelte +1 -0
- package/src/lib/components/preview/OutputDisplay.svelte +8 -6
- package/src/lib/components/preview/TabBar.svelte +6 -4
- package/src/lib/components/preview/TabContent.svelte +1 -1
- package/src/lib/components/preview/TabLayout.svelte +3 -4
- package/src/lib/components/preview/inputs/ChecklistInput.svelte +3 -3
- package/src/lib/components/preview/inputs/ColorInput.svelte +356 -14
- package/src/lib/components/preview/inputs/FileInput.svelte +3 -3
- package/src/lib/components/preview/inputs/SegmentedInput.svelte +2 -1
- package/src/lib/components/preview/inputs/TileInput.svelte +1 -1
- package/src/lib/components/primitives/CalculateButton.svelte +2 -2
- package/src/lib/components/primitives/Callout.svelte +8 -6
- package/src/lib/components/primitives/DataTable.svelte +1 -1
- package/src/lib/components/primitives/ImageUploadField.svelte +1 -1
- package/src/lib/components/primitives/alert-dialog/alert-dialog-content.svelte +1 -1
- package/src/lib/components/primitives/badge/badge.svelte +2 -2
- package/src/lib/components/primitives/button/button.svelte +6 -7
- package/src/lib/components/primitives/card/card.svelte +1 -1
- package/src/lib/components/primitives/checkbox/checkbox.svelte +1 -1
- package/src/lib/components/primitives/command/command-input.svelte +1 -1
- package/src/lib/components/primitives/command/command-item.svelte +1 -1
- package/src/lib/components/primitives/command/command-link-item.svelte +1 -1
- package/src/lib/components/primitives/command/command.svelte +1 -1
- package/src/lib/components/primitives/context-menu/context-menu-checkbox-item.svelte +1 -1
- package/src/lib/components/primitives/context-menu/context-menu-content.svelte +1 -1
- package/src/lib/components/primitives/context-menu/context-menu-item.svelte +1 -1
- package/src/lib/components/primitives/context-menu/context-menu-radio-item.svelte +1 -1
- package/src/lib/components/primitives/context-menu/context-menu-sub-content.svelte +1 -1
- package/src/lib/components/primitives/context-menu/context-menu-sub-trigger.svelte +1 -1
- package/src/lib/components/primitives/dialog/dialog-content.svelte +2 -2
- package/src/lib/components/primitives/drawer/Drawer.svelte +1 -1
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-checkbox-item.svelte +31 -11
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-content.svelte +5 -1
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-item.svelte +4 -2
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-radio-item.svelte +1 -1
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-shortcut.svelte +1 -1
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-sub-content.svelte +1 -1
- package/src/lib/components/primitives/dropdown-menu/dropdown-menu-sub-trigger.svelte +1 -1
- package/src/lib/components/primitives/index.ts +1 -1
- package/src/lib/components/primitives/input/input.svelte +2 -2
- package/src/lib/components/primitives/input-group/input-group.svelte +1 -1
- package/src/lib/components/primitives/popover/popover-content.svelte +1 -1
- package/src/lib/components/primitives/resizable/resizable-handle.svelte +2 -2
- package/src/lib/components/primitives/search/search.svelte +1 -1
- package/src/lib/components/primitives/select/select-content.svelte +1 -1
- package/src/lib/components/primitives/select/select-item.svelte +1 -1
- package/src/lib/components/primitives/select/select-trigger.svelte +1 -1
- package/src/lib/components/primitives/slider/slider.svelte +1 -1
- package/src/lib/components/primitives/switch/switch.svelte +1 -1
- package/src/lib/components/primitives/tabs/tabs-list.svelte +1 -1
- package/src/lib/components/primitives/tabs/tabs-trigger.svelte +1 -1
- package/src/lib/components/primitives/textarea/textarea.svelte +1 -1
- package/src/lib/components/primitives/toggle/toggle.svelte +6 -3
- package/src/lib/components/primitives/toggle-group/toggle-group-item.svelte +1 -1
- package/src/lib/components/primitives/toggle-group/toggle-group.svelte +1 -1
- package/src/lib/components/primitives/tooltip/index.ts +19 -0
- package/src/lib/components/primitives/tooltip/tooltip-content.svelte +34 -0
- package/src/lib/components/primitives/tooltip/tooltip-portal.svelte +7 -0
- package/src/lib/components/primitives/tooltip/tooltip-provider.svelte +7 -0
- package/src/lib/components/primitives/tooltip/tooltip-trigger.svelte +7 -0
- package/src/lib/components/primitives/tooltip/tooltip.svelte +7 -0
- package/src/lib/components/viewer/MeshMetadataPanel.svelte +1 -1
- package/src/lib/components/viewer/SceneManager.svelte +19 -19
- package/src/lib/components/viewer/Viewer.svelte +68 -157
- package/src/lib/components/viewer/ViewerDock.svelte +404 -0
- package/src/lib/i18n/messages.ts +29 -0
- package/src/lib/index.ts +1 -0
- package/src/lib/public.ts +1 -0
- package/src/lib/schema/visibility-rules.ts +27 -1
- package/src/lib/styles/base.css +81 -80
- package/src/lib/utils/color-space.ts +107 -0
- package/dist/components/primitives/theme-switcher/ThemeSwitcher.svelte +0 -39
- package/dist/components/primitives/theme-switcher/ThemeSwitcher.svelte.d.ts +0 -3
- package/dist/components/primitives/theme-switcher/index.d.ts +0 -1
- package/dist/components/primitives/theme-switcher/index.js +0 -1
- package/dist/styles/themes/cyberpunk.css +0 -98
- package/dist/styles/themes/neutral.css +0 -72
- package/dist/styles/themes/ocean.css +0 -75
- package/dist/styles/themes/selva.css +0 -105
- package/dist/theme/themeStore.svelte.d.ts +0 -12
- package/dist/theme/themeStore.svelte.js +0 -40
- package/dist/theme/themes.d.ts +0 -5
- package/dist/theme/themes.js +0 -13
- package/src/lib/components/primitives/theme-switcher/ThemeSwitcher.svelte +0 -39
- package/src/lib/components/primitives/theme-switcher/index.ts +0 -1
- package/src/lib/styles/themes/cyberpunk.css +0 -98
- package/src/lib/styles/themes/neutral.css +0 -72
- package/src/lib/styles/themes/ocean.css +0 -75
- package/src/lib/styles/themes/selva.css +0 -105
- package/src/lib/theme/themeStore.svelte.ts +0 -50
- package/src/lib/theme/themes.ts +0 -18
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { MediaQuery } from 'svelte/reactivity';
|
|
3
|
+
import {
|
|
4
|
+
Camera,
|
|
5
|
+
Grid3x3,
|
|
6
|
+
Layers,
|
|
7
|
+
LocateFixed,
|
|
8
|
+
Maximize,
|
|
9
|
+
Minimize,
|
|
10
|
+
Moon,
|
|
11
|
+
Ellipsis,
|
|
12
|
+
Palette,
|
|
13
|
+
Ruler,
|
|
14
|
+
Settings2,
|
|
15
|
+
Spline,
|
|
16
|
+
Cuboid
|
|
17
|
+
} from '@lucide/svelte';
|
|
18
|
+
import type { CameraProjection, Look, ViewPreset } from '@selvajs/visualization/render';
|
|
19
|
+
import * as DropdownMenu from '../primitives/dropdown-menu/index.js';
|
|
20
|
+
import type { ViewerMessages } from '../../i18n/messages';
|
|
21
|
+
|
|
22
|
+
interface Props {
|
|
23
|
+
t: ViewerMessages;
|
|
24
|
+
/** Fades the dock out while a host drawer covers the viewer. */
|
|
25
|
+
hidden?: boolean;
|
|
26
|
+
showDisplay: boolean;
|
|
27
|
+
showGrid: boolean;
|
|
28
|
+
showSceneManager: boolean;
|
|
29
|
+
showScreenshot: boolean;
|
|
30
|
+
showFullscreen: boolean;
|
|
31
|
+
styleOptions: { look: Look; label: string }[];
|
|
32
|
+
viewPresets: { preset: ViewPreset; label: string }[];
|
|
33
|
+
renderStyle: Look;
|
|
34
|
+
nightOn: boolean;
|
|
35
|
+
edgesVisible: boolean;
|
|
36
|
+
measureActive: boolean;
|
|
37
|
+
gridVisible: boolean;
|
|
38
|
+
sceneManagerOpen: boolean;
|
|
39
|
+
projection: CameraProjection;
|
|
40
|
+
isFullscreen: boolean;
|
|
41
|
+
onSetLook: (look: Look) => void;
|
|
42
|
+
onToggleNight: () => void;
|
|
43
|
+
onToggleEdges: () => void;
|
|
44
|
+
onToggleMeasure: () => void;
|
|
45
|
+
onToggleGrid: () => void;
|
|
46
|
+
onToggleSceneManager: () => void;
|
|
47
|
+
onToggleProjection: () => void;
|
|
48
|
+
onSetView: (preset: ViewPreset) => void;
|
|
49
|
+
onFit: () => void;
|
|
50
|
+
onScreenshot: () => void;
|
|
51
|
+
onToggleFullscreen: () => void;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
let {
|
|
55
|
+
t,
|
|
56
|
+
hidden = false,
|
|
57
|
+
showDisplay,
|
|
58
|
+
showGrid,
|
|
59
|
+
showSceneManager,
|
|
60
|
+
showScreenshot,
|
|
61
|
+
showFullscreen,
|
|
62
|
+
styleOptions,
|
|
63
|
+
viewPresets,
|
|
64
|
+
renderStyle,
|
|
65
|
+
nightOn,
|
|
66
|
+
edgesVisible,
|
|
67
|
+
measureActive,
|
|
68
|
+
gridVisible,
|
|
69
|
+
sceneManagerOpen,
|
|
70
|
+
projection,
|
|
71
|
+
isFullscreen,
|
|
72
|
+
onSetLook,
|
|
73
|
+
onToggleNight,
|
|
74
|
+
onToggleEdges,
|
|
75
|
+
onToggleMeasure,
|
|
76
|
+
onToggleGrid,
|
|
77
|
+
onToggleSceneManager,
|
|
78
|
+
onToggleProjection,
|
|
79
|
+
onSetView,
|
|
80
|
+
onFit,
|
|
81
|
+
onScreenshot,
|
|
82
|
+
onToggleFullscreen
|
|
83
|
+
}: Props = $props();
|
|
84
|
+
|
|
85
|
+
// A hairline pill at the bottom edge is the iOS home indicator on a phone, and swiping it leaves
|
|
86
|
+
// the app. Touch gets a visible round button instead.
|
|
87
|
+
const touch = new MediaQuery('(pointer: coarse)');
|
|
88
|
+
const reducedMotion = new MediaQuery('(prefers-reduced-motion: reduce)');
|
|
89
|
+
|
|
90
|
+
const COLLAPSED = $derived(touch.current ? { w: 44, h: 44 } : { w: 72, h: 8 });
|
|
91
|
+
const EXPANDED_H = $derived(touch.current ? 54 : 46);
|
|
92
|
+
const PAD = 4;
|
|
93
|
+
|
|
94
|
+
let dockEl: HTMLDivElement | undefined = $state();
|
|
95
|
+
let rowWidth = $state(0);
|
|
96
|
+
let engaged = $state(false);
|
|
97
|
+
// Set by an outside press: the dock was dismissed, so it shrinks faster.
|
|
98
|
+
let dismissed = $state(false);
|
|
99
|
+
let menusOpen = $state(0);
|
|
100
|
+
let focusWithin = $state(false);
|
|
101
|
+
let idleTimer: ReturnType<typeof setTimeout> | undefined;
|
|
102
|
+
|
|
103
|
+
const wantOpen = $derived(engaged || menusOpen > 0 || focusWithin);
|
|
104
|
+
|
|
105
|
+
// Opening leads: the pill grows first and the buttons pop in behind it. Closing mirrors it: the
|
|
106
|
+
// buttons fade first, then the pill shrinks. Without the delay on close the row is clipped mid-fade.
|
|
107
|
+
const EASE = 'cubic-bezier(0.32, 0.72, 0, 1)';
|
|
108
|
+
const containerStyle = $derived.by(() => {
|
|
109
|
+
const bottom = touch.current ? 'max(1rem,env(safe-area-inset-bottom))' : '0.75rem';
|
|
110
|
+
const geometry = wantOpen
|
|
111
|
+
? `width:${rowWidth + PAD * 2 + 2}px;height:${EXPANDED_H}px;border-radius:14px;padding:${PAD}px`
|
|
112
|
+
: `width:${COLLAPSED.w}px;height:${COLLAPSED.h}px;border-radius:${touch.current ? 22 : 99}px;padding:0px`;
|
|
113
|
+
const size = `bottom:${bottom};${geometry}`;
|
|
114
|
+
if (reducedMotion.current) return size;
|
|
115
|
+
const ms = wantOpen ? 420 : dismissed ? 130 : 170;
|
|
116
|
+
const delay = wantOpen || dismissed ? 0 : 20;
|
|
117
|
+
const props = ['width', 'height', 'border-radius', 'padding'];
|
|
118
|
+
return `${size};transition:${props.map((p) => `${p} ${ms}ms ${EASE} ${delay}ms`).join(',')},opacity 200ms ease`;
|
|
119
|
+
});
|
|
120
|
+
const itemStyle = (index: number) => {
|
|
121
|
+
if (reducedMotion.current) return `opacity:${wantOpen ? 1 : 0}`;
|
|
122
|
+
const delay = 110 + index * 35;
|
|
123
|
+
return wantOpen
|
|
124
|
+
? `opacity:1;transform:none;transition:opacity 240ms ease ${delay}ms,transform 420ms cubic-bezier(0.34,1.45,0.5,1) ${delay}ms`
|
|
125
|
+
: 'opacity:0;transform:translateY(6px) scale(0.85);transition:opacity 100ms ease,transform 100ms ease';
|
|
126
|
+
};
|
|
127
|
+
// The touch button's settings glyph hands over to the row.
|
|
128
|
+
const glyphStyle = $derived(
|
|
129
|
+
`opacity:${touch.current && !wantOpen ? 1 : 0};${reducedMotion.current ? '' : `transition:opacity ${wantOpen ? 100 : 100}ms ease ${wantOpen || dismissed ? 0 : 60}ms`}`
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
function scheduleCollapse(delay = touch.current ? 3500 : 150) {
|
|
133
|
+
clearTimeout(idleTimer);
|
|
134
|
+
idleTimer = setTimeout(() => (engaged = false), delay);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function engage() {
|
|
138
|
+
engaged = true;
|
|
139
|
+
dismissed = false;
|
|
140
|
+
clearTimeout(idleTimer);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function handlePointerMove(event: PointerEvent) {
|
|
144
|
+
if (!dockEl || touch.current || event.pointerType === 'touch') return;
|
|
145
|
+
// Orbiting or box-dragging with the button down should never pop the dock open.
|
|
146
|
+
if (event.buttons) return;
|
|
147
|
+
const host = dockEl.offsetParent;
|
|
148
|
+
if (!host || !(event.target instanceof Node) || !host.contains(event.target)) {
|
|
149
|
+
if (engaged) scheduleCollapse();
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const r = dockEl.getBoundingClientRect();
|
|
153
|
+
const near =
|
|
154
|
+
event.clientY > r.top - 36 && Math.abs(event.clientX - (r.left + r.width / 2)) < 110;
|
|
155
|
+
if (near) engage();
|
|
156
|
+
else if (engaged) scheduleCollapse();
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function handleWindowPointerDown(event: PointerEvent) {
|
|
160
|
+
if (!engaged || !dockEl || !(event.target instanceof Node)) return;
|
|
161
|
+
if (!dockEl.contains(event.target)) {
|
|
162
|
+
clearTimeout(idleTimer);
|
|
163
|
+
dismissed = true;
|
|
164
|
+
engaged = false;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function openFromCollapsed() {
|
|
169
|
+
if (wantOpen) return;
|
|
170
|
+
engage();
|
|
171
|
+
if (touch.current) scheduleCollapse();
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Any use of the open dock on touch pushes the idle collapse back.
|
|
175
|
+
function keepAlive() {
|
|
176
|
+
if (touch.current && engaged) scheduleCollapse();
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function trackMenu(open: boolean) {
|
|
180
|
+
menusOpen += open ? 1 : -1;
|
|
181
|
+
if (!open && !touch.current) scheduleCollapse(250);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Buttons in the row, in order, so the stagger index stays right when some are hidden.
|
|
185
|
+
const buttons = $derived(
|
|
186
|
+
[
|
|
187
|
+
showDisplay && 'look',
|
|
188
|
+
showSceneManager && 'scene',
|
|
189
|
+
'measure',
|
|
190
|
+
'fit',
|
|
191
|
+
showFullscreen && 'full',
|
|
192
|
+
'more'
|
|
193
|
+
].filter(Boolean) as string[]
|
|
194
|
+
);
|
|
195
|
+
const idx = (id: string) => buttons.indexOf(id);
|
|
196
|
+
|
|
197
|
+
const BTN =
|
|
198
|
+
'relative grid size-9.5 shrink-0 place-items-center rounded-lg text-muted-foreground outline-none transition-colors hover:bg-hover hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring aria-pressed:text-foreground data-[state=open]:bg-selected data-[state=open]:text-foreground pointer-coarse:size-11';
|
|
199
|
+
const DOT =
|
|
200
|
+
'aria-pressed:after:absolute aria-pressed:after:bottom-0.5 aria-pressed:after:size-1 aria-pressed:after:rounded-full aria-pressed:after:bg-primary';
|
|
201
|
+
</script>
|
|
202
|
+
|
|
203
|
+
<!-- eslint-disable shadcn/no-inline-styles -- the pill animates between measured pixel sizes and staggered per-item delays; no class can express those -->
|
|
204
|
+
|
|
205
|
+
<svelte:window onpointermove={handlePointerMove} onpointerdown={handleWindowPointerDown} />
|
|
206
|
+
|
|
207
|
+
<!-- Resting state is a pill; it grows into the row. Only the container is clickable while collapsed. -->
|
|
208
|
+
<div
|
|
209
|
+
bind:this={dockEl}
|
|
210
|
+
role="toolbar"
|
|
211
|
+
aria-label={t.toolsMenu}
|
|
212
|
+
tabindex="-1"
|
|
213
|
+
class="shadow-lg backdrop-blur-md absolute left-1/2 z-50 -translate-x-1/2 overflow-hidden border {hidden
|
|
214
|
+
? 'pointer-events-none opacity-0'
|
|
215
|
+
: ''} {wantOpen
|
|
216
|
+
? 'bg-background/70'
|
|
217
|
+
: touch.current
|
|
218
|
+
? 'cursor-pointer border-border bg-background/90'
|
|
219
|
+
: nightOn
|
|
220
|
+
? 'border-white/50 bg-white/40 hover:bg-white/65 cursor-pointer'
|
|
221
|
+
: 'cursor-pointer border-border-strong bg-faint-foreground hover:bg-muted-foreground'}"
|
|
222
|
+
style={containerStyle}
|
|
223
|
+
onclick={openFromCollapsed}
|
|
224
|
+
onkeydown={(e) => (e.key === 'Escape' ? (engaged = false) : undefined)}
|
|
225
|
+
onfocusin={() => (focusWithin = true)}
|
|
226
|
+
onfocusout={(e) => {
|
|
227
|
+
if (!dockEl?.contains(e.relatedTarget as Node | null)) focusWithin = false;
|
|
228
|
+
}}
|
|
229
|
+
onpointerdown={keepAlive}
|
|
230
|
+
>
|
|
231
|
+
{#if touch.current}
|
|
232
|
+
<span
|
|
233
|
+
class="inset-0 pointer-events-none absolute grid place-items-center text-foreground"
|
|
234
|
+
style={glyphStyle}
|
|
235
|
+
aria-hidden="true"
|
|
236
|
+
>
|
|
237
|
+
<Settings2 class="size-5" />
|
|
238
|
+
</span>
|
|
239
|
+
{/if}
|
|
240
|
+
|
|
241
|
+
<div
|
|
242
|
+
bind:offsetWidth={rowWidth}
|
|
243
|
+
class="gap-0.5 mx-auto flex w-max items-center"
|
|
244
|
+
inert={!wantOpen}
|
|
245
|
+
>
|
|
246
|
+
{#if showDisplay}
|
|
247
|
+
<div style={itemStyle(idx('look'))}>
|
|
248
|
+
<DropdownMenu.Root onOpenChange={trackMenu}>
|
|
249
|
+
<DropdownMenu.Trigger>
|
|
250
|
+
{#snippet child({ props })}
|
|
251
|
+
<button {...props} class={BTN} title={t.display} aria-label={t.display}>
|
|
252
|
+
<Palette class="size-4.5" />
|
|
253
|
+
</button>
|
|
254
|
+
{/snippet}
|
|
255
|
+
</DropdownMenu.Trigger>
|
|
256
|
+
<DropdownMenu.Content
|
|
257
|
+
side="top"
|
|
258
|
+
align="center"
|
|
259
|
+
sideOffset={12}
|
|
260
|
+
variant="glass"
|
|
261
|
+
class="min-w-52 z-10001 w-auto whitespace-nowrap"
|
|
262
|
+
>
|
|
263
|
+
<DropdownMenu.RadioGroup
|
|
264
|
+
value={renderStyle}
|
|
265
|
+
onValueChange={(look) => onSetLook(look as Look)}
|
|
266
|
+
>
|
|
267
|
+
{#each styleOptions as { look, label } (look)}
|
|
268
|
+
<DropdownMenu.RadioItem value={look} closeOnSelect={false}>
|
|
269
|
+
{label}
|
|
270
|
+
</DropdownMenu.RadioItem>
|
|
271
|
+
{/each}
|
|
272
|
+
</DropdownMenu.RadioGroup>
|
|
273
|
+
<DropdownMenu.Separator />
|
|
274
|
+
<DropdownMenu.CheckboxItem
|
|
275
|
+
switch
|
|
276
|
+
checked={edgesVisible}
|
|
277
|
+
onCheckedChange={onToggleEdges}
|
|
278
|
+
>
|
|
279
|
+
<Spline />
|
|
280
|
+
{t.edges}
|
|
281
|
+
<DropdownMenu.Shortcut class="pointer-coarse:hidden">E</DropdownMenu.Shortcut>
|
|
282
|
+
</DropdownMenu.CheckboxItem>
|
|
283
|
+
</DropdownMenu.Content>
|
|
284
|
+
</DropdownMenu.Root>
|
|
285
|
+
</div>
|
|
286
|
+
{/if}
|
|
287
|
+
|
|
288
|
+
{#if showSceneManager}
|
|
289
|
+
<div style={itemStyle(idx('scene'))}>
|
|
290
|
+
<button
|
|
291
|
+
class="{BTN} {DOT}"
|
|
292
|
+
title="{t.sceneManager} (S)"
|
|
293
|
+
aria-label={t.sceneManager}
|
|
294
|
+
aria-pressed={sceneManagerOpen}
|
|
295
|
+
onclick={onToggleSceneManager}
|
|
296
|
+
>
|
|
297
|
+
<Layers class="size-4.5" />
|
|
298
|
+
</button>
|
|
299
|
+
</div>
|
|
300
|
+
{/if}
|
|
301
|
+
|
|
302
|
+
<div style={itemStyle(idx('measure'))}>
|
|
303
|
+
<button
|
|
304
|
+
class="{BTN} {DOT}"
|
|
305
|
+
title="{t.measure} (M)"
|
|
306
|
+
aria-label={t.measure}
|
|
307
|
+
aria-pressed={measureActive}
|
|
308
|
+
onclick={onToggleMeasure}
|
|
309
|
+
>
|
|
310
|
+
<Ruler class="size-4.5" />
|
|
311
|
+
</button>
|
|
312
|
+
</div>
|
|
313
|
+
|
|
314
|
+
<div style={itemStyle(idx('fit'))}>
|
|
315
|
+
<button class={BTN} title="{t.fitToView} (F)" aria-label="{t.fitToView} (F)" onclick={onFit}>
|
|
316
|
+
<LocateFixed class="size-4.5" />
|
|
317
|
+
</button>
|
|
318
|
+
</div>
|
|
319
|
+
|
|
320
|
+
{#if showFullscreen}
|
|
321
|
+
<div style={itemStyle(idx('full'))}>
|
|
322
|
+
<button
|
|
323
|
+
class={BTN}
|
|
324
|
+
title={isFullscreen ? t.exitFullscreen : t.fullscreen}
|
|
325
|
+
aria-label={isFullscreen ? t.exitFullscreen : t.fullscreen}
|
|
326
|
+
onclick={onToggleFullscreen}
|
|
327
|
+
>
|
|
328
|
+
{#if isFullscreen}<Minimize class="size-4.5" />{:else}<Maximize class="size-4.5" />{/if}
|
|
329
|
+
</button>
|
|
330
|
+
</div>
|
|
331
|
+
{/if}
|
|
332
|
+
|
|
333
|
+
<div style={itemStyle(idx('more'))}>
|
|
334
|
+
<DropdownMenu.Root onOpenChange={trackMenu}>
|
|
335
|
+
<DropdownMenu.Trigger>
|
|
336
|
+
{#snippet child({ props })}
|
|
337
|
+
<button {...props} class={BTN} title={t.toolsMenu} aria-label={t.toolsMenu}>
|
|
338
|
+
<Ellipsis class="size-4.5" />
|
|
339
|
+
</button>
|
|
340
|
+
{/snippet}
|
|
341
|
+
</DropdownMenu.Trigger>
|
|
342
|
+
<DropdownMenu.Content
|
|
343
|
+
side="top"
|
|
344
|
+
align="end"
|
|
345
|
+
sideOffset={12}
|
|
346
|
+
variant="glass"
|
|
347
|
+
class="min-w-60 z-10001 w-auto whitespace-nowrap"
|
|
348
|
+
>
|
|
349
|
+
<DropdownMenu.Label>{t.views}</DropdownMenu.Label>
|
|
350
|
+
<div class="gap-1 px-1 pb-1 grid grid-cols-4">
|
|
351
|
+
{#each viewPresets as { preset, label } (preset)}
|
|
352
|
+
<DropdownMenu.Item
|
|
353
|
+
closeOnSelect={false}
|
|
354
|
+
onSelect={() => onSetView(preset)}
|
|
355
|
+
variant="chip"
|
|
356
|
+
>
|
|
357
|
+
{label}
|
|
358
|
+
</DropdownMenu.Item>
|
|
359
|
+
{/each}
|
|
360
|
+
</div>
|
|
361
|
+
|
|
362
|
+
<DropdownMenu.Separator />
|
|
363
|
+
|
|
364
|
+
<DropdownMenu.CheckboxItem
|
|
365
|
+
switch
|
|
366
|
+
checked={projection === 'orthographic'}
|
|
367
|
+
onCheckedChange={onToggleProjection}
|
|
368
|
+
>
|
|
369
|
+
<Cuboid />
|
|
370
|
+
{t.switchToOrthographic}
|
|
371
|
+
<DropdownMenu.Shortcut class="pointer-coarse:hidden">O</DropdownMenu.Shortcut>
|
|
372
|
+
</DropdownMenu.CheckboxItem>
|
|
373
|
+
|
|
374
|
+
{#if showGrid}
|
|
375
|
+
<DropdownMenu.CheckboxItem switch checked={gridVisible} onCheckedChange={onToggleGrid}>
|
|
376
|
+
<Grid3x3 />
|
|
377
|
+
{t.grid}
|
|
378
|
+
<DropdownMenu.Shortcut class="pointer-coarse:hidden">G</DropdownMenu.Shortcut>
|
|
379
|
+
</DropdownMenu.CheckboxItem>
|
|
380
|
+
{/if}
|
|
381
|
+
|
|
382
|
+
{#if showDisplay}
|
|
383
|
+
<DropdownMenu.CheckboxItem switch checked={nightOn} onCheckedChange={onToggleNight}>
|
|
384
|
+
<Moon />
|
|
385
|
+
{t.nightMode}
|
|
386
|
+
<DropdownMenu.Shortcut class="pointer-coarse:hidden">N</DropdownMenu.Shortcut>
|
|
387
|
+
</DropdownMenu.CheckboxItem>
|
|
388
|
+
{/if}
|
|
389
|
+
|
|
390
|
+
{#if showScreenshot}
|
|
391
|
+
<DropdownMenu.Separator />
|
|
392
|
+
{/if}
|
|
393
|
+
|
|
394
|
+
{#if showScreenshot}
|
|
395
|
+
<DropdownMenu.Item onSelect={onScreenshot}>
|
|
396
|
+
<Camera />
|
|
397
|
+
{t.screenshot}
|
|
398
|
+
</DropdownMenu.Item>
|
|
399
|
+
{/if}
|
|
400
|
+
</DropdownMenu.Content>
|
|
401
|
+
</DropdownMenu.Root>
|
|
402
|
+
</div>
|
|
403
|
+
</div>
|
|
404
|
+
</div>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { CameraProjection, Look, ViewPreset } from '@selvajs/visualization/render';
|
|
2
|
+
import type { ViewerMessages } from '../../i18n/messages';
|
|
3
|
+
interface Props {
|
|
4
|
+
t: ViewerMessages;
|
|
5
|
+
/** Fades the dock out while a host drawer covers the viewer. */
|
|
6
|
+
hidden?: boolean;
|
|
7
|
+
showDisplay: boolean;
|
|
8
|
+
showGrid: boolean;
|
|
9
|
+
showSceneManager: boolean;
|
|
10
|
+
showScreenshot: boolean;
|
|
11
|
+
showFullscreen: boolean;
|
|
12
|
+
styleOptions: {
|
|
13
|
+
look: Look;
|
|
14
|
+
label: string;
|
|
15
|
+
}[];
|
|
16
|
+
viewPresets: {
|
|
17
|
+
preset: ViewPreset;
|
|
18
|
+
label: string;
|
|
19
|
+
}[];
|
|
20
|
+
renderStyle: Look;
|
|
21
|
+
nightOn: boolean;
|
|
22
|
+
edgesVisible: boolean;
|
|
23
|
+
measureActive: boolean;
|
|
24
|
+
gridVisible: boolean;
|
|
25
|
+
sceneManagerOpen: boolean;
|
|
26
|
+
projection: CameraProjection;
|
|
27
|
+
isFullscreen: boolean;
|
|
28
|
+
onSetLook: (look: Look) => void;
|
|
29
|
+
onToggleNight: () => void;
|
|
30
|
+
onToggleEdges: () => void;
|
|
31
|
+
onToggleMeasure: () => void;
|
|
32
|
+
onToggleGrid: () => void;
|
|
33
|
+
onToggleSceneManager: () => void;
|
|
34
|
+
onToggleProjection: () => void;
|
|
35
|
+
onSetView: (preset: ViewPreset) => void;
|
|
36
|
+
onFit: () => void;
|
|
37
|
+
onScreenshot: () => void;
|
|
38
|
+
onToggleFullscreen: () => void;
|
|
39
|
+
}
|
|
40
|
+
declare const ViewerDock: import("svelte").Component<Props, {}, "">;
|
|
41
|
+
type ViewerDock = ReturnType<typeof ViewerDock>;
|
|
42
|
+
export default ViewerDock;
|
package/dist/i18n/messages.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ export interface ViewerMessages {
|
|
|
24
24
|
lookStudio: string;
|
|
25
25
|
lookShowcase: string;
|
|
26
26
|
lookNight: string;
|
|
27
|
+
nightMode: string;
|
|
27
28
|
lookArctic: string;
|
|
28
29
|
lookXray: string;
|
|
29
30
|
lookLineart: string;
|
|
@@ -103,6 +104,16 @@ export interface ViewerMessages {
|
|
|
103
104
|
/** `{max}` is replaced with the field's character limit. */
|
|
104
105
|
maxLength: string;
|
|
105
106
|
invalidFormat: string;
|
|
107
|
+
/** Trigger label; `{color}` is the current hex value. */
|
|
108
|
+
colorPick: string;
|
|
109
|
+
colorArea: string;
|
|
110
|
+
/** `{s}` and `{v}` are percentages. */
|
|
111
|
+
colorAreaValue: string;
|
|
112
|
+
colorHue: string;
|
|
113
|
+
colorHex: string;
|
|
114
|
+
colorHexInvalid: string;
|
|
115
|
+
colorPresets: string;
|
|
116
|
+
colorEyedropper: string;
|
|
106
117
|
invalidPattern: string;
|
|
107
118
|
/** The pick button when the input takes several kinds of object. */
|
|
108
119
|
geometryPickAnyOne: string;
|
package/dist/i18n/messages.js
CHANGED
|
@@ -33,6 +33,7 @@ const en = {
|
|
|
33
33
|
lookStudio: 'Studio',
|
|
34
34
|
lookShowcase: 'Showcase',
|
|
35
35
|
lookNight: 'Night',
|
|
36
|
+
nightMode: 'Night mode',
|
|
36
37
|
lookArctic: 'Arctic',
|
|
37
38
|
lookXray: 'X-Ray',
|
|
38
39
|
lookLineart: 'Line Art',
|
|
@@ -99,6 +100,14 @@ const en = {
|
|
|
99
100
|
fineDragHint: 'Hold Shift to drag finely',
|
|
100
101
|
maxLength: 'Maximum {max} characters allowed',
|
|
101
102
|
invalidFormat: 'Invalid format',
|
|
103
|
+
colorPick: 'Choose color, currently {color}',
|
|
104
|
+
colorArea: 'Saturation and brightness',
|
|
105
|
+
colorAreaValue: 'Saturation {s}%, brightness {v}%',
|
|
106
|
+
colorHue: 'Hue',
|
|
107
|
+
colorHex: 'Hex color',
|
|
108
|
+
colorHexInvalid: 'Enter a hex color such as #2f6fd6',
|
|
109
|
+
colorPresets: 'Presets',
|
|
110
|
+
colorEyedropper: 'Pick a color from the screen',
|
|
102
111
|
invalidPattern: 'Invalid validation pattern configured',
|
|
103
112
|
geometryPickAnyOne: 'Pick an object',
|
|
104
113
|
geometryPickAnyOther: 'Pick objects',
|
|
@@ -208,6 +217,7 @@ const de = {
|
|
|
208
217
|
lookStudio: 'Studio',
|
|
209
218
|
lookShowcase: 'Präsentation',
|
|
210
219
|
lookNight: 'Nacht',
|
|
220
|
+
nightMode: 'Nachtmodus',
|
|
211
221
|
lookArctic: 'Arktis',
|
|
212
222
|
lookXray: 'Röntgen',
|
|
213
223
|
lookLineart: 'Strichzeichnung',
|
|
@@ -274,6 +284,14 @@ const de = {
|
|
|
274
284
|
fineDragHint: 'Umschalttaste halten für feine Schritte',
|
|
275
285
|
maxLength: 'Höchstens {max} Zeichen erlaubt',
|
|
276
286
|
invalidFormat: 'Ungültiges Format',
|
|
287
|
+
colorPick: 'Farbe wählen, aktuell {color}',
|
|
288
|
+
colorArea: 'Sättigung und Helligkeit',
|
|
289
|
+
colorAreaValue: 'Sättigung {s} %, Helligkeit {v} %',
|
|
290
|
+
colorHue: 'Farbton',
|
|
291
|
+
colorHex: 'Hex-Farbe',
|
|
292
|
+
colorHexInvalid: 'Hex-Farbe eingeben, z. B. #2f6fd6',
|
|
293
|
+
colorPresets: 'Vorgaben',
|
|
294
|
+
colorEyedropper: 'Farbe vom Bildschirm aufnehmen',
|
|
277
295
|
invalidPattern: 'Ungültiges Prüfmuster hinterlegt',
|
|
278
296
|
geometryPickAnyOne: 'Objekt wählen',
|
|
279
297
|
geometryPickAnyOther: 'Objekte wählen',
|
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.
|