@zylem/ui 0.8.8 → 0.8.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-V47CGFWX.js +1 -0
- package/dist/index.css +1 -1
- package/dist/index.d.ts +15 -0
- package/dist/index.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/styles.js +1 -1
- package/package.json +22 -11
- package/src/components/Accordion/Accordion.tsx +10 -1
- package/src/components/AddTile/AddTile.css.ts +95 -0
- package/src/components/AddTile/AddTile.tsx +45 -0
- package/src/components/BuildLabel/BuildLabel.css.ts +31 -0
- package/src/components/BuildLabel/BuildLabel.tsx +37 -0
- package/src/components/BuildLabel/mount-build-label.ts +77 -0
- package/src/components/BuildLabel/resolve-build-version.ts +47 -0
- package/src/components/Callout/Callout.css.ts +45 -0
- package/src/components/Callout/Callout.tsx +32 -0
- package/src/components/Card/Card.css.ts +18 -0
- package/src/components/Card/Card.tsx +25 -2
- package/src/components/ColorPalette/ColorPalette.css.ts +51 -0
- package/src/components/ColorPalette/ColorPalette.tsx +78 -0
- package/src/components/Dialog/Dialog.css.ts +69 -2
- package/src/components/Dialog/Dialog.tsx +35 -7
- package/src/components/DropdownMenu/DropdownMenu.css.ts +22 -0
- package/src/components/DropdownMenu/DropdownMenu.tsx +67 -20
- package/src/components/EmptyState/EmptyState.css.ts +9 -0
- package/src/components/EmptyState/EmptyState.tsx +3 -1
- package/src/components/FrameStrip/FrameStrip.css.ts +138 -0
- package/src/components/FrameStrip/FrameStrip.tsx +146 -0
- package/src/components/Menubar/Menubar.css.ts +52 -0
- package/src/components/Menubar/Menubar.tsx +77 -0
- package/src/components/Mixer/Knob.tsx +188 -0
- package/src/components/Mixer/Mixer.css.ts +246 -0
- package/src/components/Mixer/MixerStrip.tsx +150 -0
- package/src/components/NumberField/NumberField.tsx +5 -1
- package/src/components/Panel/Panel.tsx +6 -5
- package/src/components/PianoRoll/PianoRoll.css.ts +224 -0
- package/src/components/PianoRoll/PianoRoll.tsx +353 -0
- package/src/components/PianoRoll/piano-roll-math.ts +89 -0
- package/src/components/PixelGrid/PixelGrid.css.ts +30 -0
- package/src/components/PixelGrid/PixelGrid.tsx +48 -0
- package/src/components/PlaybackControls/PlaybackControls.css.ts +53 -0
- package/src/components/PlaybackControls/PlaybackControls.tsx +80 -0
- package/src/components/Property/Property.css.ts +1 -1
- package/src/components/Property/Property.tsx +3 -0
- package/src/components/Sidebar/Sidebar.css.ts +8 -0
- package/src/components/Sidebar/Sidebar.tsx +10 -2
- package/src/components/Slider/Slider.tsx +6 -0
- package/src/components/SpriteSizePicker/SpriteSizePicker.css.ts +103 -0
- package/src/components/SpriteSizePicker/SpriteSizePicker.tsx +172 -0
- package/src/components/SpriteSizePicker/snap-size.ts +28 -0
- package/src/components/Tabs/Tabs.css.ts +48 -0
- package/src/components/Tabs/Tabs.tsx +41 -3
- package/src/components/TextField/TextField.tsx +49 -5
- package/src/components/TimelineLanes/TimelineLanes.css.ts +365 -0
- package/src/components/TimelineLanes/TimelineLanes.tsx +509 -0
- package/src/components/TimelineLanes/lanes-math.ts +182 -0
- package/src/components/TimelineTrack/TimelineTrack.css.ts +163 -0
- package/src/components/TimelineTrack/TimelineTrack.tsx +90 -0
- package/src/components/TimelineTrack/timeline-math.ts +43 -0
- package/src/components/Toast/Toast.css.ts +48 -0
- package/src/components/Toast/Toast.tsx +37 -0
- package/src/components/ToolButton/ToolButton.tsx +92 -0
- package/src/components/ToolGroup/ToolGroup.css.ts +35 -0
- package/src/components/ToolGroup/ToolGroup.tsx +29 -0
- package/src/components/ToolboxButton/ToolboxButton.css.ts +131 -0
- package/src/components/ToolboxButton/ToolboxButton.tsx +88 -0
- package/src/components/TrackHeader/TrackHeader.css.ts +162 -0
- package/src/components/TrackHeader/TrackHeader.tsx +145 -0
- package/src/components/TransportBar/TransportBar.css.ts +65 -0
- package/src/components/TransportBar/TransportBar.tsx +154 -0
- package/src/components/Waveform/Waveform.css.ts +77 -0
- package/src/components/Waveform/Waveform.tsx +195 -0
- package/src/components/Waveform/peaks.ts +49 -0
- package/src/components/index.ts +122 -0
- package/src/global/accordion.css.ts +23 -0
- package/src/global/hyperglass-base.css.ts +9 -6
- package/src/styles.ts +23 -0
- package/src/theme.css.ts +15 -0
- package/vite/collect-zylem-versions.ts +82 -0
- package/vite/index.ts +30 -0
- package/dist/chunk-3TP2SNNW.js +0 -1
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { createEffect, createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js';
|
|
2
|
+
import { clamp } from '../TimelineLanes/lanes-math';
|
|
3
|
+
import { computePeaks, peaksFromAudioBuffer } from './peaks';
|
|
4
|
+
|
|
5
|
+
export type { PeakSource } from './peaks';
|
|
6
|
+
|
|
7
|
+
export interface WaveformRegion {
|
|
8
|
+
/** Seconds. */
|
|
9
|
+
start: number;
|
|
10
|
+
end: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface WaveformProps {
|
|
14
|
+
/** Pre-computed peaks (0–1 per column); wins over `buffer`. */
|
|
15
|
+
peaks?: ArrayLike<number>;
|
|
16
|
+
/** Source audio; peaks are computed to match the drawn width. */
|
|
17
|
+
buffer?: { duration: number; numberOfChannels: number; getChannelData(channel: number): Float32Array };
|
|
18
|
+
/** Seconds the peaks span; defaults to `buffer.duration`. Needed for regions and the playhead. */
|
|
19
|
+
duration?: number;
|
|
20
|
+
/** Highlighted span with draggable edges. */
|
|
21
|
+
region?: WaveformRegion;
|
|
22
|
+
onRegionChange?: (region: WaveformRegion) => void;
|
|
23
|
+
onRegionCommit?: (region: WaveformRegion) => void;
|
|
24
|
+
/** Seconds. */
|
|
25
|
+
playhead?: number;
|
|
26
|
+
/** Any CSS color for the peaks. */
|
|
27
|
+
color?: string;
|
|
28
|
+
height?: number;
|
|
29
|
+
/** Click anywhere to seek. */
|
|
30
|
+
onSeek?: (seconds: number) => void;
|
|
31
|
+
disabled?: boolean;
|
|
32
|
+
class?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Canvas waveform with an optional trim region and playhead. Peaks are
|
|
37
|
+
* redrawn on resize so the shape stays crisp at any width.
|
|
38
|
+
*/
|
|
39
|
+
export function Waveform(props: WaveformProps) {
|
|
40
|
+
let canvas: HTMLCanvasElement | undefined;
|
|
41
|
+
let host: HTMLDivElement | undefined;
|
|
42
|
+
const [width, setWidth] = createSignal(0);
|
|
43
|
+
const height = () => props.height ?? 64;
|
|
44
|
+
const duration = () => props.duration ?? props.buffer?.duration ?? 0;
|
|
45
|
+
|
|
46
|
+
const peaks = createMemo(() => {
|
|
47
|
+
const bins = Math.max(1, Math.floor(width()));
|
|
48
|
+
if (props.peaks) {
|
|
49
|
+
const source = Float32Array.from(props.peaks as ArrayLike<number>);
|
|
50
|
+
return source.length === bins ? source : resample(source, bins);
|
|
51
|
+
}
|
|
52
|
+
if (props.buffer) return peaksFromAudioBuffer(props.buffer, bins);
|
|
53
|
+
return new Float32Array(bins);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
onMount(() => {
|
|
57
|
+
if (!host) return;
|
|
58
|
+
setWidth(host.clientWidth);
|
|
59
|
+
if (typeof ResizeObserver === 'undefined') return;
|
|
60
|
+
const observer = new ResizeObserver((entries) => {
|
|
61
|
+
const entry = entries[0];
|
|
62
|
+
if (entry) setWidth(Math.floor(entry.contentRect.width));
|
|
63
|
+
});
|
|
64
|
+
observer.observe(host);
|
|
65
|
+
onCleanup(() => observer.disconnect());
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
createEffect(() => {
|
|
69
|
+
if (!canvas) return;
|
|
70
|
+
const w = width();
|
|
71
|
+
const h = height();
|
|
72
|
+
const data = peaks();
|
|
73
|
+
const color =
|
|
74
|
+
props.color ??
|
|
75
|
+
(getComputedStyle(canvas).getPropertyValue('--zylem-color-primary').trim() || '#61a6e8');
|
|
76
|
+
const ratio = typeof devicePixelRatio === 'number' ? devicePixelRatio : 1;
|
|
77
|
+
canvas.width = Math.max(1, Math.floor(w * ratio));
|
|
78
|
+
canvas.height = Math.max(1, Math.floor(h * ratio));
|
|
79
|
+
const context = canvas.getContext('2d');
|
|
80
|
+
if (!context) return;
|
|
81
|
+
context.setTransform(ratio, 0, 0, ratio, 0, 0);
|
|
82
|
+
context.clearRect(0, 0, w, h);
|
|
83
|
+
const mid = h / 2;
|
|
84
|
+
context.strokeStyle = 'rgba(205, 232, 255, 0.18)';
|
|
85
|
+
context.beginPath();
|
|
86
|
+
context.moveTo(0, mid + 0.5);
|
|
87
|
+
context.lineTo(w, mid + 0.5);
|
|
88
|
+
context.stroke();
|
|
89
|
+
context.fillStyle = color;
|
|
90
|
+
for (let x = 0; x < data.length; x += 1) {
|
|
91
|
+
const amplitude = Math.max(1, (data[x] ?? 0) * (mid - 2));
|
|
92
|
+
context.fillRect(x, mid - amplitude, 1, amplitude * 2);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const secondsAt = (clientX: number) => {
|
|
97
|
+
if (!host || duration() <= 0) return 0;
|
|
98
|
+
const rect = host.getBoundingClientRect();
|
|
99
|
+
return clamp(((clientX - rect.left) / rect.width) * duration(), 0, duration());
|
|
100
|
+
};
|
|
101
|
+
const percent = (seconds: number) => (duration() > 0 ? (seconds / duration()) * 100 : 0);
|
|
102
|
+
|
|
103
|
+
const beginRegionDrag = (edge: 'start' | 'end') => (event: PointerEvent) => {
|
|
104
|
+
const region = props.region;
|
|
105
|
+
if (props.disabled || !region || event.button !== 0) return;
|
|
106
|
+
event.preventDefault();
|
|
107
|
+
event.stopPropagation();
|
|
108
|
+
const target = event.currentTarget as HTMLElement;
|
|
109
|
+
target.setPointerCapture?.(event.pointerId);
|
|
110
|
+
let last = region;
|
|
111
|
+
const move = (moveEvent: PointerEvent) => {
|
|
112
|
+
const seconds = secondsAt(moveEvent.clientX);
|
|
113
|
+
last =
|
|
114
|
+
edge === 'start'
|
|
115
|
+
? { start: Math.min(seconds, region.end - 0.01), end: region.end }
|
|
116
|
+
: { start: region.start, end: Math.max(seconds, region.start + 0.01) };
|
|
117
|
+
props.onRegionChange?.(last);
|
|
118
|
+
};
|
|
119
|
+
const stop = () => {
|
|
120
|
+
target.removeEventListener('pointermove', move);
|
|
121
|
+
target.removeEventListener('pointerup', stop);
|
|
122
|
+
target.removeEventListener('pointercancel', stop);
|
|
123
|
+
target.releasePointerCapture?.(event.pointerId);
|
|
124
|
+
props.onRegionCommit?.(last);
|
|
125
|
+
};
|
|
126
|
+
target.addEventListener('pointermove', move);
|
|
127
|
+
target.addEventListener('pointerup', stop);
|
|
128
|
+
target.addEventListener('pointercancel', stop);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
return (
|
|
132
|
+
<div
|
|
133
|
+
ref={host}
|
|
134
|
+
class={props.class ? `zylem-waveform ${props.class}` : 'zylem-waveform'}
|
|
135
|
+
style={{ height: `${height()}px` }}
|
|
136
|
+
data-disabled={props.disabled ? '' : undefined}
|
|
137
|
+
onPointerDown={(event) => {
|
|
138
|
+
if (props.disabled || !props.onSeek || event.button !== 0) return;
|
|
139
|
+
props.onSeek(secondsAt(event.clientX));
|
|
140
|
+
}}
|
|
141
|
+
>
|
|
142
|
+
<canvas ref={canvas} class="zylem-waveform-canvas" aria-hidden="true" />
|
|
143
|
+
<Show when={props.region && duration() > 0}>
|
|
144
|
+
{(_) => {
|
|
145
|
+
const region = () => props.region!;
|
|
146
|
+
return (
|
|
147
|
+
<>
|
|
148
|
+
<div
|
|
149
|
+
class="zylem-waveform-shade"
|
|
150
|
+
style={{ left: 0, width: `${percent(region().start)}%` }}
|
|
151
|
+
/>
|
|
152
|
+
<div
|
|
153
|
+
class="zylem-waveform-shade"
|
|
154
|
+
style={{ left: `${percent(region().end)}%`, right: 0 }}
|
|
155
|
+
/>
|
|
156
|
+
<div
|
|
157
|
+
class="zylem-waveform-edge"
|
|
158
|
+
data-edge="start"
|
|
159
|
+
style={{ left: `${percent(region().start)}%` }}
|
|
160
|
+
onPointerDown={beginRegionDrag('start')}
|
|
161
|
+
role="slider"
|
|
162
|
+
aria-label="Trim start"
|
|
163
|
+
aria-valuenow={region().start}
|
|
164
|
+
aria-valuemin={0}
|
|
165
|
+
aria-valuemax={duration()}
|
|
166
|
+
/>
|
|
167
|
+
<div
|
|
168
|
+
class="zylem-waveform-edge"
|
|
169
|
+
data-edge="end"
|
|
170
|
+
style={{ left: `${percent(region().end)}%` }}
|
|
171
|
+
onPointerDown={beginRegionDrag('end')}
|
|
172
|
+
role="slider"
|
|
173
|
+
aria-label="Trim end"
|
|
174
|
+
aria-valuenow={region().end}
|
|
175
|
+
aria-valuemin={0}
|
|
176
|
+
aria-valuemax={duration()}
|
|
177
|
+
/>
|
|
178
|
+
</>
|
|
179
|
+
);
|
|
180
|
+
}}
|
|
181
|
+
</Show>
|
|
182
|
+
<Show when={props.playhead !== undefined && duration() > 0}>
|
|
183
|
+
<div
|
|
184
|
+
class="zylem-waveform-playhead"
|
|
185
|
+
style={{ left: `${percent(props.playhead ?? 0)}%` }}
|
|
186
|
+
aria-hidden="true"
|
|
187
|
+
/>
|
|
188
|
+
</Show>
|
|
189
|
+
</div>
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function resample(source: Float32Array, bins: number): Float32Array {
|
|
194
|
+
return computePeaks({ channels: [source] }, bins);
|
|
195
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Peak extraction for waveform drawing: folds PCM samples into `bins`
|
|
3
|
+
* columns, each the largest absolute sample in its slice, normalised so the
|
|
4
|
+
* loudest bin is 1 (silence stays 0).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export interface PeakSource {
|
|
8
|
+
/** One `Float32Array` per channel; channels are mixed by taking the max. */
|
|
9
|
+
channels: readonly Float32Array[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function computePeaks(source: PeakSource | Float32Array, bins: number): Float32Array {
|
|
13
|
+
const channels = source instanceof Float32Array ? [source] : source.channels;
|
|
14
|
+
const count = Math.max(1, Math.floor(bins));
|
|
15
|
+
const peaks = new Float32Array(count);
|
|
16
|
+
const length = channels[0]?.length ?? 0;
|
|
17
|
+
if (length === 0 || channels.length === 0) return peaks;
|
|
18
|
+
const perBin = length / count;
|
|
19
|
+
let loudest = 0;
|
|
20
|
+
for (let bin = 0; bin < count; bin += 1) {
|
|
21
|
+
const from = Math.floor(bin * perBin);
|
|
22
|
+
const to = Math.min(length, Math.max(from + 1, Math.floor((bin + 1) * perBin)));
|
|
23
|
+
let peak = 0;
|
|
24
|
+
for (const channel of channels) {
|
|
25
|
+
for (let i = from; i < to; i += 1) {
|
|
26
|
+
const value = Math.abs(channel[i] ?? 0);
|
|
27
|
+
if (value > peak) peak = value;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
peaks[bin] = peak;
|
|
31
|
+
if (peak > loudest) loudest = peak;
|
|
32
|
+
}
|
|
33
|
+
if (loudest > 0 && loudest !== 1) {
|
|
34
|
+
for (let bin = 0; bin < count; bin += 1) peaks[bin] = peaks[bin]! / loudest;
|
|
35
|
+
}
|
|
36
|
+
return peaks;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Peaks from a Web Audio `AudioBuffer` without depending on its type here. */
|
|
40
|
+
export function peaksFromAudioBuffer(
|
|
41
|
+
buffer: { numberOfChannels: number; getChannelData(channel: number): Float32Array },
|
|
42
|
+
bins: number,
|
|
43
|
+
): Float32Array {
|
|
44
|
+
const channels: Float32Array[] = [];
|
|
45
|
+
for (let channel = 0; channel < buffer.numberOfChannels; channel += 1) {
|
|
46
|
+
channels.push(buffer.getChannelData(channel));
|
|
47
|
+
}
|
|
48
|
+
return computePeaks({ channels }, bins);
|
|
49
|
+
}
|
package/src/components/index.ts
CHANGED
|
@@ -38,6 +38,7 @@ export {
|
|
|
38
38
|
TabsTrigger,
|
|
39
39
|
TabsContent,
|
|
40
40
|
type TabsProps,
|
|
41
|
+
type TabsTriggerProps,
|
|
41
42
|
} from './Tabs/Tabs';
|
|
42
43
|
export {
|
|
43
44
|
Accordion,
|
|
@@ -47,17 +48,22 @@ export {
|
|
|
47
48
|
export { Tooltip, type TooltipProps } from './Tooltip/Tooltip';
|
|
48
49
|
export {
|
|
49
50
|
DropdownMenu,
|
|
51
|
+
MenuItems,
|
|
50
52
|
type DropdownMenuProps,
|
|
51
53
|
type DropdownMenuItemConfig,
|
|
52
54
|
} from './DropdownMenu/DropdownMenu';
|
|
55
|
+
export { Menubar, type MenubarProps, type MenubarMenuConfig } from './Menubar/Menubar';
|
|
53
56
|
export {
|
|
54
57
|
Dialog,
|
|
55
58
|
ConfirmDialog,
|
|
56
59
|
type DialogProps,
|
|
60
|
+
type DialogSize,
|
|
57
61
|
type ConfirmDialogProps,
|
|
58
62
|
} from './Dialog/Dialog';
|
|
59
63
|
export { Progress, type ProgressProps } from './Progress/Progress';
|
|
60
64
|
export { Badge, type BadgeProps, type BadgeTone } from './Badge/Badge';
|
|
65
|
+
export { Callout, type CalloutProps, type CalloutTone } from './Callout/Callout';
|
|
66
|
+
export { Toast, type ToastProps, type ToastTone } from './Toast/Toast';
|
|
61
67
|
export { Separator, type SeparatorProps } from './Separator/Separator';
|
|
62
68
|
|
|
63
69
|
// Composites
|
|
@@ -95,3 +101,119 @@ export { SearchInput, type SearchInputProps } from './SearchInput/SearchInput';
|
|
|
95
101
|
export { EmptyState, type EmptyStateProps } from './EmptyState/EmptyState';
|
|
96
102
|
export { ScrollArea, type ScrollAreaProps } from './ScrollArea/ScrollArea';
|
|
97
103
|
export { Kbd, type KbdProps } from './Kbd/Kbd';
|
|
104
|
+
export {
|
|
105
|
+
BuildLabel,
|
|
106
|
+
type BuildLabelProps,
|
|
107
|
+
} from './BuildLabel/BuildLabel';
|
|
108
|
+
export {
|
|
109
|
+
mountBuildLabel,
|
|
110
|
+
BUILD_LABEL_ID,
|
|
111
|
+
type BuildLabelModel,
|
|
112
|
+
} from './BuildLabel/mount-build-label';
|
|
113
|
+
export {
|
|
114
|
+
formatBuildLabel,
|
|
115
|
+
resolveBuildVersion,
|
|
116
|
+
} from './BuildLabel/resolve-build-version';
|
|
117
|
+
|
|
118
|
+
// Art / Director (Creator sprite editor, director, toolbox)
|
|
119
|
+
export { PixelGrid, type PixelGridProps } from './PixelGrid/PixelGrid';
|
|
120
|
+
export {
|
|
121
|
+
SpriteSizePicker,
|
|
122
|
+
type SpriteSizePickerProps,
|
|
123
|
+
} from './SpriteSizePicker/SpriteSizePicker';
|
|
124
|
+
export {
|
|
125
|
+
snapSize,
|
|
126
|
+
SPRITE_SIZE_PRESETS,
|
|
127
|
+
type SnapOptions,
|
|
128
|
+
type SpriteSize,
|
|
129
|
+
} from './SpriteSizePicker/snap-size';
|
|
130
|
+
export { ToolGroup, type ToolGroupProps } from './ToolGroup/ToolGroup';
|
|
131
|
+
export {
|
|
132
|
+
ToolButton,
|
|
133
|
+
ART_TOOLS,
|
|
134
|
+
ART_TOOL_ICONS,
|
|
135
|
+
ART_TOOL_LABELS,
|
|
136
|
+
type ArtTool,
|
|
137
|
+
type ToolButtonProps,
|
|
138
|
+
} from './ToolButton/ToolButton';
|
|
139
|
+
export { AddTile, type AddTileProps, type AddTileVariant } from './AddTile/AddTile';
|
|
140
|
+
export {
|
|
141
|
+
ColorPalette,
|
|
142
|
+
Swatch,
|
|
143
|
+
TRANSPARENT,
|
|
144
|
+
type ColorPaletteProps,
|
|
145
|
+
type SwatchProps,
|
|
146
|
+
} from './ColorPalette/ColorPalette';
|
|
147
|
+
export {
|
|
148
|
+
FrameStrip,
|
|
149
|
+
FrameThumb,
|
|
150
|
+
FrameActions,
|
|
151
|
+
type FrameStripProps,
|
|
152
|
+
type FrameThumbProps,
|
|
153
|
+
type FrameActionsProps,
|
|
154
|
+
} from './FrameStrip/FrameStrip';
|
|
155
|
+
export {
|
|
156
|
+
PlaybackControls,
|
|
157
|
+
type PlaybackControlsProps,
|
|
158
|
+
} from './PlaybackControls/PlaybackControls';
|
|
159
|
+
export { TimelineTrack, type TimelineTrackProps } from './TimelineTrack/TimelineTrack';
|
|
160
|
+
export {
|
|
161
|
+
formatSeconds,
|
|
162
|
+
intervalTicks,
|
|
163
|
+
markerPercent,
|
|
164
|
+
} from './TimelineTrack/timeline-math';
|
|
165
|
+
export {
|
|
166
|
+
ToolboxButton,
|
|
167
|
+
ToolboxGrid,
|
|
168
|
+
type ToolboxButtonProps,
|
|
169
|
+
type ToolboxGridProps,
|
|
170
|
+
type ToolboxSize,
|
|
171
|
+
} from './ToolboxButton/ToolboxButton';
|
|
172
|
+
|
|
173
|
+
// Timeline / Music (Creator director and music editors)
|
|
174
|
+
export {
|
|
175
|
+
TimelineLanes,
|
|
176
|
+
TimelineLane,
|
|
177
|
+
TimelineLaneGroup,
|
|
178
|
+
TimelineClip,
|
|
179
|
+
KeyframeMarker,
|
|
180
|
+
useTimeline,
|
|
181
|
+
type TimelineLanesProps,
|
|
182
|
+
type TimelineLaneProps,
|
|
183
|
+
type TimelineLaneGroupProps,
|
|
184
|
+
type TimelineClipProps,
|
|
185
|
+
type TimelineClipChange,
|
|
186
|
+
type TimelineContextValue,
|
|
187
|
+
type TimelineRange,
|
|
188
|
+
type KeyframeMarkerProps,
|
|
189
|
+
type TimeScale,
|
|
190
|
+
type TimeUnit,
|
|
191
|
+
type RulerTick,
|
|
192
|
+
type ClipBounds,
|
|
193
|
+
} from './TimelineLanes/TimelineLanes';
|
|
194
|
+
export {
|
|
195
|
+
snapTime,
|
|
196
|
+
resolveClipDrag,
|
|
197
|
+
rulerTicks,
|
|
198
|
+
majorTickTimes,
|
|
199
|
+
formatClock,
|
|
200
|
+
formatBeats,
|
|
201
|
+
} from './TimelineLanes/lanes-math';
|
|
202
|
+
export { TrackHeader, type TrackHeaderProps } from './TrackHeader/TrackHeader';
|
|
203
|
+
export { PianoRoll, type PianoRollProps, type PianoRollNote } from './PianoRoll/PianoRoll';
|
|
204
|
+
export {
|
|
205
|
+
pitchName,
|
|
206
|
+
isBlackKey,
|
|
207
|
+
resolveNoteDrag,
|
|
208
|
+
cellStart,
|
|
209
|
+
} from './PianoRoll/piano-roll-math';
|
|
210
|
+
export { Knob, arcPath, type KnobProps } from './Mixer/Knob';
|
|
211
|
+
export { MixerStrip, formatDb, formatPan, type MixerStripProps } from './Mixer/MixerStrip';
|
|
212
|
+
export { Waveform, type WaveformProps, type WaveformRegion } from './Waveform/Waveform';
|
|
213
|
+
export { computePeaks, peaksFromAudioBuffer, type PeakSource } from './Waveform/peaks';
|
|
214
|
+
export {
|
|
215
|
+
TransportBar,
|
|
216
|
+
formatTransportTime,
|
|
217
|
+
type TransportBarProps,
|
|
218
|
+
type TransportTimeSignature,
|
|
219
|
+
} from './TransportBar/TransportBar';
|
|
@@ -81,6 +81,29 @@ globalStyle('.accordion-content', {
|
|
|
81
81
|
transition: 'height 0.3s ease',
|
|
82
82
|
});
|
|
83
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Stack layout: natural-height sections, no per-section scrolling. The
|
|
86
|
+
* accordion grows with its content and leaves scrolling to the parent.
|
|
87
|
+
*/
|
|
88
|
+
globalStyle('.zylem-accordion--stack', {
|
|
89
|
+
height: 'auto',
|
|
90
|
+
flex: 'none',
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
globalStyle('.zylem-accordion--stack .accordion-item[data-expanded]', {
|
|
94
|
+
flex: 'none',
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// The parent scrolls, so headers must not pin over the sections above them.
|
|
98
|
+
globalStyle('.zylem-accordion--stack .accordion-header', {
|
|
99
|
+
position: 'static',
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
globalStyle('.zylem-accordion--stack .accordion-content', {
|
|
103
|
+
flex: 'none',
|
|
104
|
+
overflow: 'visible',
|
|
105
|
+
});
|
|
106
|
+
|
|
84
107
|
globalStyle('.accordion-trigger::after', {
|
|
85
108
|
content: "'\\25BC'",
|
|
86
109
|
position: 'relative',
|
|
@@ -46,12 +46,15 @@ globalStyle(
|
|
|
46
46
|
// containing block for the sheen — don't override them to `relative` or they
|
|
47
47
|
// stretch in flex parents. `.entity-grid-item` already sets `relative` in
|
|
48
48
|
// editor-base.
|
|
49
|
-
globalStyle(
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
globalStyle(
|
|
50
|
+
'.zylem-button:not(.zylem-console-clear), .zylem-toolbar-btn, .zylem-toolbox-btn',
|
|
51
|
+
{
|
|
52
|
+
position: 'relative',
|
|
53
|
+
},
|
|
54
|
+
);
|
|
52
55
|
|
|
53
56
|
globalStyle(
|
|
54
|
-
'.zylem-button::before, .zylem-toolbar-btn::before, .entity-grid-item::before',
|
|
57
|
+
'.zylem-button::before, .zylem-toolbar-btn::before, .zylem-toolbox-btn::before, .entity-grid-item::before',
|
|
55
58
|
{
|
|
56
59
|
content: '""',
|
|
57
60
|
position: 'absolute',
|
|
@@ -81,7 +84,7 @@ globalStyle(
|
|
|
81
84
|
);
|
|
82
85
|
|
|
83
86
|
globalStyle(
|
|
84
|
-
'.zylem-button:hover:not([disabled])::before, .zylem-toolbar-btn:hover:not([disabled])::before, .entity-grid-item:hover::before',
|
|
87
|
+
'.zylem-button:hover:not([disabled])::before, .zylem-toolbar-btn:hover:not([disabled])::before, .zylem-toolbox-btn:hover:not([disabled])::before, .entity-grid-item:hover::before',
|
|
85
88
|
{
|
|
86
89
|
backgroundPosition: '25% 50%',
|
|
87
90
|
opacity: 0.5,
|
|
@@ -94,7 +97,7 @@ globalStyle(
|
|
|
94
97
|
);
|
|
95
98
|
|
|
96
99
|
globalStyle(
|
|
97
|
-
'.zylem-button:active:not([disabled])::before, .zylem-toolbar-btn:active:not([disabled])::before, .entity-grid-item:active::before',
|
|
100
|
+
'.zylem-button:active:not([disabled])::before, .zylem-toolbar-btn:active:not([disabled])::before, .zylem-toolbox-btn:active:not([disabled])::before, .entity-grid-item:active::before',
|
|
98
101
|
{
|
|
99
102
|
backgroundPosition: '50% 15%',
|
|
100
103
|
opacity: 0.58,
|
package/src/styles.ts
CHANGED
|
@@ -32,9 +32,12 @@ import './components/Slider/Slider.css';
|
|
|
32
32
|
import './components/Tabs/Tabs.css';
|
|
33
33
|
import './components/Tooltip/Tooltip.css';
|
|
34
34
|
import './components/DropdownMenu/DropdownMenu.css';
|
|
35
|
+
import './components/Menubar/Menubar.css';
|
|
35
36
|
import './components/Dialog/Dialog.css';
|
|
36
37
|
import './components/Progress/Progress.css';
|
|
37
38
|
import './components/Badge/Badge.css';
|
|
39
|
+
import './components/Callout/Callout.css';
|
|
40
|
+
import './components/Toast/Toast.css';
|
|
38
41
|
import './components/Separator/Separator.css';
|
|
39
42
|
import './components/WindowControls/WindowControls.css';
|
|
40
43
|
import './components/TitleBar/TitleBar.css';
|
|
@@ -49,3 +52,23 @@ import './components/MenuButton/MenuButton.css';
|
|
|
49
52
|
import './components/ItemPicker/ItemPicker.css';
|
|
50
53
|
import './components/EmptyState/EmptyState.css';
|
|
51
54
|
import './components/Kbd/Kbd.css';
|
|
55
|
+
import './components/BuildLabel/BuildLabel.css';
|
|
56
|
+
|
|
57
|
+
// Art / Director surfaces (Creator sprite editor, director, toolbox).
|
|
58
|
+
import './components/PixelGrid/PixelGrid.css';
|
|
59
|
+
import './components/SpriteSizePicker/SpriteSizePicker.css';
|
|
60
|
+
import './components/ToolGroup/ToolGroup.css';
|
|
61
|
+
import './components/AddTile/AddTile.css';
|
|
62
|
+
import './components/ColorPalette/ColorPalette.css';
|
|
63
|
+
import './components/FrameStrip/FrameStrip.css';
|
|
64
|
+
import './components/PlaybackControls/PlaybackControls.css';
|
|
65
|
+
import './components/TimelineTrack/TimelineTrack.css';
|
|
66
|
+
import './components/ToolboxButton/ToolboxButton.css';
|
|
67
|
+
|
|
68
|
+
// Timeline / Music surfaces (Creator director and music editors).
|
|
69
|
+
import './components/TimelineLanes/TimelineLanes.css';
|
|
70
|
+
import './components/TrackHeader/TrackHeader.css';
|
|
71
|
+
import './components/PianoRoll/PianoRoll.css';
|
|
72
|
+
import './components/Mixer/Mixer.css';
|
|
73
|
+
import './components/Waveform/Waveform.css';
|
|
74
|
+
import './components/TransportBar/TransportBar.css';
|
package/src/theme.css.ts
CHANGED
|
@@ -112,6 +112,16 @@ const tokens = {
|
|
|
112
112
|
normal: '160ms',
|
|
113
113
|
easeOut: 'cubic-bezier(.2,.8,.2,1)',
|
|
114
114
|
},
|
|
115
|
+
/**
|
|
116
|
+
* Art / pixel-editor surfaces. The checker pair reads as "transparent"
|
|
117
|
+
* behind sprite pixels, so it sits lighter than the panel palette; canvas
|
|
118
|
+
* renderers can draw the same values from `tokenValues.art`.
|
|
119
|
+
*/
|
|
120
|
+
art: {
|
|
121
|
+
checkerLight: '#4F5C72',
|
|
122
|
+
checkerDark: '#3C4759',
|
|
123
|
+
canvasBorder: 'rgba(150, 210, 255, 0.5)',
|
|
124
|
+
},
|
|
115
125
|
/**
|
|
116
126
|
* Stacking tiers. Declared in `layers/tiers.ts` because the runtime side of
|
|
117
127
|
* the layer system reads the same ladder without loading this file.
|
|
@@ -212,6 +222,11 @@ const varNames = {
|
|
|
212
222
|
normal: 'zylem-motion-normal',
|
|
213
223
|
easeOut: 'zylem-motion-ease-out',
|
|
214
224
|
},
|
|
225
|
+
art: {
|
|
226
|
+
checkerLight: 'zylem-art-checker-light',
|
|
227
|
+
checkerDark: 'zylem-art-checker-dark',
|
|
228
|
+
canvasBorder: 'zylem-art-canvas-border',
|
|
229
|
+
},
|
|
215
230
|
layers: layerTierVarNames,
|
|
216
231
|
} as const;
|
|
217
232
|
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
|
|
4
|
+
interface PackageManifest {
|
|
5
|
+
name?: string;
|
|
6
|
+
version?: string;
|
|
7
|
+
dependencies?: Record<string, string>;
|
|
8
|
+
devDependencies?: Record<string, string>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function readManifest(dir: string): PackageManifest | null {
|
|
12
|
+
const pkgPath = join(dir, 'package.json');
|
|
13
|
+
try {
|
|
14
|
+
return JSON.parse(readFileSync(pkgPath, 'utf8')) as PackageManifest;
|
|
15
|
+
} catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Resolve an installed package directory from a declaring package's context. */
|
|
21
|
+
function resolvePackageDir(fromDir: string, name: string): string | null {
|
|
22
|
+
let dir = fromDir;
|
|
23
|
+
while (dir !== dirname(dir)) {
|
|
24
|
+
const candidate = join(dir, 'node_modules', name);
|
|
25
|
+
if (existsSync(join(candidate, 'package.json'))) {
|
|
26
|
+
return candidate;
|
|
27
|
+
}
|
|
28
|
+
dir = dirname(dir);
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Walk the resolved `@zylem/*` dependency graph starting from `rootPkgDir`
|
|
35
|
+
* and return a sorted map of package name → installed version.
|
|
36
|
+
*/
|
|
37
|
+
export function collectZylemPackageVersions(rootPkgDir: string): Record<string, string> {
|
|
38
|
+
const versions: Record<string, string> = {};
|
|
39
|
+
const seenNames = new Set<string>();
|
|
40
|
+
const visitedDirs = new Set<string>();
|
|
41
|
+
const queue: Array<{ dir: string; isRoot: boolean }> = [{ dir: rootPkgDir, isRoot: true }];
|
|
42
|
+
|
|
43
|
+
while (queue.length > 0) {
|
|
44
|
+
const { dir, isRoot } = queue.shift()!;
|
|
45
|
+
if (visitedDirs.has(dir)) continue;
|
|
46
|
+
visitedDirs.add(dir);
|
|
47
|
+
|
|
48
|
+
const manifest = readManifest(dir);
|
|
49
|
+
if (!manifest) continue;
|
|
50
|
+
|
|
51
|
+
if (typeof manifest.name === 'string' && manifest.name.startsWith('@zylem/')) {
|
|
52
|
+
versions[manifest.name] =
|
|
53
|
+
typeof manifest.version === 'string' ? manifest.version : '0.0.0';
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const depFields: Array<'dependencies' | 'devDependencies'> = isRoot
|
|
57
|
+
? ['dependencies', 'devDependencies']
|
|
58
|
+
: ['dependencies'];
|
|
59
|
+
|
|
60
|
+
for (const field of depFields) {
|
|
61
|
+
const deps = manifest[field] ?? {};
|
|
62
|
+
for (const name of Object.keys(deps)) {
|
|
63
|
+
if (!name.startsWith('@zylem/') || seenNames.has(name)) continue;
|
|
64
|
+
seenNames.add(name);
|
|
65
|
+
|
|
66
|
+
const resolvedDir = resolvePackageDir(dir, name);
|
|
67
|
+
if (!resolvedDir) continue;
|
|
68
|
+
|
|
69
|
+
const resolvedManifest = readManifest(resolvedDir);
|
|
70
|
+
if (!resolvedManifest) continue;
|
|
71
|
+
|
|
72
|
+
versions[name] =
|
|
73
|
+
typeof resolvedManifest.version === 'string'
|
|
74
|
+
? resolvedManifest.version
|
|
75
|
+
: '0.0.0';
|
|
76
|
+
queue.push({ dir: resolvedDir, isRoot: false });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return Object.fromEntries(Object.entries(versions).sort(([a], [b]) => a.localeCompare(b)));
|
|
82
|
+
}
|
package/vite/index.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Plugin } from 'vite';
|
|
2
|
+
import { collectZylemPackageVersions } from './collect-zylem-versions.ts';
|
|
3
|
+
|
|
4
|
+
export { collectZylemPackageVersions } from './collect-zylem-versions.ts';
|
|
5
|
+
|
|
6
|
+
export const VIRTUAL_ZYLEM_VERSIONS_ID = 'virtual:zylem-versions';
|
|
7
|
+
const RESOLVED_VIRTUAL_ZYLEM_VERSIONS_ID = `\0${VIRTUAL_ZYLEM_VERSIONS_ID}`;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Vite plugin that injects a `virtual:zylem-versions` module containing
|
|
11
|
+
* every resolved `@zylem/*` package version in `rootPkgDir`'s dependency
|
|
12
|
+
* graph. Demo/showcase apps mount that map as the top-right build HUD.
|
|
13
|
+
*/
|
|
14
|
+
export function zylemVersionsPlugin(rootPkgDir: string): Plugin {
|
|
15
|
+
const versions = collectZylemPackageVersions(rootPkgDir);
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
name: 'zylem-versions',
|
|
19
|
+
resolveId(id) {
|
|
20
|
+
if (id === VIRTUAL_ZYLEM_VERSIONS_ID) {
|
|
21
|
+
return RESOLVED_VIRTUAL_ZYLEM_VERSIONS_ID;
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
load(id) {
|
|
25
|
+
if (id === RESOLVED_VIRTUAL_ZYLEM_VERSIONS_ID) {
|
|
26
|
+
return `export const ZYLEM_PACKAGE_VERSIONS = ${JSON.stringify(versions)};`;
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
package/dist/chunk-3TP2SNNW.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var l={colors:{primary:"#61A6E8",primaryHover:"#3B8AD8",primaryActive:"#0C6EB8",accent:"#E64534",accentHover:"#C93A2C",accentActive:"#A82F24",background:"#11151C",backgroundTranslucent:"rgba(10, 20, 30, 0.46)",surface:"#1A1F27",surfaceHover:"#222831",border:"#2D3643",active:"rgba(20, 255, 60, 0.7)",activeHover:"rgba(20, 255, 60, 0.4)",successHover:"#2a6734b3",text:"#E6EBEF",textSecondary:"#88929E",consoleBackground:"rgba(20, 40, 60, 0.25)",consoleText:"#61A6E8"},spacing:{xxs:"0.125rem",xs:"0.25rem",sm:"0.5rem",md:"0.75rem",lg:"1rem",xl:"1.5rem",xxl:"2rem",xxxl:"3rem"},sizes:{icon:"28px",iconSm:"16px",iconLg:"96px"},typography:{fontFamily:"'Exo 2', sans-serif",fontSize:"14px"},borders:{radius:"12px",width:"1.5px"},material:{glassPanel:"linear-gradient(180deg, rgba(38, 76, 112, 0.74), rgba(10, 24, 38, 0.58))",glassPanelDark:"linear-gradient(180deg, rgba(26, 31, 39, 0.75), rgba(10, 20, 30, 0.68))",glossyBar:"linear-gradient(180deg, rgba(205, 232, 255, 0.55) 0%, rgba(97, 166, 232, 0.34) 38%, rgba(18, 54, 88, 0.86) 100%)",buttonGlass:"linear-gradient(180deg, rgba(178, 219, 255, 0.34), rgba(30, 94, 148, 0.72) 48%, rgba(9, 34, 58, 0.92))",buttonGlassHover:"linear-gradient(180deg, rgba(218, 242, 255, 0.58), rgba(48, 137, 220, 0.86) 48%, rgba(11, 62, 112, 0.96))",buttonGlassActive:"linear-gradient(180deg, rgba(190, 255, 203, 0.42), rgba(28, 174, 63, 0.78) 50%, rgba(9, 86, 31, 0.95))",buttonGlassDanger:"linear-gradient(180deg, rgba(255, 210, 202, 0.36), rgba(230, 69, 52, 0.82) 50%, rgba(96, 18, 13, 0.94))",fieldGlass:"linear-gradient(180deg, rgba(8, 19, 31, 0.82), rgba(15, 39, 62, 0.72))",panelHeaderGloss:"linear-gradient(180deg, rgba(190, 226, 255, 0.18), rgba(61, 118, 165, 0.16) 46%, rgba(10, 27, 44, 0.26))"},effects:{blurSm:"8px",blurMd:"14px",blurLg:"24px",shadowPanel:"0 22px 54px rgba(0, 0, 0, 0.48), inset 0 1px 0 rgba(255, 255, 255, 0.10)",shadowButton:"inset 0 1px 0 rgba(255,255,255,0.38), inset 0 -1px 0 rgba(0,0,0,0.45), 0 2px 7px rgba(0,0,0,0.35)",shadowInset:"inset 0 1px 2px rgba(0,0,0,0.42), inset 0 -1px 0 rgba(255,255,255,0.08)",glowPrimary:"0 0 18px rgba(97, 166, 232, 0.28)",glowActive:"0 0 20px rgba(20, 255, 60, 0.26)",glowDanger:"0 0 20px rgba(230, 69, 52, 0.24)",focusRing:"0 0 0 2px rgba(97, 166, 232, 0.38), 0 0 18px rgba(97, 166, 232, 0.22)"},radii:{window:"14px",panel:"12px",button:"7px",control:"6px",card:"10px"},motion:{fast:"120ms",normal:"160ms",easeOut:"cubic-bezier(.2,.8,.2,1)"},layers:{base:"0",panel:"1000",modal:"2000",popover:"3000",tooltip:"4000",menu:"5000"}},o={colors:{primary:"var(--zylem-color-primary)",primaryHover:"var(--zylem-color-primary-hover)",primaryActive:"var(--zylem-color-primary-active)",accent:"var(--zylem-color-accent)",accentHover:"var(--zylem-color-accent-hover)",accentActive:"var(--zylem-color-accent-active)",background:"var(--zylem-color-background)",backgroundTranslucent:"var(--zylem-color-background-translucent)",surface:"var(--zylem-color-surface)",surfaceHover:"var(--zylem-color-surface-hover)",border:"var(--zylem-color-border)",active:"var(--zylem-color-active)",activeHover:"var(--zylem-color-active-hover)",successHover:"var(--zylem-color-success-hover)",text:"var(--zylem-color-text)",textSecondary:"var(--zylem-color-text-secondary)",consoleBackground:"var(--zylem-color-console-background)",consoleText:"var(--zylem-color-console-text)"},spacing:{xxs:"var(--zylem-spacing-xxs)",xs:"var(--zylem-spacing-xs)",sm:"var(--zylem-spacing-sm)",md:"var(--zylem-spacing-md)",lg:"var(--zylem-spacing-lg)",xl:"var(--zylem-spacing-xl)",xxl:"var(--zylem-spacing-xxl)",xxxl:"var(--zylem-spacing-xxxl)"},sizes:{icon:"var(--zylem-size-icon)",iconSm:"var(--zylem-size-icon-sm)",iconLg:"var(--zylem-size-icon-lg)"},typography:{fontFamily:"var(--zylem-font-family)",fontSize:"var(--zylem-font-size)"},borders:{radius:"var(--zylem-radius)",width:"var(--zylem-border)"},material:{glassPanel:"var(--zylem-material-glass-panel)",glassPanelDark:"var(--zylem-material-glass-panel-dark)",glossyBar:"var(--zylem-material-glossy-bar)",buttonGlass:"var(--zylem-material-button-glass)",buttonGlassHover:"var(--zylem-material-button-glass-hover)",buttonGlassActive:"var(--zylem-material-button-glass-active)",buttonGlassDanger:"var(--zylem-material-button-glass-danger)",fieldGlass:"var(--zylem-material-field-glass)",panelHeaderGloss:"var(--zylem-material-panel-header-gloss)"},effects:{blurSm:"var(--zylem-effect-blur-sm)",blurMd:"var(--zylem-effect-blur-md)",blurLg:"var(--zylem-effect-blur-lg)",shadowPanel:"var(--zylem-effect-shadow-panel)",shadowButton:"var(--zylem-effect-shadow-button)",shadowInset:"var(--zylem-effect-shadow-inset)",glowPrimary:"var(--zylem-effect-glow-primary)",glowActive:"var(--zylem-effect-glow-active)",glowDanger:"var(--zylem-effect-glow-danger)",focusRing:"var(--zylem-effect-focus-ring)"},radii:{window:"var(--zylem-radius-window)",panel:"var(--zylem-radius-panel)",button:"var(--zylem-radius-button)",control:"var(--zylem-radius-control)",card:"var(--zylem-radius-card)"},motion:{fast:"var(--zylem-motion-fast)",normal:"var(--zylem-motion-normal)",easeOut:"var(--zylem-motion-ease-out)"},layers:{base:"var(--zylem-layer-base)",panel:"var(--zylem-layer-panel)",modal:"var(--zylem-layer-modal)",popover:"var(--zylem-layer-popover)",tooltip:"var(--zylem-layer-tooltip)",menu:"var(--zylem-layer-menu)"}};export{l as a,o as b};
|