From cf3f5d827b22498a7e45c427ced9c7d24712d3c2 Mon Sep 17 00:00:00 2001 From: paanSinghCoder Date: Tue, 28 Apr 2026 14:31:10 +0530 Subject: [PATCH 1/2] chore(plugin-vscode): mirror token data from HEX to OKLCH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert all 157 token color values across the plugin's TS data files to oklch() strings, matching the apsara CSS token format. Mechanical, byte-identical: every value is byte-identical in 8-bit sRGB after re-parsing the rounded oklch() output, with CIEDE2000 ΔE < 0.5. Files: - src/tokens/primitives/gray.ts (12) - src/tokens/primitives/accent.ts (13) - src/tokens/primitives/appearance.ts (96) - src/tokens/color.ts (24 overlays) - src/tokens/effects.ts (12 shadow rgba) Co-Authored-By: Claude Opus 4.7 (1M context) --- packages/plugin-vscode/src/tokens/color.ts | 48 ++--- packages/plugin-vscode/src/tokens/effects.ts | 10 +- .../src/tokens/primitives/accent.ts | 26 +-- .../src/tokens/primitives/appearance.ts | 192 +++++++++--------- .../src/tokens/primitives/gray.ts | 24 +-- 5 files changed, 150 insertions(+), 150 deletions(-) diff --git a/packages/plugin-vscode/src/tokens/color.ts b/packages/plugin-vscode/src/tokens/color.ts index 57af8ef61..5e30c3c16 100644 --- a/packages/plugin-vscode/src/tokens/color.ts +++ b/packages/plugin-vscode/src/tokens/color.ts @@ -63,32 +63,32 @@ export default { /* Overlay Colors */ 'overlay-base-primary': primitives['overlay-1'], /* Black Overlay */ - 'overlay-black-a1': '#0000000D' /* 5% opacity */, - 'overlay-black-a2': '#0000001A' /* 10% opacity */, - 'overlay-black-a3': '#00000026' /* 15% opacity */, - 'overlay-black-a4': '#00000033' /* 20% opacity */, - 'overlay-black-a5': '#0000004D' /* 30% opacity */, - 'overlay-black-a6': '#00000066' /* 40% opacity */, - 'overlay-black-a7': '#00000080' /* 50% opacity */, - 'overlay-black-a8': '#00000099' /* 60% opacity */, - 'overlay-black-a9': '#000000B3' /* 70% opacity */, - 'overlay-black-a10': '#000000CC' /* 80% opacity */, - 'overlay-black-a11': '#000000E6' /* 90% opacity */, - 'overlay-black-a12': '#000000F2' /* 95% opacity */, + 'overlay-black-a1': 'oklch(0 0 0 / 0.051)' /* 5% opacity */, + 'overlay-black-a2': 'oklch(0 0 0 / 0.102)' /* 10% opacity */, + 'overlay-black-a3': 'oklch(0 0 0 / 0.149)' /* 15% opacity */, + 'overlay-black-a4': 'oklch(0 0 0 / 0.2)' /* 20% opacity */, + 'overlay-black-a5': 'oklch(0 0 0 / 0.302)' /* 30% opacity */, + 'overlay-black-a6': 'oklch(0 0 0 / 0.4)' /* 40% opacity */, + 'overlay-black-a7': 'oklch(0 0 0 / 0.502)' /* 50% opacity */, + 'overlay-black-a8': 'oklch(0 0 0 / 0.6)' /* 60% opacity */, + 'overlay-black-a9': 'oklch(0 0 0 / 0.702)' /* 70% opacity */, + 'overlay-black-a10': 'oklch(0 0 0 / 0.8)' /* 80% opacity */, + 'overlay-black-a11': 'oklch(0 0 0 / 0.902)' /* 90% opacity */, + 'overlay-black-a12': 'oklch(0 0 0 / 0.949)' /* 95% opacity */, /* White Overlay */ - 'overlay-white-a1': '#ffffff0D' /* 5% opacity */, - 'overlay-white-a2': '#ffffff1A' /* 10% opacity */, - 'overlay-white-a3': '#ffffff26' /* 15% opacity */, - 'overlay-white-a4': '#ffffff33' /* 20% opacity */, - 'overlay-white-a5': '#ffffff4D' /* 30% opacity */, - 'overlay-white-a6': '#ffffff66' /* 40% opacity */, - 'overlay-white-a7': '#ffffff80' /* 50% opacity */, - 'overlay-white-a8': '#ffffff99' /* 60% opacity */, - 'overlay-white-a9': '#ffffffB3' /* 70% opacity */, - 'overlay-white-a10': '#ffffffCC' /* 80% opacity */, - 'overlay-white-a11': '#ffffffE6' /* 90% opacity */, - 'overlay-white-a12': '#ffffffF2' /* 95% opacity */, + 'overlay-white-a1': 'oklch(1 0 0 / 0.051)' /* 5% opacity */, + 'overlay-white-a2': 'oklch(1 0 0 / 0.102)' /* 10% opacity */, + 'overlay-white-a3': 'oklch(1 0 0 / 0.149)' /* 15% opacity */, + 'overlay-white-a4': 'oklch(1 0 0 / 0.2)' /* 20% opacity */, + 'overlay-white-a5': 'oklch(1 0 0 / 0.302)' /* 30% opacity */, + 'overlay-white-a6': 'oklch(1 0 0 / 0.4)' /* 40% opacity */, + 'overlay-white-a7': 'oklch(1 0 0 / 0.502)' /* 50% opacity */, + 'overlay-white-a8': 'oklch(1 0 0 / 0.6)' /* 60% opacity */, + 'overlay-white-a9': 'oklch(1 0 0 / 0.702)' /* 70% opacity */, + 'overlay-white-a10': 'oklch(1 0 0 / 0.8)' /* 80% opacity */, + 'overlay-white-a11': 'oklch(1 0 0 / 0.902)' /* 90% opacity */, + 'overlay-white-a12': 'oklch(1 0 0 / 0.949)' /* 95% opacity */, /* Additional Background Colors */ 'background-neutral-primary': primitives['neutral-3'], diff --git a/packages/plugin-vscode/src/tokens/effects.ts b/packages/plugin-vscode/src/tokens/effects.ts index c735fa846..5ae5209a1 100644 --- a/packages/plugin-vscode/src/tokens/effects.ts +++ b/packages/plugin-vscode/src/tokens/effects.ts @@ -4,13 +4,13 @@ export const shadow = { /* Shadows */ feather: - '0px 1px 1px 0px rgba(0, 0, 0, 0.06), 0px 4px 4px -1px rgba(0, 0, 0, 0.02)' /* sm */, - soft: '0px 2px 4px 0px rgba(0, 0, 0, 0.04), 0px 1px 2px 0px rgba(0, 0, 0, 0.04)' /* md */, + '0px 1px 1px 0px oklch(0 0 0 / 0.06), 0px 4px 4px -1px oklch(0 0 0 / 0.02)' /* sm */, + soft: '0px 2px 4px 0px oklch(0 0 0 / 0.04), 0px 1px 2px 0px oklch(0 0 0 / 0.04)' /* md */, lifted: - '0px 1px 1px 0px rgba(0, 0, 0, 0.07), 0px 2px 5px 0px rgba(0, 0, 0, 0.07), 0px 3px 8px 0px rgba(0, 0, 0, 0.07)' /* lg */, + '0px 1px 1px 0px oklch(0 0 0 / 0.07), 0px 2px 5px 0px oklch(0 0 0 / 0.07), 0px 3px 8px 0px oklch(0 0 0 / 0.07)' /* lg */, floating: - '0px 1px 1px 0px rgba(0, 0, 0, 0.04), 0px 2px 8px 0px rgba(0, 0, 0, 0.04), 0px 3px 17px 0px rgba(0, 0, 0, 0.04), 0px 4px 30px 0px rgba(0, 0, 0, 0.13)' /* xl */, - inset: '0px 1px 1px 0px rgba(0, 0, 0, 0.04) inset' + '0px 1px 1px 0px oklch(0 0 0 / 0.04), 0px 2px 8px 0px oklch(0 0 0 / 0.04), 0px 3px 17px 0px oklch(0 0 0 / 0.04), 0px 4px 30px 0px oklch(0 0 0 / 0.13)' /* xl */, + inset: '0px 1px 1px 0px oklch(0 0 0 / 0.04) inset' } as const; export const blur = { diff --git a/packages/plugin-vscode/src/tokens/primitives/accent.ts b/packages/plugin-vscode/src/tokens/primitives/accent.ts index 18c7a078b..1f2798fe9 100644 --- a/packages/plugin-vscode/src/tokens/primitives/accent.ts +++ b/packages/plugin-vscode/src/tokens/primitives/accent.ts @@ -3,17 +3,17 @@ */ export default { - 'accent-1': '#fdfdfe', - 'accent-2': '#f7f9ff', - 'accent-3': '#edf2fe', - 'accent-4': '#e1e9ff', - 'accent-5': '#d2deff', - 'accent-6': '#c1d0ff', - 'accent-7': '#abbdf9', - 'accent-8': '#8da4ef', - 'accent-9': '#3e63dd', - 'accent-10': '#3358d4', - 'accent-11': '#3a5bc7', - 'accent-12': '#1f2d5c', - 'accent-contrast': '#ffffff' + 'accent-1': 'oklch(0.9943 0.0013 286.38)', + 'accent-2': 'oklch(0.9823 0.0083 271.33)', + 'accent-3': 'oklch(0.9609 0.017 267.79)', + 'accent-4': 'oklch(0.9346 0.031 269.82)', + 'accent-5': 'oklch(0.9019 0.0471 269.62)', + 'accent-6': 'oklch(0.862 0.0675 271.09)', + 'accent-7': 'oklch(0.8062 0.0875 271.41)', + 'accent-8': 'oklch(0.7309 0.1123 270.43)', + 'accent-9': 'oklch(0.5438 0.191 267.01)', + 'accent-10': 'oklch(0.5106 0.1954 266.58)', + 'accent-11': 'oklch(0.5092 0.1725 267.17)', + 'accent-12': 'oklch(0.3126 0.0858 268.6)', + 'accent-contrast': 'oklch(1 0 0)' } as const; diff --git a/packages/plugin-vscode/src/tokens/primitives/appearance.ts b/packages/plugin-vscode/src/tokens/primitives/appearance.ts index 6f9670314..84fc118b6 100644 --- a/packages/plugin-vscode/src/tokens/primitives/appearance.ts +++ b/packages/plugin-vscode/src/tokens/primitives/appearance.ts @@ -20,110 +20,110 @@ export default { 'neutral-12': gray['gray-12'], /* Attention Colors */ - 'attention-1': '#fefdfb', - 'attention-2': '#fff9ed', - 'attention-3': '#fff4d5', - 'attention-4': '#ffecbc', - 'attention-5': '#ffe3a2', - 'attention-6': '#ffd386', - 'attention-7': '#f3ba63', - 'attention-8': '#ee9d2b', - 'attention-9': '#ffb224', - 'attention-10': '#ffa01c', - 'attention-11': '#ad5700', - 'attention-12': '#4e2009', + 'attention-1': 'oklch(0.9943 0.0028 84.56)', + 'attention-2': 'oklch(0.9835 0.0171 84.59)', + 'attention-3': 'oklch(0.9678 0.0421 90.77)', + 'attention-4': 'oklch(0.9467 0.0652 88.99)', + 'attention-5': 'oklch(0.924 0.0878 87.29)', + 'attention-6': 'oklch(0.8884 0.1073 80.68)', + 'attention-7': 'oklch(0.8239 0.1234 76.15)', + 'attention-8': 'oklch(0.7596 0.1524 69.5)', + 'attention-9': 'oklch(0.8169 0.1639 75.84)', + 'attention-10': 'oklch(0.7845 0.1678 66.73)', + 'attention-11': 'oklch(0.5509 0.1374 54.39)', + 'attention-12': 'oklch(0.3065 0.077 44.27)', /* Success Colors */ - 'success-1': '#fbfefc', - 'success-2': '#f2fcf5', - 'success-3': '#e9f9ee', - 'success-4': '#ddf3e4', - 'success-5': '#ccebd7', - 'success-6': '#b4dfc4', - 'success-7': '#92ceac', - 'success-8': '#5bb98c', - 'success-9': '#30a46c', - 'success-10': '#299764', - 'success-11': '#18794e', - 'success-12': '#153226', + 'success-1': 'oklch(0.9942 0.0041 157.18)', + 'success-2': 'oklch(0.9817 0.014 155.6)', + 'success-3': 'oklch(0.9672 0.0222 155.93)', + 'success-4': 'oklch(0.9439 0.0306 155.97)', + 'success-5': 'oklch(0.9121 0.0423 157.18)', + 'success-6': 'oklch(0.8657 0.0583 157.39)', + 'success-7': 'oklch(0.8009 0.0784 159.16)', + 'success-8': 'oklch(0.7158 0.1124 160.81)', + 'success-9': 'oklch(0.6406 0.1329 157.68)', + 'success-10': 'oklch(0.6025 0.1251 158.37)', + 'success-11': 'oklch(0.5114 0.1102 158.44)', + 'success-12': 'oklch(0.2903 0.0418 164.61)', /* Danger Colors */ - 'danger-1': '#fffcfc', - 'danger-2': '#fff8f8', - 'danger-3': '#ffefef', - 'danger-4': '#ffe5e5', - 'danger-5': '#fdd8d8', - 'danger-6': '#f9c6c6', - 'danger-7': '#f3aeaf', - 'danger-8': '#eb9091', - 'danger-9': '#e5484d', - 'danger-10': '#dc3d43', - 'danger-11': '#cd2b31', - 'danger-12': '#381316', + 'danger-1': 'oklch(0.9934 0.0032 17.21)', + 'danger-2': 'oklch(0.9845 0.0075 17.28)', + 'danger-3': 'oklch(0.9648 0.0173 17.46)', + 'danger-4': 'oklch(0.943 0.0286 17.67)', + 'danger-5': 'oklch(0.9133 0.0414 17.93)', + 'danger-6': 'oklch(0.8714 0.0583 18.33)', + 'danger-7': 'oklch(0.816 0.0812 18.02)', + 'danger-8': 'oklch(0.7479 0.1107 19.32)', + 'danger-9': 'oklch(0.6256 0.1933 23.03)', + 'danger-10': 'oklch(0.5982 0.1954 23.49)', + 'danger-11': 'oklch(0.5545 0.1972 24.96)', + 'danger-12': 'oklch(0.2462 0.0591 17.57)', /* Visualization Colors */ - 'viz-sky-11': '#00749e', - 'viz-sky-9': '#7ce2fe', - 'viz-sky-8': '#60b3d7', - 'viz-sky-6': '#a9daed', - 'viz-mint-11': '#027864', - 'viz-mint-9': '#86ead4', - 'viz-mint-8': '#4cbba5', - 'viz-mint-6': '#9ce0d0', - 'viz-lime-11': '#5c7c2f', - 'viz-lime-9': '#bdee63', - 'viz-lime-8': '#8db654', - 'viz-lime-6': '#c2da91', - 'viz-grass-11': '#2a7e3b', - 'viz-grass-9': '#46a758', - 'viz-grass-8': '#65ba74', - 'viz-grass-6': '#b2ddb5', - 'viz-green-11': '#218358', - 'viz-green-9': '#30a46c', - 'viz-green-8': '#5bb98b', - 'viz-green-6': '#adddc0', - 'viz-jade-11': '#208368', - 'viz-jade-9': '#29a383', - 'viz-jade-8': '#56ba9f', - 'viz-jade-6': '#acdec8', - 'viz-cyan-11': '#107d98', - 'viz-cyan-9': '#00a2c7', - 'viz-cyan-8': '#3db9cf', - 'viz-cyan-6': '#9ddde7', - 'viz-blue-11': '#0d74ce', - 'viz-blue-9': '#0090ff', - 'viz-blue-8': '#5eb1ef', - 'viz-blue-6': '#acd8fc', - 'viz-iris-11': '#5753c6', - 'viz-iris-9': '#5b5bd6', - 'viz-iris-8': '#9b9ef0', - 'viz-iris-6': '#cbcdff', - 'viz-purple-11': '#8145b5', - 'viz-purple-9': '#8e4ec6', - 'viz-purple-8': '#be93e4', - 'viz-purple-6': '#e0c4f4', - 'viz-pink-11': '#c2298a', - 'viz-pink-9': '#d6409f', - 'viz-pink-8': '#dd93c2', - 'viz-pink-6': '#efbfdd', - 'viz-crimson-11': '#cb1d63', - 'viz-crimson-9': '#e93d82', - 'viz-crimson-8': '#e093b2', - 'viz-crimson-6': '#f3bed1', - 'viz-orange-11': '#cc4e00', - 'viz-orange-9': '#f76b15', - 'viz-orange-8': '#ec9455', - 'viz-orange-6': '#ffc182', - 'viz-gold-11': '#71624b', - 'viz-gold-9': '#978365', - 'viz-gold-8': '#b9a88d', - 'viz-gold-6': '#d8d0bf', + 'viz-sky-11': 'oklch(0.5255 0.1079 232.55)', + 'viz-sky-9': 'oklch(0.8611 0.1027 217.8)', + 'viz-sky-8': 'oklch(0.7283 0.0961 228.43)', + 'viz-sky-6': 'oklch(0.8604 0.0571 223.65)', + 'viz-mint-11': 'oklch(0.5117 0.0955 175.6)', + 'viz-mint-9': 'oklch(0.8696 0.0999 177.98)', + 'viz-mint-8': 'oklch(0.7221 0.1063 177.84)', + 'viz-mint-6': 'oklch(0.8568 0.072 178.17)', + 'viz-lime-11': 'oklch(0.5444 0.1114 128.6)', + 'viz-lime-9': 'oklch(0.8874 0.1747 126.09)', + 'viz-lime-8': 'oklch(0.725 0.1351 128.23)', + 'viz-lime-6': 'oklch(0.8532 0.0991 123.29)', + 'viz-grass-11': 'oklch(0.5262 0.1294 147.2)', + 'viz-grass-9': 'oklch(0.6512 0.1468 147.39)', + 'viz-grass-8': 'oklch(0.7174 0.1308 148.14)', + 'viz-grass-6': 'oklch(0.8563 0.071 146.77)', + 'viz-green-11': 'oklch(0.5435 0.1116 159.5)', + 'viz-green-9': 'oklch(0.6406 0.1329 157.68)', + 'viz-green-8': 'oklch(0.7156 0.1133 160.28)', + 'viz-green-6': 'oklch(0.8558 0.0641 158.2)', + 'viz-jade-11': 'oklch(0.5475 0.0983 170.05)', + 'viz-jade-9': 'oklch(0.6422 0.115 170.73)', + 'viz-jade-8': 'oklch(0.7214 0.1026 173.12)', + 'viz-jade-6': 'oklch(0.8595 0.0601 166.24)', + 'viz-cyan-11': 'oklch(0.547 0.0966 220.75)', + 'viz-cyan-9': 'oklch(0.66 0.1217 221.74)', + 'viz-cyan-8': 'oklch(0.7276 0.1102 211.93)', + 'viz-cyan-6': 'oklch(0.8579 0.0659 208.14)', + 'viz-blue-11': 'oklch(0.5558 0.1622 252.19)', + 'viz-blue-9': 'oklch(0.6493 0.193 251.78)', + 'viz-blue-8': 'oklch(0.7336 0.1214 243.09)', + 'viz-blue-6': 'oklch(0.8633 0.0682 243.32)', + 'viz-iris-11': 'oklch(0.5111 0.1739 279.84)', + 'viz-iris-9': 'oklch(0.5403 0.1841 278.28)', + 'viz-iris-8': 'oklch(0.7293 0.1182 281.44)', + 'viz-iris-6': 'oklch(0.8634 0.0692 283.05)', + 'viz-purple-11': 'oklch(0.5168 0.1733 305.88)', + 'viz-purple-9': 'oklch(0.5556 0.1829 305.86)', + 'viz-purple-8': 'oklch(0.7331 0.1225 307.97)', + 'viz-purple-6': 'oklch(0.8592 0.0718 311.05)', + 'viz-pink-11': 'oklch(0.5575 0.2069 347.32)', + 'viz-pink-9': 'oklch(0.6168 0.2076 346)', + 'viz-pink-8': 'oklch(0.7513 0.1071 341.48)', + 'viz-pink-6': 'oklch(0.8558 0.0671 340.72)', + 'viz-crimson-11': 'oklch(0.5522 0.2073 4.49)', + 'viz-crimson-9': 'oklch(0.6341 0.213 1.28)', + 'viz-crimson-8': 'oklch(0.7493 0.1002 354.02)', + 'viz-crimson-6': 'oklch(0.8541 0.0653 355.16)', + 'viz-orange-11': 'oklch(0.5855 0.1743 42.74)', + 'viz-orange-9': 'oklch(0.6908 0.1909 45.02)', + 'viz-orange-8': 'oklch(0.745 0.1322 54.68)', + 'viz-orange-6': 'oklch(0.8537 0.1068 66.02)', + 'viz-gold-11': 'oklch(0.5042 0.0395 78.26)', + 'viz-gold-9': 'oklch(0.6204 0.0492 77.7)', + 'viz-gold-8': 'oklch(0.739 0.0423 79.36)', + 'viz-gold-6': 'oklch(0.8594 0.0247 85.79)', /* Contrast Colors */ - 'danger-contrast': '#ffffff', - 'attention-contrast': '#000000', - 'success-contrast': '#ffffff', + 'danger-contrast': 'oklch(1 0 0)', + 'attention-contrast': 'oklch(0 0 0)', + 'success-contrast': 'oklch(1 0 0)', /* Overlay color */ - 'overlay-1': '#0000004D' /* 30% opacity */ + 'overlay-1': 'oklch(0 0 0 / 0.302)' /* 30% opacity */ } as const; diff --git a/packages/plugin-vscode/src/tokens/primitives/gray.ts b/packages/plugin-vscode/src/tokens/primitives/gray.ts index 3430214d6..c296df60b 100644 --- a/packages/plugin-vscode/src/tokens/primitives/gray.ts +++ b/packages/plugin-vscode/src/tokens/primitives/gray.ts @@ -3,16 +3,16 @@ */ export default { - 'gray-1': '#fcfcfc', - 'gray-2': '#f9f9f9', - 'gray-3': '#f0f0f0', - 'gray-4': '#e8e8e8', - 'gray-5': '#e0e0e0', - 'gray-6': '#d9d9d9', - 'gray-7': '#cecece', - 'gray-8': '#bbbbbb', - 'gray-9': '#8d8d8d', - 'gray-10': '#838383', - 'gray-11': '#646464', - 'gray-12': '#202020' + 'gray-1': 'oklch(0.9911 0 0)', + 'gray-2': 'oklch(0.9821 0 0)', + 'gray-3': 'oklch(0.9551 0 0)', + 'gray-4': 'oklch(0.931 0 0)', + 'gray-5': 'oklch(0.9067 0 0)', + 'gray-6': 'oklch(0.8853 0 0)', + 'gray-7': 'oklch(0.8514 0 0)', + 'gray-8': 'oklch(0.7921 0 0)', + 'gray-9': 'oklch(0.6434 0 0)', + 'gray-10': 'oklch(0.61 0 0)', + 'gray-11': 'oklch(0.5032 0 0)', + 'gray-12': 'oklch(0.2435 0 0)' } as const; From 8c01260b43be418b9c58855554d8f5400ac298c0 Mon Sep 17 00:00:00 2001 From: paanSinghCoder Date: Tue, 28 Apr 2026 14:31:19 +0530 Subject: [PATCH 2/2] =?UTF-8?q?chore(plugin-vscode):=20swap=20color?= =?UTF-8?q?=E2=86=92culori,=20emit=20oklch()=20on=20picker=20writes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the 'color' npm package (no OKLCH support) with culori across the plugin's color parsing and serialization paths. - colorToVSCodeColor: parses oklch()/hex/rgb/etc. via culori, returns VS Code's {red,green,blue,alpha} sRGB shape, clamped to [0, 1] - VSCodeColorToColor: emits oklch() strings on picker writes so user edits stay consistent with the apsara design system convention Bump plugin version 0.1.1 → 0.2.0 (picker writeback format change). Co-Authored-By: Claude Opus 4.7 (1M context) --- packages/plugin-vscode/package.json | 5 +- packages/plugin-vscode/src/lib/utils.ts | 79 ++++++++++++++----------- pnpm-lock.yaml | 34 +++-------- 3 files changed, 56 insertions(+), 62 deletions(-) diff --git a/packages/plugin-vscode/package.json b/packages/plugin-vscode/package.json index 6631de5e7..7dfad878a 100644 --- a/packages/plugin-vscode/package.json +++ b/packages/plugin-vscode/package.json @@ -2,7 +2,7 @@ "name": "apsara-for-vscode", "displayName": "Apsara for VSCode", "publisher": "Raystack", - "version": "0.1.1", + "version": "0.2.0", "private": true, "description": "VS Code extension for @raystack/apsara", "license": "SEE LICENSE IN LICENSE.md", @@ -62,14 +62,13 @@ }, "dependencies": { "@raystack/apsara": "^0.56.6", - "color": "^5.0.0", + "culori": "^4.0.2", "vscode-languageclient": "^9.0.1", "vscode-languageserver": "^9.0.1", "vscode-languageserver-textdocument": "^1.0.12" }, "devDependencies": { "@raystack/tools-config": "workspace:*", - "@types/color": "^4.2.0", "@types/node": "20.x", "@types/vscode": "^1.70.0", "@vscode/vsce": "^3.5.0", diff --git a/packages/plugin-vscode/src/lib/utils.ts b/packages/plugin-vscode/src/lib/utils.ts index f2611082b..8273906b7 100644 --- a/packages/plugin-vscode/src/lib/utils.ts +++ b/packages/plugin-vscode/src/lib/utils.ts @@ -1,9 +1,17 @@ -import Color from 'color'; +import { converter, parse } from 'culori'; import type { Color as VSCodeColorType } from 'vscode-languageserver'; import tokens from '../tokens'; export const TOKEN_PREFIX = 'rs'; +const toRgb = converter('rgb'); +const toOklch = converter('oklch'); + +const round = (n: number | undefined, p: number) => + Number.parseFloat((n ?? 0).toFixed(p)); + +const clamp01 = (v: number | undefined) => Math.max(0, Math.min(1, v ?? 0)); + /** * Get the token name for a given token group and name * @param tokenGroupName - The name of the token group @@ -41,52 +49,55 @@ export const getTokenValueFromName = (tokenName: string): string | null => { }; /** - * Converts a Color object to VS Code Color format - * @param color - The color to convert - * @returns The color in VS Code Color format + * Parses a CSS color string (oklch, hex, rgb, etc.) into VS Code's Color shape. + * Returns null for non-renderable inputs (currentColor, inherit, parse failure). */ export const colorToVSCodeColor = (color: string): VSCodeColorType | null => { + if (color === 'transparent') { + return { red: 0, green: 0, blue: 0, alpha: 0 }; + } + if (color === 'currentColor' || color === 'inherit') { + return null; + } try { - // Handle transparent values - if (color === 'transparent') { - return { - red: 0, - green: 0, - blue: 0, - alpha: 0 - }; - } - // handles special CSS values that don't have a specific color - if (color === 'currentColor' || color === 'inherit') { - return null; - } - - const rgb = Color(color).rgb(); + const parsed = parse(color); + if (!parsed) return null; + const rgb = toRgb(parsed); + if (!rgb) return null; return { - red: rgb.red() / 255, - green: rgb.green() / 255, - blue: rgb.blue() / 255, - alpha: rgb.alpha() + red: clamp01(rgb.r), + green: clamp01(rgb.g), + blue: clamp01(rgb.b), + alpha: rgb.alpha ?? 1 }; } catch { - // If the color library can't parse the value, return null return null; } }; /** - * Converts a VS Code Color to a Color object - * @param color - The VS Code color object to convert - * @returns The color in hex format + * Serializes VS Code's Color (sRGB 0-1 floats) to an oklch() string. + * Output format matches the design system convention so picker edits + * stay consistent with the rest of the codebase. */ export const VSCodeColorToColor = (color: VSCodeColorType): string => { - return Color.rgb( - Math.round(color.red * 255), - Math.round(color.green * 255), - Math.round(color.blue * 255) - ) - .alpha(color.alpha) - .hex(); + const oklch = toOklch({ + mode: 'rgb', + r: color.red, + g: color.green, + b: color.blue, + alpha: color.alpha + }); + if (!oklch) return ''; + + const L = round(oklch.l, 4); + const C = round(oklch.c, 4); + const H = Number.isFinite(oklch.h) ? round(oklch.h, 2) : 0; + const body = `${L} ${C} ${H}`; + if (color.alpha === undefined || color.alpha === 1) { + return `oklch(${body})`; + } + return `oklch(${body} / ${round(color.alpha, 4)})`; }; // Function to get the pattern match and the range around the cursor diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7839febed..acf5dea26 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -138,9 +138,9 @@ importers: '@raystack/apsara': specifier: ^0.56.6 version: 0.56.6(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.1(react@19.2.1))(react@19.2.1) - color: - specifier: ^5.0.0 - version: 5.0.0 + culori: + specifier: ^4.0.2 + version: 4.0.2 vscode-languageclient: specifier: ^9.0.1 version: 9.0.1 @@ -154,9 +154,6 @@ importers: '@raystack/tools-config': specifier: workspace:* version: link:../tools-config - '@types/color': - specifier: ^4.2.0 - version: 4.2.0 '@types/node': specifier: 20.x version: 20.19.0 @@ -3697,15 +3694,6 @@ packages: '@types/chai@5.2.2': resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} - '@types/color-convert@2.0.4': - resolution: {integrity: sha512-Ub1MmDdyZ7mX//g25uBAoH/mWGd9swVbt8BseymnaE18SU4po/PjmCrHxqIIRjBo3hV/vh1KGr0eMxUhp+t+dQ==} - - '@types/color-name@1.1.5': - resolution: {integrity: sha512-j2K5UJqGTxeesj6oQuGpMgifpT5k9HprgQd8D1Y0lOFqKHl3PJu5GMeS4Y5EgjS55AE6OQxf8mPED9uaGbf4Cg==} - - '@types/color@4.2.0': - resolution: {integrity: sha512-6+xrIRImMtGAL2X3qYkd02Mgs+gFGs+WsK0b7VVMaO4mYRISwyTjcqNrO0mNSmYEoq++rSLDB2F5HDNmqfOe+A==} - '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} @@ -4593,6 +4581,10 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + culori@4.0.2: + resolution: {integrity: sha512-1+BhOB8ahCn4O0cep0Sh2l9KCOfOdY+BXJnKMHFFzDEouSr/el18QwXEMRlOj9UY5nCeA8UN3a/82rUWRBeyBw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + data-urls@5.0.0: resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} engines: {node: '>=18'} @@ -12829,16 +12821,6 @@ snapshots: dependencies: '@types/deep-eql': 4.0.2 - '@types/color-convert@2.0.4': - dependencies: - '@types/color-name': 1.1.5 - - '@types/color-name@1.1.5': {} - - '@types/color@4.2.0': - dependencies: - '@types/color-convert': 2.0.4 - '@types/debug@4.1.12': dependencies: '@types/ms': 0.7.34 @@ -13818,6 +13800,8 @@ snapshots: csstype@3.1.3: {} + culori@4.0.2: {} + data-urls@5.0.0: dependencies: whatwg-mimetype: 4.0.0