oklchtohex 0.5.2 → 0.6.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/dist/converter.js +1 -0
- package/dist/index.js +1 -0
- package/dist/postcss-plugin.cjs +1 -0
- package/dist/postcss-plugin.js +1 -0
- package/dist/vite-plugin.js +1 -0
- package/package.json +16 -9
- package/src/converter.js +0 -330
- package/src/index.js +0 -3
- package/src/postcss-plugin.cjs +0 -28
- package/src/postcss-plugin.js +0 -22
- package/src/tailwind-default-hex.js +0 -300
- package/src/vite-plugin.js +0 -105
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{getTailwindDefaultHexForVar as g}from"./tailwind-default-hex.js";const H=/oklch\(([^)]*)\)/gi,C=/color-mix\(\s*in\s+oklab\s*,\s*var\(\s*(--[\w-]+)\s*\)\s*([0-9.]+)%\s*,\s*transparent\s*\)/gi;function l(e,t,r){return Math.min(r,Math.max(t,e))}function u(e){const t=Number.parseFloat(e);if(Number.isNaN(t))throw new Error(`Invalid numeric token: "${e}"`);return t}function T(e){const t=e.trim().toLowerCase();if(t.endsWith("%"))return l(u(t.slice(0,-1))/100,0,1);const r=u(t);return r>1&&r<=100?l(r/100,0,1):l(r,0,1)}function I(e){const t=e.trim().toLowerCase();return t.endsWith("deg")?u(t.slice(0,-3)):t.endsWith("rad")?u(t.slice(0,-3))*180/Math.PI:t.endsWith("turn")?u(t.slice(0,-4))*360:u(t)}function L(e){if(typeof e!="string")return 1;const t=e.trim().toLowerCase();return t.endsWith("%")?l(u(t.slice(0,-1))/100,0,1):l(u(t),0,1)}function x(e){const t=e%360;return t<0?t+360:t}function k(e){if(typeof e!="string")throw new Error("parseOklch expects a string like oklch(70% 0.2 30)");const t=e.trim(),r=t.toLowerCase();if(!r.startsWith("oklch(")||!r.endsWith(")"))throw new Error(`Invalid OKLCH function: "${e}"`);const n=t.slice(t.indexOf("(")+1,-1).trim(),s=n.indexOf("/"),o=s===-1?n:n.slice(0,s).trim(),a=s===-1?void 0:n.slice(s+1).trim(),c=o.replace(/,/g," ").split(/\s+/).filter(Boolean);if(c.length<3)throw new Error(`Invalid OKLCH channels: "${e}"`);const i=T(c[0]),h=Math.max(0,u(c[1])),m=x(I(c[2])),f=L(a);return{l:i,c:h,h:m,alpha:f}}function O(e,t,r){const n=e+.3963377774*t+.2158037573*r,s=e-.1055613458*t-.0638541728*r,o=e-.0894841775*t-1.291485548*r,a=n*n*n,c=s*s*s,i=o*o*o;return{r:4.0767416621*a-3.3077115913*c+.2309699292*i,g:-1.2684380046*a+2.6097574011*c-.3413193965*i,b:-.0041960863*a-.7034186147*c+1.707614701*i}}function d(e,t,r){const n=r*Math.PI/180,s=t*Math.cos(n),o=t*Math.sin(n);return O(e,s,o)}function b(e){return e.r>=0&&e.r<=1&&e.g>=0&&e.g<=1&&e.b>=0&&e.b<=1}function M(e,t,r){const n=d(e,t,r);if(b(n))return t;let s=0,o=t;for(let a=0;a<24;a+=1){const c=(s+o)/2,i=d(e,c,r);b(i)?s=c:o=c}return s}function w(e){return e<=.0031308?12.92*e:1.055*e**(1/2.4)-.055}function p(e){const t=l(e,0,1);return Math.round(t*255).toString(16).padStart(2,"0")}function $(e){const t=e.trim().toLowerCase();if(!t.startsWith("#"))return null;const r=t.slice(1);return r.length===3?`#${r[0]}${r[0]}${r[1]}${r[1]}${r[2]}${r[2]}`:r.length===4?`#${r[0]}${r[0]}${r[1]}${r[1]}${r[2]}${r[2]}${r[3]}${r[3]}`:r.length===6||r.length===8?`#${r}`:null}function N(e){const t=$(e);if(!t)return null;const r=t.slice(1),n=r.slice(0,6),s=r.length===8?r.slice(6,8):"ff";return{rgbHex:n,alphaHex:s}}function v(e){return p(l(e,0,1))}function y(e,t){const n=Number.parseInt(e,16)/255*l(t/100,0,1);return v(n)}function E(e){if(typeof e=="string")return k(e);if(e&&typeof e=="object"&&typeof e.l=="number"&&typeof e.c=="number"&&typeof e.h=="number")return{l:l(e.l,0,1),c:Math.max(0,e.c),h:x(e.h),alpha:l(e.alpha??1,0,1)};throw new Error("Input must be an OKLCH string or { l, c, h, alpha } object")}function A(e,t={}){const{gamut:r="clip",includeAlpha:n="auto",uppercase:s=!1}=t,o=E(e),a=r==="fit"?M(o.l,o.c,o.h):o.c,c=d(o.l,a,o.h),i=w(c.r),h=w(c.g),m=w(c.b);let f=`#${p(i)}${p(h)}${p(m)}`;return(n===!0||n==="always"||n==="auto"&&o.alpha<1)&&(f+=p(o.alpha)),s?f.toUpperCase():f}function W(e){const t=/(--color-[a-z]+-\d{2,3})(\s*:\s*)oklch\(([^)]*)\)/gi;return e.replace(t,(r,n,s)=>{const o=g(n.toLowerCase());return o?`${n}${s}${o}`:r})}function S(e){const t=/(--[\w-]+)\s*:\s*(#[0-9a-fA-F]{3,8})\s*;/g,r=new Map;let n=t.exec(e);for(;n;){const s=n[1].toLowerCase(),o=$(n[2]);o&&r.set(s,o),n=t.exec(e)}return r}function _(e,t){return e.replace(C,(r,n,s)=>{const o=String(n).toLowerCase(),a=Number.parseFloat(s);if(Number.isNaN(a))return r;const c=t.get(o)??g(o);if(!c)return r;const i=N(c);if(!i)return r;const h=y(i.alphaHex,a);return`#${i.rgbHex}${h}`})}function z(e,t={}){if(typeof e!="string")throw new Error("replaceOklchInText expects a string");const{onError:r="preserve",...n}=t,o=W(e).replace(H,c=>{try{return A(c,n)}catch(i){if(r==="throw")throw i;return c}}),a=S(o);return _(o,a)}function F(e,t={}){return z(e,t)}export{F as convertTailwindCssToHex,A as oklchToHex,k as parseOklch,z as replaceOklchInText};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export*from"./converter.js";import{oklchToHexVitePlugin as t}from"./vite-plugin.js";import{oklchToHexPostcssPlugin as l}from"./postcss-plugin.js";export{l as oklchToHexPostcssPlugin,t as oklchToHexVitePlugin};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var p=Object.create;var i=Object.defineProperty;var r=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var a=Object.getPrototypeOf,g=Object.prototype.hasOwnProperty;var x=(s,o,t,e)=>{if(o&&typeof o=="object"||typeof o=="function")for(let n of u(o))!g.call(s,n)&&n!==t&&i(s,n,{get:()=>o[n],enumerable:!(e=r(o,n))||e.enumerable});return s};var d=(s,o,t)=>(t=s!=null?p(a(s)):{},x(o||!s||!s.__esModule?i(t,"default",{value:s,enumerable:!0}):t,s));function c(s){const o=s||{};return{postcssPlugin:"oklchtohex-postcss-plugin",async Once(t){const e=t.toString();if(!e.toLowerCase().includes("oklch("))return;const l=(await import("./converter.js")).replaceOklchInText(e,o);l!==e&&(t.removeAll(),t.append(l))}}}c.postcss=!0,module.exports=c,module.exports.default=c,module.exports.oklchToHexPostcssPlugin=c;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{replaceOklchInText as c}from"./converter.js";function t(n={}){return{postcssPlugin:"oklchtohex-postcss-plugin",Once(e){const s=e.toString();if(!s.toLowerCase().includes("oklch("))return;const o=c(s,n);o!==s&&(e.removeAll(),e.append(o))}}}t.postcss=!0;var r=t;export{r as default,t as oklchToHexPostcssPlugin};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{replaceOklchInText as m}from"./converter.js";const g=/\.(css|pcss|postcss|scss|sass|less|styl|stylus)(?:$|\?)/i;function y(e,n){return e instanceof RegExp?(e.lastIndex=0,e.test(n)):!1}function a(e,n){return e?e instanceof RegExp?y(e,n):typeof e=="function"?!!e(n):!1:!0}function p(e,n,t){return!(!a(n,e)||t&&a(t,e))}function d(e,n){if(typeof e!="string"||!e.toLowerCase().includes("oklch("))return null;const t=m(e,n);return t===e?null:t}function E(e={}){const{include:n=g,exclude:t,convertDev:v=!0,convertBuild:l=!0,...c}=e;let u="build";return{name:"oklchtohex-vite-plugin",enforce:"post",configResolved(r){u=r.command},transform(r,i){if(u==="serve"&&!v||u==="build"&&!l||!p(i,n,t))return null;const s=d(r,c);return s?{code:s,map:null}:null},generateBundle(r,i){if(l)for(const[s,o]of Object.entries(i)){if(o.type!=="asset"||!p(s,n,t)||typeof o.source!="string")continue;const f=d(o.source,c);f&&(o.source=f)}}}}export{E as oklchToHexVitePlugin};
|
package/package.json
CHANGED
|
@@ -1,23 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oklchtohex",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Convert OKLCH colors to HEX as a JavaScript package.",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "./
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
7
|
"exports": {
|
|
8
|
-
".": "./
|
|
9
|
-
"./vite": "./
|
|
8
|
+
".": "./dist/index.js",
|
|
9
|
+
"./vite": "./dist/vite-plugin.js",
|
|
10
10
|
"./postcss": {
|
|
11
|
-
"import": "./
|
|
12
|
-
"require": "./
|
|
13
|
-
"default": "./
|
|
11
|
+
"import": "./dist/postcss-plugin.js",
|
|
12
|
+
"require": "./dist/postcss-plugin.cjs",
|
|
13
|
+
"default": "./dist/postcss-plugin.js"
|
|
14
14
|
},
|
|
15
|
-
"./converter": "./
|
|
15
|
+
"./converter": "./dist/converter.js"
|
|
16
16
|
},
|
|
17
17
|
"files": [
|
|
18
|
-
"
|
|
18
|
+
"dist",
|
|
19
19
|
"README.md"
|
|
20
20
|
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "node ./scripts/build.mjs",
|
|
23
|
+
"prepack": "npm run build"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"esbuild": "^0.25.0"
|
|
27
|
+
},
|
|
21
28
|
"keywords": [
|
|
22
29
|
"oklch",
|
|
23
30
|
"hex",
|
package/src/converter.js
DELETED
|
@@ -1,330 +0,0 @@
|
|
|
1
|
-
import { getTailwindDefaultHexForVar } from "./tailwind-default-hex.js";
|
|
2
|
-
const OKLCH_REGEX = /oklch\(([^)]*)\)/gi;
|
|
3
|
-
const COLOR_MIX_WITH_TRANSPARENT_REGEX =
|
|
4
|
-
/color-mix\(\s*in\s+oklab\s*,\s*var\(\s*(--[\w-]+)\s*\)\s*([0-9.]+)%\s*,\s*transparent\s*\)/gi;
|
|
5
|
-
|
|
6
|
-
function clamp(value, min, max) {
|
|
7
|
-
return Math.min(max, Math.max(min, value));
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function parseNumericToken(token) {
|
|
11
|
-
const value = Number.parseFloat(token);
|
|
12
|
-
if (Number.isNaN(value)) {
|
|
13
|
-
throw new Error(`Invalid numeric token: "${token}"`);
|
|
14
|
-
}
|
|
15
|
-
return value;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function parseLightness(token) {
|
|
19
|
-
const trimmed = token.trim().toLowerCase();
|
|
20
|
-
if (trimmed.endsWith("%")) {
|
|
21
|
-
return clamp(parseNumericToken(trimmed.slice(0, -1)) / 100, 0, 1);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const value = parseNumericToken(trimmed);
|
|
25
|
-
if (value > 1 && value <= 100) {
|
|
26
|
-
return clamp(value / 100, 0, 1);
|
|
27
|
-
}
|
|
28
|
-
return clamp(value, 0, 1);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function parseHue(token) {
|
|
32
|
-
const trimmed = token.trim().toLowerCase();
|
|
33
|
-
if (trimmed.endsWith("deg")) {
|
|
34
|
-
return parseNumericToken(trimmed.slice(0, -3));
|
|
35
|
-
}
|
|
36
|
-
if (trimmed.endsWith("rad")) {
|
|
37
|
-
return (parseNumericToken(trimmed.slice(0, -3)) * 180) / Math.PI;
|
|
38
|
-
}
|
|
39
|
-
if (trimmed.endsWith("turn")) {
|
|
40
|
-
return parseNumericToken(trimmed.slice(0, -4)) * 360;
|
|
41
|
-
}
|
|
42
|
-
return parseNumericToken(trimmed);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function parseAlpha(token) {
|
|
46
|
-
if (typeof token !== "string") {
|
|
47
|
-
return 1;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const trimmed = token.trim().toLowerCase();
|
|
51
|
-
if (trimmed.endsWith("%")) {
|
|
52
|
-
return clamp(parseNumericToken(trimmed.slice(0, -1)) / 100, 0, 1);
|
|
53
|
-
}
|
|
54
|
-
return clamp(parseNumericToken(trimmed), 0, 1);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function normalizeHueDegrees(hue) {
|
|
58
|
-
const normalized = hue % 360;
|
|
59
|
-
return normalized < 0 ? normalized + 360 : normalized;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export function parseOklch(input) {
|
|
63
|
-
if (typeof input !== "string") {
|
|
64
|
-
throw new Error("parseOklch expects a string like oklch(70% 0.2 30)");
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const trimmed = input.trim();
|
|
68
|
-
const lower = trimmed.toLowerCase();
|
|
69
|
-
if (!lower.startsWith("oklch(") || !lower.endsWith(")")) {
|
|
70
|
-
throw new Error(`Invalid OKLCH function: "${input}"`);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const inner = trimmed.slice(trimmed.indexOf("(") + 1, -1).trim();
|
|
74
|
-
const slashIndex = inner.indexOf("/");
|
|
75
|
-
const colorPart = slashIndex === -1 ? inner : inner.slice(0, slashIndex).trim();
|
|
76
|
-
const alphaPart = slashIndex === -1 ? undefined : inner.slice(slashIndex + 1).trim();
|
|
77
|
-
|
|
78
|
-
const parts = colorPart
|
|
79
|
-
.replace(/,/g, " ")
|
|
80
|
-
.split(/\s+/)
|
|
81
|
-
.filter(Boolean);
|
|
82
|
-
|
|
83
|
-
if (parts.length < 3) {
|
|
84
|
-
throw new Error(`Invalid OKLCH channels: "${input}"`);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const l = parseLightness(parts[0]);
|
|
88
|
-
const c = Math.max(0, parseNumericToken(parts[1]));
|
|
89
|
-
const h = normalizeHueDegrees(parseHue(parts[2]));
|
|
90
|
-
const alpha = parseAlpha(alphaPart);
|
|
91
|
-
|
|
92
|
-
return { l, c, h, alpha };
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function oklabToLinearSrgb(l, a, b) {
|
|
96
|
-
const l_ = l + 0.3963377774 * a + 0.2158037573 * b;
|
|
97
|
-
const m_ = l - 0.1055613458 * a - 0.0638541728 * b;
|
|
98
|
-
const s_ = l - 0.0894841775 * a - 1.291485548 * b;
|
|
99
|
-
|
|
100
|
-
const l3 = l_ * l_ * l_;
|
|
101
|
-
const m3 = m_ * m_ * m_;
|
|
102
|
-
const s3 = s_ * s_ * s_;
|
|
103
|
-
|
|
104
|
-
return {
|
|
105
|
-
r: +4.0767416621 * l3 - 3.3077115913 * m3 + 0.2309699292 * s3,
|
|
106
|
-
g: -1.2684380046 * l3 + 2.6097574011 * m3 - 0.3413193965 * s3,
|
|
107
|
-
b: -0.0041960863 * l3 - 0.7034186147 * m3 + 1.707614701 * s3
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function oklchToLinearSrgb(l, c, hDegrees) {
|
|
112
|
-
const radians = (hDegrees * Math.PI) / 180;
|
|
113
|
-
const a = c * Math.cos(radians);
|
|
114
|
-
const b = c * Math.sin(radians);
|
|
115
|
-
return oklabToLinearSrgb(l, a, b);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
function isInSrgbGamut(linearRgb) {
|
|
119
|
-
return (
|
|
120
|
-
linearRgb.r >= 0 &&
|
|
121
|
-
linearRgb.r <= 1 &&
|
|
122
|
-
linearRgb.g >= 0 &&
|
|
123
|
-
linearRgb.g <= 1 &&
|
|
124
|
-
linearRgb.b >= 0 &&
|
|
125
|
-
linearRgb.b <= 1
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
function fitChromaToSrgb(l, c, h) {
|
|
130
|
-
const initial = oklchToLinearSrgb(l, c, h);
|
|
131
|
-
if (isInSrgbGamut(initial)) {
|
|
132
|
-
return c;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
let low = 0;
|
|
136
|
-
let high = c;
|
|
137
|
-
for (let i = 0; i < 24; i += 1) {
|
|
138
|
-
const mid = (low + high) / 2;
|
|
139
|
-
const rgb = oklchToLinearSrgb(l, mid, h);
|
|
140
|
-
if (isInSrgbGamut(rgb)) {
|
|
141
|
-
low = mid;
|
|
142
|
-
} else {
|
|
143
|
-
high = mid;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
return low;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
function linearToSrgbChannel(channel) {
|
|
150
|
-
if (channel <= 0.0031308) {
|
|
151
|
-
return 12.92 * channel;
|
|
152
|
-
}
|
|
153
|
-
return 1.055 * channel ** (1 / 2.4) - 0.055;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
function channelToHex(channel) {
|
|
157
|
-
const clamped = clamp(channel, 0, 1);
|
|
158
|
-
const byte = Math.round(clamped * 255);
|
|
159
|
-
return byte.toString(16).padStart(2, "0");
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
function normalizeHexColor(hex) {
|
|
163
|
-
const trimmed = hex.trim().toLowerCase();
|
|
164
|
-
if (!trimmed.startsWith("#")) {
|
|
165
|
-
return null;
|
|
166
|
-
}
|
|
167
|
-
const raw = trimmed.slice(1);
|
|
168
|
-
if (raw.length === 3) {
|
|
169
|
-
return `#${raw[0]}${raw[0]}${raw[1]}${raw[1]}${raw[2]}${raw[2]}`;
|
|
170
|
-
}
|
|
171
|
-
if (raw.length === 4) {
|
|
172
|
-
return `#${raw[0]}${raw[0]}${raw[1]}${raw[1]}${raw[2]}${raw[2]}${raw[3]}${raw[3]}`;
|
|
173
|
-
}
|
|
174
|
-
if (raw.length === 6 || raw.length === 8) {
|
|
175
|
-
return `#${raw}`;
|
|
176
|
-
}
|
|
177
|
-
return null;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
function splitHexChannels(hex) {
|
|
181
|
-
const normalized = normalizeHexColor(hex);
|
|
182
|
-
if (!normalized) {
|
|
183
|
-
return null;
|
|
184
|
-
}
|
|
185
|
-
const raw = normalized.slice(1);
|
|
186
|
-
const rgbHex = raw.slice(0, 6);
|
|
187
|
-
const alphaHex = raw.length === 8 ? raw.slice(6, 8) : "ff";
|
|
188
|
-
return { rgbHex, alphaHex };
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
function alphaToHex(alpha) {
|
|
192
|
-
return channelToHex(clamp(alpha, 0, 1));
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
function combineAlpha(existingAlphaHex, mixPercent) {
|
|
196
|
-
const baseAlpha = Number.parseInt(existingAlphaHex, 16) / 255;
|
|
197
|
-
const mixedAlpha = baseAlpha * clamp(mixPercent / 100, 0, 1);
|
|
198
|
-
return alphaToHex(mixedAlpha);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
function normalizeInput(input) {
|
|
202
|
-
if (typeof input === "string") {
|
|
203
|
-
return parseOklch(input);
|
|
204
|
-
}
|
|
205
|
-
if (input && typeof input === "object") {
|
|
206
|
-
if (
|
|
207
|
-
typeof input.l === "number" &&
|
|
208
|
-
typeof input.c === "number" &&
|
|
209
|
-
typeof input.h === "number"
|
|
210
|
-
) {
|
|
211
|
-
return {
|
|
212
|
-
l: clamp(input.l, 0, 1),
|
|
213
|
-
c: Math.max(0, input.c),
|
|
214
|
-
h: normalizeHueDegrees(input.h),
|
|
215
|
-
alpha: clamp(input.alpha ?? 1, 0, 1)
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
throw new Error("Input must be an OKLCH string or { l, c, h, alpha } object");
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
export function oklchToHex(input, options = {}) {
|
|
223
|
-
const { gamut = "clip", includeAlpha = "auto", uppercase = false } = options;
|
|
224
|
-
const parsed = normalizeInput(input);
|
|
225
|
-
|
|
226
|
-
const c =
|
|
227
|
-
gamut === "fit"
|
|
228
|
-
? fitChromaToSrgb(parsed.l, parsed.c, parsed.h)
|
|
229
|
-
: parsed.c;
|
|
230
|
-
|
|
231
|
-
const linear = oklchToLinearSrgb(parsed.l, c, parsed.h);
|
|
232
|
-
const r = linearToSrgbChannel(linear.r);
|
|
233
|
-
const g = linearToSrgbChannel(linear.g);
|
|
234
|
-
const b = linearToSrgbChannel(linear.b);
|
|
235
|
-
|
|
236
|
-
let hex = `#${channelToHex(r)}${channelToHex(g)}${channelToHex(b)}`;
|
|
237
|
-
const shouldIncludeAlpha =
|
|
238
|
-
includeAlpha === true || includeAlpha === "always" || (includeAlpha === "auto" && parsed.alpha < 1);
|
|
239
|
-
|
|
240
|
-
if (shouldIncludeAlpha) {
|
|
241
|
-
hex += channelToHex(parsed.alpha);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
return uppercase ? hex.toUpperCase() : hex;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
function replaceTailwindDefaultColorVariables(text) {
|
|
248
|
-
const declarationRegex =
|
|
249
|
-
/(--color-[a-z]+-\d{2,3})(\s*:\s*)oklch\(([^)]*)\)/gi;
|
|
250
|
-
|
|
251
|
-
return text.replace(
|
|
252
|
-
declarationRegex,
|
|
253
|
-
(fullMatch, variableName, separator) => {
|
|
254
|
-
const mappedHex = getTailwindDefaultHexForVar(variableName.toLowerCase());
|
|
255
|
-
if (!mappedHex) {
|
|
256
|
-
return fullMatch;
|
|
257
|
-
}
|
|
258
|
-
return `${variableName}${separator}${mappedHex}`;
|
|
259
|
-
}
|
|
260
|
-
);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
function collectHexVariableDeclarations(text) {
|
|
264
|
-
const declarationRegex = /(--[\w-]+)\s*:\s*(#[0-9a-fA-F]{3,8})\s*;/g;
|
|
265
|
-
const map = new Map();
|
|
266
|
-
let match = declarationRegex.exec(text);
|
|
267
|
-
while (match) {
|
|
268
|
-
const variableName = match[1].toLowerCase();
|
|
269
|
-
const normalized = normalizeHexColor(match[2]);
|
|
270
|
-
if (normalized) {
|
|
271
|
-
map.set(variableName, normalized);
|
|
272
|
-
}
|
|
273
|
-
match = declarationRegex.exec(text);
|
|
274
|
-
}
|
|
275
|
-
return map;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
function replaceTailwindColorMixWithHex(text, variableHexMap) {
|
|
279
|
-
return text.replace(
|
|
280
|
-
COLOR_MIX_WITH_TRANSPARENT_REGEX,
|
|
281
|
-
(fullMatch, variableNameRaw, percentRaw) => {
|
|
282
|
-
const variableName = String(variableNameRaw).toLowerCase();
|
|
283
|
-
const percent = Number.parseFloat(percentRaw);
|
|
284
|
-
if (Number.isNaN(percent)) {
|
|
285
|
-
return fullMatch;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
const sourceHex =
|
|
289
|
-
variableHexMap.get(variableName) ??
|
|
290
|
-
getTailwindDefaultHexForVar(variableName);
|
|
291
|
-
|
|
292
|
-
if (!sourceHex) {
|
|
293
|
-
return fullMatch;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
const channels = splitHexChannels(sourceHex);
|
|
297
|
-
if (!channels) {
|
|
298
|
-
return fullMatch;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
const alphaHex = combineAlpha(channels.alphaHex, percent);
|
|
302
|
-
return `#${channels.rgbHex}${alphaHex}`;
|
|
303
|
-
}
|
|
304
|
-
);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
export function replaceOklchInText(text, options = {}) {
|
|
308
|
-
if (typeof text !== "string") {
|
|
309
|
-
throw new Error("replaceOklchInText expects a string");
|
|
310
|
-
}
|
|
311
|
-
const { onError = "preserve", ...convertOptions } = options;
|
|
312
|
-
const withMappedTailwindDefaults = replaceTailwindDefaultColorVariables(text);
|
|
313
|
-
const withConvertedOklch = withMappedTailwindDefaults.replace(OKLCH_REGEX, (match) => {
|
|
314
|
-
try {
|
|
315
|
-
return oklchToHex(match, convertOptions);
|
|
316
|
-
} catch (error) {
|
|
317
|
-
if (onError === "throw") {
|
|
318
|
-
throw error;
|
|
319
|
-
}
|
|
320
|
-
return match;
|
|
321
|
-
}
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
const variableHexMap = collectHexVariableDeclarations(withConvertedOklch);
|
|
325
|
-
return replaceTailwindColorMixWithHex(withConvertedOklch, variableHexMap);
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
export function convertTailwindCssToHex(css, options = {}) {
|
|
329
|
-
return replaceOklchInText(css, options);
|
|
330
|
-
}
|
package/src/index.js
DELETED
package/src/postcss-plugin.cjs
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
function oklchToHexPostcssPlugin(options) {
|
|
2
|
-
const pluginOptions = options || {};
|
|
3
|
-
|
|
4
|
-
return {
|
|
5
|
-
postcssPlugin: "oklchtohex-postcss-plugin",
|
|
6
|
-
async Once(root) {
|
|
7
|
-
const originalCss = root.toString();
|
|
8
|
-
if (!originalCss.toLowerCase().includes("oklch(")) {
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const mod = await import("./converter.js");
|
|
13
|
-
const convertedCss = mod.replaceOklchInText(originalCss, pluginOptions);
|
|
14
|
-
|
|
15
|
-
if (convertedCss !== originalCss) {
|
|
16
|
-
root.removeAll();
|
|
17
|
-
root.append(convertedCss);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
oklchToHexPostcssPlugin.postcss = true;
|
|
24
|
-
|
|
25
|
-
module.exports = oklchToHexPostcssPlugin;
|
|
26
|
-
module.exports.default = oklchToHexPostcssPlugin;
|
|
27
|
-
module.exports.oklchToHexPostcssPlugin = oklchToHexPostcssPlugin;
|
|
28
|
-
|
package/src/postcss-plugin.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { replaceOklchInText } from "./converter.js";
|
|
2
|
-
|
|
3
|
-
export function oklchToHexPostcssPlugin(options = {}) {
|
|
4
|
-
return {
|
|
5
|
-
postcssPlugin: "oklchtohex-postcss-plugin",
|
|
6
|
-
Once(root) {
|
|
7
|
-
const originalCss = root.toString();
|
|
8
|
-
if (!originalCss.toLowerCase().includes("oklch(")) {
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const convertedCss = replaceOklchInText(originalCss, options);
|
|
13
|
-
if (convertedCss !== originalCss) {
|
|
14
|
-
root.removeAll();
|
|
15
|
-
root.append(convertedCss);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
oklchToHexPostcssPlugin.postcss = true;
|
|
22
|
-
export default oklchToHexPostcssPlugin;
|
|
@@ -1,300 +0,0 @@
|
|
|
1
|
-
const TAILWIND_HEX_COLORS = {
|
|
2
|
-
slate: {
|
|
3
|
-
50: "#f8fafc",
|
|
4
|
-
100: "#f1f5f9",
|
|
5
|
-
200: "#e2e8f0",
|
|
6
|
-
300: "#cbd5e1",
|
|
7
|
-
400: "#94a3b8",
|
|
8
|
-
500: "#64748b",
|
|
9
|
-
600: "#475569",
|
|
10
|
-
700: "#334155",
|
|
11
|
-
800: "#1e293b",
|
|
12
|
-
900: "#0f172a",
|
|
13
|
-
950: "#020617"
|
|
14
|
-
},
|
|
15
|
-
gray: {
|
|
16
|
-
50: "#f9fafb",
|
|
17
|
-
100: "#f3f4f6",
|
|
18
|
-
200: "#e5e7eb",
|
|
19
|
-
300: "#d1d5db",
|
|
20
|
-
400: "#9ca3af",
|
|
21
|
-
500: "#6b7280",
|
|
22
|
-
600: "#4b5563",
|
|
23
|
-
700: "#374151",
|
|
24
|
-
800: "#1f2937",
|
|
25
|
-
900: "#111827",
|
|
26
|
-
950: "#030712"
|
|
27
|
-
},
|
|
28
|
-
zinc: {
|
|
29
|
-
50: "#fafafa",
|
|
30
|
-
100: "#f4f4f5",
|
|
31
|
-
200: "#e4e4e7",
|
|
32
|
-
300: "#d4d4d8",
|
|
33
|
-
400: "#a1a1aa",
|
|
34
|
-
500: "#71717a",
|
|
35
|
-
600: "#52525b",
|
|
36
|
-
700: "#3f3f46",
|
|
37
|
-
800: "#27272a",
|
|
38
|
-
900: "#18181b",
|
|
39
|
-
950: "#09090b"
|
|
40
|
-
},
|
|
41
|
-
neutral: {
|
|
42
|
-
50: "#fafafa",
|
|
43
|
-
100: "#f5f5f5",
|
|
44
|
-
200: "#e5e5e5",
|
|
45
|
-
300: "#d4d4d4",
|
|
46
|
-
400: "#a3a3a3",
|
|
47
|
-
500: "#737373",
|
|
48
|
-
600: "#525252",
|
|
49
|
-
700: "#404040",
|
|
50
|
-
800: "#262626",
|
|
51
|
-
900: "#171717",
|
|
52
|
-
950: "#0a0a0a"
|
|
53
|
-
},
|
|
54
|
-
stone: {
|
|
55
|
-
50: "#fafaf9",
|
|
56
|
-
100: "#f5f5f4",
|
|
57
|
-
200: "#e7e5e4",
|
|
58
|
-
300: "#d6d3d1",
|
|
59
|
-
400: "#a8a29e",
|
|
60
|
-
500: "#78716c",
|
|
61
|
-
600: "#57534e",
|
|
62
|
-
700: "#44403c",
|
|
63
|
-
800: "#292524",
|
|
64
|
-
900: "#1c1917",
|
|
65
|
-
950: "#0c0a09"
|
|
66
|
-
},
|
|
67
|
-
red: {
|
|
68
|
-
50: "#fef2f2",
|
|
69
|
-
100: "#fee2e2",
|
|
70
|
-
200: "#fecaca",
|
|
71
|
-
300: "#fca5a5",
|
|
72
|
-
400: "#f87171",
|
|
73
|
-
500: "#ef4444",
|
|
74
|
-
600: "#dc2626",
|
|
75
|
-
700: "#b91c1c",
|
|
76
|
-
800: "#991b1b",
|
|
77
|
-
900: "#7f1d1d",
|
|
78
|
-
950: "#450a0a"
|
|
79
|
-
},
|
|
80
|
-
orange: {
|
|
81
|
-
50: "#fff7ed",
|
|
82
|
-
100: "#ffedd5",
|
|
83
|
-
200: "#fed7aa",
|
|
84
|
-
300: "#fdba74",
|
|
85
|
-
400: "#fb923c",
|
|
86
|
-
500: "#f97316",
|
|
87
|
-
600: "#ea580c",
|
|
88
|
-
700: "#c2410c",
|
|
89
|
-
800: "#9a3412",
|
|
90
|
-
900: "#7c2d12",
|
|
91
|
-
950: "#431407"
|
|
92
|
-
},
|
|
93
|
-
amber: {
|
|
94
|
-
50: "#fffbeb",
|
|
95
|
-
100: "#fef3c7",
|
|
96
|
-
200: "#fde68a",
|
|
97
|
-
300: "#fcd34d",
|
|
98
|
-
400: "#fbbf24",
|
|
99
|
-
500: "#f59e0b",
|
|
100
|
-
600: "#d97706",
|
|
101
|
-
700: "#b45309",
|
|
102
|
-
800: "#92400e",
|
|
103
|
-
900: "#78350f",
|
|
104
|
-
950: "#451a03"
|
|
105
|
-
},
|
|
106
|
-
yellow: {
|
|
107
|
-
50: "#fefce8",
|
|
108
|
-
100: "#fef9c3",
|
|
109
|
-
200: "#fef08a",
|
|
110
|
-
300: "#fde047",
|
|
111
|
-
400: "#facc15",
|
|
112
|
-
500: "#eab308",
|
|
113
|
-
600: "#ca8a04",
|
|
114
|
-
700: "#a16207",
|
|
115
|
-
800: "#854d0e",
|
|
116
|
-
900: "#713f12",
|
|
117
|
-
950: "#422006"
|
|
118
|
-
},
|
|
119
|
-
lime: {
|
|
120
|
-
50: "#f7fee7",
|
|
121
|
-
100: "#ecfccb",
|
|
122
|
-
200: "#d9f99d",
|
|
123
|
-
300: "#bef264",
|
|
124
|
-
400: "#a3e635",
|
|
125
|
-
500: "#84cc16",
|
|
126
|
-
600: "#65a30d",
|
|
127
|
-
700: "#4d7c0f",
|
|
128
|
-
800: "#3f6212",
|
|
129
|
-
900: "#365314",
|
|
130
|
-
950: "#1a2e05"
|
|
131
|
-
},
|
|
132
|
-
green: {
|
|
133
|
-
50: "#f0fdf4",
|
|
134
|
-
100: "#dcfce7",
|
|
135
|
-
200: "#bbf7d0",
|
|
136
|
-
300: "#86efac",
|
|
137
|
-
400: "#4ade80",
|
|
138
|
-
500: "#22c55e",
|
|
139
|
-
600: "#16a34a",
|
|
140
|
-
700: "#15803d",
|
|
141
|
-
800: "#166534",
|
|
142
|
-
900: "#14532d",
|
|
143
|
-
950: "#052e16"
|
|
144
|
-
},
|
|
145
|
-
emerald: {
|
|
146
|
-
50: "#ecfdf5",
|
|
147
|
-
100: "#d1fae5",
|
|
148
|
-
200: "#a7f3d0",
|
|
149
|
-
300: "#6ee7b7",
|
|
150
|
-
400: "#34d399",
|
|
151
|
-
500: "#10b981",
|
|
152
|
-
600: "#059669",
|
|
153
|
-
700: "#047857",
|
|
154
|
-
800: "#065f46",
|
|
155
|
-
900: "#064e3b",
|
|
156
|
-
950: "#022c22"
|
|
157
|
-
},
|
|
158
|
-
teal: {
|
|
159
|
-
50: "#f0fdfa",
|
|
160
|
-
100: "#ccfbf1",
|
|
161
|
-
200: "#99f6e4",
|
|
162
|
-
300: "#5eead4",
|
|
163
|
-
400: "#2dd4bf",
|
|
164
|
-
500: "#14b8a6",
|
|
165
|
-
600: "#0d9488",
|
|
166
|
-
700: "#0f766e",
|
|
167
|
-
800: "#115e59",
|
|
168
|
-
900: "#134e4a",
|
|
169
|
-
950: "#042f2e"
|
|
170
|
-
},
|
|
171
|
-
cyan: {
|
|
172
|
-
50: "#ecfeff",
|
|
173
|
-
100: "#cffafe",
|
|
174
|
-
200: "#a5f3fc",
|
|
175
|
-
300: "#67e8f9",
|
|
176
|
-
400: "#22d3ee",
|
|
177
|
-
500: "#06b6d4",
|
|
178
|
-
600: "#0891b2",
|
|
179
|
-
700: "#0e7490",
|
|
180
|
-
800: "#155e75",
|
|
181
|
-
900: "#164e63",
|
|
182
|
-
950: "#083344"
|
|
183
|
-
},
|
|
184
|
-
sky: {
|
|
185
|
-
50: "#f0f9ff",
|
|
186
|
-
100: "#e0f2fe",
|
|
187
|
-
200: "#bae6fd",
|
|
188
|
-
300: "#7dd3fc",
|
|
189
|
-
400: "#38bdf8",
|
|
190
|
-
500: "#0ea5e9",
|
|
191
|
-
600: "#0284c7",
|
|
192
|
-
700: "#0369a1",
|
|
193
|
-
800: "#075985",
|
|
194
|
-
900: "#0c4a6e",
|
|
195
|
-
950: "#082f49"
|
|
196
|
-
},
|
|
197
|
-
blue: {
|
|
198
|
-
50: "#eff6ff",
|
|
199
|
-
100: "#dbeafe",
|
|
200
|
-
200: "#bfdbfe",
|
|
201
|
-
300: "#93c5fd",
|
|
202
|
-
400: "#60a5fa",
|
|
203
|
-
500: "#3b82f6",
|
|
204
|
-
600: "#2563eb",
|
|
205
|
-
700: "#1d4ed8",
|
|
206
|
-
800: "#1e40af",
|
|
207
|
-
900: "#1e3a8a",
|
|
208
|
-
950: "#172554"
|
|
209
|
-
},
|
|
210
|
-
indigo: {
|
|
211
|
-
50: "#eef2ff",
|
|
212
|
-
100: "#e0e7ff",
|
|
213
|
-
200: "#c7d2fe",
|
|
214
|
-
300: "#a5b4fc",
|
|
215
|
-
400: "#818cf8",
|
|
216
|
-
500: "#6366f1",
|
|
217
|
-
600: "#4f46e5",
|
|
218
|
-
700: "#4338ca",
|
|
219
|
-
800: "#3730a3",
|
|
220
|
-
900: "#312e81",
|
|
221
|
-
950: "#1e1b4b"
|
|
222
|
-
},
|
|
223
|
-
violet: {
|
|
224
|
-
50: "#f5f3ff",
|
|
225
|
-
100: "#ede9fe",
|
|
226
|
-
200: "#ddd6fe",
|
|
227
|
-
300: "#c4b5fd",
|
|
228
|
-
400: "#a78bfa",
|
|
229
|
-
500: "#8b5cf6",
|
|
230
|
-
600: "#7c3aed",
|
|
231
|
-
700: "#6d28d9",
|
|
232
|
-
800: "#5b21b6",
|
|
233
|
-
900: "#4c1d95",
|
|
234
|
-
950: "#2e1065"
|
|
235
|
-
},
|
|
236
|
-
purple: {
|
|
237
|
-
50: "#faf5ff",
|
|
238
|
-
100: "#f3e8ff",
|
|
239
|
-
200: "#e9d5ff",
|
|
240
|
-
300: "#d8b4fe",
|
|
241
|
-
400: "#c084fc",
|
|
242
|
-
500: "#a855f7",
|
|
243
|
-
600: "#9333ea",
|
|
244
|
-
700: "#7e22ce",
|
|
245
|
-
800: "#6b21a8",
|
|
246
|
-
900: "#581c87",
|
|
247
|
-
950: "#3b0764"
|
|
248
|
-
},
|
|
249
|
-
fuchsia: {
|
|
250
|
-
50: "#fdf4ff",
|
|
251
|
-
100: "#fae8ff",
|
|
252
|
-
200: "#f5d0fe",
|
|
253
|
-
300: "#f0abfc",
|
|
254
|
-
400: "#e879f9",
|
|
255
|
-
500: "#d946ef",
|
|
256
|
-
600: "#c026d3",
|
|
257
|
-
700: "#a21caf",
|
|
258
|
-
800: "#86198f",
|
|
259
|
-
900: "#701a75",
|
|
260
|
-
950: "#4a044e"
|
|
261
|
-
},
|
|
262
|
-
pink: {
|
|
263
|
-
50: "#fdf2f8",
|
|
264
|
-
100: "#fce7f3",
|
|
265
|
-
200: "#fbcfe8",
|
|
266
|
-
300: "#f9a8d4",
|
|
267
|
-
400: "#f472b6",
|
|
268
|
-
500: "#ec4899",
|
|
269
|
-
600: "#db2777",
|
|
270
|
-
700: "#be185d",
|
|
271
|
-
800: "#9d174d",
|
|
272
|
-
900: "#831843",
|
|
273
|
-
950: "#500724"
|
|
274
|
-
},
|
|
275
|
-
rose: {
|
|
276
|
-
50: "#fff1f2",
|
|
277
|
-
100: "#ffe4e6",
|
|
278
|
-
200: "#fecdd3",
|
|
279
|
-
300: "#fda4af",
|
|
280
|
-
400: "#fb7185",
|
|
281
|
-
500: "#f43f5e",
|
|
282
|
-
600: "#e11d48",
|
|
283
|
-
700: "#be123c",
|
|
284
|
-
800: "#9f1239",
|
|
285
|
-
900: "#881337",
|
|
286
|
-
950: "#4c0519"
|
|
287
|
-
}
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
const TAILWIND_HEX_COLOR_MAP = new Map();
|
|
291
|
-
|
|
292
|
-
for (const [family, scale] of Object.entries(TAILWIND_HEX_COLORS)) {
|
|
293
|
-
for (const [step, hex] of Object.entries(scale)) {
|
|
294
|
-
TAILWIND_HEX_COLOR_MAP.set(`--color-${family}-${step}`, hex);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
export function getTailwindDefaultHexForVar(variableName) {
|
|
299
|
-
return TAILWIND_HEX_COLOR_MAP.get(variableName) ?? null;
|
|
300
|
-
}
|
package/src/vite-plugin.js
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { replaceOklchInText } from "./converter.js";
|
|
2
|
-
|
|
3
|
-
const DEFAULT_CSS_FILE_REGEX =
|
|
4
|
-
/\.(css|pcss|postcss|scss|sass|less|styl|stylus)(?:$|\?)/i;
|
|
5
|
-
|
|
6
|
-
function isRegexMatch(regex, value) {
|
|
7
|
-
if (!(regex instanceof RegExp)) {
|
|
8
|
-
return false;
|
|
9
|
-
}
|
|
10
|
-
regex.lastIndex = 0;
|
|
11
|
-
return regex.test(value);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function matches(matcher, value) {
|
|
15
|
-
if (!matcher) {
|
|
16
|
-
return true;
|
|
17
|
-
}
|
|
18
|
-
if (matcher instanceof RegExp) {
|
|
19
|
-
return isRegexMatch(matcher, value);
|
|
20
|
-
}
|
|
21
|
-
if (typeof matcher === "function") {
|
|
22
|
-
return Boolean(matcher(value));
|
|
23
|
-
}
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function shouldProcessId(id, include, exclude) {
|
|
28
|
-
if (!matches(include, id)) {
|
|
29
|
-
return false;
|
|
30
|
-
}
|
|
31
|
-
if (exclude && matches(exclude, id)) {
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
return true;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function maybeConvertCss(code, convertOptions) {
|
|
38
|
-
if (typeof code !== "string") {
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
if (!code.toLowerCase().includes("oklch(")) {
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
const converted = replaceOklchInText(code, convertOptions);
|
|
45
|
-
return converted === code ? null : converted;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function oklchToHexVitePlugin(options = {}) {
|
|
49
|
-
const {
|
|
50
|
-
include = DEFAULT_CSS_FILE_REGEX,
|
|
51
|
-
exclude,
|
|
52
|
-
convertDev = true,
|
|
53
|
-
convertBuild = true,
|
|
54
|
-
...convertOptions
|
|
55
|
-
} = options;
|
|
56
|
-
|
|
57
|
-
let command = "build";
|
|
58
|
-
|
|
59
|
-
return {
|
|
60
|
-
name: "oklchtohex-vite-plugin",
|
|
61
|
-
enforce: "post",
|
|
62
|
-
configResolved(config) {
|
|
63
|
-
command = config.command;
|
|
64
|
-
},
|
|
65
|
-
transform(code, id) {
|
|
66
|
-
if (command === "serve" && !convertDev) {
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
if (command === "build" && !convertBuild) {
|
|
70
|
-
return null;
|
|
71
|
-
}
|
|
72
|
-
if (!shouldProcessId(id, include, exclude)) {
|
|
73
|
-
return null;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const converted = maybeConvertCss(code, convertOptions);
|
|
77
|
-
if (!converted) {
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
return { code: converted, map: null };
|
|
81
|
-
},
|
|
82
|
-
generateBundle(_, bundle) {
|
|
83
|
-
if (!convertBuild) {
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
for (const [fileName, asset] of Object.entries(bundle)) {
|
|
87
|
-
if (asset.type !== "asset") {
|
|
88
|
-
continue;
|
|
89
|
-
}
|
|
90
|
-
if (!shouldProcessId(fileName, include, exclude)) {
|
|
91
|
-
continue;
|
|
92
|
-
}
|
|
93
|
-
if (typeof asset.source !== "string") {
|
|
94
|
-
continue;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const converted = maybeConvertCss(asset.source, convertOptions);
|
|
98
|
-
if (converted) {
|
|
99
|
-
asset.source = converted;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|