@motion-proto/live-tokens 0.3.7 → 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/README.md +1 -1
- package/package.json +11 -9
- 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 +73 -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
package/src/ui/UIDialog.svelte
CHANGED
|
@@ -1,58 +1,76 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
2
|
+
import { run, self } from 'svelte/legacy';
|
|
3
|
+
|
|
4
|
+
import { tick } from 'svelte';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
show?: boolean;
|
|
8
|
+
title?: string;
|
|
9
|
+
cancelLabel?: string;
|
|
10
|
+
showCancel?: boolean;
|
|
11
|
+
confirmLabel?: string;
|
|
12
|
+
confirmDisabled?: boolean;
|
|
13
|
+
width?: string;
|
|
14
|
+
children?: import('svelte').Snippet;
|
|
15
|
+
onconfirm?: () => void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
show = $bindable(false),
|
|
20
|
+
title = '',
|
|
21
|
+
cancelLabel = 'Cancel',
|
|
22
|
+
showCancel = true,
|
|
23
|
+
confirmLabel = '',
|
|
24
|
+
confirmDisabled = false,
|
|
25
|
+
width = '500px',
|
|
26
|
+
children,
|
|
27
|
+
onconfirm
|
|
28
|
+
}: Props = $props();
|
|
29
|
+
|
|
30
|
+
let closeButtonRef: HTMLButtonElement | undefined = $state();
|
|
31
|
+
let cancelButtonRef: HTMLButtonElement | undefined = $state();
|
|
32
|
+
let confirmButtonRef: HTMLButtonElement | undefined = $state();
|
|
33
|
+
|
|
34
|
+
run(() => {
|
|
35
|
+
if (show) {
|
|
36
|
+
tick().then(() => {
|
|
37
|
+
if (confirmLabel && confirmButtonRef) confirmButtonRef.focus();
|
|
38
|
+
else if (showCancel && cancelButtonRef) cancelButtonRef.focus();
|
|
39
|
+
else if (closeButtonRef) closeButtonRef.focus();
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
});
|
|
25
43
|
|
|
26
44
|
function handleClose() {
|
|
27
45
|
show = false;
|
|
28
46
|
}
|
|
29
47
|
|
|
30
48
|
function handleConfirm() {
|
|
31
|
-
|
|
49
|
+
onconfirm?.();
|
|
32
50
|
}
|
|
33
51
|
</script>
|
|
34
52
|
|
|
35
53
|
{#if show}
|
|
36
|
-
<!-- svelte-ignore
|
|
37
|
-
<div class="ui-dialog-backdrop"
|
|
54
|
+
<!-- svelte-ignore a11y_click_events_have_key_events, a11y_no_noninteractive_element_interactions, a11y_no_static_element_interactions -->
|
|
55
|
+
<div class="ui-dialog-backdrop" onclick={self(handleClose)}>
|
|
38
56
|
<div class="ui-dialog" style="width: {width}; max-width: {width};">
|
|
39
57
|
{#if title}
|
|
40
58
|
<div class="ui-dialog-header">
|
|
41
59
|
<h3 class="ui-dialog-title">{title}</h3>
|
|
42
|
-
<button bind:this={closeButtonRef} class="ui-dialog-close"
|
|
60
|
+
<button bind:this={closeButtonRef} class="ui-dialog-close" onclick={handleClose} aria-label="Close">
|
|
43
61
|
<i class="fas fa-times"></i>
|
|
44
62
|
</button>
|
|
45
63
|
</div>
|
|
46
64
|
{/if}
|
|
47
65
|
|
|
48
66
|
<div class="ui-dialog-body">
|
|
49
|
-
|
|
67
|
+
{@render children?.()}
|
|
50
68
|
</div>
|
|
51
69
|
|
|
52
70
|
{#if showCancel || confirmLabel}
|
|
53
71
|
<div class="ui-dialog-footer">
|
|
54
72
|
{#if showCancel}
|
|
55
|
-
<button bind:this={cancelButtonRef} class="ui-dialog-btn"
|
|
73
|
+
<button bind:this={cancelButtonRef} class="ui-dialog-btn" onclick={handleClose}>
|
|
56
74
|
{cancelLabel}
|
|
57
75
|
</button>
|
|
58
76
|
{/if}
|
|
@@ -60,7 +78,7 @@
|
|
|
60
78
|
<button
|
|
61
79
|
bind:this={confirmButtonRef}
|
|
62
80
|
class="ui-dialog-btn primary"
|
|
63
|
-
|
|
81
|
+
onclick={handleConfirm}
|
|
64
82
|
disabled={confirmDisabled}
|
|
65
83
|
>
|
|
66
84
|
{confirmLabel}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import { run } from 'svelte/legacy';
|
|
3
|
+
|
|
4
|
+
import { onMount, onDestroy } from 'svelte';
|
|
3
5
|
import { resolveAliasChain } from '../lib/tokenRegistry';
|
|
4
6
|
import { editorState } from '../lib/editorStore';
|
|
5
7
|
import { CSS_VAR_CHANGE_EVENT } from '../lib/cssVarSync';
|
|
@@ -8,13 +10,23 @@
|
|
|
8
10
|
import UIOptionList from './UIOptionList.svelte';
|
|
9
11
|
import UIOptionItem from './UIOptionItem.svelte';
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
interface Props {
|
|
14
|
+
variable: string;
|
|
15
|
+
component?: string | undefined;
|
|
16
|
+
canBeLinked?: boolean;
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
selectionsLocked?: boolean;
|
|
19
|
+
onchange?: () => void;
|
|
20
|
+
}
|
|
12
21
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
22
|
+
let {
|
|
23
|
+
variable,
|
|
24
|
+
component = undefined,
|
|
25
|
+
canBeLinked = false,
|
|
26
|
+
disabled = false,
|
|
27
|
+
selectionsLocked = false,
|
|
28
|
+
onchange,
|
|
29
|
+
}: Props = $props();
|
|
18
30
|
|
|
19
31
|
const options = [
|
|
20
32
|
{ key: 'display', label: 'Display' },
|
|
@@ -23,15 +35,15 @@
|
|
|
23
35
|
{ key: 'mono', label: 'Mono' },
|
|
24
36
|
];
|
|
25
37
|
|
|
26
|
-
let selector: UITokenSelector;
|
|
27
|
-
let chosenKey: string | null = null;
|
|
28
|
-
let chosenFamilyId: string | null = null;
|
|
29
|
-
let currentStack: string = '';
|
|
30
|
-
let familyNameByKey: Record<string, string> = {};
|
|
38
|
+
let selector: UITokenSelector | undefined = $state();
|
|
39
|
+
let chosenKey: string | null = $state(null);
|
|
40
|
+
let chosenFamilyId: string | null = $state(null);
|
|
41
|
+
let currentStack: string = $state('');
|
|
42
|
+
let familyNameByKey: Record<string, string> = $state({});
|
|
31
43
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
44
|
+
let fontSources = $derived($editorState.fonts.sources);
|
|
45
|
+
let allFamilies = $derived((fontSources as FontSource[]).flatMap((s) => s.families));
|
|
46
|
+
let hasProjectFonts = $derived(allFamilies.length > 0);
|
|
35
47
|
|
|
36
48
|
function parseRef(value: string): string | null {
|
|
37
49
|
const m = value.match(/var\((--font-[a-z]+)\)/);
|
|
@@ -111,41 +123,43 @@
|
|
|
111
123
|
chosenKey = null;
|
|
112
124
|
chosenFamilyId = null;
|
|
113
125
|
readResolved();
|
|
114
|
-
|
|
126
|
+
onchange?.();
|
|
115
127
|
}
|
|
116
128
|
|
|
117
129
|
function selectOption(key: string, close: () => void) {
|
|
118
130
|
const target = `--font-${key}`;
|
|
119
131
|
if (target === variable) {
|
|
120
|
-
selector
|
|
132
|
+
selector?.writeOverride(null);
|
|
121
133
|
chosenKey = null;
|
|
122
134
|
} else {
|
|
123
|
-
selector
|
|
135
|
+
selector?.writeOverride(target);
|
|
124
136
|
chosenKey = key;
|
|
125
137
|
}
|
|
126
138
|
chosenFamilyId = null;
|
|
127
139
|
readResolved();
|
|
128
140
|
close();
|
|
129
|
-
|
|
141
|
+
onchange?.();
|
|
130
142
|
}
|
|
131
143
|
|
|
132
144
|
function selectProjectFamily(family: FontFamily, close: () => void) {
|
|
133
145
|
const stack = `'${family.cssName}', ${genericFor(variable)}`;
|
|
134
|
-
selector
|
|
146
|
+
selector?.writeOverride(stack);
|
|
135
147
|
chosenKey = null;
|
|
136
148
|
chosenFamilyId = family.id;
|
|
137
149
|
readResolved();
|
|
138
150
|
close();
|
|
139
|
-
|
|
151
|
+
onchange?.();
|
|
140
152
|
}
|
|
141
153
|
|
|
142
154
|
// Re-derive `chosenKey` / `chosenFamilyId` when `variable` changes (the
|
|
143
155
|
// VariantGroup tabs view reuses the same selector instance across states).
|
|
144
|
-
let lastSeenVariable: string | null = null;
|
|
145
|
-
|
|
146
|
-
lastSeenVariable
|
|
147
|
-
|
|
148
|
-
|
|
156
|
+
let lastSeenVariable: string | null = $state(null);
|
|
157
|
+
run(() => {
|
|
158
|
+
if (variable !== lastSeenVariable) {
|
|
159
|
+
lastSeenVariable = variable;
|
|
160
|
+
initFromCurrent();
|
|
161
|
+
}
|
|
162
|
+
});
|
|
149
163
|
|
|
150
164
|
onMount(() => {
|
|
151
165
|
document.addEventListener(CSS_VAR_CHANGE_EVENT, handleVarChange);
|
|
@@ -154,10 +168,10 @@
|
|
|
154
168
|
document.removeEventListener(CSS_VAR_CHANGE_EVENT, handleVarChange);
|
|
155
169
|
});
|
|
156
170
|
|
|
157
|
-
|
|
171
|
+
let activeLabel = $derived(chosenFamilyId
|
|
158
172
|
? (allFamilies.find((f) => f.id === chosenFamilyId)?.name ?? 'Project font')
|
|
159
|
-
: (options.find((o) => o.key === chosenKey)?.label ?? '');
|
|
160
|
-
|
|
173
|
+
: (options.find((o) => o.key === chosenKey)?.label ?? ''));
|
|
174
|
+
let displayFamily = $derived(firstFamilyName(currentStack));
|
|
161
175
|
</script>
|
|
162
176
|
|
|
163
177
|
<UITokenSelector
|
|
@@ -168,57 +182,69 @@
|
|
|
168
182
|
{disabled}
|
|
169
183
|
{selectionsLocked}
|
|
170
184
|
dropdownMinWidth="14rem"
|
|
171
|
-
|
|
172
|
-
|
|
185
|
+
onreset={handleReset}
|
|
186
|
+
onvarChange={initFromCurrent}
|
|
173
187
|
>
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
<div class="pfs-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
188
|
+
{#snippet triggerTitle()}{activeLabel}{/snippet}
|
|
189
|
+
{#snippet triggerMeta()}{displayFamily || '—'}{/snippet}
|
|
190
|
+
|
|
191
|
+
{#snippet children({ close })}
|
|
192
|
+
|
|
193
|
+
<UIOptionList>
|
|
194
|
+
{#each options as opt}
|
|
195
|
+
<UIOptionItem
|
|
196
|
+
active={chosenKey === opt.key}
|
|
197
|
+
onclick={() => selectOption(opt.key, close)}
|
|
198
|
+
>
|
|
199
|
+
{#snippet preview()}
|
|
200
|
+
<span class="font-sample" style="font-family: var(--font-{opt.key});">Aa</span>
|
|
201
|
+
{/snippet}
|
|
202
|
+
{#snippet label()}
|
|
203
|
+
{opt.label}
|
|
204
|
+
{/snippet}
|
|
205
|
+
{#snippet meta()}
|
|
206
|
+
{familyNameByKey[opt.key] ?? ''}
|
|
207
|
+
{/snippet}
|
|
208
|
+
</UIOptionItem>
|
|
209
|
+
{/each}
|
|
210
|
+
|
|
211
|
+
{#if hasProjectFonts}
|
|
212
|
+
<div class="pfs-divider" role="separator"></div>
|
|
213
|
+
<div class="pfs-section">
|
|
214
|
+
<div class="pfs-trigger" class:active={chosenFamilyId !== null}>
|
|
215
|
+
<span class="pfs-label">Project Fonts</span>
|
|
216
|
+
<span class="pfs-count">{allFamilies.length}</span>
|
|
217
|
+
<i class="fas fa-chevron-right pfs-chevron" aria-hidden="true"></i>
|
|
218
|
+
</div>
|
|
219
|
+
<div class="pfs-submenu">
|
|
220
|
+
{#each fontSources as source (source.id)}
|
|
221
|
+
{#if source.families.length > 0}
|
|
222
|
+
<div class="pfs-source-label">{source.label ?? source.kind}</div>
|
|
223
|
+
{#each source.families as fam (fam.id)}
|
|
224
|
+
<UIOptionItem
|
|
225
|
+
active={chosenFamilyId === fam.id}
|
|
226
|
+
onclick={() => selectProjectFamily(fam, close)}
|
|
227
|
+
>
|
|
228
|
+
{#snippet preview()}
|
|
229
|
+
<span
|
|
230
|
+
|
|
231
|
+
class="font-sample"
|
|
232
|
+
style="font-family: '{fam.cssName}', {genericFor(variable)};"
|
|
233
|
+
>Aa</span>
|
|
234
|
+
{/snippet}
|
|
235
|
+
{#snippet label()}
|
|
236
|
+
{fam.name}
|
|
237
|
+
{/snippet}
|
|
238
|
+
</UIOptionItem>
|
|
239
|
+
{/each}
|
|
240
|
+
{/if}
|
|
241
|
+
{/each}
|
|
242
|
+
</div>
|
|
217
243
|
</div>
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
244
|
+
{/if}
|
|
245
|
+
</UIOptionList>
|
|
246
|
+
|
|
247
|
+
{/snippet}
|
|
222
248
|
</UITokenSelector>
|
|
223
249
|
|
|
224
250
|
<style>
|
|
@@ -1,17 +1,31 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { run } from 'svelte/legacy';
|
|
3
|
+
|
|
2
4
|
import { onMount, onDestroy } from 'svelte';
|
|
3
5
|
import { CSS_VAR_CHANGE_EVENT } from '../lib/cssVarSync';
|
|
4
6
|
import UIVariantSelector from './UIVariantSelector.svelte';
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
interface Props {
|
|
9
|
+
variable: string;
|
|
10
|
+
component?: string | undefined;
|
|
11
|
+
canBeLinked?: boolean;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
selectionsLocked?: boolean;
|
|
14
|
+
onchange?: () => void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let {
|
|
18
|
+
variable,
|
|
19
|
+
component = undefined,
|
|
20
|
+
canBeLinked = false,
|
|
21
|
+
disabled = false,
|
|
22
|
+
selectionsLocked = false,
|
|
23
|
+
onchange,
|
|
24
|
+
}: Props = $props();
|
|
11
25
|
|
|
12
26
|
// Icon-size variables (e.g. --tabbar-default-icon-size) pick from the
|
|
13
27
|
// --icon-size-* scale; everything else from --font-size-*.
|
|
14
|
-
|
|
28
|
+
let scalePrefix = $derived(variable.endsWith('-icon-size') ? '--icon-size-' : '--font-size-');
|
|
15
29
|
|
|
16
30
|
const options = [
|
|
17
31
|
{ key: 'xs', label: 'XS' },
|
|
@@ -26,8 +40,8 @@
|
|
|
26
40
|
{ key: '6xl', label: '6XL' },
|
|
27
41
|
] as const;
|
|
28
42
|
|
|
29
|
-
let pxByKey: Record<string, string> = {};
|
|
30
|
-
let remByKey: Record<string, string> = {};
|
|
43
|
+
let pxByKey: Record<string, string> = $state({});
|
|
44
|
+
let remByKey: Record<string, string> = $state({});
|
|
31
45
|
|
|
32
46
|
function formatRem(value: number): string {
|
|
33
47
|
const rounded = Math.round(value * 1000) / 1000;
|
|
@@ -66,7 +80,9 @@
|
|
|
66
80
|
|
|
67
81
|
// Re-read sizes when the target variable's scale changes
|
|
68
82
|
// (mounting one selector, then opening another whose variable resolves to a different scale).
|
|
69
|
-
|
|
83
|
+
run(() => {
|
|
84
|
+
if (typeof document !== 'undefined' && scalePrefix) readPxValues();
|
|
85
|
+
});
|
|
70
86
|
|
|
71
87
|
onMount(() => {
|
|
72
88
|
readPxValues();
|
|
@@ -86,18 +102,20 @@
|
|
|
86
102
|
varPrefix={scalePrefix}
|
|
87
103
|
{options}
|
|
88
104
|
dropdownGridColumns="auto auto auto auto"
|
|
89
|
-
|
|
105
|
+
{onchange}
|
|
90
106
|
>
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
<
|
|
94
|
-
<span class="size-sample
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
107
|
+
{#snippet option({ opt, active, select })}
|
|
108
|
+
|
|
109
|
+
<button class="font-size-row" class:active onclick={select}>
|
|
110
|
+
<span class="size-sample-cell">
|
|
111
|
+
<span class="size-sample" style="font-size: calc(var({scalePrefix}{opt.key}) * 1.5);">A</span>
|
|
112
|
+
</span>
|
|
113
|
+
<span class="size-label">{opt.label}</span>
|
|
114
|
+
<code class="size-measure">{pxByKey[opt.key] ?? ''}</code>
|
|
115
|
+
<code class="size-measure">{remByKey[opt.key] ?? ''}</code>
|
|
116
|
+
</button>
|
|
117
|
+
|
|
118
|
+
{/snippet}
|
|
101
119
|
</UIVariantSelector>
|
|
102
120
|
|
|
103
121
|
<style>
|
|
@@ -2,11 +2,23 @@
|
|
|
2
2
|
import UIVariantSelector from './UIVariantSelector.svelte';
|
|
3
3
|
import UIOptionItem from './UIOptionItem.svelte';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
interface Props {
|
|
6
|
+
variable: string;
|
|
7
|
+
component?: string | undefined;
|
|
8
|
+
canBeLinked?: boolean;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
selectionsLocked?: boolean;
|
|
11
|
+
onchange?: () => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let {
|
|
15
|
+
variable,
|
|
16
|
+
component = undefined,
|
|
17
|
+
canBeLinked = false,
|
|
18
|
+
disabled = false,
|
|
19
|
+
selectionsLocked = false,
|
|
20
|
+
onchange,
|
|
21
|
+
}: Props = $props();
|
|
10
22
|
|
|
11
23
|
const options = [
|
|
12
24
|
{ key: 'thin', label: 'Thin', value: '100' },
|
|
@@ -29,15 +41,23 @@
|
|
|
29
41
|
{selectionsLocked}
|
|
30
42
|
varPrefix="--font-weight-"
|
|
31
43
|
{options}
|
|
32
|
-
|
|
44
|
+
{onchange}
|
|
33
45
|
>
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
<
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
46
|
+
{#snippet option({ opt, active, select })}
|
|
47
|
+
|
|
48
|
+
<UIOptionItem {active} onclick={select}>
|
|
49
|
+
{#snippet preview()}
|
|
50
|
+
<span class="weight-sample" style="font-weight: var(--font-weight-{opt.key});">A</span>
|
|
51
|
+
{/snippet}
|
|
52
|
+
{#snippet label()}
|
|
53
|
+
{opt.label}
|
|
54
|
+
{/snippet}
|
|
55
|
+
{#snippet meta()}
|
|
56
|
+
{opt.value}
|
|
57
|
+
{/snippet}
|
|
58
|
+
</UIOptionItem>
|
|
59
|
+
|
|
60
|
+
{/snippet}
|
|
41
61
|
</UIVariantSelector>
|
|
42
62
|
|
|
43
63
|
<style>
|
|
@@ -2,11 +2,23 @@
|
|
|
2
2
|
import UIVariantSelector from './UIVariantSelector.svelte';
|
|
3
3
|
import UIOptionItem from './UIOptionItem.svelte';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
interface Props {
|
|
6
|
+
variable: string;
|
|
7
|
+
component?: string | undefined;
|
|
8
|
+
canBeLinked?: boolean;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
selectionsLocked?: boolean;
|
|
11
|
+
onchange?: () => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let {
|
|
15
|
+
variable,
|
|
16
|
+
component = undefined,
|
|
17
|
+
canBeLinked = false,
|
|
18
|
+
disabled = false,
|
|
19
|
+
selectionsLocked = false,
|
|
20
|
+
onchange,
|
|
21
|
+
}: Props = $props();
|
|
10
22
|
|
|
11
23
|
const options = [
|
|
12
24
|
{ key: 'tight', label: 'Tight', value: '1' },
|
|
@@ -25,15 +37,23 @@
|
|
|
25
37
|
{selectionsLocked}
|
|
26
38
|
varPrefix="--line-height-"
|
|
27
39
|
{options}
|
|
28
|
-
|
|
40
|
+
{onchange}
|
|
29
41
|
>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
42
|
+
{#snippet option({ opt, active, select })}
|
|
43
|
+
|
|
44
|
+
<UIOptionItem {active} onclick={select}>
|
|
45
|
+
{#snippet preview()}
|
|
46
|
+
<span class="lh-sample" style="line-height: var(--line-height-{opt.key});">≡</span>
|
|
47
|
+
{/snippet}
|
|
48
|
+
{#snippet label()}
|
|
49
|
+
{opt.label}
|
|
50
|
+
{/snippet}
|
|
51
|
+
{#snippet meta()}
|
|
52
|
+
{opt.value}
|
|
53
|
+
{/snippet}
|
|
54
|
+
</UIOptionItem>
|
|
55
|
+
|
|
56
|
+
{/snippet}
|
|
37
57
|
</UIVariantSelector>
|
|
38
58
|
|
|
39
59
|
<style>
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
interface Props {
|
|
3
|
+
linked?: boolean;
|
|
4
|
+
ontoggle?: () => void;
|
|
5
|
+
}
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
let { linked = false, ontoggle }: Props = $props();
|
|
7
8
|
|
|
8
9
|
function handleClick(e: Event) {
|
|
9
10
|
e.stopPropagation();
|
|
10
|
-
|
|
11
|
+
ontoggle?.();
|
|
11
12
|
}
|
|
12
13
|
</script>
|
|
13
14
|
|
|
@@ -16,7 +17,7 @@
|
|
|
16
17
|
class="ui-link-toggle"
|
|
17
18
|
class:linked
|
|
18
19
|
title={linked ? 'Locked across variants — click to unlink' : 'Click to link across all variants'}
|
|
19
|
-
|
|
20
|
+
onclick={handleClick}
|
|
20
21
|
>
|
|
21
22
|
<i class="fas" class:fa-lock={linked} class:fa-lock-open={!linked} aria-hidden="true"></i>
|
|
22
23
|
<span>{linked ? 'Unlink' : 'Link'}</span>
|
|
@@ -1,19 +1,33 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
|
|
2
|
+
interface Props {
|
|
3
|
+
active?: boolean;
|
|
4
|
+
preview?: import('svelte').Snippet;
|
|
5
|
+
label?: import('svelte').Snippet;
|
|
6
|
+
meta?: import('svelte').Snippet;
|
|
7
|
+
onclick?: (event: MouseEvent) => void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let {
|
|
11
|
+
active = false,
|
|
12
|
+
preview,
|
|
13
|
+
label,
|
|
14
|
+
meta,
|
|
15
|
+
onclick
|
|
16
|
+
}: Props = $props();
|
|
3
17
|
</script>
|
|
4
18
|
|
|
5
|
-
<button class="ui-option-item" class:active
|
|
6
|
-
{#if
|
|
19
|
+
<button class="ui-option-item" class:active {onclick}>
|
|
20
|
+
{#if preview}
|
|
7
21
|
<span class="ui-option-preview">
|
|
8
|
-
|
|
22
|
+
{@render preview?.()}
|
|
9
23
|
</span>
|
|
10
24
|
{/if}
|
|
11
25
|
<span class="ui-option-label">
|
|
12
|
-
|
|
26
|
+
{@render label?.()}
|
|
13
27
|
</span>
|
|
14
|
-
{#if
|
|
28
|
+
{#if meta}
|
|
15
29
|
<code class="ui-option-meta">
|
|
16
|
-
|
|
30
|
+
{@render meta?.()}
|
|
17
31
|
</code>
|
|
18
32
|
{/if}
|
|
19
33
|
</button>
|