@motion-proto/live-tokens 0.96.0 → 0.98.2
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/.claude/skills/live-tokens-check-compliance/SKILL.md +5 -0
- package/.claude/skills/live-tokens-create-component/SKILL.md +4 -3
- package/.claude/skills/live-tokens-create-component/references/contract-tests.md +71 -11
- package/CHANGELOG.md +309 -0
- package/README.md +2 -2
- package/bin/check-component.mjs +8 -0
- package/bin/check-page.mjs +6 -0
- package/bin/cli.mjs +36 -6
- package/bin/contractRunner.mjs +142 -17
- package/bin/lib/findings.mjs +20 -4
- package/bin/rules/a11y.mjs +53 -0
- package/bin/set-colors.mjs +1 -0
- package/bin/setup-claude.mjs +2 -2
- package/dist-plugin/{chunk-A4TBP4MM.js → chunk-SLICH4IH.js} +2 -2
- package/dist-plugin/index.cjs +148 -3
- package/dist-plugin/index.js +250 -105
- package/dist-plugin/setColors/index.cjs +7 -1
- package/dist-plugin/setColors/index.d.cts +9 -4
- package/dist-plugin/setColors/index.d.ts +9 -4
- package/dist-plugin/setColors/index.js +8 -2
- package/dist-plugin/setGeometry/index.d.cts +1 -1
- package/dist-plugin/setGeometry/index.d.ts +1 -1
- package/dist-plugin/setType/index.d.cts +1 -1
- package/dist-plugin/setType/index.d.ts +1 -1
- package/dist-plugin/{themeTypes-B8_Idrp4.d.cts → themeTypes-BaTQUyac.d.cts} +10 -1
- package/dist-plugin/{themeTypes-B8_Idrp4.d.ts → themeTypes-BaTQUyac.d.ts} +10 -1
- package/package.json +49 -2
- package/src/demo/LabeledSelect.svelte +1 -1
- package/src/editor/bootstrap.ts +3 -1
- package/src/editor/component-editor/BadgeEditor.svelte +13 -0
- package/src/editor/component-editor/ButtonEditor.svelte +33 -2
- package/src/editor/component-editor/CalloutEditor.svelte +13 -0
- package/src/editor/component-editor/CardEditor.svelte +12 -2
- package/src/editor/component-editor/CodeSnippetEditor.svelte +11 -1
- package/src/editor/component-editor/CollapsibleSectionEditor.svelte +18 -1
- package/src/editor/component-editor/CornerBadgeEditor.svelte +13 -0
- package/src/editor/component-editor/DialogEditor.svelte +15 -0
- package/src/editor/component-editor/IconButtonEditor.svelte +29 -1
- package/src/editor/component-editor/ImageEditor.svelte +20 -9
- package/src/editor/component-editor/ImageLightboxEditor.svelte +44 -0
- package/src/editor/component-editor/InlineEditActionsEditor.svelte +13 -1
- package/src/editor/component-editor/InputEditor.svelte +23 -0
- package/src/editor/component-editor/MenuSelectEditor.svelte +27 -1
- package/src/editor/component-editor/NotificationEditor.svelte +15 -0
- package/src/editor/component-editor/PanelEditor.svelte +1 -1
- package/src/editor/component-editor/ProgressBarEditor.svelte +13 -0
- package/src/editor/component-editor/RadioButtonEditor.svelte +20 -1
- package/src/editor/component-editor/SectionDividerEditor.svelte +41 -13
- package/src/editor/component-editor/SegmentedControlEditor.svelte +29 -1
- package/src/editor/component-editor/SideNavigationEditor.svelte +40 -1
- package/src/editor/component-editor/SlidePagerEditor.svelte +20 -0
- package/src/editor/component-editor/SliderEditor.svelte +33 -0
- package/src/editor/component-editor/TabBarEditor.svelte +23 -2
- package/src/editor/component-editor/TableEditor.svelte +14 -0
- package/src/editor/component-editor/ToggleEditor.svelte +17 -0
- package/src/editor/component-editor/TooltipEditor.svelte +11 -2
- package/src/editor/component-editor/VideoFrameEditor.svelte +8 -0
- package/src/editor/component-editor/VideoLightboxEditor.svelte +10 -0
- package/src/editor/component-editor/registration.ts +2 -1
- package/src/editor/component-editor/registry.ts +69 -27
- package/src/editor/component-editor/scaffolding/DemoHeader.svelte +2 -0
- package/src/editor/component-editor/scaffolding/StateBlock.svelte +19 -8
- package/src/editor/component-editor/scaffolding/TokenLayout.svelte +3 -0
- package/src/editor/component-editor/scaffolding/VariantGroup.svelte +70 -10
- package/src/editor/component-editor/scaffolding/editorContext.ts +7 -0
- package/src/editor/core/a11y/a11yReport.ts +101 -0
- package/src/editor/core/a11y/a11yReportTypes.ts +69 -0
- package/src/editor/core/a11y/contrastFailures.ts +22 -0
- package/src/editor/core/components/contrastPairRegistry.ts +18 -0
- package/src/editor/core/palettes/contrast.ts +44 -0
- package/src/editor/core/palettes/contrastPairs.ts +79 -0
- package/src/editor/core/palettes/resolveColor.ts +77 -0
- package/src/editor/core/store/editorPersistence.ts +9 -1
- package/src/editor/core/store/editorRenderer.ts +2 -0
- package/src/editor/core/store/editorStore.ts +29 -0
- package/src/editor/core/store/editorTypes.ts +9 -0
- package/src/editor/core/store/editorViewStore.ts +2 -2
- package/src/editor/core/store/unsavedEdits.ts +10 -0
- package/src/editor/core/themes/buildColors.ts +16 -5
- package/src/editor/core/themes/liveStateStream.ts +7 -1
- package/src/editor/core/themes/parsers/gradient.ts +5 -2
- package/src/editor/core/themes/slices/customColors.ts +226 -0
- package/src/editor/core/themes/themeTypes.ts +10 -0
- package/src/editor/docs/chapters.ts +1 -0
- package/src/editor/docs/content/accessibility.md +362 -0
- package/src/editor/docs/content/editing-tokens.md +56 -1
- package/src/editor/docs/content.generated.ts +2 -1
- package/src/editor/pages/ComponentEditorPage.svelte +10 -1
- package/src/editor/pages/EditorShell.svelte +97 -10
- package/src/editor/skill-atlas/skillSources.generated.ts +3 -3
- package/src/editor/skill-atlas/trees/check-compliance.ts +3 -3
- package/src/editor/skill-atlas/trees/create-component.ts +12 -12
- package/src/editor/ui/CustomColorReplaceStep.svelte +118 -0
- package/src/editor/ui/EditorViewSwitcher.svelte +15 -2
- package/src/editor/ui/GradientEditor.svelte +9 -1
- package/src/editor/ui/ThemePanel.svelte +4 -4
- package/src/editor/ui/UIContrastReadout.svelte +186 -0
- package/src/editor/ui/UIInfoPopover.svelte +16 -2
- package/src/editor/ui/UIPaletteSelector.svelte +347 -15
- package/src/editor/ui/UITokenSelector.svelte +33 -14
- package/src/editor/ui/VariablesTab.svelte +3 -0
- package/src/editor/ui/a11y/A11yComponentIssues.svelte +103 -0
- package/src/editor/ui/a11y/A11yFindingRow.svelte +57 -0
- package/src/editor/ui/a11y/A11yIssueRow.svelte +121 -0
- package/src/editor/ui/a11y/A11yOverview.svelte +242 -0
- package/src/editor/ui/a11y/A11yPanel.svelte +128 -0
- package/src/editor/ui/a11y/A11yPropertyMark.svelte +84 -0
- package/src/editor/ui/a11y/A11yRailMark.svelte +34 -0
- package/src/editor/ui/a11y/AccessibilityTab.svelte +334 -0
- package/src/editor/ui/a11y/a11yView.ts +218 -0
- package/src/editor/ui/anchorToTrigger.ts +63 -0
- package/src/editor/ui/contrastReadout.ts +45 -0
- package/src/editor/ui/sections/CustomColorsSection.svelte +254 -0
- package/src/live-tokens/data/themes/autumn.json +20 -20
- package/src/live-tokens/data/themes/halloween.json +20 -20
- package/src/live-tokens/data/themes/midnight-study.json +20 -20
- package/src/live-tokens/data/themes/ocean.json +20 -20
- package/src/live-tokens/data/themes/royal-velvet.json +20 -20
- package/src/live-tokens/data/themes/sketchy.json +20 -20
- package/src/live-tokens/data/themes/spring-meadow.json +20 -20
- package/src/live-tokens/data/themes/sunset.json +20 -20
- package/src/system/components/Badge.svelte +3 -3
- package/src/system/components/Button.svelte +9 -3
- package/src/system/components/CodeSnippet.svelte +8 -1
- package/src/system/components/CornerBadge.svelte +3 -3
- package/src/system/components/Dialog.svelte +43 -14
- package/src/system/components/IconButton.svelte +1 -1
- package/src/system/components/Image.svelte +7 -0
- package/src/system/components/ImageLightbox.svelte +26 -26
- package/src/system/components/Input.svelte +8 -1
- package/src/system/components/MenuSelect.svelte +30 -2
- package/src/system/components/Notification.svelte +1 -1
- package/src/system/components/ProgressBar.svelte +6 -0
- package/src/system/components/RadioButton.svelte +36 -3
- package/src/system/components/SegmentedControl.svelte +36 -2
- package/src/system/components/SlidePager.svelte +2 -2
- package/src/system/components/Slider.svelte +13 -9
- package/src/system/components/TabBar.svelte +33 -3
- package/src/system/components/Toggle.svelte +2 -2
- package/src/system/components/VideoFrame.svelte +1 -1
- package/src/system/components/VideoLightbox.svelte +2 -2
- package/src/system/internal/focusTrap.ts +35 -0
- package/src/testing-js/__aria__/badge.yml +40 -0
- package/src/testing-js/__aria__/button.yml +88 -0
- package/src/testing-js/__aria__/callout.yml +12 -0
- package/src/testing-js/__aria__/card.yml +8 -0
- package/src/testing-js/__aria__/codesnippet.yml +21 -0
- package/src/testing-js/__aria__/collapsiblesection.yml +23 -0
- package/src/testing-js/__aria__/cornerbadge.yml +24 -0
- package/src/testing-js/__aria__/dialog.yml +42 -0
- package/src/testing-js/__aria__/iconbutton.yml +57 -0
- package/src/testing-js/__aria__/image.yml +10 -0
- package/src/testing-js/__aria__/imagelightbox.yml +50 -0
- package/src/testing-js/__aria__/inlineeditactions.yml +16 -0
- package/src/testing-js/__aria__/input.yml +61 -0
- package/src/testing-js/__aria__/menuselect.yml +30 -0
- package/src/testing-js/__aria__/notification.yml +30 -0
- package/src/testing-js/__aria__/panel.yml +2 -0
- package/src/testing-js/__aria__/progressbar.yml +2 -0
- package/src/testing-js/__aria__/radiobutton.yml +20 -0
- package/src/testing-js/__aria__/sectiondivider.yml +9 -0
- package/src/testing-js/__aria__/segmentedcontrol.yml +35 -0
- package/src/testing-js/__aria__/sidenavigation.yml +304 -0
- package/src/testing-js/__aria__/slidepager.yml +72 -0
- package/src/testing-js/__aria__/slider.yml +28 -0
- package/src/testing-js/__aria__/tabbar.yml +35 -0
- package/src/testing-js/__aria__/table.yml +144 -0
- package/src/testing-js/__aria__/toggle.yml +12 -0
- package/src/testing-js/__aria__/tooltip.yml +2 -0
- package/src/testing-js/__aria__/videoframe.yml +6 -0
- package/src/testing-js/__aria__/videolightbox.yml +12 -0
- package/src/testing-js/{chunk-WIZ6W7UT.js → chunk-3WCLMOM7.js} +2 -2
- package/src/testing-js/{chunk-SHBYZUPD.js → chunk-5HNZHIHG.js} +211 -14
- package/src/testing-js/chunk-5HNZHIHG.js.map +1 -0
- package/src/testing-js/{chunk-NB3NZRBM.js → chunk-7CM5D7PF.js} +5 -1
- package/src/testing-js/chunk-7CM5D7PF.js.map +1 -0
- package/src/testing-js/chunk-EWSGE27V.js +168 -0
- package/src/testing-js/chunk-EWSGE27V.js.map +1 -0
- package/src/testing-js/{chunk-GKO27NGN.js → chunk-R54I7YL6.js} +2 -2
- package/src/testing-js/{chunk-X6KHEVIG.js → chunk-RWH46IU5.js} +97 -29
- package/src/testing-js/chunk-RWH46IU5.js.map +1 -0
- package/src/testing-js/chunk-SHLPDNAQ.js +658 -0
- package/src/testing-js/chunk-SHLPDNAQ.js.map +1 -0
- package/src/testing-js/{chunk-3UKGXCDL.js → chunk-YVVR3GJZ.js} +1 -1
- package/src/testing-js/chunk-YVVR3GJZ.js.map +1 -0
- package/src/testing-js/component-a11y.contract.js +283 -0
- package/src/testing-js/component-a11y.contract.js.map +1 -0
- package/src/testing-js/component-alias.contract.js +2 -2
- package/src/testing-js/component-behavior.contract.js +2 -2
- package/src/testing-js/component-editor.contract.js +6 -5
- package/src/testing-js/component-editor.contract.js.map +1 -1
- package/src/testing-js/component-render.contract.js +10 -6
- package/src/testing-js/component-render.contract.js.map +1 -1
- package/src/testing-js/index.d.ts +44 -16
- package/src/testing-js/index.js +9 -9
- package/src/testing-js/page-compliance.contract.js +163 -18
- package/src/testing-js/page-compliance.contract.js.map +1 -1
- package/src/testing-js/vitest.js +3 -3
- package/template/package.json +9 -0
- package/src/editor/ui/keepInViewport.ts +0 -84
- package/src/testing-js/chunk-3UKGXCDL.js.map +0 -1
- package/src/testing-js/chunk-NB3NZRBM.js.map +0 -1
- package/src/testing-js/chunk-SHBYZUPD.js.map +0 -1
- package/src/testing-js/chunk-X6KHEVIG.js.map +0 -1
- /package/src/testing-js/{chunk-WIZ6W7UT.js.map → chunk-3WCLMOM7.js.map} +0 -0
- /package/src/testing-js/{chunk-GKO27NGN.js.map → chunk-R54I7YL6.js.map} +0 -0
|
@@ -1,13 +1,32 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { untrack } from 'svelte';
|
|
3
|
+
import { get } from 'svelte/store';
|
|
3
4
|
import { slide } from 'svelte/transition';
|
|
4
5
|
import { cubicOut, cubicIn } from 'svelte/easing';
|
|
5
6
|
import { resolveAliasChain } from '../core/palettes/tokenRegistry';
|
|
6
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
editorState,
|
|
9
|
+
beginScope,
|
|
10
|
+
commitScope,
|
|
11
|
+
cancelScope,
|
|
12
|
+
beginSliderGesture,
|
|
13
|
+
addCustomColor,
|
|
14
|
+
setCustomColor,
|
|
15
|
+
removeCustomColor,
|
|
16
|
+
customColorUsages,
|
|
17
|
+
replaceAndRemoveCustomColor,
|
|
18
|
+
type Scope,
|
|
19
|
+
} from '../core/store/editorStore';
|
|
20
|
+
import { setCssVar, removeCssVar } from '../core/cssVarSync';
|
|
21
|
+
import { cssColorToOklch, hexToOklch, type Oklch } from '../core/palettes/oklch';
|
|
7
22
|
import { formatGradientStops } from '../core/themes/slices/gradients';
|
|
8
23
|
import { formatColorOpacity, parseColorOpacity } from '../core/themes/parsers/colorOpacity';
|
|
9
24
|
import type { GradientToken } from '../core/store/editorTypes';
|
|
10
25
|
import UITokenSelector from './UITokenSelector.svelte';
|
|
26
|
+
import ColorEditPanel from './ColorEditPanel.svelte';
|
|
27
|
+
import CustomColorReplaceStep from './CustomColorReplaceStep.svelte';
|
|
28
|
+
import UIContrastReadout from './UIContrastReadout.svelte';
|
|
29
|
+
import { getContrastPairs } from '../core/components/contrastPairRegistry';
|
|
11
30
|
|
|
12
31
|
/** Honor prefers-reduced-motion: `t()` zeroes durations when the OS asks for
|
|
13
32
|
* less motion, so the detail-row enter/exit slides skip outright. Mirrors
|
|
@@ -52,6 +71,9 @@
|
|
|
52
71
|
/** Forwarded to UITokenSelector — when set, writes route through this
|
|
53
72
|
* callback instead of the DOM. See UITokenSelector.onwrite. */
|
|
54
73
|
onwrite?: (value: string | null) => void;
|
|
74
|
+
/** Set on the picker a replace step opens to choose a stand-in for this
|
|
75
|
+
* custom colour. The picker omits the colour and offers no add or edit. */
|
|
76
|
+
replacing?: string | null;
|
|
55
77
|
}
|
|
56
78
|
|
|
57
79
|
let {
|
|
@@ -66,8 +88,11 @@
|
|
|
66
88
|
minOpacity = 0,
|
|
67
89
|
onchange,
|
|
68
90
|
onwrite,
|
|
91
|
+
replacing = null,
|
|
69
92
|
}: Props = $props();
|
|
70
93
|
|
|
94
|
+
let hasContrastPairs = $derived(!!component && getContrastPairs(component, variable).length > 0);
|
|
95
|
+
|
|
71
96
|
const clampOpacity = (n: number) => Math.max(minOpacity, Math.min(100, Math.round(n)));
|
|
72
97
|
let noneAllowed = $derived(showNone && minOpacity <= 0);
|
|
73
98
|
|
|
@@ -88,6 +113,12 @@
|
|
|
88
113
|
|
|
89
114
|
const familyNames = families.map(f => f.name);
|
|
90
115
|
|
|
116
|
+
/** The Custom row's family name. A custom colour is its palette step `N`, so
|
|
117
|
+
* `getVarName('palette', CUSTOM, N)` yields `--color-custom-N`. */
|
|
118
|
+
const CUSTOM = 'custom';
|
|
119
|
+
const CUSTOM_PREFIX = '--color-custom-';
|
|
120
|
+
const customNumber = (v: string) => v.slice(CUSTOM_PREFIX.length);
|
|
121
|
+
|
|
91
122
|
const paletteSteps = ['100', '200', '300', '400', '500', '600', '700', '800', '850', '900', '950'];
|
|
92
123
|
|
|
93
124
|
const surfaceSteps = [
|
|
@@ -233,6 +264,9 @@
|
|
|
233
264
|
if (!varMatch) return null;
|
|
234
265
|
const varName = varMatch[1];
|
|
235
266
|
|
|
267
|
+
const customM = varName.match(/^--color-custom-(\d+)$/);
|
|
268
|
+
if (customM) return { category: 'palette', family: CUSTOM, step: customM[1] };
|
|
269
|
+
|
|
236
270
|
const paletteM = varName.match(/^--color-([a-z]+)-(\d{3})$/);
|
|
237
271
|
if (paletteM && familyNames.includes(paletteM[1]) && paletteSteps.includes(paletteM[2])) {
|
|
238
272
|
return { category: 'palette', family: paletteM[1], step: paletteM[2] };
|
|
@@ -452,6 +486,7 @@
|
|
|
452
486
|
}
|
|
453
487
|
|
|
454
488
|
function handleClose() {
|
|
489
|
+
if (session) cancelSession();
|
|
455
490
|
selectedFamily = null;
|
|
456
491
|
}
|
|
457
492
|
|
|
@@ -464,6 +499,7 @@
|
|
|
464
499
|
}
|
|
465
500
|
|
|
466
501
|
function backToFamilies() {
|
|
502
|
+
if (session) cancelSession();
|
|
467
503
|
selectedFamily = null;
|
|
468
504
|
}
|
|
469
505
|
|
|
@@ -530,6 +566,130 @@
|
|
|
530
566
|
onchange?.();
|
|
531
567
|
}
|
|
532
568
|
|
|
569
|
+
let customTokens = $derived(
|
|
570
|
+
$editorState.customColors.tokens
|
|
571
|
+
.filter((t) => t.variable !== replacing)
|
|
572
|
+
.sort((a, b) => Number(customNumber(a.variable)) - Number(customNumber(b.variable))),
|
|
573
|
+
);
|
|
574
|
+
let customOutOfFamily = $derived(familyFilter !== null && familyFilter !== CUSTOM);
|
|
575
|
+
|
|
576
|
+
/** An open add, edit, or replace-on-remove of one custom colour. */
|
|
577
|
+
interface CustomSession {
|
|
578
|
+
mode: 'add' | 'edit' | 'remove';
|
|
579
|
+
variable: string;
|
|
580
|
+
draft: Oklch;
|
|
581
|
+
}
|
|
582
|
+
let session = $state<CustomSession | null>(null);
|
|
583
|
+
// Held outside $state: the store matches an open scope by identity, and a
|
|
584
|
+
// proxied handle would never match.
|
|
585
|
+
let sessionScope: Scope | null = null;
|
|
586
|
+
let slotRawBeforeAdd = '';
|
|
587
|
+
|
|
588
|
+
function readSlotRaw(): string {
|
|
589
|
+
return document.documentElement.style.getPropertyValue(variable).trim();
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
function rgbChannelsToOklch(r: number, g: number, b: number): Oklch {
|
|
593
|
+
const hex = (n: number) => Math.max(0, Math.min(255, Math.round(n))).toString(16).padStart(2, '0');
|
|
594
|
+
return hexToOklch(`#${hex(r)}${hex(g)}${hex(b)}`);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/** The slot's colour as the browser paints it. A custom property's computed
|
|
598
|
+
* value is its unresolved text, so a probe's `color` does the resolving. */
|
|
599
|
+
function resolvedSlotColor(): Oklch {
|
|
600
|
+
const probe = document.createElement('span');
|
|
601
|
+
probe.style.color = `var(${variable})`;
|
|
602
|
+
document.body.appendChild(probe);
|
|
603
|
+
const css = getComputedStyle(probe).color.trim();
|
|
604
|
+
probe.remove();
|
|
605
|
+
const rgb = css.match(/^rgba?\(\s*([\d.]+)[\s,]+([\d.]+)[\s,]+([\d.]+)/i);
|
|
606
|
+
if (rgb) return rgbChannelsToOklch(+rgb[1], +rgb[2], +rgb[3]);
|
|
607
|
+
const srgb = css.match(/^color\(srgb\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)/i);
|
|
608
|
+
if (srgb) return rgbChannelsToOklch(+srgb[1] * 255, +srgb[2] * 255, +srgb[3] * 255);
|
|
609
|
+
return cssColorToOklch(css) ?? { l: 0.6, c: 0, h: 0 };
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
function openAdd() {
|
|
613
|
+
const seed = resolvedSlotColor();
|
|
614
|
+
slotRawBeforeAdd = readSlotRaw();
|
|
615
|
+
sessionScope = beginScope({ label: 'add custom colour', collapseToOne: true, clipUndoFloor: true });
|
|
616
|
+
const added = addCustomColor(seed);
|
|
617
|
+
chosenNone = false;
|
|
618
|
+
chosenStatic = null;
|
|
619
|
+
chosenGradient = null;
|
|
620
|
+
chosenAngle = null;
|
|
621
|
+
chosenCategory = 'palette';
|
|
622
|
+
chosenFamily = CUSTOM;
|
|
623
|
+
chosenStep = customNumber(added);
|
|
624
|
+
selector?.writeOverride(buildValue(added));
|
|
625
|
+
onchange?.();
|
|
626
|
+
session = { mode: 'add', variable: added, draft: seed };
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
function openEdit(customVar: string) {
|
|
630
|
+
const token = get(editorState).customColors.tokens.find((t) => t.variable === customVar);
|
|
631
|
+
if (!token) return;
|
|
632
|
+
sessionScope = beginScope({ label: `edit custom colour ${customVar}`, collapseToOne: true, clipUndoFloor: true });
|
|
633
|
+
session = { mode: 'edit', variable: customVar, draft: { ...token.color } };
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
function editDraft(h: number, c: number, lPct: number) {
|
|
637
|
+
if (!session) return;
|
|
638
|
+
session.draft = { l: lPct / 100, c, h };
|
|
639
|
+
setCustomColor(session.variable, session.draft);
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
function confirmSession() {
|
|
643
|
+
if (!session) return;
|
|
644
|
+
const added = session.mode === 'add';
|
|
645
|
+
if (sessionScope) commitScope(sessionScope);
|
|
646
|
+
sessionScope = null;
|
|
647
|
+
session = null;
|
|
648
|
+
if (added) {
|
|
649
|
+
selectedFamily = null;
|
|
650
|
+
selector?.close();
|
|
651
|
+
onchange?.();
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
// A cancelled add would leave the slot naming a colour the scope removed, so
|
|
656
|
+
// the scope restores the slot with it. A slot that writes only to the DOM
|
|
657
|
+
// sits outside the store, so its prior value goes back by hand.
|
|
658
|
+
function cancelSession() {
|
|
659
|
+
const added = session?.mode === 'add';
|
|
660
|
+
if (sessionScope) cancelScope(sessionScope);
|
|
661
|
+
sessionScope = null;
|
|
662
|
+
session = null;
|
|
663
|
+
if (added && !component && !onwrite) {
|
|
664
|
+
if (slotRawBeforeAdd) setCssVar(variable, slotRawBeforeAdd);
|
|
665
|
+
else removeCssVar(variable);
|
|
666
|
+
}
|
|
667
|
+
initFromCurrent();
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
function requestRemove(customVar: string) {
|
|
671
|
+
if (customColorUsages(get(editorState), customVar).length === 0) {
|
|
672
|
+
removeCustomColor(customVar);
|
|
673
|
+
initFromCurrent();
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
const token = get(editorState).customColors.tokens.find((t) => t.variable === customVar);
|
|
677
|
+
if (!token) return;
|
|
678
|
+
session = { mode: 'remove', variable: customVar, draft: { ...token.color } };
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
function confirmReplace(replacement: string) {
|
|
682
|
+
if (!session) return;
|
|
683
|
+
const customVar = session.variable;
|
|
684
|
+
session = null;
|
|
685
|
+
replaceAndRemoveCustomColor(customVar, replacement);
|
|
686
|
+
initFromCurrent();
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
function cancelReplace() {
|
|
690
|
+
session = null;
|
|
691
|
+
}
|
|
692
|
+
|
|
533
693
|
// Re-derive trigger state when the bound `variable` changes (e.g. when a
|
|
534
694
|
// VariantGroup tabs view reuses the same selector instance across states).
|
|
535
695
|
// The wrapper UITokenSelector forwards `var-change` only for the currently
|
|
@@ -567,9 +727,11 @@
|
|
|
567
727
|
? getVarName(chosenCategory, chosenFamily, chosenStep).replace(/^--/, '') + (opacity < 100 ? ` (${opacity}%)` : '')
|
|
568
728
|
: ''));
|
|
569
729
|
|
|
570
|
-
let availableTabs = $derived(selectedFamily
|
|
571
|
-
? allCategories.filter(c => c.id
|
|
572
|
-
:
|
|
730
|
+
let availableTabs = $derived(selectedFamily === CUSTOM
|
|
731
|
+
? allCategories.filter(c => c.id === 'palette')
|
|
732
|
+
: selectedFamily
|
|
733
|
+
? allCategories.filter(c => c.id !== 'text' || familiesWithText.includes(selectedFamily!))
|
|
734
|
+
: allCategories);
|
|
573
735
|
|
|
574
736
|
$effect(() => {
|
|
575
737
|
const family = selectedFamily;
|
|
@@ -582,6 +744,10 @@
|
|
|
582
744
|
});
|
|
583
745
|
</script>
|
|
584
746
|
|
|
747
|
+
{#snippet contrastReadout()}
|
|
748
|
+
{#if component}<UIContrastReadout {component} {variable} />{/if}
|
|
749
|
+
{/snippet}
|
|
750
|
+
|
|
585
751
|
<UITokenSelector
|
|
586
752
|
bind:this={selector}
|
|
587
753
|
{variable}
|
|
@@ -590,7 +756,8 @@
|
|
|
590
756
|
{disabled}
|
|
591
757
|
{selectionsLocked}
|
|
592
758
|
{onwrite}
|
|
593
|
-
|
|
759
|
+
metaAfter={hasContrastPairs ? contrastReadout : undefined}
|
|
760
|
+
dropdownMinWidth={session ? '22rem' : '14rem'}
|
|
594
761
|
dropdownMaxWidth="calc(100vw - 2rem)"
|
|
595
762
|
hideDefaultHeader={!!selectedFamily}
|
|
596
763
|
onreset={handleReset}
|
|
@@ -632,7 +799,7 @@
|
|
|
632
799
|
{/if}
|
|
633
800
|
</div>
|
|
634
801
|
<div class="family-list">
|
|
635
|
-
{#each families as fam}
|
|
802
|
+
{#each families as fam (fam.name)}
|
|
636
803
|
{@const outOfFamily = familyFilter !== null && fam.name !== familyFilter}
|
|
637
804
|
<button
|
|
638
805
|
class="family-item"
|
|
@@ -652,9 +819,30 @@
|
|
|
652
819
|
{/if}
|
|
653
820
|
</button>
|
|
654
821
|
{/each}
|
|
822
|
+
<button
|
|
823
|
+
class="family-item"
|
|
824
|
+
class:active={!chosenNone && chosenFamily === CUSTOM}
|
|
825
|
+
class:out-of-family={customOutOfFamily}
|
|
826
|
+
disabled={customOutOfFamily}
|
|
827
|
+
onclick={() => selectFamily(CUSTOM)}
|
|
828
|
+
>
|
|
829
|
+
<div class="family-swatches">
|
|
830
|
+
{#each [0, 1, 2] as i (i)}
|
|
831
|
+
{#if customTokens[i]}
|
|
832
|
+
<div class="mini-swatch" style="background: var({customTokens[i].variable});"></div>
|
|
833
|
+
{:else}
|
|
834
|
+
<div class="mini-swatch mini-swatch--empty"></div>
|
|
835
|
+
{/if}
|
|
836
|
+
{/each}
|
|
837
|
+
</div>
|
|
838
|
+
<span class="family-label">Custom</span>
|
|
839
|
+
{#if !customOutOfFamily}
|
|
840
|
+
<i class="fas fa-chevron-right family-arrow"></i>
|
|
841
|
+
{/if}
|
|
842
|
+
</button>
|
|
655
843
|
{#if gradientsAllowed && gradientTokens.length > 0}
|
|
656
844
|
<div class="family-divider">Gradients</div>
|
|
657
|
-
{#each gradientTokens as g}
|
|
845
|
+
{#each gradientTokens as g (g.variable)}
|
|
658
846
|
<button class="family-item" class:active={chosenGradient === g.variable} onclick={() => selectGradient(g.variable, close)}>
|
|
659
847
|
<div class="family-swatches">
|
|
660
848
|
<div class="gradient-swatch" style="background: var({g.variable});"></div>
|
|
@@ -667,11 +855,11 @@
|
|
|
667
855
|
{:else}
|
|
668
856
|
<button class="dropdown-back" onclick={backToFamilies}>
|
|
669
857
|
<i class="fas fa-chevron-left"></i>
|
|
670
|
-
<span>{families.find(f => f.name === selectedFamily)?.label}</span>
|
|
858
|
+
<span>{selectedFamily === CUSTOM ? 'Custom' : families.find(f => f.name === selectedFamily)?.label}</span>
|
|
671
859
|
</button>
|
|
672
860
|
|
|
673
861
|
<div class="tab-bar">
|
|
674
|
-
{#each availableTabs as tab}
|
|
862
|
+
{#each availableTabs as tab (tab.id)}
|
|
675
863
|
<button
|
|
676
864
|
class="tab-btn"
|
|
677
865
|
class:selected={selectedCategory === tab.id}
|
|
@@ -681,9 +869,79 @@
|
|
|
681
869
|
{/each}
|
|
682
870
|
</div>
|
|
683
871
|
|
|
684
|
-
{#if
|
|
872
|
+
{#if selectedFamily === CUSTOM}
|
|
685
873
|
<div class="step-grid">
|
|
686
|
-
{#each
|
|
874
|
+
{#each customTokens as token (token.variable)}
|
|
875
|
+
{@const n = customNumber(token.variable)}
|
|
876
|
+
<div class="custom-cell">
|
|
877
|
+
<button
|
|
878
|
+
class="step-item"
|
|
879
|
+
class:active={chosenCategory === 'palette' && chosenFamily === CUSTOM && chosenStep === n}
|
|
880
|
+
disabled={session !== null}
|
|
881
|
+
onclick={() => selectSwatch('palette', n, close)}
|
|
882
|
+
>
|
|
883
|
+
<div class="step-swatch" style="background: var({token.variable});"></div>
|
|
884
|
+
<span class="step-label">{n}</span>
|
|
885
|
+
</button>
|
|
886
|
+
{#if !replacing}
|
|
887
|
+
<button
|
|
888
|
+
type="button"
|
|
889
|
+
class="custom-edit"
|
|
890
|
+
title="Edit custom colour {n}"
|
|
891
|
+
aria-label="Edit custom colour {n}"
|
|
892
|
+
disabled={session !== null}
|
|
893
|
+
onclick={() => openEdit(token.variable)}
|
|
894
|
+
><i class="fas fa-pen" aria-hidden="true"></i></button>
|
|
895
|
+
<button
|
|
896
|
+
type="button"
|
|
897
|
+
class="custom-remove"
|
|
898
|
+
title="Remove custom colour {n}"
|
|
899
|
+
aria-label="Remove custom colour {n}"
|
|
900
|
+
disabled={session !== null}
|
|
901
|
+
onclick={() => requestRemove(token.variable)}
|
|
902
|
+
><i class="fas fa-trash" aria-hidden="true"></i></button>
|
|
903
|
+
{/if}
|
|
904
|
+
</div>
|
|
905
|
+
{/each}
|
|
906
|
+
{#if !replacing}
|
|
907
|
+
<button
|
|
908
|
+
class="step-item"
|
|
909
|
+
title="Add a custom colour"
|
|
910
|
+
aria-label="Add a custom colour"
|
|
911
|
+
disabled={session !== null}
|
|
912
|
+
onclick={openAdd}
|
|
913
|
+
>
|
|
914
|
+
<div class="step-swatch step-swatch--add"><i class="fas fa-plus" aria-hidden="true"></i></div>
|
|
915
|
+
<span class="step-label">Add</span>
|
|
916
|
+
</button>
|
|
917
|
+
{/if}
|
|
918
|
+
</div>
|
|
919
|
+
{#if session}
|
|
920
|
+
<div class="custom-panel">
|
|
921
|
+
{#if session.mode === 'remove'}
|
|
922
|
+
<CustomColorReplaceStep
|
|
923
|
+
variable={session.variable}
|
|
924
|
+
color={session.draft}
|
|
925
|
+
onconfirm={confirmReplace}
|
|
926
|
+
oncancel={cancelReplace}
|
|
927
|
+
/>
|
|
928
|
+
{:else}
|
|
929
|
+
<ColorEditPanel
|
|
930
|
+
title="Custom › {customNumber(session.variable)}"
|
|
931
|
+
hue={session.draft.h}
|
|
932
|
+
chroma={session.draft.c}
|
|
933
|
+
lightness={session.draft.l * 100}
|
|
934
|
+
onHueChromaChange={editDraft}
|
|
935
|
+
onSliderStart={() => beginSliderGesture(`edit ${session?.variable ?? 'custom colour'}`)}
|
|
936
|
+
onConfirm={confirmSession}
|
|
937
|
+
onCancel={cancelSession}
|
|
938
|
+
/>
|
|
939
|
+
{/if}
|
|
940
|
+
</div>
|
|
941
|
+
{/if}
|
|
942
|
+
{:else if selectedCategory === 'palette'}
|
|
943
|
+
<div class="step-grid">
|
|
944
|
+
{#each paletteSteps as step (step)}
|
|
687
945
|
<button
|
|
688
946
|
class="step-item"
|
|
689
947
|
class:active={chosenCategory === 'palette' && chosenFamily === selectedFamily && chosenStep === step}
|
|
@@ -696,7 +954,7 @@
|
|
|
696
954
|
</div>
|
|
697
955
|
{:else if selectedCategory === 'surface'}
|
|
698
956
|
<div class="step-grid">
|
|
699
|
-
{#each surfaceSteps as step}
|
|
957
|
+
{#each surfaceSteps as step (step.key)}
|
|
700
958
|
<button
|
|
701
959
|
class="step-item"
|
|
702
960
|
class:active={chosenCategory === 'surface' && chosenFamily === selectedFamily && chosenStep === step.key}
|
|
@@ -709,7 +967,7 @@
|
|
|
709
967
|
</div>
|
|
710
968
|
{:else if selectedCategory === 'border'}
|
|
711
969
|
<div class="step-grid">
|
|
712
|
-
{#each borderSteps as step}
|
|
970
|
+
{#each borderSteps as step (step.key)}
|
|
713
971
|
<button
|
|
714
972
|
class="step-item"
|
|
715
973
|
class:active={chosenCategory === 'border' && chosenFamily === selectedFamily && chosenStep === step.key}
|
|
@@ -722,7 +980,7 @@
|
|
|
722
980
|
</div>
|
|
723
981
|
{:else if selectedCategory === 'text'}
|
|
724
982
|
<div class="step-grid">
|
|
725
|
-
{#each (selectedFamily === 'neutral' ? neutralTextSteps : textSteps) as step}
|
|
983
|
+
{#each (selectedFamily === 'neutral' ? neutralTextSteps : textSteps) as step (step.key)}
|
|
726
984
|
<button
|
|
727
985
|
class="step-item"
|
|
728
986
|
class:active={chosenCategory === 'text' && chosenFamily === selectedFamily && chosenStep === step.key}
|
|
@@ -756,7 +1014,7 @@
|
|
|
756
1014
|
<span class="detail-label">orientation</span>
|
|
757
1015
|
<div class="orientation-body">
|
|
758
1016
|
<div class="dir-grid">
|
|
759
|
-
{#each directionGrid as d}
|
|
1017
|
+
{#each directionGrid as d (d.angle)}
|
|
760
1018
|
<button
|
|
761
1019
|
type="button"
|
|
762
1020
|
class="dir-btn"
|
|
@@ -1061,6 +1319,80 @@
|
|
|
1061
1319
|
border-radius: 2px;
|
|
1062
1320
|
}
|
|
1063
1321
|
|
|
1322
|
+
.mini-swatch--empty {
|
|
1323
|
+
border: 1px dashed var(--ui-border);
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
.custom-cell {
|
|
1327
|
+
position: relative;
|
|
1328
|
+
display: flex;
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
.custom-cell > .step-item {
|
|
1332
|
+
flex: 1;
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
.custom-edit,
|
|
1336
|
+
.custom-remove {
|
|
1337
|
+
position: absolute;
|
|
1338
|
+
top: 0;
|
|
1339
|
+
display: inline-flex;
|
|
1340
|
+
align-items: center;
|
|
1341
|
+
justify-content: center;
|
|
1342
|
+
width: 1.125rem;
|
|
1343
|
+
height: 1.125rem;
|
|
1344
|
+
padding: 0;
|
|
1345
|
+
background: var(--ui-surface-high);
|
|
1346
|
+
border: 1px solid var(--ui-border);
|
|
1347
|
+
border-radius: var(--ui-radius-sm);
|
|
1348
|
+
color: var(--ui-text-secondary);
|
|
1349
|
+
font-size: 0.5625rem;
|
|
1350
|
+
cursor: pointer;
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1353
|
+
.custom-edit {
|
|
1354
|
+
right: 0;
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
.custom-remove {
|
|
1358
|
+
left: 0;
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
.custom-edit:hover:not(:disabled),
|
|
1362
|
+
.custom-remove:hover:not(:disabled) {
|
|
1363
|
+
color: var(--ui-text-primary);
|
|
1364
|
+
border-color: var(--ui-border-higher);
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
.custom-edit:disabled,
|
|
1368
|
+
.custom-remove:disabled {
|
|
1369
|
+
cursor: default;
|
|
1370
|
+
opacity: 0.5;
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
.step-item:disabled {
|
|
1374
|
+
cursor: default;
|
|
1375
|
+
opacity: 0.5;
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
.step-item:disabled:hover {
|
|
1379
|
+
background: none;
|
|
1380
|
+
border-color: transparent;
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
.step-swatch--add {
|
|
1384
|
+
display: flex;
|
|
1385
|
+
align-items: center;
|
|
1386
|
+
justify-content: center;
|
|
1387
|
+
border: 1px dashed var(--ui-border-higher);
|
|
1388
|
+
color: var(--ui-text-muted);
|
|
1389
|
+
font-size: var(--ui-font-size-xs);
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
.custom-panel {
|
|
1393
|
+
padding: 0 var(--ui-space-8) var(--ui-space-8);
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1064
1396
|
.gradient-swatch {
|
|
1065
1397
|
width: 2.5rem;
|
|
1066
1398
|
height: 0.75rem;
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
} from '../core/store/editorStore';
|
|
23
23
|
import UILinkToggle from './UILinkToggle.svelte';
|
|
24
24
|
import UIRelinkConfirmDialog from './UIRelinkConfirmDialog.svelte';
|
|
25
|
-
import {
|
|
25
|
+
import { anchorToTrigger } from './anchorToTrigger';
|
|
26
|
+
import A11yPropertyMark from './a11y/A11yPropertyMark.svelte';
|
|
26
27
|
|
|
27
28
|
type DropdownContext = { close: () => void; handleReset: () => void };
|
|
28
29
|
|
|
@@ -53,6 +54,8 @@
|
|
|
53
54
|
triggerTitle?: Snippet;
|
|
54
55
|
/** Optional meta text rendered after the trigger. Renamed from `slot="trigger-meta"` in 0.5.0. */
|
|
55
56
|
triggerMeta?: Snippet;
|
|
57
|
+
/** Optional content after the meta text, in the same column. The meta text truncates first. */
|
|
58
|
+
metaAfter?: Snippet;
|
|
56
59
|
/** Optional dropdown header replacement. */
|
|
57
60
|
header?: Snippet;
|
|
58
61
|
/** Optional dropdown content above the selections. */
|
|
@@ -87,6 +90,7 @@
|
|
|
87
90
|
triggerText,
|
|
88
91
|
triggerTitle,
|
|
89
92
|
triggerMeta,
|
|
93
|
+
metaAfter,
|
|
90
94
|
header,
|
|
91
95
|
subheader,
|
|
92
96
|
children,
|
|
@@ -100,6 +104,7 @@
|
|
|
100
104
|
|
|
101
105
|
let open = $state(false);
|
|
102
106
|
let container: HTMLElement;
|
|
107
|
+
let triggerEl = $state<HTMLButtonElement | undefined>(undefined);
|
|
103
108
|
let relinkOpen = $state(false);
|
|
104
109
|
let relinkCandidates: { variable: string; alias: string }[] = $state([]);
|
|
105
110
|
|
|
@@ -291,7 +296,9 @@
|
|
|
291
296
|
bind:this={container}
|
|
292
297
|
>
|
|
293
298
|
<div class="ui-ts-trigger-wrap">
|
|
299
|
+
<A11yPropertyMark variables={[variable]} placement="gutter" />
|
|
294
300
|
<button
|
|
301
|
+
bind:this={triggerEl}
|
|
295
302
|
class="ui-ts-trigger"
|
|
296
303
|
class:linked={isLinkedDisplay}
|
|
297
304
|
class:unlinked={showLinkToggle && !isLinkedDisplay}
|
|
@@ -329,7 +336,7 @@
|
|
|
329
336
|
<div
|
|
330
337
|
class="ui-ts-dropdown"
|
|
331
338
|
style="min-width: {dropdownMinWidth};{dropdownMaxWidth ? ` max-width: ${dropdownMaxWidth};` : ''}"
|
|
332
|
-
use:
|
|
339
|
+
use:anchorToTrigger={triggerEl!}
|
|
333
340
|
>
|
|
334
341
|
{#if !hideDefaultHeader}
|
|
335
342
|
{#if header}
|
|
@@ -360,11 +367,20 @@
|
|
|
360
367
|
{/if}
|
|
361
368
|
</div>
|
|
362
369
|
|
|
363
|
-
{#
|
|
370
|
+
{#snippet metaText(meta: Snippet)}
|
|
364
371
|
<span
|
|
365
372
|
class="ui-ts-meta-text"
|
|
366
373
|
use:mirrorTextToTitle
|
|
367
|
-
>{@render
|
|
374
|
+
>{@render meta()}</span>
|
|
375
|
+
{/snippet}
|
|
376
|
+
|
|
377
|
+
{#if metaAfter}
|
|
378
|
+
<div class="ui-ts-meta">
|
|
379
|
+
{#if triggerMeta}{@render metaText(triggerMeta)}{/if}
|
|
380
|
+
{@render metaAfter()}
|
|
381
|
+
</div>
|
|
382
|
+
{:else if triggerMeta}
|
|
383
|
+
{@render metaText(triggerMeta)}
|
|
368
384
|
{/if}
|
|
369
385
|
</div>
|
|
370
386
|
|
|
@@ -452,8 +468,7 @@
|
|
|
452
468
|
background: var(--ui-surface-high);
|
|
453
469
|
}
|
|
454
470
|
|
|
455
|
-
/* Link-state pop-bar. The wrap already has `position: relative`
|
|
456
|
-
dropdown can anchor). The bar is a `::before` anchored at the wrap's
|
|
471
|
+
/* Link-state pop-bar. The wrap already has `position: relative`. The bar is a `::before` anchored at the wrap's
|
|
457
472
|
left edge — same column position regardless of state, so a stack of
|
|
458
473
|
mixed linked/unlinked rows shares one continuous link-state column.
|
|
459
474
|
Linked rows: bar is teal, full size, sitting flush against the trigger.
|
|
@@ -488,12 +503,6 @@
|
|
|
488
503
|
height: 0.875rem;
|
|
489
504
|
border-radius: 1px;
|
|
490
505
|
}
|
|
491
|
-
/* Keep the dropdown's left edge aligned with the (indented) trigger rather
|
|
492
|
-
than the column anchor, so an open dropdown doesn't bleed left of its
|
|
493
|
-
associated control. */
|
|
494
|
-
.ui-ts-trigger-wrap:has(> .ui-ts-trigger.unlinked) > .ui-ts-dropdown {
|
|
495
|
-
left: 0.5rem;
|
|
496
|
-
}
|
|
497
506
|
@media (prefers-reduced-motion: reduce) {
|
|
498
507
|
.ui-ts-trigger-wrap,
|
|
499
508
|
.ui-ts-trigger-wrap::before { transition: none; }
|
|
@@ -523,6 +532,16 @@
|
|
|
523
532
|
min-width: 0;
|
|
524
533
|
}
|
|
525
534
|
|
|
535
|
+
/* Column 3 when `metaAfter` is set. `min-width: 0` keeps the pair from
|
|
536
|
+
widening the column; the meta text gives up width first. */
|
|
537
|
+
.ui-ts-meta {
|
|
538
|
+
display: flex;
|
|
539
|
+
align-items: center;
|
|
540
|
+
gap: var(--ui-space-6);
|
|
541
|
+
align-self: center;
|
|
542
|
+
min-width: 0;
|
|
543
|
+
}
|
|
544
|
+
|
|
526
545
|
.ui-ts-chevron {
|
|
527
546
|
font-size: 0.625rem;
|
|
528
547
|
color: var(--ui-text-secondary);
|
|
@@ -534,8 +553,8 @@
|
|
|
534
553
|
}
|
|
535
554
|
|
|
536
555
|
.ui-ts-dropdown {
|
|
537
|
-
position:
|
|
538
|
-
top:
|
|
556
|
+
position: fixed;
|
|
557
|
+
top: 0;
|
|
539
558
|
left: 0;
|
|
540
559
|
background: var(--ui-surface-higher);
|
|
541
560
|
border: 1px solid var(--ui-border-high);
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import ColumnsSection from './sections/ColumnsSection.svelte';
|
|
9
9
|
import TokenScaleTable from './sections/TokenScaleTable.svelte';
|
|
10
10
|
import WashesSection from './sections/WashesSection.svelte';
|
|
11
|
+
import CustomColorsSection from './sections/CustomColorsSection.svelte';
|
|
11
12
|
import GradientsSection from './sections/GradientsSection.svelte';
|
|
12
13
|
import ShadowsSection from './sections/ShadowsSection.svelte';
|
|
13
14
|
import {
|
|
@@ -139,6 +140,8 @@
|
|
|
139
140
|
<!-- Overlays -->
|
|
140
141
|
<WashesSection {copiedVar} oncopy={copyVariable} />
|
|
141
142
|
|
|
143
|
+
<CustomColorsSection {copiedVar} oncopy={copyVariable} />
|
|
144
|
+
|
|
142
145
|
<!-- Gradients -->
|
|
143
146
|
<GradientsSection {copiedVar} oncopy={copyVariable} />
|
|
144
147
|
|