@selvajs/ui 6.6.0-beta.15 → 6.6.0-beta.16
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 +7 -5
- 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/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 +9 -10
- 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 +7 -5
- 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/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 '$lib/components/primitives/dropdown-menu/index.js';
|
|
20
|
+
import type { ViewerMessages } from '$lib/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>
|
package/src/lib/i18n/messages.ts
CHANGED
|
@@ -41,6 +41,7 @@ export interface ViewerMessages {
|
|
|
41
41
|
lookStudio: string;
|
|
42
42
|
lookShowcase: string;
|
|
43
43
|
lookNight: string;
|
|
44
|
+
nightMode: string;
|
|
44
45
|
lookArctic: string;
|
|
45
46
|
lookXray: string;
|
|
46
47
|
lookLineart: string;
|
|
@@ -132,6 +133,16 @@ export interface ViewerMessages {
|
|
|
132
133
|
/** `{max}` is replaced with the field's character limit. */
|
|
133
134
|
maxLength: string;
|
|
134
135
|
invalidFormat: string;
|
|
136
|
+
/** Trigger label; `{color}` is the current hex value. */
|
|
137
|
+
colorPick: string;
|
|
138
|
+
colorArea: string;
|
|
139
|
+
/** `{s}` and `{v}` are percentages. */
|
|
140
|
+
colorAreaValue: string;
|
|
141
|
+
colorHue: string;
|
|
142
|
+
colorHex: string;
|
|
143
|
+
colorHexInvalid: string;
|
|
144
|
+
colorPresets: string;
|
|
145
|
+
colorEyedropper: string;
|
|
135
146
|
invalidPattern: string;
|
|
136
147
|
|
|
137
148
|
// Geometry input (Rhino only)
|
|
@@ -270,6 +281,7 @@ const en: ViewerMessages = {
|
|
|
270
281
|
lookStudio: 'Studio',
|
|
271
282
|
lookShowcase: 'Showcase',
|
|
272
283
|
lookNight: 'Night',
|
|
284
|
+
nightMode: 'Night mode',
|
|
273
285
|
lookArctic: 'Arctic',
|
|
274
286
|
lookXray: 'X-Ray',
|
|
275
287
|
lookLineart: 'Line Art',
|
|
@@ -342,6 +354,14 @@ const en: ViewerMessages = {
|
|
|
342
354
|
fineDragHint: 'Hold Shift to drag finely',
|
|
343
355
|
maxLength: 'Maximum {max} characters allowed',
|
|
344
356
|
invalidFormat: 'Invalid format',
|
|
357
|
+
colorPick: 'Choose color, currently {color}',
|
|
358
|
+
colorArea: 'Saturation and brightness',
|
|
359
|
+
colorAreaValue: 'Saturation {s}%, brightness {v}%',
|
|
360
|
+
colorHue: 'Hue',
|
|
361
|
+
colorHex: 'Hex color',
|
|
362
|
+
colorHexInvalid: 'Enter a hex color such as #2f6fd6',
|
|
363
|
+
colorPresets: 'Presets',
|
|
364
|
+
colorEyedropper: 'Pick a color from the screen',
|
|
345
365
|
invalidPattern: 'Invalid validation pattern configured',
|
|
346
366
|
|
|
347
367
|
geometryPickAnyOne: 'Pick an object',
|
|
@@ -464,6 +484,7 @@ const de: ViewerMessages = {
|
|
|
464
484
|
lookStudio: 'Studio',
|
|
465
485
|
lookShowcase: 'Präsentation',
|
|
466
486
|
lookNight: 'Nacht',
|
|
487
|
+
nightMode: 'Nachtmodus',
|
|
467
488
|
lookArctic: 'Arktis',
|
|
468
489
|
lookXray: 'Röntgen',
|
|
469
490
|
lookLineart: 'Strichzeichnung',
|
|
@@ -537,6 +558,14 @@ const de: ViewerMessages = {
|
|
|
537
558
|
fineDragHint: 'Umschalttaste halten für feine Schritte',
|
|
538
559
|
maxLength: 'Höchstens {max} Zeichen erlaubt',
|
|
539
560
|
invalidFormat: 'Ungültiges Format',
|
|
561
|
+
colorPick: 'Farbe wählen, aktuell {color}',
|
|
562
|
+
colorArea: 'Sättigung und Helligkeit',
|
|
563
|
+
colorAreaValue: 'Sättigung {s} %, Helligkeit {v} %',
|
|
564
|
+
colorHue: 'Farbton',
|
|
565
|
+
colorHex: 'Hex-Farbe',
|
|
566
|
+
colorHexInvalid: 'Hex-Farbe eingeben, z. B. #2f6fd6',
|
|
567
|
+
colorPresets: 'Vorgaben',
|
|
568
|
+
colorEyedropper: 'Farbe vom Bildschirm aufnehmen',
|
|
540
569
|
invalidPattern: 'Ungültiges Prüfmuster hinterlegt',
|
|
541
570
|
|
|
542
571
|
geometryPickAnyOne: 'Objekt wählen',
|
package/src/lib/styles/base.css
CHANGED
|
@@ -1,81 +1,92 @@
|
|
|
1
1
|
@custom-variant dark (&:where(.dark, .dark *));
|
|
2
2
|
|
|
3
|
+
/* Surfaces, edges and states share one set of names in both modes; each mode only changes the
|
|
4
|
+
values. Ratios are WCAG 2.x. The roles and when to use each: docs/contributing/design-system.md. */
|
|
3
5
|
:root {
|
|
4
|
-
--radius: 0.625rem;
|
|
5
6
|
--header-h: 3.5rem;
|
|
6
7
|
--below-header-h: calc(100svh - var(--header-h));
|
|
7
8
|
--page-px: 1rem;
|
|
8
9
|
--page-py: 1.75rem;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
white on background alone is too close to see. */
|
|
10
|
+
/* Canvas, then surface (cards, panels), then raised (rows, menus, popovers). Light can't go
|
|
11
|
+
lighter than white, so raised is white too and lifts with a border and a shadow instead. */
|
|
12
|
+
--background: oklch(0.91 0 0);
|
|
13
13
|
--card: oklch(1 0 0);
|
|
14
|
+
--raised: oklch(1 0 0);
|
|
15
|
+
/* Recessed fill for trays, table heads, code and skeletons: darker than the surface around it. */
|
|
16
|
+
--muted: oklch(0.94 0 0);
|
|
17
|
+
/* Fill of anything you type into, on a card: the same step as raised, in both modes. The edge
|
|
18
|
+
(`--input`) carries the boundary. A recessed fill reads as a disabled control. */
|
|
19
|
+
--field: var(--raised);
|
|
20
|
+
--foreground: oklch(0.22 0 0);
|
|
14
21
|
--card-foreground: oklch(0.22 0 0);
|
|
15
|
-
--popover: oklch(0.99 0 0);
|
|
16
22
|
--popover-foreground: oklch(0.22 0 0);
|
|
17
|
-
/* 4.5:1
|
|
18
|
-
--
|
|
19
|
-
|
|
20
|
-
--
|
|
21
|
-
|
|
22
|
-
--
|
|
23
|
-
--
|
|
24
|
-
|
|
25
|
-
--
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
--
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
/* 4.5:1 on every surface. */
|
|
24
|
+
--muted-foreground: oklch(0.48 0 0);
|
|
25
|
+
/* Icons, placeholders, disabled text: 3:1 on every surface. */
|
|
26
|
+
--faint-foreground: oklch(0.6 0 0);
|
|
27
|
+
/* State overlays, laid over whatever surface is underneath. */
|
|
28
|
+
--hover: oklch(0 0 0 / 6%);
|
|
29
|
+
--selected: oklch(0 0 0 / 12%);
|
|
30
|
+
/* Rest fill of a neutral filled control; its hover is `selected`. */
|
|
31
|
+
--secondary: oklch(0 0 0 / 7%);
|
|
32
|
+
--secondary-foreground: oklch(0.22 0 0);
|
|
33
|
+
/* Outlines and separators. */
|
|
34
|
+
--border: oklch(0 0 0 / 11%);
|
|
35
|
+
/* Popovers, outline buttons, dashed drop zones. */
|
|
36
|
+
--border-strong: oklch(0 0 0 / 24%);
|
|
37
|
+
/* Edge of anything you type into or toggle, slider tracks included: at least 3:1 against the
|
|
38
|
+
surfaces around it, the WCAG minimum for a control's boundary. */
|
|
39
|
+
--input: oklch(0 0 0 / 44%);
|
|
33
40
|
--ring: oklch(0.55 0 0);
|
|
34
|
-
--
|
|
41
|
+
--elevation-raised: 0 1px 2px oklch(0 0 0 / 6%);
|
|
42
|
+
--elevation-popover: 0 8px 24px oklch(0 0 0 / 12%);
|
|
43
|
+
/* 4.5:1 as text on a card and under its foreground; 3:1 as a fill on every surface. */
|
|
44
|
+
--primary: #4a7c52;
|
|
45
|
+
--primary-foreground: oklch(0.985 0 0);
|
|
46
|
+
--destructive: #c9302d;
|
|
47
|
+
--destructive-foreground: #fbfbfb;
|
|
48
|
+
/* 3:1 on every surface, as icons and dots. */
|
|
49
|
+
--success: #51a556;
|
|
35
50
|
--success-foreground: oklch(0.99 0 0);
|
|
36
|
-
--warning:
|
|
51
|
+
--warning: #bd8630;
|
|
37
52
|
--warning-foreground: oklch(0.25 0.04 75);
|
|
38
|
-
--info:
|
|
53
|
+
--info: #5399d1;
|
|
39
54
|
--info-foreground: oklch(0.99 0 0);
|
|
40
55
|
--chart-1: oklch(0.65 0.14 135);
|
|
41
56
|
--chart-2: oklch(0.7 0.11 200);
|
|
42
57
|
--chart-3: oklch(0.6 0.13 260);
|
|
43
58
|
--chart-4: oklch(0.78 0.13 80);
|
|
44
59
|
--chart-5: oklch(0.68 0.15 30);
|
|
45
|
-
--sidebar: oklch(0.96 0 0);
|
|
46
|
-
--sidebar-foreground: oklch(0.25 0 0);
|
|
47
|
-
--sidebar-primary: oklch(0.52 0.07 135);
|
|
48
|
-
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
49
|
-
--sidebar-accent: oklch(0.93 0 0);
|
|
50
|
-
--sidebar-accent-foreground: oklch(0.3 0 0);
|
|
51
|
-
--sidebar-border: oklch(0.88 0 0);
|
|
52
|
-
--sidebar-ring: oklch(0.55 0 0);
|
|
53
|
-
--inputparam: oklch(1 0 0);
|
|
54
|
-
--outputparam: oklch(1 0 0);
|
|
55
60
|
/* Scrim behind modal dialogs and drawers. */
|
|
56
61
|
--overlay: oklch(0 0 0 / 50%);
|
|
57
62
|
}
|
|
58
63
|
|
|
59
64
|
.dark {
|
|
60
|
-
--background: oklch(0.
|
|
65
|
+
--background: oklch(0.155 0 0);
|
|
66
|
+
--card: oklch(0.235 0 0);
|
|
67
|
+
--raised: oklch(0.275 0 0);
|
|
68
|
+
--muted: oklch(0.18 0 0);
|
|
61
69
|
--foreground: oklch(0.96 0 0);
|
|
62
|
-
--card: oklch(0.23 0 0);
|
|
63
70
|
--card-foreground: oklch(0.96 0 0);
|
|
64
|
-
--popover: oklch(0.23 0 0);
|
|
65
71
|
--popover-foreground: oklch(0.96 0 0);
|
|
66
|
-
--primary: oklch(0.74 0.07 135);
|
|
67
|
-
--primary-foreground: oklch(0.18 0 0);
|
|
68
|
-
--secondary: oklch(0.3 0 0);
|
|
69
|
-
--secondary-foreground: oklch(0.96 0 0);
|
|
70
|
-
--muted: oklch(0.27 0 0);
|
|
71
72
|
--muted-foreground: oklch(0.72 0 0);
|
|
72
|
-
--
|
|
73
|
-
--
|
|
74
|
-
--
|
|
75
|
-
--
|
|
76
|
-
--
|
|
77
|
-
--
|
|
73
|
+
--faint-foreground: oklch(0.56 0 0);
|
|
74
|
+
--hover: oklch(1 0 0 / 6%);
|
|
75
|
+
--selected: oklch(1 0 0 / 12%);
|
|
76
|
+
--secondary: oklch(1 0 0 / 8%);
|
|
77
|
+
--secondary-foreground: oklch(0.96 0 0);
|
|
78
|
+
--border: oklch(1 0 0 / 11%);
|
|
79
|
+
--border-strong: oklch(1 0 0 / 24%);
|
|
80
|
+
--input: oklch(1 0 0 / 41%);
|
|
78
81
|
--ring: oklch(0.74 0 0);
|
|
82
|
+
/* Shadows barely show on a dark canvas, so raised things catch a top highlight instead. */
|
|
83
|
+
--elevation-raised: inset 0 1px 0 oklch(1 0 0 / 5%);
|
|
84
|
+
--elevation-popover: 0 8px 24px oklch(0 0 0 / 50%), inset 0 1px 0 oklch(1 0 0 / 6%);
|
|
85
|
+
--primary: #86ab78;
|
|
86
|
+
--primary-foreground: oklch(0.18 0 0);
|
|
87
|
+
/* White text can't reach 4.5:1 on a red light enough to also be text on the dark card. */
|
|
88
|
+
--destructive: oklch(0.7 0.17 22);
|
|
89
|
+
--destructive-foreground: oklch(0.18 0 0);
|
|
79
90
|
--success: oklch(0.74 0.15 145);
|
|
80
91
|
--success-foreground: oklch(0.18 0.03 145);
|
|
81
92
|
--warning: oklch(0.8 0.14 75);
|
|
@@ -87,41 +98,39 @@
|
|
|
87
98
|
--chart-3: oklch(0.68 0.14 260);
|
|
88
99
|
--chart-4: oklch(0.78 0.14 80);
|
|
89
100
|
--chart-5: oklch(0.7 0.16 30);
|
|
90
|
-
--sidebar: oklch(0.21 0 0);
|
|
91
|
-
--sidebar-foreground: oklch(0.96 0 0);
|
|
92
|
-
--sidebar-primary: oklch(0.74 0.07 135);
|
|
93
|
-
--sidebar-primary-foreground: oklch(0.18 0 0);
|
|
94
|
-
--sidebar-accent: oklch(0.32 0 0);
|
|
95
|
-
--sidebar-accent-foreground: oklch(0.92 0 0);
|
|
96
|
-
--sidebar-border: oklch(1 0 0 / 10%);
|
|
97
|
-
--sidebar-ring: oklch(0.74 0 0);
|
|
98
|
-
--inputparam: oklch(0.15 0 0);
|
|
99
|
-
--outputparam: oklch(0.25 0 0);
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
@theme inline {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
--radius-
|
|
104
|
+
/* Concentric: an item inside a padded container takes the container's radius minus the
|
|
105
|
+
padding. A 12px menu with 4px padding holds 8px items; a 10px control with 2px padding
|
|
106
|
+
holds 8px segments. */
|
|
107
|
+
--radius-sm: 6px;
|
|
108
|
+
--radius-inner: 8px;
|
|
109
|
+
--radius-md: 10px;
|
|
110
|
+
--radius-lg: 12px;
|
|
111
|
+
--radius-xl: 16px;
|
|
107
112
|
--color-background: var(--background);
|
|
108
113
|
--color-foreground: var(--foreground);
|
|
109
114
|
--color-card: var(--card);
|
|
110
115
|
--color-card-foreground: var(--card-foreground);
|
|
111
|
-
--color-
|
|
116
|
+
--color-raised: var(--raised);
|
|
117
|
+
--color-popover: var(--raised);
|
|
112
118
|
--color-popover-foreground: var(--popover-foreground);
|
|
113
|
-
--color-
|
|
114
|
-
--color-primary-foreground: var(--primary-foreground);
|
|
115
|
-
--color-secondary: var(--secondary);
|
|
116
|
-
--color-secondary-foreground: var(--secondary-foreground);
|
|
119
|
+
--color-field: var(--field);
|
|
117
120
|
--color-muted: var(--muted);
|
|
118
121
|
--color-muted-foreground: var(--muted-foreground);
|
|
119
|
-
--color-
|
|
120
|
-
--color-
|
|
122
|
+
--color-faint-foreground: var(--faint-foreground);
|
|
123
|
+
--color-hover: var(--hover);
|
|
124
|
+
--color-selected: var(--selected);
|
|
125
|
+
--color-secondary: var(--secondary);
|
|
126
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
127
|
+
--color-primary: var(--primary);
|
|
128
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
121
129
|
--color-destructive: var(--destructive);
|
|
122
130
|
--color-destructive-foreground: var(--destructive-foreground);
|
|
123
131
|
--color-overlay: var(--overlay);
|
|
124
132
|
--color-border: var(--border);
|
|
133
|
+
--color-border-strong: var(--border-strong);
|
|
125
134
|
--color-input: var(--input);
|
|
126
135
|
--color-ring: var(--ring);
|
|
127
136
|
--color-success: var(--success);
|
|
@@ -135,16 +144,8 @@
|
|
|
135
144
|
--color-chart-3: var(--chart-3);
|
|
136
145
|
--color-chart-4: var(--chart-4);
|
|
137
146
|
--color-chart-5: var(--chart-5);
|
|
138
|
-
--
|
|
139
|
-
--
|
|
140
|
-
--color-sidebar-primary: var(--sidebar-primary);
|
|
141
|
-
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
142
|
-
--color-sidebar-accent: var(--sidebar-accent);
|
|
143
|
-
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
144
|
-
--color-sidebar-border: var(--sidebar-border);
|
|
145
|
-
--color-sidebar-ring: var(--sidebar-ring);
|
|
146
|
-
--color-inputparam: var(--inputparam);
|
|
147
|
-
--color-outputparam: var(--outputparam);
|
|
147
|
+
--shadow-raised: var(--elevation-raised);
|
|
148
|
+
--shadow-popover: var(--elevation-popover);
|
|
148
149
|
}
|
|
149
150
|
|
|
150
151
|
/* Design tokens beyond Tailwind's defaults. Reach for these before an arbitrary value: the
|