vite-rgbify 1.0.0

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/index.cjs ADDED
@@ -0,0 +1,283 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ default: () => rgbify
24
+ });
25
+ module.exports = __toCommonJS(index_exports);
26
+ function rgbify() {
27
+ return {
28
+ name: "vite-rgbify",
29
+ enforce: "post",
30
+ generateBundle(_, bundle) {
31
+ for (const file of Object.values(bundle)) {
32
+ if (file.type === "asset" && file.fileName.endsWith(".css") && typeof file.source === "string") {
33
+ file.source = transformCss(file.source);
34
+ }
35
+ }
36
+ }
37
+ };
38
+ }
39
+ function transformCss(css) {
40
+ css = unwrapColorMixSupports(css);
41
+ css = css.replace(/oklch\([^)]+\)/gi, oklchToRgb);
42
+ css = css.replace(/oklab\([^)]+\)/gi, oklabToRgb);
43
+ css = css.replace(/(?<![a-z-])lch\([^)]+\)/gi, lchToRgb);
44
+ css = css.replace(/(?<![a-z-])lab\([^)]+\)/gi, labToRgb);
45
+ css = replaceColorMix(css);
46
+ return css;
47
+ }
48
+ function unwrapColorMixSupports(css) {
49
+ const re = /@supports\s*\(/g;
50
+ let m;
51
+ let out = "";
52
+ let last = 0;
53
+ while ((m = re.exec(css)) !== null) {
54
+ let depth = 1;
55
+ let i = m.index + m[0].length;
56
+ while (i < css.length && depth > 0) {
57
+ if (css[i] === "(") depth++;
58
+ else if (css[i] === ")") depth--;
59
+ i++;
60
+ }
61
+ if (!css.slice(m.index, i).includes("color-mix")) {
62
+ re.lastIndex = i;
63
+ continue;
64
+ }
65
+ const between = css.slice(i);
66
+ const braceIdx = between.search(/\S/);
67
+ if (braceIdx === -1 || between[braceIdx] !== "{") {
68
+ re.lastIndex = i;
69
+ continue;
70
+ }
71
+ const bodyStart = i + braceIdx + 1;
72
+ depth = 1;
73
+ let j = bodyStart;
74
+ while (j < css.length && depth > 0) {
75
+ if (css[j] === "{") depth++;
76
+ else if (css[j] === "}") depth--;
77
+ j++;
78
+ }
79
+ out += css.slice(last, m.index);
80
+ out += css.slice(bodyStart, j - 1);
81
+ last = j;
82
+ re.lastIndex = j;
83
+ }
84
+ return out + css.slice(last);
85
+ }
86
+ var ARG = "[-+\\w.%]+";
87
+ var ARGS_RE = new RegExp(
88
+ `\\(\\s*(${ARG})\\s+(${ARG})\\s+(${ARG})(?:\\s*/\\s*(${ARG}))?\\s*\\)`
89
+ );
90
+ function comp(s, pctScale) {
91
+ if (s === "none") return 0;
92
+ if (s.endsWith("%")) return parseFloat(s) / 100 * pctScale;
93
+ return parseFloat(s);
94
+ }
95
+ function angleDeg(s) {
96
+ if (s === "none") return 0;
97
+ const n = parseFloat(s);
98
+ if (s.endsWith("rad")) return n * 180 / Math.PI;
99
+ if (s.endsWith("grad")) return n * 0.9;
100
+ if (s.endsWith("turn")) return n * 360;
101
+ return n;
102
+ }
103
+ function gammaEncode(c) {
104
+ return c <= 31308e-7 ? 12.92 * c : 1.055 * c ** (1 / 2.4) - 0.055;
105
+ }
106
+ function toByte(linear) {
107
+ return Math.round(Math.max(0, Math.min(1, gammaEncode(linear))) * 255);
108
+ }
109
+ function rgbStr(r, g, b, a) {
110
+ const R = toByte(r), G = toByte(g), B = toByte(b);
111
+ return a < 1 ? `rgba(${R},${G},${B},${+a.toFixed(4)})` : `rgb(${R},${G},${B})`;
112
+ }
113
+ function oklabLinear(L, a, b) {
114
+ const l_ = L + 0.3963377774 * a + 0.2158037573 * b;
115
+ const m_ = L - 0.1055613458 * a - 0.0638541728 * b;
116
+ const s_ = L - 0.0894841775 * a - 1.291485548 * b;
117
+ const l = l_ ** 3, m = m_ ** 3, s = s_ ** 3;
118
+ return [
119
+ 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
120
+ -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
121
+ -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s
122
+ ];
123
+ }
124
+ function oklabToRgb(expr) {
125
+ const m = expr.match(ARGS_RE);
126
+ if (!m) return expr;
127
+ let L = comp(m[1], 1);
128
+ if (L > 1) L /= 100;
129
+ const [r, g, b] = oklabLinear(L, comp(m[2], 0.4), comp(m[3], 0.4));
130
+ return rgbStr(r, g, b, m[4] ? comp(m[4], 1) : 1);
131
+ }
132
+ function oklchToRgb(expr) {
133
+ const m = expr.match(ARGS_RE);
134
+ if (!m) return expr;
135
+ let L = comp(m[1], 1);
136
+ if (L > 1) L /= 100;
137
+ const C = comp(m[2], 0.4);
138
+ const H = angleDeg(m[3]) * Math.PI / 180;
139
+ const [r, g, b] = oklabLinear(L, C * Math.cos(H), C * Math.sin(H));
140
+ return rgbStr(r, g, b, m[4] ? comp(m[4], 1) : 1);
141
+ }
142
+ function labLinear(L, a, b) {
143
+ const fy = (L + 16) / 116;
144
+ const fx = a / 500 + fy;
145
+ const fz = fy - b / 200;
146
+ const e = 8856e-6, k = 903.3;
147
+ const xr = fx ** 3 > e ? fx ** 3 : (116 * fx - 16) / k;
148
+ const yr = L > k * e ? ((L + 16) / 116) ** 3 : L / k;
149
+ const zr = fz ** 3 > e ? fz ** 3 : (116 * fz - 16) / k;
150
+ const X = xr * 0.95047, Y = yr, Z = zr * 1.08883;
151
+ return [
152
+ 3.2404542 * X - 1.5371385 * Y - 0.4985314 * Z,
153
+ -0.969266 * X + 1.8760108 * Y + 0.041556 * Z,
154
+ 0.0556434 * X - 0.2040259 * Y + 1.0572252 * Z
155
+ ];
156
+ }
157
+ function labToRgb(expr) {
158
+ const m = expr.match(ARGS_RE);
159
+ if (!m) return expr;
160
+ const [r, g, b] = labLinear(
161
+ comp(m[1], 100),
162
+ comp(m[2], 125),
163
+ comp(m[3], 125)
164
+ );
165
+ return rgbStr(r, g, b, m[4] ? comp(m[4], 1) : 1);
166
+ }
167
+ function lchToRgb(expr) {
168
+ const m = expr.match(ARGS_RE);
169
+ if (!m) return expr;
170
+ const L = comp(m[1], 100), C = comp(m[2], 150);
171
+ const H = angleDeg(m[3]) * Math.PI / 180;
172
+ const [r, g, b] = labLinear(L, C * Math.cos(H), C * Math.sin(H));
173
+ return rgbStr(r, g, b, m[4] ? comp(m[4], 1) : 1);
174
+ }
175
+ function replaceColorMix(css) {
176
+ const tag = "color-mix(";
177
+ let out = "";
178
+ let pos = 0;
179
+ while (pos < css.length) {
180
+ const idx = css.toLowerCase().indexOf(tag, pos);
181
+ if (idx === -1) {
182
+ out += css.slice(pos);
183
+ break;
184
+ }
185
+ out += css.slice(pos, idx);
186
+ let depth = 1, j = idx + tag.length;
187
+ while (j < css.length && depth > 0) {
188
+ if (css[j] === "(") depth++;
189
+ else if (css[j] === ")") depth--;
190
+ j++;
191
+ }
192
+ out += evaluateMix(css.slice(idx, j));
193
+ pos = j;
194
+ }
195
+ return out;
196
+ }
197
+ function splitTopCommas(s) {
198
+ const parts = [];
199
+ let depth = 0, start = 0;
200
+ for (let i = 0; i < s.length; i++) {
201
+ if (s[i] === "(") depth++;
202
+ else if (s[i] === ")") depth--;
203
+ else if (s[i] === "," && depth === 0) {
204
+ parts.push(s.slice(start, i));
205
+ start = i + 1;
206
+ }
207
+ }
208
+ parts.push(s.slice(start));
209
+ return parts;
210
+ }
211
+ function evaluateMix(expr) {
212
+ const inner = expr.slice(expr.indexOf("(") + 1, expr.lastIndexOf(")"));
213
+ const parts = splitTopCommas(inner);
214
+ if (parts.length !== 3) return expr;
215
+ const { color: c1, pct: p1r } = colorAndPct(parts[1].trim());
216
+ const { color: c2, pct: p2r } = colorAndPct(parts[2].trim());
217
+ let p1 = p1r, p2 = p2r;
218
+ if (p1 === null && p2 === null) {
219
+ p1 = 50;
220
+ p2 = 50;
221
+ } else if (p1 === null) p1 = 100 - p2;
222
+ else if (p2 === null) p2 = 100 - p1;
223
+ const rgba1 = readRgba(c1);
224
+ const rgba2 = readRgba(c2);
225
+ if (!rgba1 || !rgba2) return expr;
226
+ const sum = p1 + p2;
227
+ if (sum <= 0) return expr;
228
+ const w1 = p1 / sum, w2 = p2 / sum;
229
+ const alphaScale = Math.min(sum, 100) / 100;
230
+ const [r1, g1, b1, a1] = rgba1;
231
+ const [r2, g2, b2, a2] = rgba2;
232
+ const pa = a1 * w1 + a2 * w2;
233
+ const pr = r1 * a1 * w1 + r2 * a2 * w2;
234
+ const pg = g1 * a1 * w1 + g2 * a2 * w2;
235
+ const pb = b1 * a1 * w1 + b2 * a2 * w2;
236
+ const a = +(pa * alphaScale).toFixed(4);
237
+ const r = pa > 0 ? Math.round(Math.max(0, Math.min(255, pr / pa))) : 0;
238
+ const g = pa > 0 ? Math.round(Math.max(0, Math.min(255, pg / pa))) : 0;
239
+ const b = pa > 0 ? Math.round(Math.max(0, Math.min(255, pb / pa))) : 0;
240
+ return a < 1 ? `rgba(${r},${g},${b},${a})` : `rgb(${r},${g},${b})`;
241
+ }
242
+ function colorAndPct(s) {
243
+ let depth = 0;
244
+ let pctCharIdx = -1;
245
+ for (let i = 0; i < s.length; i++) {
246
+ if (s[i] === "(") depth++;
247
+ else if (s[i] === ")") depth--;
248
+ else if (s[i] === "%" && depth === 0) pctCharIdx = i;
249
+ }
250
+ if (pctCharIdx === -1) return { color: s.trim(), pct: null };
251
+ let numStart = pctCharIdx - 1;
252
+ while (numStart >= 0 && /[\d.]/.test(s[numStart])) numStart--;
253
+ numStart++;
254
+ if (numStart >= pctCharIdx) return { color: s.trim(), pct: null };
255
+ return {
256
+ color: s.slice(0, numStart).trim(),
257
+ pct: parseFloat(s.slice(numStart, pctCharIdx))
258
+ };
259
+ }
260
+ function readRgba(s) {
261
+ const c = s.trim().toLowerCase();
262
+ if (c === "transparent") return [0, 0, 0, 0];
263
+ let m = c.match(
264
+ /rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)(?:\s*,\s*([\d.]+))?\s*\)/
265
+ );
266
+ if (m) return [+m[1], +m[2], +m[3], m[4] ? +m[4] : 1];
267
+ m = c.match(
268
+ /rgba?\(\s*([\d.]+)\s+([\d.]+)\s+([\d.]+)(?:\s*\/\s*([\d.]+))?\s*\)/
269
+ );
270
+ if (m) return [+m[1], +m[2], +m[3], m[4] ? +m[4] : 1];
271
+ m = c.match(/^#([0-9a-f]{3,8})$/);
272
+ if (m) {
273
+ const h = m[1];
274
+ const p = (i, len) => parseInt(len === 1 ? h[i] + h[i] : h.slice(i, i + len), 16);
275
+ if (h.length === 3) return [p(0, 1), p(1, 1), p(2, 1), 1];
276
+ if (h.length === 4)
277
+ return [p(0, 1), p(1, 1), p(2, 1), p(3, 1) / 255];
278
+ if (h.length === 6) return [p(0, 2), p(2, 2), p(4, 2), 1];
279
+ if (h.length === 8)
280
+ return [p(0, 2), p(2, 2), p(4, 2), p(6, 2) / 255];
281
+ }
282
+ return null;
283
+ }
@@ -0,0 +1,5 @@
1
+ import { Plugin } from 'vite';
2
+
3
+ declare function rgbify(): Plugin;
4
+
5
+ export { rgbify as default };
@@ -0,0 +1,5 @@
1
+ import { Plugin } from 'vite';
2
+
3
+ declare function rgbify(): Plugin;
4
+
5
+ export { rgbify as default };
package/dist/index.js ADDED
@@ -0,0 +1,262 @@
1
+ // index.ts
2
+ function rgbify() {
3
+ return {
4
+ name: "vite-rgbify",
5
+ enforce: "post",
6
+ generateBundle(_, bundle) {
7
+ for (const file of Object.values(bundle)) {
8
+ if (file.type === "asset" && file.fileName.endsWith(".css") && typeof file.source === "string") {
9
+ file.source = transformCss(file.source);
10
+ }
11
+ }
12
+ }
13
+ };
14
+ }
15
+ function transformCss(css) {
16
+ css = unwrapColorMixSupports(css);
17
+ css = css.replace(/oklch\([^)]+\)/gi, oklchToRgb);
18
+ css = css.replace(/oklab\([^)]+\)/gi, oklabToRgb);
19
+ css = css.replace(/(?<![a-z-])lch\([^)]+\)/gi, lchToRgb);
20
+ css = css.replace(/(?<![a-z-])lab\([^)]+\)/gi, labToRgb);
21
+ css = replaceColorMix(css);
22
+ return css;
23
+ }
24
+ function unwrapColorMixSupports(css) {
25
+ const re = /@supports\s*\(/g;
26
+ let m;
27
+ let out = "";
28
+ let last = 0;
29
+ while ((m = re.exec(css)) !== null) {
30
+ let depth = 1;
31
+ let i = m.index + m[0].length;
32
+ while (i < css.length && depth > 0) {
33
+ if (css[i] === "(") depth++;
34
+ else if (css[i] === ")") depth--;
35
+ i++;
36
+ }
37
+ if (!css.slice(m.index, i).includes("color-mix")) {
38
+ re.lastIndex = i;
39
+ continue;
40
+ }
41
+ const between = css.slice(i);
42
+ const braceIdx = between.search(/\S/);
43
+ if (braceIdx === -1 || between[braceIdx] !== "{") {
44
+ re.lastIndex = i;
45
+ continue;
46
+ }
47
+ const bodyStart = i + braceIdx + 1;
48
+ depth = 1;
49
+ let j = bodyStart;
50
+ while (j < css.length && depth > 0) {
51
+ if (css[j] === "{") depth++;
52
+ else if (css[j] === "}") depth--;
53
+ j++;
54
+ }
55
+ out += css.slice(last, m.index);
56
+ out += css.slice(bodyStart, j - 1);
57
+ last = j;
58
+ re.lastIndex = j;
59
+ }
60
+ return out + css.slice(last);
61
+ }
62
+ var ARG = "[-+\\w.%]+";
63
+ var ARGS_RE = new RegExp(
64
+ `\\(\\s*(${ARG})\\s+(${ARG})\\s+(${ARG})(?:\\s*/\\s*(${ARG}))?\\s*\\)`
65
+ );
66
+ function comp(s, pctScale) {
67
+ if (s === "none") return 0;
68
+ if (s.endsWith("%")) return parseFloat(s) / 100 * pctScale;
69
+ return parseFloat(s);
70
+ }
71
+ function angleDeg(s) {
72
+ if (s === "none") return 0;
73
+ const n = parseFloat(s);
74
+ if (s.endsWith("rad")) return n * 180 / Math.PI;
75
+ if (s.endsWith("grad")) return n * 0.9;
76
+ if (s.endsWith("turn")) return n * 360;
77
+ return n;
78
+ }
79
+ function gammaEncode(c) {
80
+ return c <= 31308e-7 ? 12.92 * c : 1.055 * c ** (1 / 2.4) - 0.055;
81
+ }
82
+ function toByte(linear) {
83
+ return Math.round(Math.max(0, Math.min(1, gammaEncode(linear))) * 255);
84
+ }
85
+ function rgbStr(r, g, b, a) {
86
+ const R = toByte(r), G = toByte(g), B = toByte(b);
87
+ return a < 1 ? `rgba(${R},${G},${B},${+a.toFixed(4)})` : `rgb(${R},${G},${B})`;
88
+ }
89
+ function oklabLinear(L, a, b) {
90
+ const l_ = L + 0.3963377774 * a + 0.2158037573 * b;
91
+ const m_ = L - 0.1055613458 * a - 0.0638541728 * b;
92
+ const s_ = L - 0.0894841775 * a - 1.291485548 * b;
93
+ const l = l_ ** 3, m = m_ ** 3, s = s_ ** 3;
94
+ return [
95
+ 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
96
+ -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
97
+ -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s
98
+ ];
99
+ }
100
+ function oklabToRgb(expr) {
101
+ const m = expr.match(ARGS_RE);
102
+ if (!m) return expr;
103
+ let L = comp(m[1], 1);
104
+ if (L > 1) L /= 100;
105
+ const [r, g, b] = oklabLinear(L, comp(m[2], 0.4), comp(m[3], 0.4));
106
+ return rgbStr(r, g, b, m[4] ? comp(m[4], 1) : 1);
107
+ }
108
+ function oklchToRgb(expr) {
109
+ const m = expr.match(ARGS_RE);
110
+ if (!m) return expr;
111
+ let L = comp(m[1], 1);
112
+ if (L > 1) L /= 100;
113
+ const C = comp(m[2], 0.4);
114
+ const H = angleDeg(m[3]) * Math.PI / 180;
115
+ const [r, g, b] = oklabLinear(L, C * Math.cos(H), C * Math.sin(H));
116
+ return rgbStr(r, g, b, m[4] ? comp(m[4], 1) : 1);
117
+ }
118
+ function labLinear(L, a, b) {
119
+ const fy = (L + 16) / 116;
120
+ const fx = a / 500 + fy;
121
+ const fz = fy - b / 200;
122
+ const e = 8856e-6, k = 903.3;
123
+ const xr = fx ** 3 > e ? fx ** 3 : (116 * fx - 16) / k;
124
+ const yr = L > k * e ? ((L + 16) / 116) ** 3 : L / k;
125
+ const zr = fz ** 3 > e ? fz ** 3 : (116 * fz - 16) / k;
126
+ const X = xr * 0.95047, Y = yr, Z = zr * 1.08883;
127
+ return [
128
+ 3.2404542 * X - 1.5371385 * Y - 0.4985314 * Z,
129
+ -0.969266 * X + 1.8760108 * Y + 0.041556 * Z,
130
+ 0.0556434 * X - 0.2040259 * Y + 1.0572252 * Z
131
+ ];
132
+ }
133
+ function labToRgb(expr) {
134
+ const m = expr.match(ARGS_RE);
135
+ if (!m) return expr;
136
+ const [r, g, b] = labLinear(
137
+ comp(m[1], 100),
138
+ comp(m[2], 125),
139
+ comp(m[3], 125)
140
+ );
141
+ return rgbStr(r, g, b, m[4] ? comp(m[4], 1) : 1);
142
+ }
143
+ function lchToRgb(expr) {
144
+ const m = expr.match(ARGS_RE);
145
+ if (!m) return expr;
146
+ const L = comp(m[1], 100), C = comp(m[2], 150);
147
+ const H = angleDeg(m[3]) * Math.PI / 180;
148
+ const [r, g, b] = labLinear(L, C * Math.cos(H), C * Math.sin(H));
149
+ return rgbStr(r, g, b, m[4] ? comp(m[4], 1) : 1);
150
+ }
151
+ function replaceColorMix(css) {
152
+ const tag = "color-mix(";
153
+ let out = "";
154
+ let pos = 0;
155
+ while (pos < css.length) {
156
+ const idx = css.toLowerCase().indexOf(tag, pos);
157
+ if (idx === -1) {
158
+ out += css.slice(pos);
159
+ break;
160
+ }
161
+ out += css.slice(pos, idx);
162
+ let depth = 1, j = idx + tag.length;
163
+ while (j < css.length && depth > 0) {
164
+ if (css[j] === "(") depth++;
165
+ else if (css[j] === ")") depth--;
166
+ j++;
167
+ }
168
+ out += evaluateMix(css.slice(idx, j));
169
+ pos = j;
170
+ }
171
+ return out;
172
+ }
173
+ function splitTopCommas(s) {
174
+ const parts = [];
175
+ let depth = 0, start = 0;
176
+ for (let i = 0; i < s.length; i++) {
177
+ if (s[i] === "(") depth++;
178
+ else if (s[i] === ")") depth--;
179
+ else if (s[i] === "," && depth === 0) {
180
+ parts.push(s.slice(start, i));
181
+ start = i + 1;
182
+ }
183
+ }
184
+ parts.push(s.slice(start));
185
+ return parts;
186
+ }
187
+ function evaluateMix(expr) {
188
+ const inner = expr.slice(expr.indexOf("(") + 1, expr.lastIndexOf(")"));
189
+ const parts = splitTopCommas(inner);
190
+ if (parts.length !== 3) return expr;
191
+ const { color: c1, pct: p1r } = colorAndPct(parts[1].trim());
192
+ const { color: c2, pct: p2r } = colorAndPct(parts[2].trim());
193
+ let p1 = p1r, p2 = p2r;
194
+ if (p1 === null && p2 === null) {
195
+ p1 = 50;
196
+ p2 = 50;
197
+ } else if (p1 === null) p1 = 100 - p2;
198
+ else if (p2 === null) p2 = 100 - p1;
199
+ const rgba1 = readRgba(c1);
200
+ const rgba2 = readRgba(c2);
201
+ if (!rgba1 || !rgba2) return expr;
202
+ const sum = p1 + p2;
203
+ if (sum <= 0) return expr;
204
+ const w1 = p1 / sum, w2 = p2 / sum;
205
+ const alphaScale = Math.min(sum, 100) / 100;
206
+ const [r1, g1, b1, a1] = rgba1;
207
+ const [r2, g2, b2, a2] = rgba2;
208
+ const pa = a1 * w1 + a2 * w2;
209
+ const pr = r1 * a1 * w1 + r2 * a2 * w2;
210
+ const pg = g1 * a1 * w1 + g2 * a2 * w2;
211
+ const pb = b1 * a1 * w1 + b2 * a2 * w2;
212
+ const a = +(pa * alphaScale).toFixed(4);
213
+ const r = pa > 0 ? Math.round(Math.max(0, Math.min(255, pr / pa))) : 0;
214
+ const g = pa > 0 ? Math.round(Math.max(0, Math.min(255, pg / pa))) : 0;
215
+ const b = pa > 0 ? Math.round(Math.max(0, Math.min(255, pb / pa))) : 0;
216
+ return a < 1 ? `rgba(${r},${g},${b},${a})` : `rgb(${r},${g},${b})`;
217
+ }
218
+ function colorAndPct(s) {
219
+ let depth = 0;
220
+ let pctCharIdx = -1;
221
+ for (let i = 0; i < s.length; i++) {
222
+ if (s[i] === "(") depth++;
223
+ else if (s[i] === ")") depth--;
224
+ else if (s[i] === "%" && depth === 0) pctCharIdx = i;
225
+ }
226
+ if (pctCharIdx === -1) return { color: s.trim(), pct: null };
227
+ let numStart = pctCharIdx - 1;
228
+ while (numStart >= 0 && /[\d.]/.test(s[numStart])) numStart--;
229
+ numStart++;
230
+ if (numStart >= pctCharIdx) return { color: s.trim(), pct: null };
231
+ return {
232
+ color: s.slice(0, numStart).trim(),
233
+ pct: parseFloat(s.slice(numStart, pctCharIdx))
234
+ };
235
+ }
236
+ function readRgba(s) {
237
+ const c = s.trim().toLowerCase();
238
+ if (c === "transparent") return [0, 0, 0, 0];
239
+ let m = c.match(
240
+ /rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)(?:\s*,\s*([\d.]+))?\s*\)/
241
+ );
242
+ if (m) return [+m[1], +m[2], +m[3], m[4] ? +m[4] : 1];
243
+ m = c.match(
244
+ /rgba?\(\s*([\d.]+)\s+([\d.]+)\s+([\d.]+)(?:\s*\/\s*([\d.]+))?\s*\)/
245
+ );
246
+ if (m) return [+m[1], +m[2], +m[3], m[4] ? +m[4] : 1];
247
+ m = c.match(/^#([0-9a-f]{3,8})$/);
248
+ if (m) {
249
+ const h = m[1];
250
+ const p = (i, len) => parseInt(len === 1 ? h[i] + h[i] : h.slice(i, i + len), 16);
251
+ if (h.length === 3) return [p(0, 1), p(1, 1), p(2, 1), 1];
252
+ if (h.length === 4)
253
+ return [p(0, 1), p(1, 1), p(2, 1), p(3, 1) / 255];
254
+ if (h.length === 6) return [p(0, 2), p(2, 2), p(4, 2), 1];
255
+ if (h.length === 8)
256
+ return [p(0, 2), p(2, 2), p(4, 2), p(6, 2) / 255];
257
+ }
258
+ return null;
259
+ }
260
+ export {
261
+ rgbify as default
262
+ };
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "vite-rgbify",
3
+ "version": "1.0.0",
4
+ "description": "Vite plugin that converts modern CSS colors (oklch, oklab, lab, lch, color-mix) to rgb/rgba for FiveM NUI compatibility",
5
+ "homepage": "https://github.com/ARIBUDEV/vite-rgbify",
6
+ "bugs": "https://github.com/ARIBUDEV/vite-rgbify/issues",
7
+ "repository": {
8
+ "url": "https://github.com/ARIBUDEV/vite-rgbify",
9
+ "type": "git"
10
+ },
11
+ "type": "module",
12
+ "main": "dist/index.cjs",
13
+ "module": "dist/index.js",
14
+ "types": "dist/index.d.ts",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "import": "./dist/index.js",
19
+ "require": "./dist/index.cjs"
20
+ }
21
+ },
22
+ "files": ["dist"],
23
+ "scripts": {
24
+ "build": "tsup index.ts --format esm,cjs --dts"
25
+ },
26
+ "keywords": ["vite", "plugin", "fivem", "nui", "tailwind", "oklch", "oklab", "rgb", "css"],
27
+ "license": "MIT",
28
+ "peerDependencies": {
29
+ "vite": ">=8.0.3"
30
+ },
31
+ "devDependencies": {
32
+ "tsup": "^8.5.1",
33
+ "typescript": "^6.0.2",
34
+ "vite": "^8.0.3"
35
+ }
36
+ }