@zylem/ui 0.8.14 → 0.9.1
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-YJVLOHJL.js +1 -0
- package/dist/index.css +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/styles.js +1 -1
- package/package.json +1 -1
- package/src/components/Accordion/Accordion.tsx +6 -1
- package/src/components/BuildLabel/BuildLabel.tsx +0 -1
- package/src/components/BuildLabel/mount-build-label.ts +0 -1
- package/src/components/Button/Button.css.ts +85 -66
- package/src/components/Button/Button.tsx +9 -3
- package/src/components/Callout/Callout.css.ts +1 -1
- package/src/components/Callout/Callout.tsx +1 -1
- package/src/components/Card/Card.css.ts +1 -0
- package/src/components/Card/Card.tsx +11 -2
- package/src/components/Checkbox/Checkbox.tsx +4 -2
- package/src/components/ColorPalette/ColorPalette.tsx +1 -1
- package/src/components/Console/Console.css.ts +1 -1
- package/src/components/Console/Console.tsx +3 -0
- package/src/components/Dialog/Dialog.css.ts +41 -17
- package/src/components/Dialog/Dialog.tsx +134 -53
- package/src/components/FrameStrip/FrameStrip.css.ts +1 -0
- package/src/components/FrameStrip/FrameStrip.tsx +2 -3
- package/src/components/ItemPicker/ItemPicker.tsx +46 -33
- package/src/components/MenuButton/MenuButton.css.ts +49 -46
- package/src/components/MenuButton/MenuButton.tsx +17 -5
- package/src/components/Menubar/Menubar.css.ts +1 -1
- package/src/components/Mixer/Knob.tsx +10 -3
- package/src/components/Mixer/Mixer.css.ts +21 -0
- package/src/components/Mixer/MixerStrip.tsx +29 -8
- package/src/components/NumberField/NumberField.css.ts +32 -26
- package/src/components/NumberField/NumberField.tsx +7 -2
- package/src/components/Panel/Panel.css.ts +1 -0
- package/src/components/Panel/Panel.tsx +9 -1
- package/src/components/PianoRoll/PianoRoll.tsx +1 -0
- package/src/components/Progress/Progress.css.ts +1 -1
- package/src/components/Progress/Progress.tsx +3 -0
- package/src/components/Property/Property.css.ts +13 -0
- package/src/components/Property/Property.tsx +3 -2
- package/src/components/SearchInput/SearchInput.tsx +1 -1
- package/src/components/Select/Select.css.ts +7 -1
- package/src/components/Select/Select.tsx +7 -2
- package/src/components/Sidebar/Sidebar.css.ts +1 -0
- package/src/components/Sidebar/Sidebar.tsx +23 -5
- package/src/components/Slider/Slider.css.ts +1 -1
- package/src/components/Slider/Slider.tsx +4 -2
- package/src/components/SpriteSizePicker/SpriteSizePicker.css.ts +2 -0
- package/src/components/Switch/Switch.tsx +3 -1
- package/src/components/Tabs/Tabs.css.ts +0 -5
- package/src/components/Tabs/Tabs.tsx +23 -12
- package/src/components/TextField/TextField.tsx +4 -0
- package/src/components/TimelineLanes/TimelineLanes.css.ts +7 -0
- package/src/components/TimelineLanes/TimelineLanes.tsx +52 -4
- package/src/components/TimelineLanes/lanes-math.ts +51 -0
- package/src/components/TimelineTrack/TimelineTrack.css.ts +3 -2
- package/src/components/TimelineTrack/TimelineTrack.tsx +16 -3
- package/src/components/TitleBar/TitleBar.css.ts +1 -0
- package/src/components/TitleBar/TitleBar.tsx +7 -1
- package/src/components/Toast/Toast.tsx +1 -2
- package/src/components/ToolButton/ToolButton.tsx +1 -1
- package/src/components/Toolbar/Toolbar.tsx +6 -1
- package/src/components/ToolbarButton/ToolbarButton.tsx +9 -2
- package/src/components/ToolboxButton/ToolboxButton.tsx +2 -1
- package/src/components/TrackHeader/TrackHeader.css.ts +21 -0
- package/src/components/TrackHeader/TrackHeader.tsx +37 -12
- package/src/components/TransportBar/TransportBar.css.ts +5 -0
- package/src/components/TransportBar/TransportBar.tsx +4 -1
- package/src/components/Waveform/Waveform.css.ts +10 -0
- package/src/components/Waveform/Waveform.tsx +59 -27
- package/src/components/WindowControls/WindowControls.css.ts +46 -63
- package/src/components/WindowControls/WindowControls.tsx +7 -6
- package/src/components/index.ts +1 -0
- package/src/components/shared/Heading.tsx +30 -0
- package/src/fonts.css +1 -1
- package/src/global/accordion.css.ts +9 -5
- package/src/global/common.css.ts +13 -0
- package/src/global/editor-base.css.ts +9 -0
- package/src/layers/LayerContext.tsx +2 -2
- package/src/sprinkles.css.ts +4 -1
- package/src/theme.css.ts +6 -0
- package/dist/chunk-V47CGFWX.js +0 -1
|
@@ -3,7 +3,7 @@ import { type JSX, Show } from 'solid-js';
|
|
|
3
3
|
import { NumberField } from '../NumberField/NumberField';
|
|
4
4
|
import { PlaybackControls } from '../PlaybackControls/PlaybackControls';
|
|
5
5
|
import { Select } from '../Select/Select';
|
|
6
|
-
import { formatBeats, formatClock, type TimeUnit } from '../TimelineLanes/lanes-math';
|
|
6
|
+
import { describeTime, formatBeats, formatClock, type TimeUnit } from '../TimelineLanes/lanes-math';
|
|
7
7
|
import { TimelineTrack } from '../TimelineTrack/TimelineTrack';
|
|
8
8
|
import { ToolbarButton } from '../ToolbarButton/ToolbarButton';
|
|
9
9
|
|
|
@@ -107,6 +107,8 @@ export function TransportBar(props: TransportBarProps) {
|
|
|
107
107
|
max={props.length}
|
|
108
108
|
onChange={(value) => props.onSeek?.(value)}
|
|
109
109
|
disabled={props.disabled || !props.onSeek}
|
|
110
|
+
aria-label="Position"
|
|
111
|
+
valueText={(value) => describeTime(value, { unit: unit(), beatsPerBar: bpb() })}
|
|
110
112
|
class="zylem-transport-track"
|
|
111
113
|
/>
|
|
112
114
|
<span class="zylem-transport-time" aria-live="off">
|
|
@@ -133,6 +135,7 @@ export function TransportBar(props: TransportBarProps) {
|
|
|
133
135
|
<Show when={props.timeSignature}>
|
|
134
136
|
{(signature) => (
|
|
135
137
|
<Select
|
|
138
|
+
aria-label="Time signature"
|
|
136
139
|
options={signatureOptions()}
|
|
137
140
|
value={signatureKey(signature())}
|
|
138
141
|
disabled={props.disabled || !props.onTimeSignatureChange}
|
|
@@ -66,6 +66,16 @@ globalStyle('.zylem-waveform-edge::after', {
|
|
|
66
66
|
boxSizing: 'border-box',
|
|
67
67
|
});
|
|
68
68
|
|
|
69
|
+
// The ring goes on the grip: around the full-height edge it would be clipped.
|
|
70
|
+
globalStyle('.zylem-waveform-edge:focus-visible', {
|
|
71
|
+
outline: 'none',
|
|
72
|
+
boxShadow: 'none',
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
globalStyle('.zylem-waveform-edge:focus-visible::after', {
|
|
76
|
+
boxShadow: vars.effects.focusRing,
|
|
77
|
+
});
|
|
78
|
+
|
|
69
79
|
globalStyle('.zylem-waveform-playhead', {
|
|
70
80
|
position: 'absolute',
|
|
71
81
|
top: 0,
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
import { createEffect, createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js';
|
|
2
|
-
import { clamp } from '../TimelineLanes/lanes-math';
|
|
1
|
+
import { createEffect, createMemo, createSignal, For, onCleanup, onMount, Show } from 'solid-js';
|
|
2
|
+
import { clamp, describeSeconds, sliderKeyValue } from '../TimelineLanes/lanes-math';
|
|
3
3
|
import { computePeaks, peaksFromAudioBuffer } from './peaks';
|
|
4
4
|
|
|
5
|
+
/** Seconds the trim edges must stay apart. */
|
|
6
|
+
const MIN_REGION = 0.01;
|
|
7
|
+
|
|
8
|
+
const EDGES = [
|
|
9
|
+
{ edge: 'start', label: 'Trim start' },
|
|
10
|
+
{ edge: 'end', label: 'Trim end' },
|
|
11
|
+
] as const;
|
|
12
|
+
|
|
5
13
|
export type { PeakSource } from './peaks';
|
|
6
14
|
|
|
7
15
|
export interface WaveformRegion {
|
|
@@ -17,7 +25,10 @@ export interface WaveformProps {
|
|
|
17
25
|
buffer?: { duration: number; numberOfChannels: number; getChannelData(channel: number): Float32Array };
|
|
18
26
|
/** Seconds the peaks span; defaults to `buffer.duration`. Needed for regions and the playhead. */
|
|
19
27
|
duration?: number;
|
|
20
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Highlighted span with draggable edges. Focused, an edge also takes the
|
|
30
|
+
* arrow keys (1% of the duration, 10% with Shift) and Home / End.
|
|
31
|
+
*/
|
|
21
32
|
region?: WaveformRegion;
|
|
22
33
|
onRegionChange?: (region: WaveformRegion) => void;
|
|
23
34
|
onRegionCommit?: (region: WaveformRegion) => void;
|
|
@@ -106,14 +117,15 @@ export function Waveform(props: WaveformProps) {
|
|
|
106
117
|
event.preventDefault();
|
|
107
118
|
event.stopPropagation();
|
|
108
119
|
const target = event.currentTarget as HTMLElement;
|
|
120
|
+
target.focus({ preventScroll: true });
|
|
109
121
|
target.setPointerCapture?.(event.pointerId);
|
|
110
122
|
let last = region;
|
|
111
123
|
const move = (moveEvent: PointerEvent) => {
|
|
112
124
|
const seconds = secondsAt(moveEvent.clientX);
|
|
113
125
|
last =
|
|
114
126
|
edge === 'start'
|
|
115
|
-
? { start: Math.min(seconds, region.end -
|
|
116
|
-
: { start: region.start, end: Math.max(seconds, region.start +
|
|
127
|
+
? { start: Math.min(seconds, region.end - MIN_REGION), end: region.end }
|
|
128
|
+
: { start: region.start, end: Math.max(seconds, region.start + MIN_REGION) };
|
|
117
129
|
props.onRegionChange?.(last);
|
|
118
130
|
};
|
|
119
131
|
const stop = () => {
|
|
@@ -128,6 +140,29 @@ export function Waveform(props: WaveformProps) {
|
|
|
128
140
|
target.addEventListener('pointercancel', stop);
|
|
129
141
|
};
|
|
130
142
|
|
|
143
|
+
/** The span each edge may move in, short of crossing the other edge. */
|
|
144
|
+
const edgeBounds = (edge: 'start' | 'end', region: WaveformRegion) =>
|
|
145
|
+
edge === 'start'
|
|
146
|
+
? { min: 0, max: Math.max(0, region.end - MIN_REGION) }
|
|
147
|
+
: { min: Math.min(duration(), region.start + MIN_REGION), max: duration() };
|
|
148
|
+
|
|
149
|
+
const nudgeEdge = (edge: 'start' | 'end') => (event: KeyboardEvent) => {
|
|
150
|
+
const region = props.region;
|
|
151
|
+
if (props.disabled || !region) return;
|
|
152
|
+
const next = sliderKeyValue(event, {
|
|
153
|
+
value: region[edge],
|
|
154
|
+
...edgeBounds(edge, region),
|
|
155
|
+
step: duration() / 100,
|
|
156
|
+
});
|
|
157
|
+
if (next === null) return;
|
|
158
|
+
event.preventDefault();
|
|
159
|
+
// Page-level shortcuts (Home to rewind, arrows to seek) must not also act on it.
|
|
160
|
+
event.stopPropagation();
|
|
161
|
+
const changed = { ...region, [edge]: next };
|
|
162
|
+
props.onRegionChange?.(changed);
|
|
163
|
+
props.onRegionCommit?.(changed);
|
|
164
|
+
};
|
|
165
|
+
|
|
131
166
|
return (
|
|
132
167
|
<div
|
|
133
168
|
ref={host}
|
|
@@ -153,28 +188,25 @@ export function Waveform(props: WaveformProps) {
|
|
|
153
188
|
class="zylem-waveform-shade"
|
|
154
189
|
style={{ left: `${percent(region().end)}%`, right: 0 }}
|
|
155
190
|
/>
|
|
156
|
-
<
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
aria-valuemin={0}
|
|
176
|
-
aria-valuemax={duration()}
|
|
177
|
-
/>
|
|
191
|
+
<For each={EDGES}>
|
|
192
|
+
{(edge) => (
|
|
193
|
+
<div
|
|
194
|
+
class="zylem-waveform-edge"
|
|
195
|
+
data-edge={edge.edge}
|
|
196
|
+
style={{ left: `${percent(region()[edge.edge])}%` }}
|
|
197
|
+
onPointerDown={beginRegionDrag(edge.edge)}
|
|
198
|
+
onKeyDown={nudgeEdge(edge.edge)}
|
|
199
|
+
role="slider"
|
|
200
|
+
tabIndex={props.disabled ? -1 : 0}
|
|
201
|
+
aria-label={edge.label}
|
|
202
|
+
aria-valuenow={region()[edge.edge]}
|
|
203
|
+
aria-valuemin={edgeBounds(edge.edge, region()).min}
|
|
204
|
+
aria-valuemax={edgeBounds(edge.edge, region()).max}
|
|
205
|
+
aria-valuetext={describeSeconds(region()[edge.edge])}
|
|
206
|
+
aria-disabled={props.disabled ? 'true' : undefined}
|
|
207
|
+
/>
|
|
208
|
+
)}
|
|
209
|
+
</For>
|
|
178
210
|
</>
|
|
179
211
|
);
|
|
180
212
|
}}
|
|
@@ -1,89 +1,72 @@
|
|
|
1
1
|
import { globalStyle } from '@vanilla-extract/css';
|
|
2
2
|
import { vars } from '../../theme.css';
|
|
3
3
|
|
|
4
|
-
/** Soft drop plus a light top rim and a darker lower edge. */
|
|
5
|
-
const jewelDepth =
|
|
6
|
-
'inset 0 1px 0 rgba(255,255,255,0.72), inset 0 -1px 0 rgba(0,0,0,0.28), 0 2px 4px rgba(0,0,0,0.4)';
|
|
7
|
-
|
|
8
4
|
globalStyle('.zylem-window-controls', {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
display: 'flex',
|
|
6
|
+
alignItems: 'center',
|
|
7
|
+
flexShrink: 0,
|
|
8
|
+
gap: '6px',
|
|
13
9
|
});
|
|
14
10
|
|
|
15
11
|
/**
|
|
16
|
-
* Shared
|
|
12
|
+
* Shared ghost control used for panel chrome: window controls, floating
|
|
17
13
|
* panels, and detached panels. `.floating-panel-button` is kept as an alias
|
|
18
14
|
* so existing panel markup shares this single definition.
|
|
19
15
|
*
|
|
20
|
-
*
|
|
16
|
+
* Resting controls match the ghost button. Close stays that way until it is
|
|
17
|
+
* hovered or focused, when it takes the danger color.
|
|
21
18
|
*/
|
|
22
19
|
globalStyle('.zylem-window-control, .floating-panel-button', {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
transition: `filter ${vars.motion.fast} ${vars.motion.easeOut}, transform ${vars.motion.fast} ${vars.motion.easeOut}, background ${vars.motion.fast} ${vars.motion.easeOut}, border-color ${vars.motion.fast} ${vars.motion.easeOut}, box-shadow ${vars.motion.fast} ${vars.motion.easeOut}`,
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
/** Top-edge gloss. Clipped by the button; the icon sits above it. */
|
|
43
|
-
globalStyle('.zylem-window-control::before, .floating-panel-button::before', {
|
|
44
|
-
content: '""',
|
|
45
|
-
position: 'absolute',
|
|
46
|
-
left: '2px',
|
|
47
|
-
right: '2px',
|
|
48
|
-
top: '1px',
|
|
49
|
-
height: '48%',
|
|
50
|
-
borderRadius: '5px 5px 46% 46%',
|
|
51
|
-
background:
|
|
52
|
-
'linear-gradient(180deg, rgba(255,255,255,0.55), rgba(255,255,255,0.1) 55%, rgba(255,255,255,0))',
|
|
53
|
-
pointerEvents: 'none',
|
|
20
|
+
all: 'unset',
|
|
21
|
+
boxSizing: 'border-box',
|
|
22
|
+
position: 'relative',
|
|
23
|
+
cursor: 'pointer',
|
|
24
|
+
flexShrink: 0,
|
|
25
|
+
width: '28px',
|
|
26
|
+
height: '18px',
|
|
27
|
+
display: 'inline-flex',
|
|
28
|
+
alignItems: 'center',
|
|
29
|
+
justifyContent: 'center',
|
|
30
|
+
color: vars.colors.primary,
|
|
31
|
+
borderRadius: '6px',
|
|
32
|
+
border: '1px solid rgba(97, 166, 232, 0.35)',
|
|
33
|
+
background: 'transparent',
|
|
34
|
+
boxShadow: 'none',
|
|
35
|
+
transition: `color ${vars.motion.fast} ${vars.motion.easeOut}, transform ${vars.motion.fast} ${vars.motion.easeOut}, background ${vars.motion.fast} ${vars.motion.easeOut}, border-color ${vars.motion.fast} ${vars.motion.easeOut}, box-shadow ${vars.motion.fast} ${vars.motion.easeOut}`,
|
|
54
36
|
});
|
|
55
37
|
|
|
56
38
|
globalStyle('.zylem-window-control svg, .floating-panel-button svg', {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
filter: 'drop-shadow(0 1px 1px rgba(0,0,0,0.4))',
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
globalStyle('.zylem-window-control--close', {
|
|
64
|
-
borderColor: 'rgba(255, 198, 188, 0.88)',
|
|
65
|
-
background:
|
|
66
|
-
'linear-gradient(180deg, rgba(255, 196, 186, 0.78) 0%, rgba(228, 82, 70, 0.9) 44%, rgba(186, 46, 40, 0.96) 100%)',
|
|
67
|
-
boxShadow: `${jewelDepth}, 0 0 8px rgba(230, 69, 52, 0.34)`,
|
|
39
|
+
position: 'relative',
|
|
40
|
+
zIndex: 1,
|
|
41
|
+
display: 'block',
|
|
68
42
|
});
|
|
69
43
|
|
|
70
44
|
globalStyle('.zylem-window-control:hover, .floating-panel-button:hover', {
|
|
71
|
-
|
|
72
|
-
|
|
45
|
+
background: 'rgba(97, 166, 232, 0.12)',
|
|
46
|
+
boxShadow: vars.effects.glowPrimary,
|
|
47
|
+
color: vars.colors.primary,
|
|
48
|
+
transform: 'translateY(-1px)',
|
|
73
49
|
});
|
|
74
50
|
|
|
75
51
|
globalStyle('.zylem-window-control:active, .floating-panel-button:active', {
|
|
76
|
-
|
|
77
|
-
|
|
52
|
+
transform: 'translateY(1px)',
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
globalStyle('.zylem-window-control:focus-visible, .floating-panel-button:focus-visible', {
|
|
56
|
+
background: 'rgba(97, 166, 232, 0.12)',
|
|
57
|
+
boxShadow: `${vars.effects.glowPrimary}, ${vars.effects.focusRing}`,
|
|
78
58
|
});
|
|
79
59
|
|
|
80
|
-
globalStyle(
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
);
|
|
60
|
+
globalStyle('.zylem-window-control--close:hover', {
|
|
61
|
+
borderColor: 'rgba(255, 132, 114, 0.78)',
|
|
62
|
+
background: 'rgba(230, 69, 52, 0.16)',
|
|
63
|
+
color: '#ffb4a8',
|
|
64
|
+
boxShadow: vars.effects.glowDanger,
|
|
65
|
+
});
|
|
86
66
|
|
|
87
67
|
globalStyle('.zylem-window-control--close:focus-visible', {
|
|
88
|
-
|
|
68
|
+
borderColor: 'rgba(255, 132, 114, 0.78)',
|
|
69
|
+
background: 'rgba(230, 69, 52, 0.16)',
|
|
70
|
+
color: '#ffb4a8',
|
|
71
|
+
boxShadow: `${vars.effects.glowDanger}, ${vars.effects.focusRing}`,
|
|
89
72
|
});
|
|
@@ -17,13 +17,14 @@ export interface WindowControlsProps {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
* Shared
|
|
21
|
-
*
|
|
20
|
+
* Shared ghost window controls, used by floating and detached panels. Close
|
|
21
|
+
* takes the danger color only while hovered or focused. Only controls with a
|
|
22
|
+
* handler are rendered.
|
|
22
23
|
*/
|
|
23
24
|
export function WindowControls(props: WindowControlsProps) {
|
|
24
25
|
return (
|
|
25
26
|
<Show when={props.onClose || props.onCollapse}>
|
|
26
|
-
<div class="zylem-window-controls" aria-label="Window controls">
|
|
27
|
+
<div class="zylem-window-controls" role="group" aria-label="Window controls">
|
|
27
28
|
<Show when={props.onCollapse}>
|
|
28
29
|
<button
|
|
29
30
|
type="button"
|
|
@@ -33,9 +34,9 @@ export function WindowControls(props: WindowControlsProps) {
|
|
|
33
34
|
onClick={() => props.onCollapse?.()}
|
|
34
35
|
>
|
|
35
36
|
{props.collapsed ? (
|
|
36
|
-
<ChevronUp size={11} strokeWidth={2.5} />
|
|
37
|
+
<ChevronUp size={11} strokeWidth={2.5} aria-hidden="true" />
|
|
37
38
|
) : (
|
|
38
|
-
<ChevronDown size={11} strokeWidth={2.5} />
|
|
39
|
+
<ChevronDown size={11} strokeWidth={2.5} aria-hidden="true" />
|
|
39
40
|
)}
|
|
40
41
|
</button>
|
|
41
42
|
</Show>
|
|
@@ -48,7 +49,7 @@ export function WindowControls(props: WindowControlsProps) {
|
|
|
48
49
|
data-testid={props.closeTestId}
|
|
49
50
|
onClick={() => props.onClose?.()}
|
|
50
51
|
>
|
|
51
|
-
<X size={11} strokeWidth={2.5} />
|
|
52
|
+
<X size={11} strokeWidth={2.5} aria-hidden="true" />
|
|
52
53
|
</button>
|
|
53
54
|
</Show>
|
|
54
55
|
</div>
|
package/src/components/index.ts
CHANGED
|
@@ -24,6 +24,7 @@ export {
|
|
|
24
24
|
} from '../layers';
|
|
25
25
|
|
|
26
26
|
// Primitives
|
|
27
|
+
export { type HeadingLevel } from './shared/Heading';
|
|
27
28
|
export { Button, type ButtonProps, type ButtonVariant, type ButtonSize } from './Button/Button';
|
|
28
29
|
export { ToolbarButton, type ToolbarButtonProps } from './ToolbarButton/ToolbarButton';
|
|
29
30
|
export { TextField, type TextFieldProps } from './TextField/TextField';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { JSX } from 'solid-js';
|
|
2
|
+
import { Dynamic } from 'solid-js/web';
|
|
3
|
+
|
|
4
|
+
/** Outline level of a component's title: `2` renders an `<h2>`. */
|
|
5
|
+
export type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
6
|
+
|
|
7
|
+
/** The element name for a level, for primitives that take an `as` tag. */
|
|
8
|
+
export function headingTag(level: HeadingLevel) {
|
|
9
|
+
return `h${level}` as const;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface HeadingProps {
|
|
13
|
+
level: HeadingLevel;
|
|
14
|
+
id?: string | undefined;
|
|
15
|
+
class?: string | undefined;
|
|
16
|
+
title?: string | undefined;
|
|
17
|
+
children: JSX.Element;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* An `<h1>`…`<h6>` chosen at runtime, for titles whose place in the page
|
|
22
|
+
* outline is the host's call.
|
|
23
|
+
*/
|
|
24
|
+
export function Heading(props: HeadingProps) {
|
|
25
|
+
return (
|
|
26
|
+
<Dynamic component={headingTag(props.level)} id={props.id} class={props.class} title={props.title}>
|
|
27
|
+
{props.children}
|
|
28
|
+
</Dynamic>
|
|
29
|
+
);
|
|
30
|
+
}
|
package/src/fonts.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@import url('https://fonts.googleapis.com/css2?family=Exo+2:ital,wght@0,100..900;1,100..900&display=swap');
|
|
1
|
+
@import url('https://fonts.googleapis.com/css2?family=Exo+2:ital,wght@0,100..900;1,100..900&family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap');
|
|
@@ -14,11 +14,14 @@ globalStyle('.zylem-accordion', {
|
|
|
14
14
|
minHeight: 0,
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
+
// The header is a heading element; its UA margins would open gaps around the
|
|
18
|
+
// trigger, and differ by heading level.
|
|
17
19
|
globalStyle('.accordion-header', {
|
|
18
20
|
position: 'sticky',
|
|
19
21
|
top: 0,
|
|
20
22
|
zIndex: 1,
|
|
21
23
|
display: 'flex',
|
|
24
|
+
margin: 0,
|
|
22
25
|
});
|
|
23
26
|
|
|
24
27
|
globalStyle('.accordion-item', {
|
|
@@ -104,15 +107,16 @@ globalStyle('.zylem-accordion--stack .accordion-content', {
|
|
|
104
107
|
overflow: 'visible',
|
|
105
108
|
});
|
|
106
109
|
|
|
107
|
-
globalStyle('.accordion-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
+
globalStyle('.accordion-chevron', {
|
|
111
|
+
width: '16px',
|
|
112
|
+
height: '16px',
|
|
113
|
+
flexShrink: 0,
|
|
114
|
+
stroke: 'currentColor',
|
|
110
115
|
color: vars.colors.textSecondary,
|
|
111
|
-
fontSize: '10px',
|
|
112
116
|
transition: `transform ${vars.motion.normal} ${vars.motion.easeOut}`,
|
|
113
117
|
});
|
|
114
118
|
|
|
115
|
-
globalStyle('.accordion-trigger[data-expanded]
|
|
119
|
+
globalStyle('.accordion-trigger[data-expanded] .accordion-chevron', {
|
|
116
120
|
transform: 'rotate(180deg)',
|
|
117
121
|
color: '#F4FAFF',
|
|
118
122
|
});
|
package/src/global/common.css.ts
CHANGED
|
@@ -13,6 +13,19 @@ globalStyle('.overlay', {
|
|
|
13
13
|
pointerEvents: 'none',
|
|
14
14
|
});
|
|
15
15
|
|
|
16
|
+
// Text for assistive tech only: off screen, still in the accessibility tree.
|
|
17
|
+
globalStyle('.zylem-visually-hidden', {
|
|
18
|
+
position: 'absolute',
|
|
19
|
+
width: '1px',
|
|
20
|
+
height: '1px',
|
|
21
|
+
padding: 0,
|
|
22
|
+
margin: '-1px',
|
|
23
|
+
overflow: 'hidden',
|
|
24
|
+
clip: 'rect(0, 0, 0, 0)',
|
|
25
|
+
whiteSpace: 'nowrap',
|
|
26
|
+
border: 0,
|
|
27
|
+
});
|
|
28
|
+
|
|
16
29
|
// Default scrollbars: slim glass rail (use `.zylem-scroll` for the full
|
|
17
30
|
// 13px HyperGlass treatment defined in hyperglass-base.css.ts).
|
|
18
31
|
globalStyle('::-webkit-scrollbar', {
|
|
@@ -37,6 +37,15 @@ globalStyle('.zylem-exo-2', {
|
|
|
37
37
|
fontStyle: 'normal',
|
|
38
38
|
});
|
|
39
39
|
|
|
40
|
+
/** Time and units: clocks, beats, dimensions, levels. */
|
|
41
|
+
globalStyle('.zylem-mono', {
|
|
42
|
+
fontFamily: vars.typography.fontFamilyMono,
|
|
43
|
+
fontOpticalSizing: 'auto',
|
|
44
|
+
fontWeight: 400,
|
|
45
|
+
fontStyle: 'normal',
|
|
46
|
+
fontVariantNumeric: 'tabular-nums',
|
|
47
|
+
});
|
|
48
|
+
|
|
40
49
|
globalStyle('.scrollable-y', {
|
|
41
50
|
overflowY: 'scroll',
|
|
42
51
|
overflowX: 'hidden',
|
|
@@ -60,8 +60,8 @@ export interface LayerScopeProps {
|
|
|
60
60
|
* them can paint above anything outside; and the scope owns the portal container
|
|
61
61
|
* its descendants mount into, so overlays opened inside it stay inside it.
|
|
62
62
|
*
|
|
63
|
-
* A dialog
|
|
64
|
-
*
|
|
63
|
+
* A dialog puts its card in one, so a menu opened within the dialog mounts
|
|
64
|
+
* inside the `<dialog>`, floats over the card, and is not clipped by it.
|
|
65
65
|
*/
|
|
66
66
|
export function LayerScope(props: LayerScopeProps) {
|
|
67
67
|
const [container, setContainer] = createSignal<HTMLElement>();
|
package/src/sprinkles.css.ts
CHANGED
|
@@ -149,7 +149,10 @@ const visual = defineProperties({
|
|
|
149
149
|
bold: '2px',
|
|
150
150
|
},
|
|
151
151
|
borderStyle: ['solid', 'dashed', 'dotted', 'none'],
|
|
152
|
-
fontFamily: {
|
|
152
|
+
fontFamily: {
|
|
153
|
+
default: vars.typography.fontFamily,
|
|
154
|
+
mono: vars.typography.fontFamilyMono,
|
|
155
|
+
},
|
|
153
156
|
fontSize: { default: vars.typography.fontSize },
|
|
154
157
|
lineHeight: ['1', '1.2', '1.35', '1.45', '1.5'],
|
|
155
158
|
letterSpacing: {
|
package/src/theme.css.ts
CHANGED
|
@@ -53,8 +53,13 @@ const tokens = {
|
|
|
53
53
|
iconSm: '16px',
|
|
54
54
|
iconLg: '96px',
|
|
55
55
|
},
|
|
56
|
+
/**
|
|
57
|
+
* Exo 2 is the interface face. JetBrains Mono is for time and units
|
|
58
|
+
* (clocks, beats, dimensions, levels) so digits keep a stable width.
|
|
59
|
+
*/
|
|
56
60
|
typography: {
|
|
57
61
|
fontFamily: "'Exo 2', sans-serif",
|
|
62
|
+
fontFamilyMono: "'JetBrains Mono', ui-monospace, monospace",
|
|
58
63
|
fontSize: '14px',
|
|
59
64
|
},
|
|
60
65
|
borders: {
|
|
@@ -178,6 +183,7 @@ const varNames = {
|
|
|
178
183
|
},
|
|
179
184
|
typography: {
|
|
180
185
|
fontFamily: 'zylem-font-family',
|
|
186
|
+
fontFamilyMono: 'zylem-font-family-mono',
|
|
181
187
|
fontSize: 'zylem-font-size',
|
|
182
188
|
},
|
|
183
189
|
borders: {
|
package/dist/chunk-V47CGFWX.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)"},art:{checkerLight:"#4F5C72",checkerDark:"#3C4759",canvasBorder:"rgba(150, 210, 255, 0.5)"},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)"},art:{checkerLight:"var(--zylem-art-checker-light)",checkerDark:"var(--zylem-art-checker-dark)",canvasBorder:"var(--zylem-art-canvas-border)"},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};
|