@motion-proto/live-tokens 0.3.9 → 0.5.0
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/package.json +9 -8
- package/src/component-editor/BadgeEditor.svelte +24 -22
- package/src/component-editor/CalloutEditor.svelte +3 -3
- package/src/component-editor/CardEditor.svelte +25 -21
- package/src/component-editor/CollapsibleSectionEditor.svelte +27 -25
- package/src/component-editor/CornerBadgeEditor.svelte +37 -35
- package/src/component-editor/DialogEditor.svelte +26 -24
- package/src/component-editor/ImageEditor.svelte +11 -9
- package/src/component-editor/InlineEditActionsEditor.svelte +17 -15
- package/src/component-editor/NotificationEditor.svelte +32 -30
- package/src/component-editor/ProgressBarEditor.svelte +3 -3
- package/src/component-editor/RadioButtonEditor.svelte +31 -29
- package/src/component-editor/SectionDividerEditor.svelte +30 -28
- package/src/component-editor/SegmentedControlEditor.svelte +29 -25
- package/src/component-editor/StandardButtonsEditor.svelte +42 -38
- package/src/component-editor/TabBarEditor.svelte +20 -18
- package/src/component-editor/TableEditor.svelte +4 -4
- package/src/component-editor/TooltipEditor.svelte +11 -9
- package/src/component-editor/registry.ts +2 -2
- package/src/component-editor/scaffolding/AngleDial.svelte +20 -19
- package/src/component-editor/scaffolding/ComponentEditorBase.svelte +44 -20
- package/src/component-editor/scaffolding/ComponentFileManager.svelte +260 -37
- package/src/component-editor/scaffolding/ComponentFileMenu.svelte +41 -29
- package/src/component-editor/scaffolding/ComponentsTab.svelte +7 -3
- package/src/component-editor/scaffolding/CopyFromMenu.svelte +21 -12
- package/src/component-editor/scaffolding/DemoHeader.svelte +13 -4
- package/src/component-editor/scaffolding/DividerEditor.svelte +27 -14
- package/src/component-editor/scaffolding/FieldsetWrapper.svelte +10 -4
- package/src/component-editor/scaffolding/GradientCard.svelte +25 -20
- package/src/component-editor/scaffolding/LinkageChart.svelte +43 -34
- package/src/component-editor/scaffolding/LinkedBlock.svelte +24 -21
- package/src/component-editor/scaffolding/NonStylableConfig.svelte +6 -1
- package/src/component-editor/scaffolding/SaveAsDialog.svelte +39 -35
- package/src/component-editor/scaffolding/ShadowBackdrop.svelte +21 -9
- package/src/component-editor/scaffolding/ShadowBackdropControls.svelte +8 -3
- package/src/component-editor/scaffolding/StateBlock.svelte +30 -13
- package/src/component-editor/scaffolding/TokenLayout.svelte +46 -30
- package/src/component-editor/scaffolding/TypeEditor.svelte +52 -26
- package/src/component-editor/scaffolding/VariantGroup.svelte +81 -48
- package/src/component-editor/scaffolding/componentSectionType.ts +2 -2
- package/src/components/Badge.svelte +45 -26
- package/src/components/Button.svelte +44 -21
- package/src/components/Callout.svelte +17 -12
- package/src/components/Card.svelte +23 -11
- package/src/components/CollapsibleSection.svelte +56 -27
- package/src/components/CornerBadge.svelte +32 -18
- package/src/components/Dialog.svelte +55 -31
- package/src/components/Image.svelte +14 -5
- package/src/components/InlineEditActions.svelte +22 -10
- package/src/components/Notification.svelte +39 -19
- package/src/components/ProgressBar.svelte +27 -17
- package/src/components/RadioButton.svelte +27 -10
- package/src/components/SectionDivider.svelte +34 -26
- package/src/components/SegmentedControl.svelte +23 -9
- package/src/components/TabBar.svelte +23 -10
- package/src/components/Table.svelte +8 -3
- package/src/components/Tooltip.svelte +15 -5
- package/src/lib/ColumnsOverlay.svelte +3 -3
- package/src/lib/LiveEditorOverlay.svelte +57 -36
- package/src/pages/ComponentEditorPage.svelte +17 -13
- package/src/pages/EditorShell.svelte +24 -20
- package/src/styles/form-controls.css +2 -2
- package/src/styles/tokens.css +59 -81
- package/src/ui/BezierCurveEditor.svelte +59 -43
- package/src/ui/ColorEditPanel.svelte +71 -44
- package/src/ui/EditorViewSwitcher.svelte +9 -5
- package/src/ui/FontStackEditor.svelte +16 -15
- package/src/ui/GradientEditor.svelte +42 -33
- package/src/ui/GradientStopPicker.svelte +18 -29
- package/src/ui/PaletteEditor.svelte +238 -212
- package/src/ui/PresetFileManager.svelte +20 -18
- package/src/ui/ProjectFontsSection.svelte +30 -30
- package/src/ui/SurfacesTab.svelte +3 -3
- package/src/ui/TextTab.svelte +2 -2
- package/src/ui/ThemeFileManager.svelte +38 -35
- package/src/ui/Toggle.svelte +11 -9
- package/src/ui/UICopyPopover.svelte +19 -15
- package/src/ui/UIDialog.svelte +48 -30
- package/src/ui/UIFontFamilySelector.svelte +104 -78
- package/src/ui/UIFontSizeSelector.svelte +38 -20
- package/src/ui/UIFontWeightSelector.svelte +33 -13
- package/src/ui/UILineHeightSelector.svelte +33 -13
- package/src/ui/UILinkToggle.svelte +7 -6
- package/src/ui/UIOptionItem.svelte +21 -7
- package/src/ui/UIOptionList.svelte +9 -3
- package/src/ui/UIPaddingSelector.svelte +108 -82
- package/src/ui/UIPaletteSelector.svelte +186 -161
- package/src/ui/UIRadio.svelte +23 -8
- package/src/ui/UIRadioGroup.svelte +9 -8
- package/src/ui/UIRelinkConfirmPopover.svelte +26 -16
- package/src/ui/UITokenSelector.svelte +112 -68
- package/src/ui/UIVariantSelector.svelte +79 -57
- package/src/ui/VariablesTab.svelte +15 -15
- package/src/ui/palette/GradientStopEditor.svelte +45 -26
- package/src/ui/palette/OverridesPanel.svelte +85 -49
- package/src/ui/palette/PaletteBase.svelte +60 -32
- package/src/ui/palette/ScaleCurveEditor.svelte +25 -10
- package/src/ui/sections/ColumnsSection.svelte +13 -13
- package/src/ui/sections/GradientsSection.svelte +12 -9
- package/src/ui/sections/OverlaysSection.svelte +50 -47
- package/src/ui/sections/ShadowsSection.svelte +110 -104
- package/src/ui/sections/TokenScaleTable.svelte +38 -22
- package/src/ui/sections/tokenScales.ts +2 -2
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
interface Props {
|
|
3
|
+
text?: string;
|
|
4
|
+
position?: 'top' | 'bottom';
|
|
5
|
+
open?: boolean;
|
|
6
|
+
children?: import('svelte').Snippet;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
let {
|
|
10
|
+
text = '',
|
|
11
|
+
position = 'top',
|
|
12
|
+
open = false,
|
|
13
|
+
children
|
|
14
|
+
}: Props = $props();
|
|
5
15
|
</script>
|
|
6
16
|
|
|
7
17
|
<div class="tooltip-wrapper" class:open>
|
|
8
|
-
|
|
18
|
+
{@render children?.()}
|
|
9
19
|
{#if text}
|
|
10
20
|
<div class="tooltip" class:bottom={position === 'bottom'}>
|
|
11
21
|
{text}
|
|
@@ -20,7 +30,7 @@
|
|
|
20
30
|
--tooltip-text-font-family: var(--font-sans);
|
|
21
31
|
--tooltip-text-font-size: var(--font-size-sm);
|
|
22
32
|
--tooltip-text-font-weight: var(--font-weight-normal);
|
|
23
|
-
--tooltip-text-line-height: var(--line-height-
|
|
33
|
+
--tooltip-text-line-height: var(--line-height-md);
|
|
24
34
|
--tooltip-border: var(--border-neutral);
|
|
25
35
|
--tooltip-border-width: var(--border-width-0);
|
|
26
36
|
--tooltip-radius: var(--radius-md);
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
const isInIframe = typeof window !== 'undefined' && window.parent !== window;
|
|
7
7
|
const enabled = isDev && !isInIframe;
|
|
8
8
|
|
|
9
|
-
let count = 12;
|
|
10
|
-
let gutter = '';
|
|
11
|
-
let margin = '';
|
|
9
|
+
let count = $state(12);
|
|
10
|
+
let gutter = $state('');
|
|
11
|
+
let margin = $state('');
|
|
12
12
|
|
|
13
13
|
function readTokens() {
|
|
14
14
|
const cs = getComputedStyle(document.documentElement);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<script
|
|
1
|
+
<script module lang="ts">
|
|
2
2
|
// __PROJECT_ROOT__ is injected by the themeFileApi Vite plugin as a `define`.
|
|
3
3
|
// Consumers don't need to configure it themselves. We declare it locally so
|
|
4
4
|
// this component's type-check passes in consumer projects that haven't added
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
</script>
|
|
13
13
|
|
|
14
14
|
<script lang="ts">
|
|
15
|
+
import { run } from 'svelte/legacy';
|
|
16
|
+
|
|
15
17
|
import { onMount, onDestroy } from 'svelte';
|
|
16
18
|
import { fade } from 'svelte/transition';
|
|
17
19
|
import { cubicInOut } from 'svelte/easing';
|
|
@@ -23,12 +25,23 @@
|
|
|
23
25
|
import { postParentRoute } from './parentRouteStore';
|
|
24
26
|
import type { NavLink } from './navLinkTypes';
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
interface Props {
|
|
29
|
+
open?: boolean | undefined;
|
|
30
|
+
editorPath?: string;
|
|
31
|
+
navLinks?: NavLink[];
|
|
32
|
+
pageSources?: Record<string, string>;
|
|
33
|
+
hidePageSourceOn?: string[];
|
|
34
|
+
projectRoot?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let {
|
|
38
|
+
open = $bindable(undefined),
|
|
39
|
+
editorPath = '/editor',
|
|
40
|
+
navLinks = [],
|
|
41
|
+
pageSources = {},
|
|
42
|
+
hidePageSourceOn = [],
|
|
43
|
+
projectRoot = INJECTED_PROJECT_ROOT
|
|
44
|
+
}: Props = $props();
|
|
32
45
|
|
|
33
46
|
// Self-gate: only render in dev, and never inside an iframe (the /editor
|
|
34
47
|
// page embeds this same app in an iframe and would otherwise recursively
|
|
@@ -44,25 +57,33 @@
|
|
|
44
57
|
if (!consumerControlsOpen) {
|
|
45
58
|
open = enabled && quietGet(OPEN_KEY) === '1';
|
|
46
59
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
60
|
+
run(() => {
|
|
61
|
+
if (!consumerControlsOpen && typeof window !== 'undefined') {
|
|
62
|
+
quietSet(OPEN_KEY, open ? '1' : '0');
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
run(() => {
|
|
66
|
+
overlayOpen.set(!!open);
|
|
67
|
+
});
|
|
51
68
|
|
|
52
69
|
// Hide the overlay entirely when the user is already on the editor route
|
|
53
70
|
// (the editor page has its own chrome).
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
71
|
+
let onEditorPath = $derived($route === editorPath);
|
|
72
|
+
let sourceFile = $derived(pageSources[$route]);
|
|
73
|
+
let showSource = $derived(!!sourceFile && !!projectRoot && !hidePageSourceOn.includes($route));
|
|
57
74
|
|
|
58
75
|
// Mount the iframe the first time the editor is shown, then keep it mounted
|
|
59
76
|
// across hide/show cycles so editor state (unsaved slider values, scroll
|
|
60
77
|
// position, expanded sections) survives.
|
|
61
|
-
let hasBeenOpen: boolean = !!open;
|
|
62
|
-
|
|
78
|
+
let hasBeenOpen: boolean = $state(!!open);
|
|
79
|
+
run(() => {
|
|
80
|
+
if (open) hasBeenOpen = true;
|
|
81
|
+
});
|
|
63
82
|
|
|
64
|
-
let editorFrame: HTMLIFrameElement | undefined;
|
|
65
|
-
|
|
83
|
+
let editorFrame: HTMLIFrameElement | undefined = $state();
|
|
84
|
+
run(() => {
|
|
85
|
+
postParentRoute(editorFrame?.contentWindow, $route);
|
|
86
|
+
});
|
|
66
87
|
|
|
67
88
|
type Mode = 'docked' | 'floating';
|
|
68
89
|
|
|
@@ -109,9 +130,9 @@
|
|
|
109
130
|
}
|
|
110
131
|
|
|
111
132
|
const initial = loadState();
|
|
112
|
-
let mode: Mode = initial.mode;
|
|
113
|
-
let dockedWidth: number = Math.max(MIN_WIDTH, initial.dockedWidth);
|
|
114
|
-
let floating = { ...initial.floating };
|
|
133
|
+
let mode: Mode = $state(initial.mode);
|
|
134
|
+
let dockedWidth: number = $state(Math.max(MIN_WIDTH, initial.dockedWidth));
|
|
135
|
+
let floating = $state({ ...initial.floating });
|
|
115
136
|
|
|
116
137
|
// Approximate natural size of the collapsed pill (Editor title + columns toggle).
|
|
117
138
|
// A few pixels of overshoot is fine — the panel has overflow:hidden.
|
|
@@ -125,11 +146,11 @@
|
|
|
125
146
|
|
|
126
147
|
// Suppress CSS transitions during gestures and mode swaps so dragging doesn't
|
|
127
148
|
// re-animate every frame, and floating↔docked swaps snap cleanly.
|
|
128
|
-
let suppressTransition = false;
|
|
149
|
+
let suppressTransition = $state(false);
|
|
129
150
|
|
|
130
151
|
// Gesture state — a transparent scrim covers the iframe while any gesture is active
|
|
131
152
|
// so pointer events land on the panel, not on content inside the iframe.
|
|
132
|
-
let gesturing: 'drag' | 'resize-left' | 'resize-se' | null = null;
|
|
153
|
+
let gesturing: 'drag' | 'resize-left' | 'resize-se' | null = $state(null);
|
|
133
154
|
|
|
134
155
|
function startDrag(e: PointerEvent) {
|
|
135
156
|
if (!open || mode !== 'floating') return;
|
|
@@ -244,15 +265,15 @@
|
|
|
244
265
|
window.removeEventListener('lt-overlay-toggle', handleToggleRequest);
|
|
245
266
|
});
|
|
246
267
|
|
|
247
|
-
|
|
268
|
+
let panelStyle = $derived(!open
|
|
248
269
|
? `position: fixed; top: 12px; right: 12px; width: ${COLLAPSED_WIDTH}px; height: ${COLLAPSED_HEIGHT}px;`
|
|
249
270
|
: mode === 'docked'
|
|
250
271
|
? `position: fixed; top: 0; right: 0; width: ${dockedWidth}px; height: 100vh;`
|
|
251
|
-
: `position: fixed; top: ${floating.y}px; left: ${floating.x}px; width: ${floating.width}px; height: ${floating.height}px
|
|
272
|
+
: `position: fixed; top: ${floating.y}px; left: ${floating.x}px; width: ${floating.width}px; height: ${floating.height}px;`);
|
|
252
273
|
</script>
|
|
253
274
|
|
|
254
275
|
{#if enabled && !onEditorPath}
|
|
255
|
-
<!-- svelte-ignore
|
|
276
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
256
277
|
<div
|
|
257
278
|
class="lt-overlay"
|
|
258
279
|
style={panelStyle}
|
|
@@ -264,13 +285,13 @@
|
|
|
264
285
|
>
|
|
265
286
|
<div
|
|
266
287
|
class="header"
|
|
267
|
-
|
|
268
|
-
|
|
288
|
+
onpointerdown={startDrag}
|
|
289
|
+
ondblclick={handleHeaderDblClick}
|
|
269
290
|
title={open ? 'Double-click to hide' : 'Double-click to show'}
|
|
270
291
|
>
|
|
271
292
|
<button
|
|
272
293
|
class="hdr-btn text title"
|
|
273
|
-
|
|
294
|
+
onclick={toggleOpen}
|
|
274
295
|
title={open ? 'Hide Editor' : 'Show Editor'}
|
|
275
296
|
>
|
|
276
297
|
<i class="fas {open ? 'fa-chevron-right' : 'fa-chevron-left'}"></i>
|
|
@@ -280,7 +301,7 @@
|
|
|
280
301
|
<button
|
|
281
302
|
class="hdr-btn icon"
|
|
282
303
|
class:active={$columnsVisible}
|
|
283
|
-
|
|
304
|
+
onclick={toggleColumns}
|
|
284
305
|
title="{$columnsVisible ? 'Hide' : 'Show'} columns"
|
|
285
306
|
>
|
|
286
307
|
<i class="fas fa-grip-lines-vertical"></i>
|
|
@@ -290,7 +311,7 @@
|
|
|
290
311
|
<button
|
|
291
312
|
class="hdr-btn icon"
|
|
292
313
|
title={mode === 'docked' ? 'Float' : 'Dock to right'}
|
|
293
|
-
|
|
314
|
+
onclick={toggleMode}
|
|
294
315
|
transition:fade={BTN_FADE}
|
|
295
316
|
>
|
|
296
317
|
<i class={mode === 'docked' ? 'fas fa-up-right-from-square' : 'fas fa-thumbtack'}></i>
|
|
@@ -313,7 +334,7 @@
|
|
|
313
334
|
transition:fade={BTN_FADE}
|
|
314
335
|
>
|
|
315
336
|
<i class="fas fa-code"></i>
|
|
316
|
-
Show
|
|
337
|
+
Show page source
|
|
317
338
|
</a>
|
|
318
339
|
{/if}
|
|
319
340
|
|
|
@@ -329,7 +350,7 @@
|
|
|
329
350
|
class:active={$route === link.path}
|
|
330
351
|
aria-selected={$route === link.path}
|
|
331
352
|
disabled={link.disabled}
|
|
332
|
-
|
|
353
|
+
onclick={() => navigate(link.path)}
|
|
333
354
|
>
|
|
334
355
|
{#if link.icon}<i class="fas {link.icon}"></i>{/if}
|
|
335
356
|
<span>{link.label}</span>
|
|
@@ -347,7 +368,7 @@
|
|
|
347
368
|
title="Token editor"
|
|
348
369
|
class="editor-frame"
|
|
349
370
|
bind:this={editorFrame}
|
|
350
|
-
|
|
371
|
+
onload={() => postParentRoute(editorFrame?.contentWindow, $route)}
|
|
351
372
|
></iframe>
|
|
352
373
|
{#if gesturing}
|
|
353
374
|
<div class="gesture-scrim"></div>
|
|
@@ -355,9 +376,9 @@
|
|
|
355
376
|
</div>
|
|
356
377
|
|
|
357
378
|
{#if mode === 'docked'}
|
|
358
|
-
<div class="resize-left"
|
|
379
|
+
<div class="resize-left" onpointerdown={startDockedResize}></div>
|
|
359
380
|
{:else}
|
|
360
|
-
<div class="resize-se"
|
|
381
|
+
<div class="resize-se" onpointerdown={startFloatingResize}></div>
|
|
361
382
|
{/if}
|
|
362
383
|
{/if}
|
|
363
384
|
</div>
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { run } from 'svelte/legacy';
|
|
3
|
+
|
|
2
4
|
import { onMount, onDestroy } from 'svelte';
|
|
3
5
|
import ComponentsTab from '../component-editor/scaffolding/ComponentsTab.svelte';
|
|
4
6
|
import PresetFileManager from '../ui/PresetFileManager.svelte';
|
|
@@ -7,19 +9,19 @@
|
|
|
7
9
|
import { listComponents } from '../lib/componentConfigService';
|
|
8
10
|
import { selectedComponent } from '../lib/editorViewStore';
|
|
9
11
|
|
|
10
|
-
let drawerOpen = true;
|
|
12
|
+
let drawerOpen = $state(true);
|
|
11
13
|
|
|
12
14
|
// Demo page is statically imported from `./Demo.svelte` in App.svelte; the
|
|
13
15
|
// glob resolves to an empty object if the file has been deleted, in which
|
|
14
16
|
// case we hide the demo option from the page-switcher.
|
|
15
17
|
const demoExists = Object.keys(import.meta.glob('./Demo.svelte')).length > 0;
|
|
16
18
|
|
|
17
|
-
let pageMenuOpen = false;
|
|
18
|
-
let pageMenuRoot: HTMLElement;
|
|
19
|
+
let pageMenuOpen = $state(false);
|
|
20
|
+
let pageMenuRoot: HTMLElement | undefined = $state();
|
|
19
21
|
|
|
20
22
|
const HINT_DELAY_MS = 80;
|
|
21
|
-
let hintLabel: string | null = null;
|
|
22
|
-
let hintTop = 0;
|
|
23
|
+
let hintLabel: string | null = $state(null);
|
|
24
|
+
let hintTop = $state(0);
|
|
23
25
|
let hintTimer: ReturnType<typeof setTimeout> | null = null;
|
|
24
26
|
|
|
25
27
|
function showHint(label: string, target: HTMLElement) {
|
|
@@ -40,7 +42,9 @@
|
|
|
40
42
|
hintLabel = null;
|
|
41
43
|
}
|
|
42
44
|
|
|
43
|
-
|
|
45
|
+
run(() => {
|
|
46
|
+
if (drawerOpen) hideHint();
|
|
47
|
+
});
|
|
44
48
|
|
|
45
49
|
function selectComponent(id: string) {
|
|
46
50
|
selectedComponent.set(id);
|
|
@@ -101,7 +105,7 @@
|
|
|
101
105
|
class="rail-toggle"
|
|
102
106
|
aria-label={drawerOpen ? 'Collapse components menu' : 'Expand components menu'}
|
|
103
107
|
aria-expanded={drawerOpen}
|
|
104
|
-
|
|
108
|
+
onclick={() => (drawerOpen = !drawerOpen)}
|
|
105
109
|
>
|
|
106
110
|
<i class="fas {drawerOpen ? 'fa-arrow-left' : 'fa-arrow-right'}"></i>
|
|
107
111
|
</button>
|
|
@@ -112,19 +116,19 @@
|
|
|
112
116
|
aria-haspopup="menu"
|
|
113
117
|
aria-expanded={pageMenuOpen}
|
|
114
118
|
tabindex={drawerOpen ? 0 : -1}
|
|
115
|
-
|
|
119
|
+
onclick={() => drawerOpen && (pageMenuOpen = !pageMenuOpen)}
|
|
116
120
|
>
|
|
117
121
|
<span class="rail-label">Components</span>
|
|
118
122
|
<i class="fas fa-chevron-down rail-chevron" class:open={pageMenuOpen}></i>
|
|
119
123
|
</button>
|
|
120
124
|
{#if pageMenuOpen && drawerOpen}
|
|
121
125
|
<div class="page-menu" role="menu">
|
|
122
|
-
<button class="page-menu-item" role="menuitem"
|
|
126
|
+
<button class="page-menu-item" role="menuitem" onclick={() => selectPage('/')}>
|
|
123
127
|
<i class="fas fa-home"></i>
|
|
124
128
|
<span>Main site</span>
|
|
125
129
|
</button>
|
|
126
130
|
{#if demoExists}
|
|
127
|
-
<button class="page-menu-item" role="menuitem"
|
|
131
|
+
<button class="page-menu-item" role="menuitem" onclick={() => selectPage('/demo')}>
|
|
128
132
|
<i class="fas fa-box-open"></i>
|
|
129
133
|
<span>Demo page</span>
|
|
130
134
|
</button>
|
|
@@ -137,9 +141,9 @@
|
|
|
137
141
|
<button
|
|
138
142
|
class="nav-item"
|
|
139
143
|
class:active={$selectedComponent === item.id}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
144
|
+
onmouseenter={(e) => showHint(item.label, e.currentTarget)}
|
|
145
|
+
onmouseleave={hideHint}
|
|
146
|
+
onclick={() => selectComponent(item.id)}
|
|
143
147
|
>
|
|
144
148
|
<i class={item.icon}></i>
|
|
145
149
|
<span class="rail-label">{item.label}</span>
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { run } from 'svelte/legacy';
|
|
3
|
+
|
|
2
4
|
import { onMount, onDestroy } from 'svelte';
|
|
3
5
|
import { get } from 'svelte/store';
|
|
4
6
|
import VariablesTab from '../ui/VariablesTab.svelte';
|
|
@@ -28,18 +30,18 @@
|
|
|
28
30
|
|
|
29
31
|
const componentNavItems = componentRegistryEntries.map(({ id, label, icon }) => ({ id, label, icon }));
|
|
30
32
|
|
|
31
|
-
let selectedTokenSection: string | null = null;
|
|
32
|
-
let saveStatus: 'idle' | 'saving' | 'saved' | 'error' = 'idle';
|
|
33
|
+
let selectedTokenSection: string | null = $state(null);
|
|
34
|
+
let saveStatus: 'idle' | 'saving' | 'saved' | 'error' = $state('idle');
|
|
33
35
|
|
|
34
|
-
let shellEl: HTMLElement | null = null;
|
|
35
|
-
let shellWidth = 1024;
|
|
36
|
+
let shellEl: HTMLElement | null = $state(null);
|
|
37
|
+
let shellWidth = $state(1024);
|
|
36
38
|
const CONDENSE_BELOW = 520;
|
|
37
39
|
|
|
38
|
-
|
|
40
|
+
let condensed = $derived($sidebarCondensed === 'auto' ? shellWidth < CONDENSE_BELOW : $sidebarCondensed);
|
|
39
41
|
|
|
40
42
|
const HINT_DELAY_MS = 80;
|
|
41
|
-
let hintLabel: string | null = null;
|
|
42
|
-
let hintTop = 0;
|
|
43
|
+
let hintLabel: string | null = $state(null);
|
|
44
|
+
let hintTop = $state(0);
|
|
43
45
|
let hintTimer: ReturnType<typeof setTimeout> | null = null;
|
|
44
46
|
|
|
45
47
|
function showHint(label: string, target: HTMLElement) {
|
|
@@ -60,7 +62,9 @@
|
|
|
60
62
|
hintLabel = null;
|
|
61
63
|
}
|
|
62
64
|
|
|
63
|
-
|
|
65
|
+
run(() => {
|
|
66
|
+
if (!condensed) hideHint();
|
|
67
|
+
});
|
|
64
68
|
|
|
65
69
|
function scrollToSection(sectionId: string) {
|
|
66
70
|
selectedTokenSection = sectionId;
|
|
@@ -80,8 +84,8 @@
|
|
|
80
84
|
});
|
|
81
85
|
}
|
|
82
86
|
|
|
83
|
-
async function handleSave(
|
|
84
|
-
const { fileName, displayName } =
|
|
87
|
+
async function handleSave(detail: { fileName: string; displayName: string }) {
|
|
88
|
+
const { fileName, displayName } = detail;
|
|
85
89
|
saveStatus = 'saving';
|
|
86
90
|
try {
|
|
87
91
|
await persistTheme(get(editorState), fileName, displayName);
|
|
@@ -93,9 +97,9 @@
|
|
|
93
97
|
}
|
|
94
98
|
}
|
|
95
99
|
|
|
96
|
-
async function handleLoad(
|
|
100
|
+
async function handleLoad(detail: { fileName: string }) {
|
|
97
101
|
try {
|
|
98
|
-
await hydrateTheme(
|
|
102
|
+
await hydrateTheme(detail.fileName);
|
|
99
103
|
} catch {
|
|
100
104
|
// silent
|
|
101
105
|
}
|
|
@@ -132,7 +136,7 @@
|
|
|
132
136
|
class="rail-toggle"
|
|
133
137
|
aria-label={condensed ? 'Expand sidebar' : 'Collapse sidebar'}
|
|
134
138
|
aria-expanded={!condensed}
|
|
135
|
-
|
|
139
|
+
onclick={toggleCondensed}
|
|
136
140
|
>
|
|
137
141
|
<i class="fas {condensed ? 'fa-arrow-right' : 'fa-arrow-left'}"></i>
|
|
138
142
|
</button>
|
|
@@ -146,9 +150,9 @@
|
|
|
146
150
|
<button
|
|
147
151
|
class="nav-item"
|
|
148
152
|
class:active={selectedTokenSection === item.id}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
153
|
+
onmouseenter={(e) => showHint(item.label, e.currentTarget)}
|
|
154
|
+
onmouseleave={hideHint}
|
|
155
|
+
onclick={() => scrollToSection(item.id)}
|
|
152
156
|
>
|
|
153
157
|
<i class={item.icon}></i>
|
|
154
158
|
<span class="nav-label">{item.label}</span>
|
|
@@ -157,7 +161,7 @@
|
|
|
157
161
|
</div>
|
|
158
162
|
{#if !condensed}
|
|
159
163
|
<div class="sidebar-footer">
|
|
160
|
-
<ThemeFileManager {saveStatus}
|
|
164
|
+
<ThemeFileManager {saveStatus} onsave={handleSave} onload={handleLoad} />
|
|
161
165
|
</div>
|
|
162
166
|
{/if}
|
|
163
167
|
{:else}
|
|
@@ -166,9 +170,9 @@
|
|
|
166
170
|
<button
|
|
167
171
|
class="nav-item"
|
|
168
172
|
class:active={$selectedComponent === item.id}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
173
|
+
onmouseenter={(e) => showHint(item.label, e.currentTarget)}
|
|
174
|
+
onmouseleave={hideHint}
|
|
175
|
+
onclick={() => selectComponent(item.id)}
|
|
172
176
|
>
|
|
173
177
|
<i class={item.icon}></i>
|
|
174
178
|
<span class="nav-label">{item.label}</span>
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
font-family: var(--font-sans);
|
|
70
70
|
font-size: var(--font-size-md);
|
|
71
71
|
font-weight: var(--font-weight-light);
|
|
72
|
-
line-height: var(--line-height-
|
|
72
|
+
line-height: var(--line-height-md);
|
|
73
73
|
vertical-align: middle;
|
|
74
74
|
cursor: pointer;
|
|
75
75
|
transition: all var(--duration-150);
|
|
@@ -124,7 +124,7 @@
|
|
|
124
124
|
min-height: 2rem;
|
|
125
125
|
font-size: var(--font-size-md);
|
|
126
126
|
font-family: var(--font-sans);
|
|
127
|
-
line-height: var(--line-height-
|
|
127
|
+
line-height: var(--line-height-md);
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
/* Disabled options */
|