@motion-proto/live-tokens 0.49.1 → 0.52.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/CHANGELOG.md +72 -0
- package/dist-plugin/adjust/index.d.cts +1 -1
- package/dist-plugin/adjust/index.d.ts +1 -1
- package/dist-plugin/{chunk-76TFDTJO.js → chunk-JIGIIE5P.js} +60 -132
- package/dist-plugin/{chunk-44RSTAII.js → chunk-TKZBVIW5.js} +33 -5
- package/dist-plugin/chunk-YR6GPXW2.js +129 -0
- package/dist-plugin/generateColorsAndType/index.cjs +100 -33
- package/dist-plugin/generateColorsAndType/index.d.cts +1 -1
- package/dist-plugin/generateColorsAndType/index.d.ts +1 -1
- package/dist-plugin/generateColorsAndType/index.js +35 -14
- package/dist-plugin/index.cjs +95 -55
- package/dist-plugin/index.js +5 -3
- package/dist-plugin/{themeTypes-DSwKq-bj.d.cts → themeTypes-Dky03HL9.d.cts} +18 -5
- package/dist-plugin/{themeTypes-DSwKq-bj.d.ts → themeTypes-Dky03HL9.d.ts} +18 -5
- package/dist-plugin/tokensCssMigrations/index.cjs +71 -5
- package/dist-plugin/tokensCssMigrations/index.d.cts +20 -9
- package/dist-plugin/tokensCssMigrations/index.d.ts +20 -9
- package/dist-plugin/tokensCssMigrations/index.js +4 -1
- package/package.json +8 -1
- package/src/editor/bootstrap.ts +2 -0
- package/src/editor/component-editor/ButtonEditor.svelte +1 -1
- package/src/editor/component-editor/CardEditor.svelte +5 -2
- package/src/editor/component-editor/IconButtonEditor.svelte +1 -1
- package/src/editor/component-editor/ImageEditor.svelte +1 -1
- package/src/editor/component-editor/NotificationEditor.svelte +6 -0
- package/src/editor/component-editor/SectionDividerEditor.svelte +4 -1
- package/src/editor/component-editor/SideNavigationEditor.svelte +6 -0
- package/src/editor/component-editor/TabBarEditor.svelte +1 -5
- package/src/editor/component-editor/scaffolding/ComponentEditorBase.svelte +8 -1
- package/src/editor/component-editor/scaffolding/ComponentFileManager.svelte +10 -32
- package/src/editor/component-editor/scaffolding/StateBlock.svelte +2 -0
- package/src/editor/component-editor/scaffolding/TypeEditor.svelte +3 -1
- package/src/editor/component-editor/scaffolding/types.ts +3 -0
- package/src/editor/core/components/componentConfigService.ts +25 -0
- package/src/editor/core/cssVarSync.ts +65 -7
- package/src/editor/core/fonts/fontLoader.ts +12 -3
- package/src/editor/core/fonts/fontWeightAvailability.ts +97 -0
- package/src/editor/core/palettes/oklch.ts +3 -137
- package/src/editor/core/palettes/paletteDerivation.ts +79 -37
- package/src/editor/core/preview/lookPreview.ts +23 -18
- package/src/editor/core/store/editorRenderer.ts +22 -7
- package/src/editor/core/store/editorStore.ts +31 -0
- package/src/editor/core/store/gradientSource.ts +5 -0
- package/src/editor/core/themes/colorsAndTypeService.ts +2 -12
- package/src/editor/core/themes/generateColorsAndType.ts +18 -8
- package/src/editor/core/themes/migrations/2026-05-20-sectiondivider-slim-variants.ts +4 -1
- package/src/editor/core/themes/migrations/2026-05-21-sectiondivider-spacing-to-padding.ts +4 -1
- package/src/editor/core/themes/migrations/2026-05-25-cornerbadge-flatten-variants.ts +8 -0
- package/src/editor/core/themes/slices/fonts.ts +4 -5
- package/src/editor/core/themes/themeDocumentSync.ts +66 -0
- package/src/editor/core/themes/themeInit.ts +7 -10
- package/src/editor/core/themes/themeService.ts +10 -3
- package/src/editor/core/themes/themeTypes.ts +18 -6
- package/src/editor/docs/content/editing-tokens.md +6 -2
- package/src/editor/docs/content/themes-workflow.md +14 -11
- package/src/editor/docs/content/where-themes-live.md +2 -2
- package/src/editor/docs/content.generated.ts +3 -3
- package/src/editor/ui/BezierCurveEditor.svelte +90 -67
- package/src/editor/ui/FileLoadList.svelte +1 -0
- package/src/editor/ui/FontStackEditor.svelte +1 -2
- package/src/editor/ui/GradientEditor.svelte +5 -1
- package/src/editor/ui/PaletteEditor.svelte +150 -44
- package/src/editor/ui/ProjectFontsSection.svelte +0 -5
- package/src/editor/ui/ThemePanel.svelte +206 -42
- package/src/editor/ui/Toggle.svelte +14 -2
- package/src/editor/ui/UIDialog.svelte +7 -1
- package/src/editor/ui/UIFontFamilySelector.svelte +13 -13
- package/src/editor/ui/UIFontSizeSelector.svelte +5 -5
- package/src/editor/ui/UIFontWeightSelector.svelte +52 -2
- package/src/editor/ui/UIOptionItem.svelte +14 -1
- package/src/editor/ui/UIPaddingSelector.svelte +4 -3
- package/src/editor/ui/UIPaletteSelector.svelte +20 -13
- package/src/editor/ui/UIRelinkConfirmDialog.svelte +18 -3
- package/src/editor/ui/UITextTransformSelector.svelte +5 -5
- package/src/editor/ui/UITokenSelector.svelte +29 -7
- package/src/editor/ui/colors/ColorStory.svelte +12 -8
- package/src/editor/ui/curveEngine.ts +101 -21
- package/src/editor/ui/palette/OverridesPanel.svelte +19 -5
- package/src/editor/ui/palette/PaletteBase.svelte +17 -78
- package/src/editor/ui/palette/ScaleCurveEditor.svelte +109 -20
- package/src/editor/ui/palette/curveSummary.ts +20 -0
- package/src/editor/ui/palette/dockMagnify.ts +5 -13
- package/src/editor/ui/palette/paletteMath.ts +7 -4
- package/src/live-tokens/data/colors-and-type/autumn.json +528 -528
- package/src/live-tokens/data/colors-and-type/default.json +247 -247
- package/src/live-tokens/data/colors-and-type/halloween.json +532 -532
- package/src/live-tokens/data/colors-and-type/midnight-study.json +538 -538
- package/src/live-tokens/data/colors-and-type/ocean.json +521 -521
- package/src/live-tokens/data/colors-and-type/royal-velvet.json +532 -532
- package/src/live-tokens/data/colors-and-type/spring-meadow.json +504 -504
- package/src/live-tokens/data/colors-and-type/sunset.json +531 -531
- package/src/live-tokens/data/themes/autumn.json +527 -527
- package/src/live-tokens/data/themes/halloween.json +531 -531
- package/src/live-tokens/data/themes/midnight-study.json +537 -537
- package/src/live-tokens/data/themes/ocean.json +520 -520
- package/src/live-tokens/data/themes/royal-velvet.json +531 -531
- package/src/live-tokens/data/themes/spring-meadow.json +516 -514
- package/src/live-tokens/data/themes/sunset.json +531 -531
- package/src/live-tokens/data/tokens.generated.css +282 -282
- package/src/system/components/Button.svelte +2 -1
- package/src/system/components/FloatingTokenTags.css +2 -2
- package/src/system/components/FloatingTokenTags.svelte +11 -0
- package/src/system/components/IconButton.svelte +2 -1
- package/src/system/components/Image.svelte +9 -3
- package/src/system/components/ImageLightbox.svelte +2 -0
- package/src/system/components/SectionDivider.svelte +20 -2
- package/src/system/components/SideNavigation.svelte +15 -1
- package/src/system/internal/backgroundContrast.ts +7 -0
- package/src/system/internal/oklch.ts +189 -0
- package/src/system/styles/fonts.css +6 -6
- package/src/system/styles/tokens.css +283 -283
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,77 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.52.1 — Notification header actions are previewable
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **The Notification editor can show a header action.** The four
|
|
8
|
+
`--notification-*-action-surface` tokens paint the backdrop behind a
|
|
9
|
+
header-slot button, and no preview ever rendered one, so nothing in the
|
|
10
|
+
editor could show what they do. A "Header button" checkbox in the preview
|
|
11
|
+
toolbar turns the slot on.
|
|
12
|
+
|
|
13
|
+
## 0.52.0 — A third palette curve
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **Palettes gain a third curve, for hue.** Alongside Saturation and
|
|
18
|
+
Lightness, a Hue curve offsets each step by up to ±45 degrees, so a
|
|
19
|
+
palette can drift warmer or cooler across its ramp without moving
|
|
20
|
+
contrast. OKLCH keeps hue rotation close to lightness-preserving, which
|
|
21
|
+
makes that possible. The curve is closed by default, and existing
|
|
22
|
+
themes are unaffected: an absent hue curve renders as flat zero, exactly
|
|
23
|
+
as before.
|
|
24
|
+
|
|
25
|
+
## 0.51.0 — OKLCH end to end
|
|
26
|
+
|
|
27
|
+
### Changed (breaking)
|
|
28
|
+
|
|
29
|
+
- **Color tokens are written as `oklch()`, not hex.** The editor already
|
|
30
|
+
stored, edited, and computed color in OKLCH; only the final CSS string was
|
|
31
|
+
hex, which quantized every value to 8 bits on the way out. Derived colors now
|
|
32
|
+
serialize as `oklch()` in the live `:root` and in `tokens.generated.css`, and
|
|
33
|
+
`tokens.css` ships its 283 primitives in the same form. Values are still
|
|
34
|
+
clamped into the sRGB gamut before serialization, so nothing changes color.
|
|
35
|
+
Hex remains the readout and text-field format in the editor, and is still
|
|
36
|
+
what you copy out.
|
|
37
|
+
|
|
38
|
+
This sets a browser floor of Chrome 111, Safari 15.4, and Firefox 113
|
|
39
|
+
(2023). Run `npx live-tokens migrate` to convert a vendored `tokens.css`; the
|
|
40
|
+
transform is idempotent and touches values only, never names. Because it
|
|
41
|
+
rewrites values rather than renaming them, it never auto-applies — the dev
|
|
42
|
+
plugin will not touch your file.
|
|
43
|
+
|
|
44
|
+
Any code of your own that parses these tokens as hex needs updating. Inside
|
|
45
|
+
the package, the generator's contrast gate, the Color Story readouts, and the
|
|
46
|
+
runtime background-contrast picker were the three such readers.
|
|
47
|
+
|
|
48
|
+
## 0.50.0 — Live editing stays in sync
|
|
49
|
+
|
|
50
|
+
### Added
|
|
51
|
+
|
|
52
|
+
- **Save and Adopt can capture every unsaved component.** When component
|
|
53
|
+
editors have pending changes, the Theme panel offers to save them together
|
|
54
|
+
before saving or adopting the theme, so the look on screen can be persisted
|
|
55
|
+
without visiting each component editor first.
|
|
56
|
+
|
|
57
|
+
- **Font-weight choices follow the selected family.** The editor detects the
|
|
58
|
+
weights available for project and Google fonts, keeps the current custom
|
|
59
|
+
value visible, and avoids offering weights the font cannot render.
|
|
60
|
+
|
|
61
|
+
### Fixed
|
|
62
|
+
|
|
63
|
+
- **Theme changes paint as one transaction.** Loading, previewing, and applying
|
|
64
|
+
a theme now update colors, type, and components together instead of exposing
|
|
65
|
+
intermediate mixed states or flashing through the previous live look.
|
|
66
|
+
|
|
67
|
+
- **Editor controls react reliably to live token changes.** Reused selectors,
|
|
68
|
+
gradient controls, linked aliases, typography, spacing, and component state
|
|
69
|
+
now refresh when their bound variable or upstream token changes.
|
|
70
|
+
|
|
71
|
+
- **Component saves preserve migrated values.** Theme-level saves serialize
|
|
72
|
+
the current component state consistently, including corrected migration
|
|
73
|
+
handling for Section Divider and Corner Badge configurations.
|
|
74
|
+
|
|
3
75
|
## 0.49.1 — Automatic working-copy cleanup
|
|
4
76
|
|
|
5
77
|
### Fixed
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as AliasDiskValue, a as ComponentConfig } from '../themeTypes-
|
|
1
|
+
import { A as AliasDiskValue, a as ComponentConfig } from '../themeTypes-Dky03HL9.cjs';
|
|
2
2
|
export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-DBN0RPuT.cjs';
|
|
3
3
|
|
|
4
4
|
type AdjustKind = 'radius' | 'padding' | 'gap' | 'border-width';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as AliasDiskValue, a as ComponentConfig } from '../themeTypes-
|
|
1
|
+
import { A as AliasDiskValue, a as ComponentConfig } from '../themeTypes-Dky03HL9.js';
|
|
2
2
|
export { r as readLiveTokensConfig, a as resolveDataDirs } from '../dataPaths-DBN0RPuT.js';
|
|
3
3
|
|
|
4
4
|
type AdjustKind = 'radius' | 'padding' | 'gap' | 'border-width';
|
|
@@ -1,103 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cssColorToOklch,
|
|
3
|
+
gamutClamp,
|
|
4
|
+
oklchToCssClamped
|
|
5
|
+
} from "./chunk-YR6GPXW2.js";
|
|
6
|
+
|
|
1
7
|
// src/editor/core/storage/files/versionedFileResourceClient.ts
|
|
2
8
|
function sanitizeFileName(name) {
|
|
3
9
|
return name.toLowerCase().trim().replace(/\s+/g, "-").replace(/[^a-z0-9\-_]/g, "").replace(/-+/g, "-").replace(/^[-_]+|-+$/g, "") || "unnamed";
|
|
4
10
|
}
|
|
5
11
|
|
|
6
|
-
// src/editor/core/palettes/oklch.ts
|
|
7
|
-
function srgbToLinear(c) {
|
|
8
|
-
return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
|
|
9
|
-
}
|
|
10
|
-
function linearToSrgb(c) {
|
|
11
|
-
return c <= 31308e-7 ? 12.92 * c : 1.055 * Math.pow(c, 1 / 2.4) - 0.055;
|
|
12
|
-
}
|
|
13
|
-
function hexToLinearRgb(hex) {
|
|
14
|
-
const r = parseInt(hex.slice(1, 3), 16) / 255;
|
|
15
|
-
const g = parseInt(hex.slice(3, 5), 16) / 255;
|
|
16
|
-
const b = parseInt(hex.slice(5, 7), 16) / 255;
|
|
17
|
-
return [srgbToLinear(r), srgbToLinear(g), srgbToLinear(b)];
|
|
18
|
-
}
|
|
19
|
-
function linearRgbToHex(r, g, b) {
|
|
20
|
-
const toHex = (c) => {
|
|
21
|
-
const v = Math.round(Math.max(0, Math.min(1, linearToSrgb(c))) * 255);
|
|
22
|
-
return v.toString(16).padStart(2, "0");
|
|
23
|
-
};
|
|
24
|
-
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
25
|
-
}
|
|
26
|
-
function linearRgbToOklab(r, g, b) {
|
|
27
|
-
const l_ = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b;
|
|
28
|
-
const m_ = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b;
|
|
29
|
-
const s_ = 0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b;
|
|
30
|
-
const l = Math.cbrt(l_);
|
|
31
|
-
const m = Math.cbrt(m_);
|
|
32
|
-
const s = Math.cbrt(s_);
|
|
33
|
-
return [
|
|
34
|
-
0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,
|
|
35
|
-
1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,
|
|
36
|
-
0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s
|
|
37
|
-
];
|
|
38
|
-
}
|
|
39
|
-
function oklabToLinearRgb(L, a, b) {
|
|
40
|
-
const l_ = L + 0.3963377774 * a + 0.2158037573 * b;
|
|
41
|
-
const m_ = L - 0.1055613458 * a - 0.0638541728 * b;
|
|
42
|
-
const s_ = L - 0.0894841775 * a - 1.291485548 * b;
|
|
43
|
-
const l = l_ * l_ * l_;
|
|
44
|
-
const m = m_ * m_ * m_;
|
|
45
|
-
const s = s_ * s_ * s_;
|
|
46
|
-
return [
|
|
47
|
-
4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
|
|
48
|
-
-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
|
|
49
|
-
-0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s
|
|
50
|
-
];
|
|
51
|
-
}
|
|
52
|
-
function oklabToOklch(L, a, b) {
|
|
53
|
-
const c = Math.sqrt(a * a + b * b);
|
|
54
|
-
let h = Math.atan2(b, a) * 180 / Math.PI;
|
|
55
|
-
if (h < 0) h += 360;
|
|
56
|
-
return { l: L, c, h };
|
|
57
|
-
}
|
|
58
|
-
function oklchToOklab(l, c, h) {
|
|
59
|
-
const hRad = h * Math.PI / 180;
|
|
60
|
-
return [l, c * Math.cos(hRad), c * Math.sin(hRad)];
|
|
61
|
-
}
|
|
62
|
-
function hexToOklch(hex) {
|
|
63
|
-
const [r, g, b] = hexToLinearRgb(hex);
|
|
64
|
-
const [L, a, bVal] = linearRgbToOklab(r, g, b);
|
|
65
|
-
return oklabToOklch(L, a, bVal);
|
|
66
|
-
}
|
|
67
|
-
function oklchToHex(l, c, h) {
|
|
68
|
-
const [L, a, b] = oklchToOklab(l, c, h);
|
|
69
|
-
const [r, g, bVal] = oklabToLinearRgb(L, a, b);
|
|
70
|
-
return linearRgbToHex(r, g, bVal);
|
|
71
|
-
}
|
|
72
|
-
function isInGamut(r, g, b) {
|
|
73
|
-
const eps = 1e-4;
|
|
74
|
-
return r >= -eps && r <= 1 + eps && g >= -eps && g <= 1 + eps && b >= -eps && b <= 1 + eps;
|
|
75
|
-
}
|
|
76
|
-
function oklchToHexClamped(l, c, h) {
|
|
77
|
-
const g = gamutClamp(l, c, h);
|
|
78
|
-
return oklchToHex(g.l, g.c, g.h);
|
|
79
|
-
}
|
|
80
|
-
function gamutClamp(l, c, h) {
|
|
81
|
-
if (l <= 0) return { l: 0, c: 0, h };
|
|
82
|
-
if (l >= 1) return { l: 1, c: 0, h };
|
|
83
|
-
const [L, a, b] = oklchToOklab(l, c, h);
|
|
84
|
-
const [r, g, bVal] = oklabToLinearRgb(L, a, b);
|
|
85
|
-
if (isInGamut(r, g, bVal)) return { l, c, h };
|
|
86
|
-
let lo = 0;
|
|
87
|
-
let hi = c;
|
|
88
|
-
for (let i = 0; i < 20; i++) {
|
|
89
|
-
const mid = (lo + hi) / 2;
|
|
90
|
-
const [La, aa, ba] = oklchToOklab(l, mid, h);
|
|
91
|
-
const [rr, gg, bb] = oklabToLinearRgb(La, aa, ba);
|
|
92
|
-
if (isInGamut(rr, gg, bb)) {
|
|
93
|
-
lo = mid;
|
|
94
|
-
} else {
|
|
95
|
-
hi = mid;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
return { l, c: lo, h };
|
|
99
|
-
}
|
|
100
|
-
|
|
101
12
|
// src/editor/ui/curveEngine.ts
|
|
102
13
|
function makeAnchor(x, y, tangentLen = 15) {
|
|
103
14
|
return { x, y, inDx: -tangentLen, inDy: 0, outDx: tangentLen, outDy: 0 };
|
|
@@ -121,6 +32,15 @@ function tangentAnchor(x, y, prev, next) {
|
|
|
121
32
|
const outDx = next ? (next.x - x) * HANDLE_SPAN : 0;
|
|
122
33
|
return { x, y, inDx, inDy: m * inDx, outDx, outDy: m * outDx };
|
|
123
34
|
}
|
|
35
|
+
function isCornerAnchor(a) {
|
|
36
|
+
return a.inDx === 0 && a.inDy === 0 && a.outDx === 0 && a.outDy === 0;
|
|
37
|
+
}
|
|
38
|
+
function resmoothAutoCurve(anchors) {
|
|
39
|
+
if (anchors.length < 2) return anchors;
|
|
40
|
+
return anchors.map(
|
|
41
|
+
(a, i) => isCornerAnchor(a) ? a : tangentAnchor(a.x, a.y, anchors[i - 1] ?? null, anchors[i + 1] ?? null)
|
|
42
|
+
);
|
|
43
|
+
}
|
|
124
44
|
function evalBezier(p0x, p0y, c0x, c0y, c1x, c1y, p1x, p1y, t) {
|
|
125
45
|
const u = 1 - t, u2 = u * u, u3 = u2 * u;
|
|
126
46
|
const t2 = t * t, t3 = t2 * t;
|
|
@@ -216,37 +136,39 @@ var SCALES = [
|
|
|
216
136
|
];
|
|
217
137
|
var BW_GUARD_MIN_L = 0.17;
|
|
218
138
|
var BW_GUARD_MAX_L = 0.93;
|
|
219
|
-
var
|
|
220
|
-
var
|
|
139
|
+
var autoCurve = (...anchors) => resmoothAutoCurve(anchors);
|
|
140
|
+
var DEFAULT_PALETTE_LIGHTNESS = () => autoCurve(makeAnchor(0, 95), makeAnchor(100, 8));
|
|
141
|
+
var DEFAULT_PALETTE_SATURATION = () => autoCurve(makeAnchor(0, 100), makeAnchor(100, 100));
|
|
142
|
+
var wrapHue = (h) => (h % 360 + 360) % 360;
|
|
221
143
|
function scaleCurveDefaults(scheme = "dark") {
|
|
222
144
|
if (scheme === "light") {
|
|
223
145
|
return {
|
|
224
146
|
Surfaces: {
|
|
225
|
-
lightness: () =>
|
|
226
|
-
saturation: () =>
|
|
147
|
+
lightness: () => autoCurve(makeAnchor(0, 98), makeAnchor(100, 82)),
|
|
148
|
+
saturation: () => autoCurve(makeAnchor(0, 100), makeAnchor(100, 100))
|
|
227
149
|
},
|
|
228
150
|
Borders: {
|
|
229
|
-
lightness: () =>
|
|
230
|
-
saturation: () =>
|
|
151
|
+
lightness: () => autoCurve(makeAnchor(0, 92), makeAnchor(100, 45)),
|
|
152
|
+
saturation: () => autoCurve(makeAnchor(0, 100), makeAnchor(100, 100))
|
|
231
153
|
},
|
|
232
154
|
Text: {
|
|
233
|
-
lightness: () =>
|
|
234
|
-
saturation: () =>
|
|
155
|
+
lightness: () => autoCurve(makeAnchor(0, 30), makeAnchor(100, 120)),
|
|
156
|
+
saturation: () => autoCurve(makeAnchor(0, 100), makeAnchor(100, 15))
|
|
235
157
|
}
|
|
236
158
|
};
|
|
237
159
|
}
|
|
238
160
|
return {
|
|
239
161
|
Surfaces: {
|
|
240
|
-
lightness: () =>
|
|
241
|
-
saturation: () =>
|
|
162
|
+
lightness: () => autoCurve(makeAnchor(0, 15), makeAnchor(100, 47)),
|
|
163
|
+
saturation: () => autoCurve(makeAnchor(0, 100), makeAnchor(100, 100))
|
|
242
164
|
},
|
|
243
165
|
Borders: {
|
|
244
|
-
lightness: () =>
|
|
245
|
-
saturation: () =>
|
|
166
|
+
lightness: () => autoCurve(makeAnchor(0, 25), makeAnchor(100, 80)),
|
|
167
|
+
saturation: () => autoCurve(makeAnchor(0, 100), makeAnchor(100, 100))
|
|
246
168
|
},
|
|
247
169
|
Text: {
|
|
248
|
-
lightness: () =>
|
|
249
|
-
saturation: () =>
|
|
170
|
+
lightness: () => autoCurve(makeAnchor(0, 120), makeAnchor(100, 55)),
|
|
171
|
+
saturation: () => autoCurve(makeAnchor(0, 100), makeAnchor(100, 15))
|
|
250
172
|
}
|
|
251
173
|
};
|
|
252
174
|
}
|
|
@@ -265,14 +187,16 @@ function scaleStepToX(step, scale) {
|
|
|
265
187
|
return scale.steps.length > 1 ? idx / (scale.steps.length - 1) * 100 : 50;
|
|
266
188
|
}
|
|
267
189
|
function serializeDerivedValue(value) {
|
|
268
|
-
return value.kind === "raw" ? value.css :
|
|
190
|
+
return value.kind === "raw" ? value.css : oklchToCssClamped(value.l, value.c, value.h);
|
|
269
191
|
}
|
|
270
|
-
function computePaletteOklch(index, base, lightnessCurve, saturationCurve, curveOffset) {
|
|
271
|
-
const { c: baseC
|
|
192
|
+
function computePaletteOklch(index, base, lightnessCurve, saturationCurve, curveOffset, hueCurve) {
|
|
193
|
+
const { c: baseC } = base;
|
|
272
194
|
const xPos = stepIndexToX(index);
|
|
273
195
|
const targetL = Math.max(0, Math.min(100, sampleCurve(lightnessCurve, xPos) + (curveOffset.lightness ?? 0))) / 100;
|
|
274
196
|
const satMul = Math.max(0, Math.min(2, (sampleCurve(saturationCurve, xPos) + (curveOffset.saturation ?? 0)) / 100));
|
|
275
197
|
const targetC = baseC * satMul;
|
|
198
|
+
const hueDelta = (hueCurve ? sampleCurve(hueCurve, xPos) : 0) + (curveOffset.hue ?? 0);
|
|
199
|
+
const h = hueDelta === 0 ? base.h : wrapHue(base.h + hueDelta);
|
|
276
200
|
return gamutClamp(targetL, targetC, h);
|
|
277
201
|
}
|
|
278
202
|
function nearestPaletteStep(lightnessCurve, baseL) {
|
|
@@ -368,10 +292,12 @@ function syncBaseAnchor(cfg) {
|
|
|
368
292
|
const fresh = prev === void 0;
|
|
369
293
|
let lCurve = cfg.lightnessCurve;
|
|
370
294
|
let sCurve = cfg.saturationCurve;
|
|
295
|
+
let hCurve = cfg.hueCurve;
|
|
371
296
|
if (prev) {
|
|
372
297
|
const prevX = stepIndexToX(prev.step);
|
|
373
298
|
lCurve = liftCurveAnchor(lCurve, prevX, prev.displacedL);
|
|
374
299
|
sCurve = liftCurveAnchor(sCurve, prevX, prev.displacedS);
|
|
300
|
+
if (hCurve) hCurve = liftCurveAnchor(hCurve, prevX, prev.displacedH);
|
|
375
301
|
}
|
|
376
302
|
const step = nearestPaletteStep(lCurve, cfg.baseColor.l);
|
|
377
303
|
const x = stepIndexToX(step);
|
|
@@ -379,12 +305,19 @@ function syncBaseAnchor(cfg) {
|
|
|
379
305
|
const s = setCurveAnchor(sCurve, x, 100, fresh);
|
|
380
306
|
cfg.lightnessCurve = l.curve;
|
|
381
307
|
cfg.saturationCurve = s.curve;
|
|
308
|
+
const h = hCurve ? setCurveAnchor(hCurve, x, 0, fresh) : void 0;
|
|
309
|
+
if (h) cfg.hueCurve = h.curve;
|
|
382
310
|
cfg.anchorPlacement = {
|
|
383
311
|
step,
|
|
384
312
|
displacedL: l.displacedY,
|
|
385
313
|
displacedS: s.displacedY,
|
|
314
|
+
displacedH: h?.displacedY,
|
|
386
315
|
priorLightnessEndpoints: prev?.priorLightnessEndpoints ?? l.priorEndpoints,
|
|
387
|
-
priorSaturationEndpoints: prev?.priorSaturationEndpoints ?? s.priorEndpoints
|
|
316
|
+
priorSaturationEndpoints: prev?.priorSaturationEndpoints ?? s.priorEndpoints,
|
|
317
|
+
// No else-branch reading `prev?.priorHueEndpoints`: that could only fire
|
|
318
|
+
// if a placed hue curve later went absent, which RJC 7 (reset never
|
|
319
|
+
// deletes) never lets happen.
|
|
320
|
+
priorHueEndpoints: h ? prev?.priorHueEndpoints ?? h.priorEndpoints : void 0
|
|
388
321
|
};
|
|
389
322
|
}
|
|
390
323
|
function computeDerivedOklch(step, base, scaleTitle, scaleCurves, curveOffset) {
|
|
@@ -393,8 +326,10 @@ function computeDerivedOklch(step, base, scaleTitle, scaleCurves, curveOffset) {
|
|
|
393
326
|
const defs = defaultScaleCurves[scaleTitle];
|
|
394
327
|
const lCurve = scaleCurves[scaleTitle]?.lightness ?? defs.lightness();
|
|
395
328
|
const sCurve = scaleCurves[scaleTitle]?.saturation ?? defs.saturation();
|
|
329
|
+
const hCurve = scaleCurves[scaleTitle]?.hue;
|
|
396
330
|
const lOff = curveOffset[`${scaleTitle}-lightness`] ?? 0;
|
|
397
331
|
const sOff = curveOffset[`${scaleTitle}-saturation`] ?? 0;
|
|
332
|
+
const hOff = curveOffset[`${scaleTitle}-hue`] ?? 0;
|
|
398
333
|
const { l: baseL, c: baseC, h: baseH } = base;
|
|
399
334
|
let targetL;
|
|
400
335
|
if (scale.isText) {
|
|
@@ -405,7 +340,9 @@ function computeDerivedOklch(step, base, scaleTitle, scaleCurves, curveOffset) {
|
|
|
405
340
|
}
|
|
406
341
|
const satMul = Math.max(0, Math.min(2, (sampleCurve(sCurve, xPos) + sOff) / 100));
|
|
407
342
|
const targetC = baseC * satMul;
|
|
408
|
-
|
|
343
|
+
const hueDelta = (hCurve ? sampleCurve(hCurve, xPos) : 0) + hOff;
|
|
344
|
+
const targetH = hueDelta === 0 ? baseH : wrapHue(baseH + hueDelta);
|
|
345
|
+
return gamutClamp(targetL, targetC, targetH);
|
|
409
346
|
}
|
|
410
347
|
function scaleToCssVar(scaleTitle, stepName, cssNamespace) {
|
|
411
348
|
if (cssNamespace === null) return null;
|
|
@@ -434,7 +371,7 @@ function derivePaletteValues(spec, config) {
|
|
|
434
371
|
const saturationCurve = config.saturationCurve ?? DEFAULT_PALETTE_SATURATION();
|
|
435
372
|
PALETTE_STEPS.forEach((ps, index) => {
|
|
436
373
|
const k = paletteStepKey(ps.label);
|
|
437
|
-
const value = k in overrides ? { kind: "color", ...overrides[k] } : { kind: "color", ...computePaletteOklch(index, baseColor, lightnessCurve, saturationCurve, curveOffset) };
|
|
374
|
+
const value = k in overrides ? { kind: "color", ...overrides[k] } : { kind: "color", ...computePaletteOklch(index, baseColor, lightnessCurve, saturationCurve, curveOffset, config.hueCurve) };
|
|
438
375
|
out[`--color-${spec.cssNamespace}-${ps.label}`] = value;
|
|
439
376
|
});
|
|
440
377
|
for (const scale of SCALES) {
|
|
@@ -469,8 +406,8 @@ function derivePaletteValues(spec, config) {
|
|
|
469
406
|
);
|
|
470
407
|
const stopsCss = sortedStops.map((s) => {
|
|
471
408
|
const stopValue = out[`--color-${spec.cssNamespace}-${s.paletteLabel}`];
|
|
472
|
-
const
|
|
473
|
-
return `${
|
|
409
|
+
const css = stopValue ? serializeDerivedValue(stopValue) : "oklch(0 0 0)";
|
|
410
|
+
return `${css} ${s.position}%`;
|
|
474
411
|
}).join(", ");
|
|
475
412
|
let gradient;
|
|
476
413
|
switch (gradientStyle) {
|
|
@@ -489,13 +426,6 @@ function derivePaletteValues(spec, config) {
|
|
|
489
426
|
}
|
|
490
427
|
return out;
|
|
491
428
|
}
|
|
492
|
-
function derivePaletteVars(spec, config) {
|
|
493
|
-
const out = {};
|
|
494
|
-
for (const [k, v] of Object.entries(derivePaletteValues(spec, config))) {
|
|
495
|
-
out[k] = serializeDerivedValue(v);
|
|
496
|
-
}
|
|
497
|
-
return out;
|
|
498
|
-
}
|
|
499
429
|
function palettesToValues(palettes) {
|
|
500
430
|
const out = {};
|
|
501
431
|
for (const spec of PALETTE_SPECS) {
|
|
@@ -510,7 +440,6 @@ function palettesToVars(palettes) {
|
|
|
510
440
|
}
|
|
511
441
|
return out;
|
|
512
442
|
}
|
|
513
|
-
var HEX_RE = /^#[0-9a-f]{6}$/i;
|
|
514
443
|
function reconcilePalettesFromCssVars(palettes, cssVars) {
|
|
515
444
|
const next = structuredClone(palettes);
|
|
516
445
|
const consumed = /* @__PURE__ */ new Set();
|
|
@@ -519,16 +448,17 @@ function reconcilePalettesFromCssVars(palettes, cssVars) {
|
|
|
519
448
|
const current = next[spec.label];
|
|
520
449
|
if (current === void 0) continue;
|
|
521
450
|
if (current._imported === true) {
|
|
522
|
-
const
|
|
523
|
-
|
|
524
|
-
|
|
451
|
+
const anchor = cssVars[`--color-${spec.cssNamespace}-500`];
|
|
452
|
+
const anchorOklch = anchor ? cssColorToOklch(anchor) : null;
|
|
453
|
+
if (anchorOklch) {
|
|
454
|
+
next[spec.label] = { ...current, baseColor: anchorOklch, _imported: false };
|
|
525
455
|
syncBaseAnchor(next[spec.label]);
|
|
526
456
|
snapped.add(spec.label);
|
|
527
457
|
} else {
|
|
528
458
|
next[spec.label] = { ...current, _imported: false };
|
|
529
459
|
}
|
|
530
460
|
}
|
|
531
|
-
for (const k of Object.keys(
|
|
461
|
+
for (const k of Object.keys(derivePaletteValues(spec, next[spec.label]))) {
|
|
532
462
|
consumed.add(k);
|
|
533
463
|
}
|
|
534
464
|
}
|
|
@@ -537,10 +467,8 @@ function reconcilePalettesFromCssVars(palettes, cssVars) {
|
|
|
537
467
|
|
|
538
468
|
export {
|
|
539
469
|
sanitizeFileName,
|
|
540
|
-
hexToOklch,
|
|
541
|
-
oklchToHex,
|
|
542
|
-
gamutClamp,
|
|
543
470
|
makeAnchor,
|
|
471
|
+
resmoothAutoCurve,
|
|
544
472
|
PALETTE_SPECS,
|
|
545
473
|
PALETTE_STEPS,
|
|
546
474
|
SCALES,
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
hexToOklch,
|
|
3
|
+
oklchToCss
|
|
4
|
+
} from "./chunk-YR6GPXW2.js";
|
|
5
|
+
|
|
1
6
|
// src/editor/core/themes/parsers/globalRootBlock.ts
|
|
2
7
|
function extractGlobalRootBody(source) {
|
|
3
8
|
const re = /:global\(:root\)\s*\{([^}]*)\}/g;
|
|
@@ -12,11 +17,17 @@ function extractGlobalRootBody(source) {
|
|
|
12
17
|
// vite-plugin/tokensCssMigrations/cssTokenOps.ts
|
|
13
18
|
var DECL_RE = /(^|[\s;{])(--[a-z0-9-]+)\s*:/gi;
|
|
14
19
|
var REF_RE = /var\(\s*(--[a-z0-9-]+)/gi;
|
|
20
|
+
var DECL_VALUE_RE = /(^|[\s;{])(--[a-z0-9-]+)\s*:([^;}]*)/gi;
|
|
15
21
|
function collectDefinedTokens(css) {
|
|
16
22
|
const out = /* @__PURE__ */ new Set();
|
|
17
23
|
for (const m of css.matchAll(DECL_RE)) out.add(m[2]);
|
|
18
24
|
return out;
|
|
19
25
|
}
|
|
26
|
+
function collectTokenValues(css) {
|
|
27
|
+
const out = /* @__PURE__ */ new Map();
|
|
28
|
+
for (const m of css.matchAll(DECL_VALUE_RE)) out.set(m[2], m[3].trim());
|
|
29
|
+
return out;
|
|
30
|
+
}
|
|
20
31
|
function collectReferencedTokens(css) {
|
|
21
32
|
const out = /* @__PURE__ */ new Set();
|
|
22
33
|
for (const m of css.matchAll(REF_RE)) out.add(m[1]);
|
|
@@ -350,6 +361,20 @@ var tokensCssMigration_2026_07_20_semanticTextStyles = {
|
|
|
350
361
|
}
|
|
351
362
|
};
|
|
352
363
|
|
|
364
|
+
// vite-plugin/tokensCssMigrations/migrations/2026-08-19-oklch-color-values.ts
|
|
365
|
+
var HEX_DECLARATION_RE = /(--[a-z0-9-]+:\s*)#([0-9a-f]{6})(?=\s*[;}])/gi;
|
|
366
|
+
var tokensCssMigration_2026_08_19_oklchColorValues = {
|
|
367
|
+
id: "2026-08-19-oklch-color-values",
|
|
368
|
+
kind: "breaking",
|
|
369
|
+
description: "Rewrite hex token values as oklch()",
|
|
370
|
+
apply(css) {
|
|
371
|
+
return css.replace(HEX_DECLARATION_RE, (_match, prefix, hex) => {
|
|
372
|
+
const { l, c, h } = hexToOklch(`#${hex}`);
|
|
373
|
+
return `${prefix}${oklchToCss(l, c, h)}`;
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
|
|
353
378
|
// vite-plugin/tokensCssMigrations/index.ts
|
|
354
379
|
var TOKENS_CSS_MIGRATIONS = [
|
|
355
380
|
tokensCssMigration_2026_05_29_typographyScaleAdditions,
|
|
@@ -358,7 +383,8 @@ var TOKENS_CSS_MIGRATIONS = [
|
|
|
358
383
|
tokensCssMigration_2026_06_04_removeDeadSizeIconScale,
|
|
359
384
|
tokensCssMigration_2026_06_04_easingColorAndTypescaleAdditions,
|
|
360
385
|
tokensCssMigration_2026_07_20_lineHeightRename,
|
|
361
|
-
tokensCssMigration_2026_07_20_semanticTextStyles
|
|
386
|
+
tokensCssMigration_2026_07_20_semanticTextStyles,
|
|
387
|
+
tokensCssMigration_2026_08_19_oklchColorValues
|
|
362
388
|
];
|
|
363
389
|
function runTokensCssMigrations(css) {
|
|
364
390
|
return foldMigrations(css, () => true);
|
|
@@ -383,10 +409,11 @@ function findContractViolations(canonicalCss) {
|
|
|
383
409
|
const violations = [];
|
|
384
410
|
for (const m of TOKENS_CSS_MIGRATIONS) {
|
|
385
411
|
if (m.kind !== "additive") continue;
|
|
386
|
-
const before =
|
|
387
|
-
const after =
|
|
388
|
-
const removed = [...before].filter((t) => !after.has(t)).sort();
|
|
389
|
-
|
|
412
|
+
const before = collectTokenValues(canonicalCss);
|
|
413
|
+
const after = collectTokenValues(m.apply(canonicalCss));
|
|
414
|
+
const removed = [...before.keys()].filter((t) => !after.has(t)).sort();
|
|
415
|
+
const changed = [...before.entries()].filter(([t, v]) => after.has(t) && after.get(t) !== v).map(([t]) => t).sort();
|
|
416
|
+
if (removed.length || changed.length) violations.push({ id: m.id, removed, changed });
|
|
390
417
|
}
|
|
391
418
|
return violations;
|
|
392
419
|
}
|
|
@@ -446,6 +473,7 @@ function validateTokensCss(input) {
|
|
|
446
473
|
export {
|
|
447
474
|
extractGlobalRootBody,
|
|
448
475
|
collectDefinedTokens,
|
|
476
|
+
collectTokenValues,
|
|
449
477
|
collectReferencedTokens,
|
|
450
478
|
ensureScale,
|
|
451
479
|
renameToken,
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
// src/system/internal/oklch.ts
|
|
2
|
+
function srgbToLinear(c) {
|
|
3
|
+
return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
|
|
4
|
+
}
|
|
5
|
+
function linearToSrgb(c) {
|
|
6
|
+
return c <= 31308e-7 ? 12.92 * c : 1.055 * Math.pow(c, 1 / 2.4) - 0.055;
|
|
7
|
+
}
|
|
8
|
+
function hexToLinearRgb(hex) {
|
|
9
|
+
const r = parseInt(hex.slice(1, 3), 16) / 255;
|
|
10
|
+
const g = parseInt(hex.slice(3, 5), 16) / 255;
|
|
11
|
+
const b = parseInt(hex.slice(5, 7), 16) / 255;
|
|
12
|
+
return [srgbToLinear(r), srgbToLinear(g), srgbToLinear(b)];
|
|
13
|
+
}
|
|
14
|
+
function linearRgbToHex(r, g, b) {
|
|
15
|
+
const toHex = (c) => {
|
|
16
|
+
const v = Math.round(Math.max(0, Math.min(1, linearToSrgb(c))) * 255);
|
|
17
|
+
return v.toString(16).padStart(2, "0");
|
|
18
|
+
};
|
|
19
|
+
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
20
|
+
}
|
|
21
|
+
function linearRgbToOklab(r, g, b) {
|
|
22
|
+
const l_ = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b;
|
|
23
|
+
const m_ = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b;
|
|
24
|
+
const s_ = 0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b;
|
|
25
|
+
const l = Math.cbrt(l_);
|
|
26
|
+
const m = Math.cbrt(m_);
|
|
27
|
+
const s = Math.cbrt(s_);
|
|
28
|
+
return [
|
|
29
|
+
0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,
|
|
30
|
+
1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,
|
|
31
|
+
0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
function oklabToLinearRgb(L, a, b) {
|
|
35
|
+
const l_ = L + 0.3963377774 * a + 0.2158037573 * b;
|
|
36
|
+
const m_ = L - 0.1055613458 * a - 0.0638541728 * b;
|
|
37
|
+
const s_ = L - 0.0894841775 * a - 1.291485548 * b;
|
|
38
|
+
const l = l_ * l_ * l_;
|
|
39
|
+
const m = m_ * m_ * m_;
|
|
40
|
+
const s = s_ * s_ * s_;
|
|
41
|
+
return [
|
|
42
|
+
4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
|
|
43
|
+
-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
|
|
44
|
+
-0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s
|
|
45
|
+
];
|
|
46
|
+
}
|
|
47
|
+
function oklabToOklch(L, a, b) {
|
|
48
|
+
const c = Math.sqrt(a * a + b * b);
|
|
49
|
+
let h = Math.atan2(b, a) * 180 / Math.PI;
|
|
50
|
+
if (h < 0) h += 360;
|
|
51
|
+
return { l: L, c, h };
|
|
52
|
+
}
|
|
53
|
+
function oklchToOklab(l, c, h) {
|
|
54
|
+
const hRad = h * Math.PI / 180;
|
|
55
|
+
return [l, c * Math.cos(hRad), c * Math.sin(hRad)];
|
|
56
|
+
}
|
|
57
|
+
function hexToOklch(hex) {
|
|
58
|
+
const [r, g, b] = hexToLinearRgb(hex);
|
|
59
|
+
const [L, a, bVal] = linearRgbToOklab(r, g, b);
|
|
60
|
+
return oklabToOklch(L, a, bVal);
|
|
61
|
+
}
|
|
62
|
+
function oklchToHex(l, c, h) {
|
|
63
|
+
const [L, a, b] = oklchToOklab(l, c, h);
|
|
64
|
+
const [r, g, bVal] = oklabToLinearRgb(L, a, b);
|
|
65
|
+
return linearRgbToHex(r, g, bVal);
|
|
66
|
+
}
|
|
67
|
+
function isInGamut(r, g, b) {
|
|
68
|
+
const eps = 1e-4;
|
|
69
|
+
return r >= -eps && r <= 1 + eps && g >= -eps && g <= 1 + eps && b >= -eps && b <= 1 + eps;
|
|
70
|
+
}
|
|
71
|
+
function oklchToHexClamped(l, c, h) {
|
|
72
|
+
const g = gamutClamp(l, c, h);
|
|
73
|
+
return oklchToHex(g.l, g.c, g.h);
|
|
74
|
+
}
|
|
75
|
+
function gamutClamp(l, c, h) {
|
|
76
|
+
if (l <= 0) return { l: 0, c: 0, h };
|
|
77
|
+
if (l >= 1) return { l: 1, c: 0, h };
|
|
78
|
+
const [L, a, b] = oklchToOklab(l, c, h);
|
|
79
|
+
const [r, g, bVal] = oklabToLinearRgb(L, a, b);
|
|
80
|
+
if (isInGamut(r, g, bVal)) return { l, c, h };
|
|
81
|
+
let lo = 0;
|
|
82
|
+
let hi = c;
|
|
83
|
+
for (let i = 0; i < 20; i++) {
|
|
84
|
+
const mid = (lo + hi) / 2;
|
|
85
|
+
const [La, aa, ba] = oklchToOklab(l, mid, h);
|
|
86
|
+
const [rr, gg, bb] = oklabToLinearRgb(La, aa, ba);
|
|
87
|
+
if (isInGamut(rr, gg, bb)) {
|
|
88
|
+
lo = mid;
|
|
89
|
+
} else {
|
|
90
|
+
hi = mid;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return { l, c: lo, h };
|
|
94
|
+
}
|
|
95
|
+
function trim(value, decimals) {
|
|
96
|
+
return Number(value.toFixed(decimals)).toString();
|
|
97
|
+
}
|
|
98
|
+
function oklchToCss(l, c, h) {
|
|
99
|
+
const cs = trim(c, 4);
|
|
100
|
+
return `oklch(${trim(l, 4)} ${cs} ${cs === "0" ? "0" : trim(h, 2)})`;
|
|
101
|
+
}
|
|
102
|
+
function oklchToCssClamped(l, c, h) {
|
|
103
|
+
const g = gamutClamp(l, c, h);
|
|
104
|
+
return oklchToCss(g.l, g.c, g.h);
|
|
105
|
+
}
|
|
106
|
+
var OKLCH_RE = /^oklch\(\s*([\d.]+)(%?)\s+([\d.]+)(%?)\s+([\d.]+)(?:deg)?\s*\)$/i;
|
|
107
|
+
var HEX6_RE = /^#[0-9a-f]{6}$/i;
|
|
108
|
+
function parseOklchCss(value) {
|
|
109
|
+
const m = OKLCH_RE.exec(value.trim());
|
|
110
|
+
if (!m) return null;
|
|
111
|
+
const l = Number.parseFloat(m[1]) / (m[2] === "%" ? 100 : 1);
|
|
112
|
+
const c = Number.parseFloat(m[3]) * (m[4] === "%" ? 4e-3 : 1);
|
|
113
|
+
return { l, c, h: Number.parseFloat(m[5]) };
|
|
114
|
+
}
|
|
115
|
+
function cssColorToOklch(value) {
|
|
116
|
+
const raw = value.trim();
|
|
117
|
+
if (HEX6_RE.test(raw)) return hexToOklch(raw);
|
|
118
|
+
return parseOklchCss(raw);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export {
|
|
122
|
+
hexToOklch,
|
|
123
|
+
oklchToHex,
|
|
124
|
+
oklchToHexClamped,
|
|
125
|
+
gamutClamp,
|
|
126
|
+
oklchToCss,
|
|
127
|
+
oklchToCssClamped,
|
|
128
|
+
cssColorToOklch
|
|
129
|
+
};
|