@arbidocs/blocks 0.5.63 → 0.5.65
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ConnectedDocumentViewer-7VKAM6KD.js → ConnectedDocumentViewer-HKIBNGGG.js} +10 -9
- package/dist/{ConnectedDocumentViewer-7VKAM6KD.js.map → ConnectedDocumentViewer-HKIBNGGG.js.map} +1 -1
- package/dist/{ConnectedDocumentViewer-FGQ27H4B.cjs → ConnectedDocumentViewer-YSZWOVGN.cjs} +11 -10
- package/dist/{ConnectedDocumentViewer-FGQ27H4B.cjs.map → ConnectedDocumentViewer-YSZWOVGN.cjs.map} +1 -1
- package/dist/{ConnectedNativeDocxComparison-HJ4FTVH6.cjs → ConnectedNativeDocxComparison-L3R3ROPZ.cjs} +7 -7
- package/dist/{ConnectedNativeDocxComparison-HJ4FTVH6.cjs.map → ConnectedNativeDocxComparison-L3R3ROPZ.cjs.map} +1 -1
- package/dist/{ConnectedNativeDocxComparison-FPW3BNBN.js → ConnectedNativeDocxComparison-PSAP3Q7D.js} +6 -6
- package/dist/{ConnectedNativeDocxComparison-FPW3BNBN.js.map → ConnectedNativeDocxComparison-PSAP3Q7D.js.map} +1 -1
- package/dist/{ConnectedNativeDocxEditor-S7NJMDSU.js → ConnectedNativeDocxEditor-PI6QTPXZ.js} +5 -5
- package/dist/{ConnectedNativeDocxEditor-S7NJMDSU.js.map → ConnectedNativeDocxEditor-PI6QTPXZ.js.map} +1 -1
- package/dist/{ConnectedNativeDocxEditor-PF46MU5H.cjs → ConnectedNativeDocxEditor-VDBC4XRT.cjs} +7 -7
- package/dist/{ConnectedNativeDocxEditor-PF46MU5H.cjs.map → ConnectedNativeDocxEditor-VDBC4XRT.cjs.map} +1 -1
- package/dist/{ConnectedStreamedWordArtifact-5MHLV24V.js → ConnectedStreamedWordArtifact-V4MTKVNE.js} +6 -6
- package/dist/ConnectedStreamedWordArtifact-V4MTKVNE.js.map +1 -0
- package/dist/{ConnectedStreamedWordArtifact-LNGW7YGV.cjs → ConnectedStreamedWordArtifact-YSW6D7AG.cjs} +7 -7
- package/dist/ConnectedStreamedWordArtifact-YSW6D7AG.cjs.map +1 -0
- package/dist/{DocumentReviewCard-VFNMJSK7.cjs → DocumentReviewCard-BQ6ZD5MD.cjs} +6 -6
- package/dist/{DocumentReviewCard-VFNMJSK7.cjs.map → DocumentReviewCard-BQ6ZD5MD.cjs.map} +1 -1
- package/dist/{DocumentReviewCard-5U3TGJZA.js → DocumentReviewCard-TQQADJ36.js} +6 -6
- package/dist/{DocumentReviewCard-5U3TGJZA.js.map → DocumentReviewCard-TQQADJ36.js.map} +1 -1
- package/dist/{WorkspaceTableView-DHMCJRC6.cjs → WorkspaceTableView-GKMVTECZ.cjs} +6 -6
- package/dist/{WorkspaceTableView-DHMCJRC6.cjs.map → WorkspaceTableView-GKMVTECZ.cjs.map} +1 -1
- package/dist/{WorkspaceTableView-EH5CEB44.js → WorkspaceTableView-YFLVFRJL.js} +4 -4
- package/dist/{WorkspaceTableView-EH5CEB44.js.map → WorkspaceTableView-YFLVFRJL.js.map} +1 -1
- package/dist/agents/index.cjs +345 -344
- package/dist/agents/index.js +6 -5
- package/dist/{chunk-NDVLCOWS.js → chunk-2LUA7UDE.js} +7 -7
- package/dist/{chunk-NDVLCOWS.js.map → chunk-2LUA7UDE.js.map} +1 -1
- package/dist/{chunk-77IAOKZO.js → chunk-2VH2PT3J.js} +5 -38
- package/dist/chunk-2VH2PT3J.js.map +1 -0
- package/dist/{chunk-IC6SBDYA.js → chunk-4CI42DCG.js} +3 -3
- package/dist/{chunk-IC6SBDYA.js.map → chunk-4CI42DCG.js.map} +1 -1
- package/dist/{chunk-IFLFLP4K.js → chunk-4Q7ON335.js} +6 -5
- package/dist/chunk-4Q7ON335.js.map +1 -0
- package/dist/{chunk-IUFS3AYQ.js → chunk-5EGTGHBW.js} +7 -7
- package/dist/{chunk-IUFS3AYQ.js.map → chunk-5EGTGHBW.js.map} +1 -1
- package/dist/{chunk-OLDGMBEF.cjs → chunk-67AFX23Y.cjs} +185 -91
- package/dist/chunk-67AFX23Y.cjs.map +1 -0
- package/dist/{chunk-5CWBAINB.js → chunk-6OMIIF76.js} +3 -3
- package/dist/{chunk-5CWBAINB.js.map → chunk-6OMIIF76.js.map} +1 -1
- package/dist/chunk-6QZ35CTZ.js +594 -0
- package/dist/chunk-6QZ35CTZ.js.map +1 -0
- package/dist/{chunk-4RJPTXUQ.cjs → chunk-7MOQO6NO.cjs} +5 -5
- package/dist/{chunk-4RJPTXUQ.cjs.map → chunk-7MOQO6NO.cjs.map} +1 -1
- package/dist/chunk-AESJLGMC.cjs +1228 -0
- package/dist/chunk-AESJLGMC.cjs.map +1 -0
- package/dist/{chunk-EOIJ5JYP.cjs → chunk-B3CRSCLK.cjs} +4 -4
- package/dist/{chunk-EOIJ5JYP.cjs.map → chunk-B3CRSCLK.cjs.map} +1 -1
- package/dist/{chunk-GRDLCRNL.js → chunk-BELZ2WD2.js} +5 -5
- package/dist/{chunk-GRDLCRNL.js.map → chunk-BELZ2WD2.js.map} +1 -1
- package/dist/chunk-C2S246BV.js +1225 -0
- package/dist/chunk-C2S246BV.js.map +1 -0
- package/dist/{chunk-TAI23FCY.js → chunk-CEKOZAGO.js} +3 -3
- package/dist/{chunk-TAI23FCY.js.map → chunk-CEKOZAGO.js.map} +1 -1
- package/dist/{chunk-HVOPUYAG.cjs → chunk-CJF7B5A7.cjs} +29 -28
- package/dist/chunk-CJF7B5A7.cjs.map +1 -0
- package/dist/{chunk-LBKTTQUR.cjs → chunk-CMYJEIZB.cjs} +12 -12
- package/dist/{chunk-LBKTTQUR.cjs.map → chunk-CMYJEIZB.cjs.map} +1 -1
- package/dist/{chunk-2SLDVFOZ.js → chunk-CRHY7DBO.js} +3 -3
- package/dist/{chunk-2SLDVFOZ.js.map → chunk-CRHY7DBO.js.map} +1 -1
- package/dist/{chunk-23ACBETH.cjs → chunk-D27BBGUF.cjs} +4 -4
- package/dist/{chunk-23ACBETH.cjs.map → chunk-D27BBGUF.cjs.map} +1 -1
- package/dist/{chunk-3X37I6QE.cjs → chunk-DJE2E7YH.cjs} +29 -29
- package/dist/{chunk-3X37I6QE.cjs.map → chunk-DJE2E7YH.cjs.map} +1 -1
- package/dist/{chunk-CCSF7RI4.cjs → chunk-EG3BB32W.cjs} +3 -3
- package/dist/{chunk-CCSF7RI4.cjs.map → chunk-EG3BB32W.cjs.map} +1 -1
- package/dist/{chunk-MAKTAR7H.cjs → chunk-F777MGVA.cjs} +18 -18
- package/dist/{chunk-MAKTAR7H.cjs.map → chunk-F777MGVA.cjs.map} +1 -1
- package/dist/{chunk-TFWCREOL.js → chunk-GPYLXEZO.js} +9 -506
- package/dist/chunk-GPYLXEZO.js.map +1 -0
- package/dist/{chunk-OY3I32ZS.js → chunk-GX37C5QT.js} +4 -4
- package/dist/{chunk-OY3I32ZS.js.map → chunk-GX37C5QT.js.map} +1 -1
- package/dist/chunk-I4IS6ST6.cjs +48 -0
- package/dist/chunk-I4IS6ST6.cjs.map +1 -0
- package/dist/{chunk-OZL5ABLF.js → chunk-IRXPUQFP.js} +3 -3
- package/dist/{chunk-OZL5ABLF.js.map → chunk-IRXPUQFP.js.map} +1 -1
- package/dist/chunk-J77BACGX.js +575 -0
- package/dist/chunk-J77BACGX.js.map +1 -0
- package/dist/{chunk-X3JJTHQ4.cjs → chunk-JSHBC47B.cjs} +55 -55
- package/dist/{chunk-X3JJTHQ4.cjs.map → chunk-JSHBC47B.cjs.map} +1 -1
- package/dist/{chunk-Y6ZNWC7E.cjs → chunk-K26RLK2Y.cjs} +3 -3
- package/dist/{chunk-Y6ZNWC7E.cjs.map → chunk-K26RLK2Y.cjs.map} +1 -1
- package/dist/{chunk-PKDPQS6Z.js → chunk-KNOSLLTC.js} +3 -3
- package/dist/{chunk-PKDPQS6Z.js.map → chunk-KNOSLLTC.js.map} +1 -1
- package/dist/chunk-LFS6UWSJ.cjs +602 -0
- package/dist/chunk-LFS6UWSJ.cjs.map +1 -0
- package/dist/{chunk-YQFEN7UJ.js → chunk-LNH6NYG4.js} +6 -90
- package/dist/chunk-LNH6NYG4.js.map +1 -0
- package/dist/chunk-LRPGXNMA.js +44 -0
- package/dist/chunk-LRPGXNMA.js.map +1 -0
- package/dist/chunk-NEGFHF3V.cjs +617 -0
- package/dist/chunk-NEGFHF3V.cjs.map +1 -0
- package/dist/{chunk-NHPBONMR.js → chunk-O4FBMC6S.js} +186 -71
- package/dist/chunk-O4FBMC6S.js.map +1 -0
- package/dist/{chunk-7P24MJQN.js → chunk-PBIFISDD.js} +3 -3
- package/dist/{chunk-7P24MJQN.js.map → chunk-PBIFISDD.js.map} +1 -1
- package/dist/{chunk-OWUNCJFO.cjs → chunk-PZOX4JF6.cjs} +30 -30
- package/dist/{chunk-OWUNCJFO.cjs.map → chunk-PZOX4JF6.cjs.map} +1 -1
- package/dist/{chunk-CKNUL4LM.cjs → chunk-QK546T4C.cjs} +3 -3
- package/dist/{chunk-CKNUL4LM.cjs.map → chunk-QK546T4C.cjs.map} +1 -1
- package/dist/{chunk-QAXIVZEJ.cjs → chunk-ROWJU4SK.cjs} +13 -513
- package/dist/chunk-ROWJU4SK.cjs.map +1 -0
- package/dist/{chunk-JWRTUYLC.js → chunk-SBAM3UZX.js} +3 -3
- package/dist/{chunk-JWRTUYLC.js.map → chunk-SBAM3UZX.js.map} +1 -1
- package/dist/{chunk-COZDIUG7.cjs → chunk-TJ7QEGVP.cjs} +18 -18
- package/dist/{chunk-COZDIUG7.cjs.map → chunk-TJ7QEGVP.cjs.map} +1 -1
- package/dist/{chunk-PVPGD6QR.js → chunk-VWM3J6ES.js} +3 -3
- package/dist/{chunk-PVPGD6QR.js.map → chunk-VWM3J6ES.js.map} +1 -1
- package/dist/{chunk-UDMII47W.cjs → chunk-WBLCPCWR.cjs} +7 -7
- package/dist/{chunk-UDMII47W.cjs.map → chunk-WBLCPCWR.cjs.map} +1 -1
- package/dist/{chunk-3T3IKNGF.cjs → chunk-ZXW6WFZG.cjs} +5 -41
- package/dist/chunk-ZXW6WFZG.cjs.map +1 -0
- package/dist/{chunk-ODQK3LX5.cjs → chunk-ZZHMJXM5.cjs} +4 -93
- package/dist/chunk-ZZHMJXM5.cjs.map +1 -0
- package/dist/connect/docx.cjs +11 -11
- package/dist/connect/docx.js +7 -7
- package/dist/connect/index.cjs +496 -493
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.js +36 -33
- package/dist/connect/index.js.map +1 -1
- package/dist/connect/viewer.cjs +9 -8
- package/dist/connect/viewer.js +8 -7
- package/dist/dashboards/index.cjs +1 -1
- package/dist/dashboards/index.js +1 -1
- package/dist/document-tools/index.cjs +17 -17
- package/dist/document-tools/index.js +2 -2
- package/dist/embed/index.cjs +11 -10
- package/dist/embed/index.js +8 -7
- package/dist/facts/index.cjs +1 -1
- package/dist/facts/index.js +1 -1
- package/dist/files/index.cjs +1 -1
- package/dist/files/index.js +1 -1
- package/dist/index.cjs +653 -618
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +19 -16
- package/dist/index.js.map +1 -1
- package/dist/shell/index.cjs +78 -77
- package/dist/shell/index.js +3 -2
- package/dist/site/index.cjs +105 -81
- package/dist/site/index.d.ts +3 -1
- package/dist/site/index.js +4 -4
- package/dist/studio/index.cjs +60 -55
- package/dist/studio/index.cjs.map +1 -1
- package/dist/studio/index.js +12 -7
- package/dist/studio/index.js.map +1 -1
- package/dist/theme/ThemeControls.d.ts +71 -0
- package/dist/theme/ThemeEditor.d.ts +5 -2
- package/dist/theme/ThemePreview.d.ts +20 -0
- package/dist/theme/color.d.ts +17 -1
- package/dist/theme/derive.d.ts +75 -0
- package/dist/theme/editorModel.d.ts +36 -0
- package/dist/theme/previewLabels.d.ts +38 -0
- package/dist/theme/store.d.ts +51 -13
- package/dist/theme/tokens.d.ts +2 -0
- package/dist/workflow-canvas/index.cjs +37 -36
- package/dist/workflow-canvas/index.cjs.map +1 -1
- package/dist/workflow-canvas/index.js +13 -12
- package/dist/workflow-canvas/index.js.map +1 -1
- package/node_modules/@arbidocs/coedit/package.json +1 -1
- package/package.json +5 -5
- package/dist/ConnectedStreamedWordArtifact-5MHLV24V.js.map +0 -1
- package/dist/ConnectedStreamedWordArtifact-LNGW7YGV.cjs.map +0 -1
- package/dist/chunk-3T3IKNGF.cjs.map +0 -1
- package/dist/chunk-77IAOKZO.js.map +0 -1
- package/dist/chunk-HVOPUYAG.cjs.map +0 -1
- package/dist/chunk-IFLFLP4K.js.map +0 -1
- package/dist/chunk-N5WJBQYF.cjs +0 -476
- package/dist/chunk-N5WJBQYF.cjs.map +0 -1
- package/dist/chunk-NHPBONMR.js.map +0 -1
- package/dist/chunk-ODQK3LX5.cjs.map +0 -1
- package/dist/chunk-OLDGMBEF.cjs.map +0 -1
- package/dist/chunk-QAXIVZEJ.cjs.map +0 -1
- package/dist/chunk-QCLYRNOC.js +0 -466
- package/dist/chunk-QCLYRNOC.js.map +0 -1
- package/dist/chunk-TFWCREOL.js.map +0 -1
- package/dist/chunk-YQFEN7UJ.js.map +0 -1
|
@@ -0,0 +1,575 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
|
4
|
+
import { cn } from '@arbidocs/react/ui';
|
|
5
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
// src/theme/color.ts
|
|
8
|
+
var NUM = String.raw`-?\d*\.?\d+(?:e-?\d+)?`;
|
|
9
|
+
var TRIPLET_RE = new RegExp(String.raw`^(${NUM})(?:deg)?\s+(${NUM})%\s+(${NUM})%$`);
|
|
10
|
+
var HSL_FN_RE = new RegExp(
|
|
11
|
+
String.raw`^hsla?\(\s*(${NUM})(?:deg)?[\s,]+(${NUM})%[\s,]+(${NUM})%\s*(?:[,/]\s*${NUM}%?\s*)?\)$`,
|
|
12
|
+
"i"
|
|
13
|
+
);
|
|
14
|
+
var RGB_FN_RE = new RegExp(
|
|
15
|
+
String.raw`^rgba?\(\s*(${NUM})[\s,]+(${NUM})[\s,]+(${NUM})\s*(?:[,/]\s*${NUM}%?\s*)?\)$`,
|
|
16
|
+
"i"
|
|
17
|
+
);
|
|
18
|
+
var clamp = (n, lo, hi) => Math.min(hi, Math.max(lo, n));
|
|
19
|
+
var fmt = (n) => String(Math.round(n * 10) / 10);
|
|
20
|
+
function rgbToHsl({ r, g, b }) {
|
|
21
|
+
const rn = r / 255;
|
|
22
|
+
const gn = g / 255;
|
|
23
|
+
const bn = b / 255;
|
|
24
|
+
const max = Math.max(rn, gn, bn);
|
|
25
|
+
const min = Math.min(rn, gn, bn);
|
|
26
|
+
const l = (max + min) / 2;
|
|
27
|
+
const d = max - min;
|
|
28
|
+
let h = 0;
|
|
29
|
+
let s = 0;
|
|
30
|
+
if (d !== 0) {
|
|
31
|
+
s = d / (1 - Math.abs(2 * l - 1));
|
|
32
|
+
if (max === rn) h = 60 * ((gn - bn) / d % 6);
|
|
33
|
+
else if (max === gn) h = 60 * ((bn - rn) / d + 2);
|
|
34
|
+
else h = 60 * ((rn - gn) / d + 4);
|
|
35
|
+
}
|
|
36
|
+
if (h < 0) h += 360;
|
|
37
|
+
return { h, s: s * 100, l: l * 100 };
|
|
38
|
+
}
|
|
39
|
+
function hslToRgb({ h, s, l }) {
|
|
40
|
+
const sn = clamp(s, 0, 100) / 100;
|
|
41
|
+
const ln = clamp(l, 0, 100) / 100;
|
|
42
|
+
const hn = (h % 360 + 360) % 360;
|
|
43
|
+
const c = (1 - Math.abs(2 * ln - 1)) * sn;
|
|
44
|
+
const x = c * (1 - Math.abs(hn / 60 % 2 - 1));
|
|
45
|
+
const m = ln - c / 2;
|
|
46
|
+
const [r1, g1, b1] = hn < 60 ? [c, x, 0] : hn < 120 ? [x, c, 0] : hn < 180 ? [0, c, x] : hn < 240 ? [0, x, c] : hn < 300 ? [x, 0, c] : [c, 0, x];
|
|
47
|
+
return { r: (r1 + m) * 255, g: (g1 + m) * 255, b: (b1 + m) * 255 };
|
|
48
|
+
}
|
|
49
|
+
function parseHex(value) {
|
|
50
|
+
let hex = value.slice(1);
|
|
51
|
+
if (hex.length === 3 || hex.length === 4) {
|
|
52
|
+
hex = hex.slice(0, 3).split("").map((ch) => ch + ch).join("");
|
|
53
|
+
} else if (hex.length === 8) {
|
|
54
|
+
hex = hex.slice(0, 6);
|
|
55
|
+
}
|
|
56
|
+
if (!/^[0-9a-fA-F]{6}$/.test(hex)) return null;
|
|
57
|
+
return {
|
|
58
|
+
r: parseInt(hex.slice(0, 2), 16),
|
|
59
|
+
g: parseInt(hex.slice(2, 4), 16),
|
|
60
|
+
b: parseInt(hex.slice(4, 6), 16)
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function parseColor(value) {
|
|
64
|
+
const c = value.trim();
|
|
65
|
+
if (c.startsWith("#")) return parseHex(c);
|
|
66
|
+
const rgb = RGB_FN_RE.exec(c);
|
|
67
|
+
if (rgb) return { r: Number(rgb[1]), g: Number(rgb[2]), b: Number(rgb[3]) };
|
|
68
|
+
const hsl2 = HSL_FN_RE.exec(c) ?? TRIPLET_RE.exec(c);
|
|
69
|
+
if (hsl2) return hslToRgb({ h: Number(hsl2[1]), s: Number(hsl2[2]), l: Number(hsl2[3]) });
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
function parseHsl(value) {
|
|
73
|
+
const c = value.trim();
|
|
74
|
+
const m = TRIPLET_RE.exec(c) ?? HSL_FN_RE.exec(c);
|
|
75
|
+
if (m) return { h: Number(m[1]), s: Number(m[2]), l: Number(m[3]) };
|
|
76
|
+
const rgb = parseColor(c);
|
|
77
|
+
return rgb ? rgbToHsl(rgb) : null;
|
|
78
|
+
}
|
|
79
|
+
var hex2 = (n) => Math.round(clamp(n, 0, 255)).toString(16).padStart(2, "0");
|
|
80
|
+
function rgbToHex({ r, g, b }) {
|
|
81
|
+
return `#${hex2(r)}${hex2(g)}${hex2(b)}`;
|
|
82
|
+
}
|
|
83
|
+
function hslToHex(hsl2) {
|
|
84
|
+
return rgbToHex(hslToRgb(hsl2));
|
|
85
|
+
}
|
|
86
|
+
function toHex(value, fallback = "#000000") {
|
|
87
|
+
const rgb = parseColor(value);
|
|
88
|
+
return rgb ? rgbToHex(rgb) : fallback;
|
|
89
|
+
}
|
|
90
|
+
function formatHslTriplet({ h, s, l }) {
|
|
91
|
+
return `${fmt((h % 360 + 360) % 360)} ${fmt(s)}% ${fmt(l)}%`;
|
|
92
|
+
}
|
|
93
|
+
function toHslTriplet(color) {
|
|
94
|
+
const c = color.trim();
|
|
95
|
+
if (TRIPLET_RE.test(c)) return c;
|
|
96
|
+
const hsl2 = parseHsl(c);
|
|
97
|
+
return hsl2 ? formatHslTriplet(hsl2) : c;
|
|
98
|
+
}
|
|
99
|
+
function toCssColor(value) {
|
|
100
|
+
const c = value.trim();
|
|
101
|
+
return TRIPLET_RE.test(c) ? `hsl(${c})` : c;
|
|
102
|
+
}
|
|
103
|
+
var channel = (v) => {
|
|
104
|
+
const c = v / 255;
|
|
105
|
+
return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
|
|
106
|
+
};
|
|
107
|
+
function relativeLuminance(rgb) {
|
|
108
|
+
return 0.2126 * channel(rgb.r) + 0.7152 * channel(rgb.g) + 0.0722 * channel(rgb.b);
|
|
109
|
+
}
|
|
110
|
+
function contrastRatio(a, b) {
|
|
111
|
+
const ra = parseColor(a);
|
|
112
|
+
const rb = parseColor(b);
|
|
113
|
+
if (!ra || !rb) return null;
|
|
114
|
+
const la = relativeLuminance(ra);
|
|
115
|
+
const lb = relativeLuminance(rb);
|
|
116
|
+
return (Math.max(la, lb) + 0.05) / (Math.min(la, lb) + 0.05);
|
|
117
|
+
}
|
|
118
|
+
var AA_TEXT = 4.5;
|
|
119
|
+
var AA_UI = 3;
|
|
120
|
+
function ensureContrast(fg, bg, ratio) {
|
|
121
|
+
const fgHsl = parseHsl(fg);
|
|
122
|
+
const bgRgb = parseColor(bg);
|
|
123
|
+
if (!fgHsl || !bgRgb) return fg;
|
|
124
|
+
const pass = (l) => (contrastRatio(hslToHex({ ...fgHsl, l }), rgbToHex(bgRgb)) ?? 0) >= ratio;
|
|
125
|
+
if (pass(fgHsl.l)) return hslToHex(fgHsl);
|
|
126
|
+
const bgDark = relativeLuminance(bgRgb) < 0.18;
|
|
127
|
+
const directions = bgDark ? [1, -1] : [-1, 1];
|
|
128
|
+
for (const dir of directions) {
|
|
129
|
+
const end = dir < 0 ? 0 : 100;
|
|
130
|
+
if (!pass(end)) continue;
|
|
131
|
+
let lo = fgHsl.l;
|
|
132
|
+
let hi = end;
|
|
133
|
+
for (let i = 0; i < 24; i++) {
|
|
134
|
+
const mid = (lo + hi) / 2;
|
|
135
|
+
if (pass(mid)) hi = mid;
|
|
136
|
+
else lo = mid;
|
|
137
|
+
}
|
|
138
|
+
return hslToHex({ ...fgHsl, l: hi });
|
|
139
|
+
}
|
|
140
|
+
const black = contrastRatio("#000000", rgbToHex(bgRgb)) ?? 0;
|
|
141
|
+
const white = contrastRatio("#ffffff", rgbToHex(bgRgb)) ?? 0;
|
|
142
|
+
return black >= white ? "#000000" : "#ffffff";
|
|
143
|
+
}
|
|
144
|
+
function mix(a, b, amount) {
|
|
145
|
+
const ra = parseColor(a);
|
|
146
|
+
const rb = parseColor(b);
|
|
147
|
+
if (!ra || !rb) return a;
|
|
148
|
+
const t = clamp(amount, 0, 1);
|
|
149
|
+
return rgbToHex({
|
|
150
|
+
r: ra.r + (rb.r - ra.r) * t,
|
|
151
|
+
g: ra.g + (rb.g - ra.g) * t,
|
|
152
|
+
b: ra.b + (rb.b - ra.b) * t
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// src/theme/tokens.ts
|
|
157
|
+
var THEME_STYLE_ID = "arbi-theme-vars";
|
|
158
|
+
function themeCssVars(colors) {
|
|
159
|
+
const vars = {};
|
|
160
|
+
for (const [key, value] of Object.entries(colors)) {
|
|
161
|
+
vars[`--${key}`] = toHslTriplet(value);
|
|
162
|
+
vars[`--color-${key}`] = toCssColor(value);
|
|
163
|
+
}
|
|
164
|
+
return vars;
|
|
165
|
+
}
|
|
166
|
+
function themeMetaVars(theme) {
|
|
167
|
+
return {
|
|
168
|
+
"--font-display": theme.fonts.display,
|
|
169
|
+
"--font-sans": theme.fonts.sans,
|
|
170
|
+
"--radius": `${theme.radius}rem`
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function renderBlock(selector, vars) {
|
|
174
|
+
const body = Object.entries(vars).map(([name, value]) => ` ${name}: ${value};`).join("\n");
|
|
175
|
+
return `${selector} {
|
|
176
|
+
${body}
|
|
177
|
+
}`;
|
|
178
|
+
}
|
|
179
|
+
function emitCssVars(theme, dark) {
|
|
180
|
+
if (typeof document === "undefined") return;
|
|
181
|
+
let css = renderBlock(":root", { ...themeCssVars(theme.colors), ...themeMetaVars(theme) });
|
|
182
|
+
if (dark) css += `
|
|
183
|
+
${renderBlock(":root.dark", themeCssVars(dark))}`;
|
|
184
|
+
let style = document.getElementById(THEME_STYLE_ID);
|
|
185
|
+
if (!style) {
|
|
186
|
+
style = document.createElement("style");
|
|
187
|
+
style.id = THEME_STYLE_ID;
|
|
188
|
+
document.head.appendChild(style);
|
|
189
|
+
}
|
|
190
|
+
style.textContent = css;
|
|
191
|
+
}
|
|
192
|
+
function removeCssVars() {
|
|
193
|
+
if (typeof document === "undefined") return;
|
|
194
|
+
document.getElementById(THEME_STYLE_ID)?.remove();
|
|
195
|
+
}
|
|
196
|
+
function normalizeOptions(optionsOrRoot) {
|
|
197
|
+
if (typeof HTMLElement !== "undefined" && optionsOrRoot instanceof HTMLElement) {
|
|
198
|
+
return { root: optionsOrRoot };
|
|
199
|
+
}
|
|
200
|
+
return optionsOrRoot;
|
|
201
|
+
}
|
|
202
|
+
function applyThemeVars(theme, optionsOrRoot = {}) {
|
|
203
|
+
const { mode = "flat", dark, root = document.documentElement } = normalizeOptions(optionsOrRoot);
|
|
204
|
+
if (mode === "cssVars") {
|
|
205
|
+
emitCssVars(theme, dark);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
for (const [name, value] of Object.entries({
|
|
209
|
+
...themeCssVars(theme.colors),
|
|
210
|
+
...themeMetaVars(theme)
|
|
211
|
+
})) {
|
|
212
|
+
root.style.setProperty(name, value);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
function applyFontVars(fonts, root = document.documentElement) {
|
|
216
|
+
root.style.setProperty("--font-display", fonts.display);
|
|
217
|
+
root.style.setProperty("--font-sans", fonts.sans);
|
|
218
|
+
}
|
|
219
|
+
function clearFontVars(root = document.documentElement) {
|
|
220
|
+
root.style.removeProperty("--font-display");
|
|
221
|
+
root.style.removeProperty("--font-sans");
|
|
222
|
+
}
|
|
223
|
+
function clearThemeVars(theme, optionsOrRoot = {}) {
|
|
224
|
+
const { mode = "flat", root = document.documentElement } = normalizeOptions(optionsOrRoot);
|
|
225
|
+
if (mode === "cssVars") {
|
|
226
|
+
removeCssVars();
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
for (const key of Object.keys(theme.colors)) {
|
|
230
|
+
root.style.removeProperty(`--${key}`);
|
|
231
|
+
root.style.removeProperty(`--color-${key}`);
|
|
232
|
+
}
|
|
233
|
+
root.style.removeProperty("--font-display");
|
|
234
|
+
root.style.removeProperty("--font-sans");
|
|
235
|
+
root.style.removeProperty("--radius");
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// src/theme/derive.ts
|
|
239
|
+
var P = "primary";
|
|
240
|
+
var A = "accent";
|
|
241
|
+
var W = "warmth";
|
|
242
|
+
var surface = (key, deps = [W]) => ({
|
|
243
|
+
key,
|
|
244
|
+
group: "surfaces",
|
|
245
|
+
deps
|
|
246
|
+
});
|
|
247
|
+
var text = (key, deps = [W]) => ({
|
|
248
|
+
key,
|
|
249
|
+
group: "text",
|
|
250
|
+
deps
|
|
251
|
+
});
|
|
252
|
+
var family = (hue, input) => ["bg", "text", "border", "solid", "text-strong"].map((part) => ({
|
|
253
|
+
key: `${hue}-${part}`,
|
|
254
|
+
group: "status",
|
|
255
|
+
deps: [input]
|
|
256
|
+
}));
|
|
257
|
+
var DERIVED_TOKENS = [
|
|
258
|
+
// Brand
|
|
259
|
+
{ key: "primary", group: "brand", deps: [P] },
|
|
260
|
+
{ key: "ring", group: "brand", deps: [P, W] },
|
|
261
|
+
{ key: "hero", group: "brand", deps: [P] },
|
|
262
|
+
{ key: "secondary", group: "brand", deps: [A, W] },
|
|
263
|
+
{ key: "theme-cyan", group: "brand", deps: [A] },
|
|
264
|
+
{ key: "theme-cyan-bright", group: "brand", deps: [A, P] },
|
|
265
|
+
{ key: "ai-ink", group: "brand", deps: [A] },
|
|
266
|
+
{ key: "ai-soft", group: "brand", deps: [A] },
|
|
267
|
+
{ key: "ai-accent", group: "brand", deps: [A] },
|
|
268
|
+
{ key: "ai-accent-soft", group: "brand", deps: [A] },
|
|
269
|
+
// Surfaces
|
|
270
|
+
surface("background"),
|
|
271
|
+
surface("card"),
|
|
272
|
+
surface("popover"),
|
|
273
|
+
surface("muted"),
|
|
274
|
+
surface("accent", [P, W]),
|
|
275
|
+
surface("border"),
|
|
276
|
+
surface("input"),
|
|
277
|
+
surface("ai-surface"),
|
|
278
|
+
{ key: "sidebar", group: "surfaces", deps: [P, W, "sidebar"] },
|
|
279
|
+
{ key: "sidebar-foreground", group: "surfaces", deps: [P, W, "sidebar"] },
|
|
280
|
+
{ key: "sidebar-muted", group: "surfaces", deps: [P, W, "sidebar"] },
|
|
281
|
+
{ key: "sidebar-accent", group: "surfaces", deps: [P, W, "sidebar"] },
|
|
282
|
+
{ key: "sidebar-accent-foreground", group: "surfaces", deps: [P, W, "sidebar"] },
|
|
283
|
+
{ key: "sidebar-border", group: "surfaces", deps: [P, W, "sidebar"] },
|
|
284
|
+
{ key: "sidebar-primary", group: "surfaces", deps: [P, A, "sidebar"] },
|
|
285
|
+
// Text
|
|
286
|
+
text("foreground"),
|
|
287
|
+
text("card-foreground"),
|
|
288
|
+
text("popover-foreground"),
|
|
289
|
+
text("muted-foreground"),
|
|
290
|
+
text("primary-foreground", [P, W]),
|
|
291
|
+
text("accent-foreground", [P, W]),
|
|
292
|
+
text("secondary-foreground", [A, W]),
|
|
293
|
+
text("ai-accent-foreground", [A]),
|
|
294
|
+
text("destructive-foreground", ["danger"]),
|
|
295
|
+
// Status
|
|
296
|
+
{ key: "destructive", group: "status", deps: ["danger"] },
|
|
297
|
+
{ key: "success", group: "status", deps: ["success"] },
|
|
298
|
+
{ key: "warning", group: "status", deps: ["warning"] },
|
|
299
|
+
...family("red", "danger"),
|
|
300
|
+
...family("green", "success"),
|
|
301
|
+
...family("yellow", "warning"),
|
|
302
|
+
// Charts (the step bar's start/finish accent follows the first series)
|
|
303
|
+
...[1, 2, 3, 4, 5].map((i) => ({
|
|
304
|
+
key: `chart-${i}`,
|
|
305
|
+
group: "charts",
|
|
306
|
+
deps: [P, A, "charts"]
|
|
307
|
+
})),
|
|
308
|
+
{ key: "wf-start", group: "charts", deps: [P, A, "charts"] }
|
|
309
|
+
];
|
|
310
|
+
new Map(DERIVED_TOKENS.map((t) => [t.key, t]));
|
|
311
|
+
function keysOfInput(input) {
|
|
312
|
+
return DERIVED_TOKENS.filter((t) => t.deps.includes(input)).map((t) => t.key);
|
|
313
|
+
}
|
|
314
|
+
var DEFAULT_INPUTS = {
|
|
315
|
+
primary: "#202b61",
|
|
316
|
+
accent: "#00adef",
|
|
317
|
+
danger: "#bf3b3b",
|
|
318
|
+
success: "#1f8a5b",
|
|
319
|
+
warning: "#c08a2d"};
|
|
320
|
+
var isWarm = (h) => h >= 15 && h <= 90;
|
|
321
|
+
var isCool = (h) => h >= 180 && h <= 270;
|
|
322
|
+
var clamp2 = (n, lo, hi) => Math.min(hi, Math.max(lo, n));
|
|
323
|
+
function warmthOf(colors) {
|
|
324
|
+
const bg = parseHsl(colors.background ?? "");
|
|
325
|
+
const tint = parseHsl(colors.muted ?? colors.border ?? colors.card ?? "");
|
|
326
|
+
const sign = (hsl2) => !hsl2 ? 0 : isWarm(hsl2.h) ? 1 : isCool(hsl2.h) ? -1 : 0;
|
|
327
|
+
if (bg && bg.l < 99 && bg.s > 3) {
|
|
328
|
+
return sign(bg) * (0.5 + Math.min(0.5, (100 - bg.l) / 12));
|
|
329
|
+
}
|
|
330
|
+
if (!tint) return 0;
|
|
331
|
+
return sign(tint) * Math.min(0.5, tint.s / 40);
|
|
332
|
+
}
|
|
333
|
+
function inferInputs(colors) {
|
|
334
|
+
const hex = (key, fallback) => colors[key] && parseColor(colors[key]) ? toHex(colors[key]) : fallback;
|
|
335
|
+
const saturated = (key) => (parseHsl(colors[key] ?? "")?.s ?? 0) >= 35;
|
|
336
|
+
const accentKey = ["ai-accent", "ai-ink", "secondary", "theme-cyan"].find(
|
|
337
|
+
(k) => colors[k] && saturated(k)
|
|
338
|
+
);
|
|
339
|
+
const sidebar = parseColor(colors.sidebar ?? "");
|
|
340
|
+
return {
|
|
341
|
+
primary: hex("primary", DEFAULT_INPUTS.primary),
|
|
342
|
+
accent: accentKey ? toHex(colors[accentKey]) : DEFAULT_INPUTS.accent,
|
|
343
|
+
warmth: Math.round(warmthOf(colors) * 100) / 100,
|
|
344
|
+
sidebar: sidebar && relativeLuminance(sidebar) < 0.2 ? "brand" : "light",
|
|
345
|
+
charts: "harmonious",
|
|
346
|
+
danger: hex("destructive", DEFAULT_INPUTS.danger),
|
|
347
|
+
success: hex("success", DEFAULT_INPUTS.success),
|
|
348
|
+
warning: hex("warning", DEFAULT_INPUTS.warning),
|
|
349
|
+
secondaryRole: colors.secondary && !saturated("secondary") ? "surface" : "accent"
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
var hsl = (h, s, l) => hslToHex({ h, s, l });
|
|
353
|
+
function readableOn(bg, light, dark, ratio = AA_TEXT) {
|
|
354
|
+
const pick = (contrastRatio(light, bg) ?? 0) >= (contrastRatio(dark, bg) ?? 0) ? light : dark;
|
|
355
|
+
return ensureContrast(pick, bg, ratio);
|
|
356
|
+
}
|
|
357
|
+
function hueDistance(a, b) {
|
|
358
|
+
const d = Math.abs(a - b) % 360;
|
|
359
|
+
return d > 180 ? 360 - d : d;
|
|
360
|
+
}
|
|
361
|
+
function chartHues(p, a, style) {
|
|
362
|
+
const base = p.s >= 12 ? p.h : a.s >= 12 ? a.h : 220;
|
|
363
|
+
const second = a.s >= 12 ? a.h : (base + 150) % 360;
|
|
364
|
+
if (style === "distinct") return [0, 1, 2, 3, 4].map((i) => (base + i * 72) % 360);
|
|
365
|
+
const chosen = [base, hueDistance(base, second) < 25 ? (base + 150) % 360 : second];
|
|
366
|
+
const candidates = [180, 60, -60, 120, -120, 30, -30].flatMap((d) => [
|
|
367
|
+
(base + d + 360) % 360,
|
|
368
|
+
(chosen[1] + d + 360) % 360
|
|
369
|
+
]);
|
|
370
|
+
while (chosen.length < 5) {
|
|
371
|
+
let best = candidates[0];
|
|
372
|
+
let bestScore = -1;
|
|
373
|
+
for (const c of candidates) {
|
|
374
|
+
const score = Math.min(...chosen.map((h) => hueDistance(h, c)));
|
|
375
|
+
if (score > bestScore) {
|
|
376
|
+
best = c;
|
|
377
|
+
bestScore = score;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
chosen.push(best);
|
|
381
|
+
}
|
|
382
|
+
return chosen;
|
|
383
|
+
}
|
|
384
|
+
function deriveColors(inputs, scheme) {
|
|
385
|
+
const dark = scheme === "dark";
|
|
386
|
+
const p = parseHsl(inputs.primary) ?? parseHsl(DEFAULT_INPUTS.primary);
|
|
387
|
+
const a = parseHsl(inputs.accent) ?? parseHsl(DEFAULT_INPUTS.accent);
|
|
388
|
+
const w = clamp2(inputs.warmth, -1, 1);
|
|
389
|
+
const strength = Math.abs(w);
|
|
390
|
+
const pageTint = Math.max(0, strength - 0.5) * 2;
|
|
391
|
+
const sh = w > 0 ? 42 : 218;
|
|
392
|
+
const ss = strength * (w > 0 ? 35 : 25);
|
|
393
|
+
const out = {};
|
|
394
|
+
const bgL = dark ? 7 : 100 - 6 * pageTint;
|
|
395
|
+
const neutralS = dark ? Math.min(ss, 22) : ss;
|
|
396
|
+
out.background = hsl(sh, neutralS, bgL);
|
|
397
|
+
out.card = dark ? hsl(sh, neutralS, 9) : mix(out.background, "#ffffff", 0.85);
|
|
398
|
+
out.popover = dark ? hsl(sh, neutralS, 10) : out.card;
|
|
399
|
+
out.muted = hsl(sh, neutralS * (dark ? 0.8 : 1), dark ? 14 : bgL - 4 - 1.5 * pageTint);
|
|
400
|
+
out.border = hsl(sh, neutralS * (dark ? 0.7 : 0.8), dark ? 20 : bgL - 10);
|
|
401
|
+
out.input = ensureContrast(hsl(sh, neutralS * 0.6, dark ? 42 : 58), out.background, AA_UI);
|
|
402
|
+
out["ai-surface"] = out.card;
|
|
403
|
+
const accentS = Math.min(p.s + 10, 62) * (1 - 0.5 * Math.max(0, w));
|
|
404
|
+
out.accent = dark ? hsl(p.h, Math.min(p.s, 35), 21) : hsl(p.h, accentS, bgL - 5);
|
|
405
|
+
const primary = dark && p.l < 55 ? hsl(p.h, Math.min(p.s + 20, 80), 70) : toHex(inputs.primary);
|
|
406
|
+
out.primary = primary;
|
|
407
|
+
out.ring = ensureContrast(
|
|
408
|
+
hsl(p.h, Math.min(p.s, 60) * (dark ? 0.9 : 0.8), dark ? 65 : 54),
|
|
409
|
+
out.background,
|
|
410
|
+
AA_UI
|
|
411
|
+
);
|
|
412
|
+
out.hero = dark ? hsl(p.h, Math.min(p.s, 50), 17) : p.l <= 30 ? toHex(inputs.primary) : hsl(p.h, p.s, 22);
|
|
413
|
+
const accent = dark && a.l < 45 ? hsl(a.h, a.s, 55) : toHex(inputs.accent);
|
|
414
|
+
out["ai-soft"] = mix(accent, out.background, dark ? 0.82 : 0.88);
|
|
415
|
+
out["ai-ink"] = ensureContrast(accent, out["ai-soft"], AA_TEXT);
|
|
416
|
+
out["ai-accent"] = out["ai-ink"];
|
|
417
|
+
out["ai-accent-soft"] = out["ai-soft"];
|
|
418
|
+
out["theme-cyan"] = ensureContrast(accent, out.background, AA_TEXT);
|
|
419
|
+
out["theme-cyan-bright"] = ensureContrast(hsl(a.h, a.s, Math.max(a.l, 47)), out.hero, AA_TEXT);
|
|
420
|
+
const ink = hsl(sh, Math.min(10 + ss, 40), 12);
|
|
421
|
+
const paper = hsl(sh, Math.min(ss, 30), dark ? 93 : 98);
|
|
422
|
+
out.foreground = ensureContrast(dark ? hsl(sh, 18, 93) : ink, out.background, 7);
|
|
423
|
+
out["card-foreground"] = out.foreground;
|
|
424
|
+
out["popover-foreground"] = out.foreground;
|
|
425
|
+
out["muted-foreground"] = ensureContrast(
|
|
426
|
+
hsl(sh, Math.min(ss, 15), dark ? 70 : 42),
|
|
427
|
+
out.muted,
|
|
428
|
+
AA_TEXT
|
|
429
|
+
);
|
|
430
|
+
out["primary-foreground"] = readableOn(primary, paper, dark ? hsl(p.h, 30, 8) : ink);
|
|
431
|
+
out["accent-foreground"] = dark ? ensureContrast(hsl(p.h, 70, 92), out.accent, AA_TEXT) : ensureContrast(primary, out.accent, AA_TEXT);
|
|
432
|
+
out["ai-accent-foreground"] = readableOn(out["ai-accent"], "#ffffff", ink);
|
|
433
|
+
if (inputs.secondaryRole === "surface") {
|
|
434
|
+
out.secondary = hsl(sh, neutralS, dark ? 18 : bgL - 7);
|
|
435
|
+
out["secondary-foreground"] = ensureContrast(out.foreground, out.secondary, AA_TEXT);
|
|
436
|
+
} else {
|
|
437
|
+
out.secondary = accent;
|
|
438
|
+
out["secondary-foreground"] = readableOn(accent, paper, ink);
|
|
439
|
+
}
|
|
440
|
+
if (inputs.sidebar === "brand") {
|
|
441
|
+
const panel = hsl(p.h, Math.min(p.s, 45), dark ? 9 : 10);
|
|
442
|
+
out.sidebar = panel;
|
|
443
|
+
out["sidebar-accent"] = hsl(p.h, Math.min(p.s, 45), 18);
|
|
444
|
+
out["sidebar-border"] = hsl(p.h, Math.min(p.s, 40), 20);
|
|
445
|
+
out["sidebar-foreground"] = ensureContrast(hsl(p.h, 15, 82), panel, AA_TEXT);
|
|
446
|
+
out["sidebar-muted"] = ensureContrast(hsl(p.h, 10, 60), panel, AA_TEXT);
|
|
447
|
+
out["sidebar-accent-foreground"] = ensureContrast(paper, out["sidebar-accent"], AA_TEXT);
|
|
448
|
+
out["sidebar-primary"] = ensureContrast(hsl(a.h, a.s, Math.max(a.l, 50)), panel, AA_UI);
|
|
449
|
+
} else {
|
|
450
|
+
out.sidebar = hsl(sh, neutralS, dark ? 10 : bgL - 3);
|
|
451
|
+
out["sidebar-accent"] = out.accent;
|
|
452
|
+
out["sidebar-border"] = out.border;
|
|
453
|
+
out["sidebar-foreground"] = out.foreground;
|
|
454
|
+
out["sidebar-muted"] = ensureContrast(out["muted-foreground"], out.sidebar, AA_TEXT);
|
|
455
|
+
out["sidebar-accent-foreground"] = out["accent-foreground"];
|
|
456
|
+
out["sidebar-primary"] = ensureContrast(primary, out.sidebar, AA_UI);
|
|
457
|
+
}
|
|
458
|
+
const status = (hue, color) => {
|
|
459
|
+
const c = toHex(color);
|
|
460
|
+
const solid = dark && (parseHsl(c)?.l ?? 50) < 45 ? mix(c, "#ffffff", 0.25) : c;
|
|
461
|
+
const bg = mix(solid, out.background, dark ? 0.85 : 0.9);
|
|
462
|
+
out[`${hue}-bg`] = bg;
|
|
463
|
+
out[`${hue}-border`] = mix(solid, out.background, dark ? 0.65 : 0.72);
|
|
464
|
+
out[`${hue}-solid`] = solid;
|
|
465
|
+
out[`${hue}-text`] = ensureContrast(solid, bg, AA_TEXT);
|
|
466
|
+
out[`${hue}-text-strong`] = ensureContrast(solid, bg, 7);
|
|
467
|
+
return solid;
|
|
468
|
+
};
|
|
469
|
+
const danger = status("red", inputs.danger);
|
|
470
|
+
out.success = status("green", inputs.success);
|
|
471
|
+
out.warning = status("yellow", inputs.warning);
|
|
472
|
+
out.destructive = dark ? hsl(parseHsl(danger).h, 55, 42) : toHex(inputs.danger);
|
|
473
|
+
out["destructive-foreground"] = readableOn(out.destructive, "#ffffff", ink);
|
|
474
|
+
const hues = chartHues(p, a, inputs.charts);
|
|
475
|
+
const lightness = dark ? [62, 58, 68, 54, 72] : [44, 50, 58, 38, 64];
|
|
476
|
+
hues.forEach((h, i) => {
|
|
477
|
+
const s = clamp2(i === 0 ? p.s : i === 1 ? a.s : Math.max(p.s, a.s), 55, 80);
|
|
478
|
+
out[`chart-${i + 1}`] = ensureContrast(hsl(h, s, lightness[i]), out.background, AA_UI);
|
|
479
|
+
});
|
|
480
|
+
out["wf-start"] = out["chart-1"];
|
|
481
|
+
return out;
|
|
482
|
+
}
|
|
483
|
+
var CONTRAST_PAIRS = [
|
|
484
|
+
{ fg: "foreground", bg: "background", min: AA_TEXT, label: "Body text on the page" },
|
|
485
|
+
{ fg: "card-foreground", bg: "card", min: AA_TEXT, label: "Text on cards" },
|
|
486
|
+
{ fg: "popover-foreground", bg: "popover", min: AA_TEXT, label: "Text in menus" },
|
|
487
|
+
{ fg: "muted-foreground", bg: "background", min: AA_TEXT, label: "Secondary text on the page" },
|
|
488
|
+
{ fg: "muted-foreground", bg: "muted", min: AA_TEXT, label: "Secondary text on muted areas" },
|
|
489
|
+
{ fg: "primary-foreground", bg: "primary", min: AA_TEXT, label: "Text on primary buttons" },
|
|
490
|
+
{ fg: "secondary-foreground", bg: "secondary", min: AA_TEXT, label: "Text on secondary fills" },
|
|
491
|
+
{ fg: "accent-foreground", bg: "accent", min: AA_TEXT, label: "Text on hover and selection" },
|
|
492
|
+
{
|
|
493
|
+
fg: "destructive-foreground",
|
|
494
|
+
bg: "destructive",
|
|
495
|
+
min: AA_TEXT,
|
|
496
|
+
label: "Text on danger buttons"
|
|
497
|
+
},
|
|
498
|
+
{ fg: "ring", bg: "background", min: AA_UI, label: "Focus ring on the page" },
|
|
499
|
+
{ fg: "input", bg: "background", min: AA_UI, label: "Field borders on the page" }
|
|
500
|
+
];
|
|
501
|
+
function contrastIssues(resolve, pairs = CONTRAST_PAIRS) {
|
|
502
|
+
const issues = [];
|
|
503
|
+
for (const pair of pairs) {
|
|
504
|
+
const fg = resolve(pair.fg);
|
|
505
|
+
const bg = resolve(pair.bg);
|
|
506
|
+
if (!fg || !bg) continue;
|
|
507
|
+
const ratio = contrastRatio(fg, bg);
|
|
508
|
+
if (ratio === null || ratio >= pair.min) continue;
|
|
509
|
+
issues.push({ ...pair, ratio, fix: ensureContrast(fg, bg, pair.min) });
|
|
510
|
+
}
|
|
511
|
+
return issues;
|
|
512
|
+
}
|
|
513
|
+
function Tabs({ items, testId }) {
|
|
514
|
+
const list = items ?? [];
|
|
515
|
+
const [active, setActive] = useState("0");
|
|
516
|
+
const activeIndex = Math.min(Number(active), Math.max(list.length - 1, 0));
|
|
517
|
+
return /* @__PURE__ */ jsxs(TabsPrimitive.Root, { value: String(activeIndex), onValueChange: setActive, "data-testid": testId, children: [
|
|
518
|
+
/* @__PURE__ */ jsx(TabsPrimitive.List, { className: "flex flex-wrap gap-1 border-b border-border", children: list.map((t, i) => /* @__PURE__ */ jsx(
|
|
519
|
+
TabsPrimitive.Trigger,
|
|
520
|
+
{
|
|
521
|
+
value: String(i),
|
|
522
|
+
className: cn(
|
|
523
|
+
"-mb-px border-b-2 px-4 py-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11",
|
|
524
|
+
i === activeIndex ? "border-primary text-foreground" : "border-transparent text-muted-foreground hover:text-foreground"
|
|
525
|
+
),
|
|
526
|
+
"data-testid": testId && `${testId}-tab-${i}`,
|
|
527
|
+
children: t.label
|
|
528
|
+
},
|
|
529
|
+
i
|
|
530
|
+
)) }),
|
|
531
|
+
list.map((t, i) => /* @__PURE__ */ jsx(
|
|
532
|
+
TabsPrimitive.Content,
|
|
533
|
+
{
|
|
534
|
+
value: String(i),
|
|
535
|
+
className: "pt-5 text-sm leading-relaxed text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
536
|
+
"data-testid": i === activeIndex ? testId && `${testId}-panel` : void 0,
|
|
537
|
+
children: t.content
|
|
538
|
+
},
|
|
539
|
+
i
|
|
540
|
+
))
|
|
541
|
+
] });
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// src/theme/previewLabels.ts
|
|
545
|
+
var DEFAULT_THEME_PREVIEW_LABELS = {
|
|
546
|
+
title: "Preview",
|
|
547
|
+
subtitle: "How your theme looks on real components",
|
|
548
|
+
primaryAction: "Save",
|
|
549
|
+
accentAction: "Ask AI",
|
|
550
|
+
secondaryAction: "Cancel",
|
|
551
|
+
outlineAction: "Export",
|
|
552
|
+
dangerAction: "Delete",
|
|
553
|
+
fieldLabel: "Search",
|
|
554
|
+
fieldPlaceholder: "Find a document",
|
|
555
|
+
cardBody: "Cards hold a title, a short summary and their actions.",
|
|
556
|
+
tabs: ["Overview", "Activity", "Settings"],
|
|
557
|
+
tabBody: "The active tab is underlined in the primary colour.",
|
|
558
|
+
nav: ["Home", "Inbox", "Documents"],
|
|
559
|
+
steps: ["Intake", "Review", "Sign"],
|
|
560
|
+
chartLabel: "Documents per month, two series",
|
|
561
|
+
chartMonths: ["Jan", "Feb", "Mar", "Apr"],
|
|
562
|
+
chartSeries: ["Received", "Completed"],
|
|
563
|
+
toastTitle: "Changes saved",
|
|
564
|
+
toastBody: "Your theme is live for everyone.",
|
|
565
|
+
toastAction: "Undo",
|
|
566
|
+
badges: { neutral: "Draft", success: "Done", warning: "Due soon", danger: "Overdue", ai: "AI" },
|
|
567
|
+
alerts: {
|
|
568
|
+
info: "A new version is available.",
|
|
569
|
+
danger: "The upload failed."
|
|
570
|
+
}
|
|
571
|
+
};
|
|
572
|
+
|
|
573
|
+
export { CONTRAST_PAIRS, DEFAULT_THEME_PREVIEW_LABELS, DERIVED_TOKENS, THEME_STYLE_ID, Tabs, applyFontVars, applyThemeVars, clearFontVars, clearThemeVars, contrastIssues, contrastRatio, deriveColors, ensureContrast, inferInputs, keysOfInput, parseColor, themeCssVars, themeMetaVars, toCssColor, toHex, toHslTriplet };
|
|
574
|
+
//# sourceMappingURL=chunk-J77BACGX.js.map
|
|
575
|
+
//# sourceMappingURL=chunk-J77BACGX.js.map
|