@vinicunca/unocss-preset 0.0.2 → 0.1.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/client.cjs +2 -0
- package/dist/index.cjs +154 -245
- package/dist/index.d.ts +7 -7
- package/dist/index.mjs +153 -246
- package/package.json +13 -13
package/dist/client.cjs
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
3
5
|
const jsUtilities = require('@vinicunca/js-utilities');
|
|
4
6
|
const core = require('@unocss/core');
|
|
5
|
-
const presetMini = require('@unocss/preset-mini');
|
|
6
|
-
const unocss = require('unocss');
|
|
7
7
|
|
|
8
8
|
const DEFAULT_PREFIX = "vin-";
|
|
9
9
|
class PresetCore {
|
|
10
10
|
constructor(options) {
|
|
11
|
-
this.prefix = options.prefix ??
|
|
12
|
-
this.
|
|
11
|
+
this.prefix = options.prefix ?? DEFAULT_PREFIX;
|
|
12
|
+
this.classBase = options.classBase ?? "";
|
|
13
|
+
this.classProps = options.classProps ?? {};
|
|
13
14
|
}
|
|
14
15
|
genVariable(key = "") {
|
|
15
16
|
return `--${this.prefix}${key}`;
|
|
@@ -21,14 +22,12 @@ class PresetCore {
|
|
|
21
22
|
return prev;
|
|
22
23
|
}, {});
|
|
23
24
|
}
|
|
24
|
-
getColorKeys() {
|
|
25
|
-
return Array.from(new Set(this.colorKeys));
|
|
26
|
-
}
|
|
27
25
|
}
|
|
28
26
|
|
|
29
27
|
class Color extends PresetCore {
|
|
30
28
|
constructor(options) {
|
|
31
29
|
super(options);
|
|
30
|
+
this.varTextOpacity = "--un-text-opacity";
|
|
32
31
|
}
|
|
33
32
|
getRules() {
|
|
34
33
|
return [
|
|
@@ -38,17 +37,14 @@ class Color extends PresetCore {
|
|
|
38
37
|
}
|
|
39
38
|
getTextRule() {
|
|
40
39
|
return [
|
|
41
|
-
/^text-(?<body>(?:on-)?(?<color>.+))/,
|
|
40
|
+
/^text-brand-(?<body>(?:on-)?(?<color>.+))/,
|
|
42
41
|
({ groups }) => {
|
|
43
42
|
const { body, color } = groups;
|
|
44
|
-
if (!this.getColorKeys().includes(color)) {
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
43
|
const colorBody = /^on-[a-z]/.test(body) ? `on-${color}` : color;
|
|
48
44
|
const colorVar = this.genVariable(`theme-${colorBody}`);
|
|
49
45
|
return {
|
|
50
|
-
|
|
51
|
-
|
|
46
|
+
[this.varTextOpacity]: 1,
|
|
47
|
+
color: `rgba(var(${colorVar}), var(${this.varTextOpacity}))`
|
|
52
48
|
};
|
|
53
49
|
},
|
|
54
50
|
{ layer: "vinicunca" }
|
|
@@ -56,18 +52,15 @@ class Color extends PresetCore {
|
|
|
56
52
|
}
|
|
57
53
|
getBgRule() {
|
|
58
54
|
return [
|
|
59
|
-
/^bg-(.+)$/,
|
|
55
|
+
/^bg-brand-(.+)$/,
|
|
60
56
|
([, body]) => {
|
|
61
|
-
if (!this.colorKeys.includes(body)) {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
57
|
const bgColorVar = this.genVariable(`theme-${body}`);
|
|
65
58
|
const colorVar = this.genVariable(`theme-on-${body}`);
|
|
66
59
|
return {
|
|
67
|
-
|
|
60
|
+
[this.varTextOpacity]: 1,
|
|
68
61
|
"--un-bg-opacity": 1,
|
|
69
62
|
"background-color": `rgba(var(${bgColorVar}),var(--un-bg-opacity))`,
|
|
70
|
-
"color": `rgba(var(${colorVar}), var(
|
|
63
|
+
"color": `rgba(var(${colorVar}), var(${this.varTextOpacity}))`
|
|
71
64
|
};
|
|
72
65
|
},
|
|
73
66
|
{ layer: "vinicunca" }
|
|
@@ -143,7 +136,6 @@ const DEFAULT_THEME = {
|
|
|
143
136
|
dark: false,
|
|
144
137
|
colors: {
|
|
145
138
|
"background": "#FFFFFF",
|
|
146
|
-
"invert": "#000000",
|
|
147
139
|
"surface": "#FFFFFF",
|
|
148
140
|
"surface-variant": "#424242",
|
|
149
141
|
"on-surface-variant": "#EEEEEE",
|
|
@@ -156,24 +148,23 @@ const DEFAULT_THEME = {
|
|
|
156
148
|
},
|
|
157
149
|
variables: {
|
|
158
150
|
"border-color": "#000000",
|
|
159
|
-
"border
|
|
160
|
-
"high-emphasis
|
|
161
|
-
"medium-emphasis
|
|
162
|
-
"disabled
|
|
163
|
-
"idle
|
|
164
|
-
"hover
|
|
165
|
-
"focus
|
|
166
|
-
"selected
|
|
167
|
-
"activated
|
|
168
|
-
"pressed
|
|
169
|
-
"dragged
|
|
151
|
+
"opacity-border": 0.12,
|
|
152
|
+
"opacity-high-emphasis": 0.87,
|
|
153
|
+
"opacity-medium-emphasis": 0.6,
|
|
154
|
+
"opacity-disabled": 0.38,
|
|
155
|
+
"opacity-idle": 0.04,
|
|
156
|
+
"opacity-hover": 0.04,
|
|
157
|
+
"opacity-focus": 0.12,
|
|
158
|
+
"opacity-selected": 0.08,
|
|
159
|
+
"opacity-activated": 0.12,
|
|
160
|
+
"opacity-pressed": 0.12,
|
|
161
|
+
"opacity-dragged": 0.08
|
|
170
162
|
}
|
|
171
163
|
},
|
|
172
164
|
dark: {
|
|
173
165
|
dark: true,
|
|
174
166
|
colors: {
|
|
175
167
|
"background": "#121212",
|
|
176
|
-
"invert": "#FFFFFF",
|
|
177
168
|
"surface": "#212121",
|
|
178
169
|
"surface-variant": "#BDBDBD",
|
|
179
170
|
"on-surface-variant": "#424242",
|
|
@@ -186,17 +177,17 @@ const DEFAULT_THEME = {
|
|
|
186
177
|
},
|
|
187
178
|
variables: {
|
|
188
179
|
"border-color": "#FFFFFF",
|
|
189
|
-
"border
|
|
190
|
-
"high-emphasis
|
|
191
|
-
"medium-emphasis
|
|
192
|
-
"disabled
|
|
193
|
-
"idle
|
|
194
|
-
"hover
|
|
195
|
-
"focus
|
|
196
|
-
"selected
|
|
197
|
-
"activated
|
|
198
|
-
"pressed
|
|
199
|
-
"dragged
|
|
180
|
+
"opacity-border": 0.12,
|
|
181
|
+
"opacity-high-emphasis": 0.87,
|
|
182
|
+
"opacity-medium-emphasis": 0.6,
|
|
183
|
+
"opacity-disabled": 0.38,
|
|
184
|
+
"opacity-idle": 0.1,
|
|
185
|
+
"opacity-hover": 0.04,
|
|
186
|
+
"opacity-focus": 0.12,
|
|
187
|
+
"opacity-selected": 0.08,
|
|
188
|
+
"opacity-activated": 0.12,
|
|
189
|
+
"opacity-pressed": 0.16,
|
|
190
|
+
"opacity-dragged": 0.08
|
|
200
191
|
}
|
|
201
192
|
}
|
|
202
193
|
};
|
|
@@ -205,98 +196,7 @@ function createCssSelector({ selector, content }) {
|
|
|
205
196
|
return `${selector} { ${content.join(" ")} }`;
|
|
206
197
|
}
|
|
207
198
|
|
|
208
|
-
|
|
209
|
-
const theme = {};
|
|
210
|
-
for (const color of Object.keys(colors)) {
|
|
211
|
-
let colorKey = color;
|
|
212
|
-
if (/^on-[a-z]/.test(color)) {
|
|
213
|
-
colorKey = jsUtilities.toCamelCase(color);
|
|
214
|
-
}
|
|
215
|
-
const data = presetMini.parseColor(color, {
|
|
216
|
-
colors: {
|
|
217
|
-
[colorKey]: colors[color]
|
|
218
|
-
}
|
|
219
|
-
});
|
|
220
|
-
if (data?.cssColor?.components) {
|
|
221
|
-
const colorValue = data.cssColor.components.join(",");
|
|
222
|
-
theme[color] = colorValue;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
return theme;
|
|
226
|
-
}
|
|
227
|
-
function colorToInt(color) {
|
|
228
|
-
let rgb;
|
|
229
|
-
if (typeof color === "number") {
|
|
230
|
-
rgb = color;
|
|
231
|
-
} else if (typeof color === "string") {
|
|
232
|
-
let c = color.startsWith("#") ? color.substring(1) : color;
|
|
233
|
-
if (c.length === 3) {
|
|
234
|
-
c = c.split("").map((char) => char + char).join("");
|
|
235
|
-
}
|
|
236
|
-
if (c.length !== 6 && c.length !== 8) {
|
|
237
|
-
console.warn(`'${color}' is not a valid rgb color`);
|
|
238
|
-
}
|
|
239
|
-
rgb = parseInt(c, 16);
|
|
240
|
-
} else {
|
|
241
|
-
throw new TypeError(`Colors can only be numbers or strings, recieved ${color == null ? color : color.constructor.name} instead`);
|
|
242
|
-
}
|
|
243
|
-
if (rgb < 0) {
|
|
244
|
-
console.warn(`Colors cannot be negative: '${color}'`);
|
|
245
|
-
rgb = 0;
|
|
246
|
-
} else if (rgb > 4294967295 || isNaN(rgb)) {
|
|
247
|
-
console.warn(`'${color}' is not a valid rgb color`);
|
|
248
|
-
rgb = 16777215;
|
|
249
|
-
}
|
|
250
|
-
return rgb;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
const mainTRC = 2.4;
|
|
254
|
-
const Rco = 0.2126729;
|
|
255
|
-
const Gco = 0.7151522;
|
|
256
|
-
const Bco = 0.072175;
|
|
257
|
-
const normBG = 0.55;
|
|
258
|
-
const normTXT = 0.58;
|
|
259
|
-
const revTXT = 0.57;
|
|
260
|
-
const revBG = 0.62;
|
|
261
|
-
const blkThrs = 0.03;
|
|
262
|
-
const blkClmp = 1.45;
|
|
263
|
-
const deltaYmin = 5e-4;
|
|
264
|
-
const scaleBoW = 1.25;
|
|
265
|
-
const scaleWoB = 1.25;
|
|
266
|
-
const loConThresh = 0.078;
|
|
267
|
-
const loConFactor = 12.82051282051282;
|
|
268
|
-
const loConOffset = 0.06;
|
|
269
|
-
const loClip = 1e-3;
|
|
270
|
-
function APCAcontrast(text, background) {
|
|
271
|
-
const Rtxt = ((text >> 16 & 255) / 255) ** mainTRC;
|
|
272
|
-
const Gtxt = ((text >> 8 & 255) / 255) ** mainTRC;
|
|
273
|
-
const Btxt = ((text >> 0 & 255) / 255) ** mainTRC;
|
|
274
|
-
const Rbg = ((background >> 16 & 255) / 255) ** mainTRC;
|
|
275
|
-
const Gbg = ((background >> 8 & 255) / 255) ** mainTRC;
|
|
276
|
-
const Bbg = ((background >> 0 & 255) / 255) ** mainTRC;
|
|
277
|
-
let Ytxt = Rtxt * Rco + Gtxt * Gco + Btxt * Bco;
|
|
278
|
-
let Ybg = Rbg * Rco + Gbg * Gco + Bbg * Bco;
|
|
279
|
-
if (Ytxt <= blkThrs) {
|
|
280
|
-
Ytxt += (blkThrs - Ytxt) ** blkClmp;
|
|
281
|
-
}
|
|
282
|
-
if (Ybg <= blkThrs) {
|
|
283
|
-
Ybg += (blkThrs - Ybg) ** blkClmp;
|
|
284
|
-
}
|
|
285
|
-
if (Math.abs(Ybg - Ytxt) < deltaYmin) {
|
|
286
|
-
return 0;
|
|
287
|
-
}
|
|
288
|
-
let outputContrast;
|
|
289
|
-
if (Ybg > Ytxt) {
|
|
290
|
-
const SAPC = (Ybg ** normBG - Ytxt ** normTXT) * scaleBoW;
|
|
291
|
-
outputContrast = SAPC < loClip ? 0 : SAPC < loConThresh ? SAPC - SAPC * loConFactor * loConOffset : SAPC - loConOffset;
|
|
292
|
-
} else {
|
|
293
|
-
const SAPC = (Ybg ** revBG - Ytxt ** revTXT) * scaleWoB;
|
|
294
|
-
outputContrast = SAPC > -loClip ? 0 : SAPC > -loConThresh ? SAPC - SAPC * loConFactor * loConOffset : SAPC + loConOffset;
|
|
295
|
-
}
|
|
296
|
-
return outputContrast * 100;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
class Theme extends PresetCore {
|
|
199
|
+
class Brand extends PresetCore {
|
|
300
200
|
constructor(options) {
|
|
301
201
|
super(options);
|
|
302
202
|
const parsedOptions = this.parseThemeOptions(options?.themes);
|
|
@@ -309,18 +209,39 @@ class Theme extends PresetCore {
|
|
|
309
209
|
getCSS: () => {
|
|
310
210
|
const lines = [];
|
|
311
211
|
lines.push(createCssSelector({
|
|
312
|
-
selector: "root
|
|
212
|
+
selector: ":root",
|
|
313
213
|
content: [
|
|
314
214
|
core.entriesToCss(Object.entries(this.remapVariables({ tokens: this.preflights })))
|
|
315
215
|
]
|
|
316
216
|
}));
|
|
317
|
-
|
|
217
|
+
lines.push(createCssSelector({
|
|
218
|
+
selector: ":root",
|
|
219
|
+
content: this.genCssVariables(this.themes.light)
|
|
220
|
+
}));
|
|
221
|
+
return lines.join("\n");
|
|
318
222
|
}
|
|
319
223
|
};
|
|
320
224
|
}
|
|
321
|
-
|
|
225
|
+
genCssVariables(theme) {
|
|
226
|
+
const lightOverlay = theme.dark ? 2 : 1;
|
|
227
|
+
const darkOverlay = theme.dark ? 1 : 2;
|
|
228
|
+
const themeVariables = {};
|
|
229
|
+
for (const [key, value] of Object.entries(theme.colors)) {
|
|
230
|
+
const rgb = jsUtilities.parseColor(value);
|
|
231
|
+
themeVariables[key] = `${rgb.r},${rgb.g},${rgb.b}`;
|
|
232
|
+
if (!key.startsWith("on-")) {
|
|
233
|
+
themeVariables[`${key}-overlay-multiplier`] = (jsUtilities.getLuma(value) > 0.18 ? lightOverlay : darkOverlay).toString();
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const variables = {};
|
|
237
|
+
for (const [key, value] of Object.entries(theme.variables)) {
|
|
238
|
+
const color = typeof value === "string" && value.startsWith("#") ? jsUtilities.parseColor(value) : void 0;
|
|
239
|
+
const rgb = color ? `${color.r},${color.g},${color.b}` : void 0;
|
|
240
|
+
variables[key] = `${rgb ?? value}`;
|
|
241
|
+
}
|
|
322
242
|
return [
|
|
323
|
-
this.
|
|
243
|
+
core.entriesToCss(Object.entries(this.remapVariables({ tokens: themeVariables, key: "theme-" }))),
|
|
244
|
+
core.entriesToCss(Object.entries(this.remapVariables({ tokens: variables })))
|
|
324
245
|
];
|
|
325
246
|
}
|
|
326
247
|
parseThemeOptions(options) {
|
|
@@ -346,102 +267,93 @@ class Theme extends PresetCore {
|
|
|
346
267
|
continue;
|
|
347
268
|
}
|
|
348
269
|
const onColor = `on-${color}`;
|
|
349
|
-
const colorValue =
|
|
350
|
-
const blackContrast = Math.abs(
|
|
351
|
-
const whiteContrast = Math.abs(
|
|
270
|
+
const colorValue = jsUtilities.parseColor(theme.colors[color]);
|
|
271
|
+
const blackContrast = Math.abs(jsUtilities.APCAContrast(jsUtilities.parseColor(0), colorValue));
|
|
272
|
+
const whiteContrast = Math.abs(jsUtilities.APCAContrast(jsUtilities.parseColor(16777215), colorValue));
|
|
352
273
|
theme.colors[onColor] = whiteContrast > Math.min(blackContrast, 50) ? "#fff" : "#000";
|
|
353
|
-
this.colorKeys.push(color);
|
|
354
274
|
}
|
|
355
275
|
}
|
|
356
276
|
return acc;
|
|
357
277
|
}
|
|
358
|
-
getVariablesRule() {
|
|
359
|
-
return [
|
|
360
|
-
new RegExp(`^theme-(?<name>${Object.keys(this.themes).join("|")})$`),
|
|
361
|
-
({ groups }) => {
|
|
362
|
-
if (!groups?.name) {
|
|
363
|
-
return {};
|
|
364
|
-
}
|
|
365
|
-
const themeName = this.themes[groups.name];
|
|
366
|
-
const themeColors = themeName.colors ?? {};
|
|
367
|
-
const rgbs = generateRGBs(themeColors);
|
|
368
|
-
return {
|
|
369
|
-
"color-scheme": themeName.dark ? "dark" : "light",
|
|
370
|
-
...this.remapVariables({ tokens: rgbs, key: "theme-" }),
|
|
371
|
-
...this.remapVariables({ tokens: themeName.variables })
|
|
372
|
-
};
|
|
373
|
-
},
|
|
374
|
-
{ layer: "vinicunca" }
|
|
375
|
-
];
|
|
376
|
-
}
|
|
377
278
|
}
|
|
378
279
|
|
|
379
280
|
class Button extends PresetCore {
|
|
380
281
|
constructor(options) {
|
|
381
282
|
super(options);
|
|
382
|
-
this.
|
|
383
|
-
this.
|
|
283
|
+
this.regexCache = {};
|
|
284
|
+
this.classPropsKeys = Object.keys(this.classProps);
|
|
285
|
+
this.regexes = {
|
|
286
|
+
core: new RegExp(`(?<!--)((?:${this.prefix}button)+?)(?:--\\[((?:[\\w\\s-])+?)\\](?!\\s*?=>))?`, "gm")
|
|
287
|
+
};
|
|
288
|
+
this.classPropsKeys.forEach((key) => {
|
|
289
|
+
this.regexes[key] = new RegExp(`${key}-(${Object.keys(this.classProps[key]).join("|")})`, "g");
|
|
290
|
+
});
|
|
384
291
|
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
292
|
+
makeRegexClass(key) {
|
|
293
|
+
if (!this.regexCache[key]) {
|
|
294
|
+
this.regexCache[key] = this.regexes[key];
|
|
295
|
+
}
|
|
296
|
+
this.regexCache[key].lastIndex = 0;
|
|
297
|
+
return this.regexCache[key];
|
|
298
|
+
}
|
|
299
|
+
parseButtonClasses(str) {
|
|
300
|
+
const regexCore = this.makeRegexClass("core");
|
|
301
|
+
let hasChanged = false;
|
|
302
|
+
let content = str.toString();
|
|
303
|
+
let depth = 5;
|
|
304
|
+
do {
|
|
305
|
+
const before = content;
|
|
306
|
+
content = content.replace(
|
|
307
|
+
regexCore,
|
|
308
|
+
(_from, _pre, body) => {
|
|
309
|
+
const results = [this.classBase];
|
|
310
|
+
if (body) {
|
|
311
|
+
const bodyContent = body.split(/\s/g).filter(Boolean);
|
|
312
|
+
this.classPropsKeys.forEach((propKey) => {
|
|
313
|
+
const propRegex = this.makeRegexClass(propKey);
|
|
314
|
+
const defaultValue = this.classProps[propKey].default || "";
|
|
315
|
+
let hasProp = true;
|
|
316
|
+
if (bodyContent.length) {
|
|
317
|
+
for (let idx = 0; idx < bodyContent.length; idx++) {
|
|
318
|
+
const propBody = bodyContent[idx];
|
|
319
|
+
const match = propRegex.exec(propBody);
|
|
320
|
+
if (match) {
|
|
321
|
+
const [, key] = match;
|
|
322
|
+
results.push(this.classProps[propKey][key]);
|
|
323
|
+
bodyContent.splice(idx, 1);
|
|
324
|
+
hasProp = true;
|
|
325
|
+
break;
|
|
326
|
+
}
|
|
327
|
+
hasProp = false;
|
|
328
|
+
}
|
|
329
|
+
if (!hasProp) {
|
|
330
|
+
results.push(defaultValue);
|
|
331
|
+
}
|
|
332
|
+
} else {
|
|
333
|
+
results.push(defaultValue);
|
|
334
|
+
}
|
|
335
|
+
});
|
|
403
336
|
} else {
|
|
404
|
-
results.push(
|
|
337
|
+
results.push(
|
|
338
|
+
...this.classPropsKeys.map(
|
|
339
|
+
(key) => this.classProps[key].default || ""
|
|
340
|
+
)
|
|
341
|
+
);
|
|
405
342
|
}
|
|
406
|
-
|
|
407
|
-
results.push(`hover:${this.prefix}text-on-invert`);
|
|
408
|
-
results.push(`hover:before:${this.prefix}bg-invert`);
|
|
343
|
+
return results.join(" ").replace(/(\r\n|\n|\r)/gm, " ");
|
|
409
344
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
345
|
+
);
|
|
346
|
+
hasChanged = content !== before;
|
|
347
|
+
depth -= 1;
|
|
348
|
+
} while (hasChanged && depth);
|
|
349
|
+
return {
|
|
350
|
+
expanded: content.replace(/\s+/gm, " "),
|
|
351
|
+
hasChanged
|
|
352
|
+
};
|
|
416
353
|
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
/^button$/,
|
|
421
|
-
() => {
|
|
422
|
-
const size = this.sizes.default ?? "";
|
|
423
|
-
const variant = this.variants.default ?? "";
|
|
424
|
-
return `${size} ${variant}`;
|
|
425
|
-
},
|
|
426
|
-
{ layer: "vinicunca" }
|
|
427
|
-
],
|
|
428
|
-
[
|
|
429
|
-
new RegExp(`^button--size-(?<size>${Object.keys(this.sizes).join("|")})?$`),
|
|
430
|
-
({ groups }) => {
|
|
431
|
-
const size = groups?.size || "default";
|
|
432
|
-
return this.sizes[size] ?? "";
|
|
433
|
-
},
|
|
434
|
-
{ layer: "vinicunca" }
|
|
435
|
-
],
|
|
436
|
-
[
|
|
437
|
-
new RegExp(`^button--variant-(?<variant>${Object.keys(this.variants).join("|")})?$`),
|
|
438
|
-
({ groups }) => {
|
|
439
|
-
const variant = groups?.variant || "elevated";
|
|
440
|
-
return this.variants[variant] ?? "";
|
|
441
|
-
},
|
|
442
|
-
{ layer: "variants" }
|
|
443
|
-
]
|
|
444
|
-
];
|
|
354
|
+
transfromClasses(str) {
|
|
355
|
+
const { expanded } = this.parseButtonClasses(str.toString());
|
|
356
|
+
return str.length() ? str.overwrite(0, str.length(), expanded) : str;
|
|
445
357
|
}
|
|
446
358
|
}
|
|
447
359
|
|
|
@@ -458,7 +370,7 @@ class Overlay extends PresetCore {
|
|
|
458
370
|
lines.push(createCssSelector({
|
|
459
371
|
selector: `html.${this.scrollBlockedClass.name}`,
|
|
460
372
|
content: [
|
|
461
|
-
|
|
373
|
+
core.entriesToCss(Object.entries(this.scrollBlockedClass.html))
|
|
462
374
|
]
|
|
463
375
|
}));
|
|
464
376
|
return lines.join("");
|
|
@@ -479,25 +391,21 @@ class Overlay extends PresetCore {
|
|
|
479
391
|
|
|
480
392
|
class VinicuncaConfig {
|
|
481
393
|
constructor(options) {
|
|
482
|
-
const { prefix, components,
|
|
483
|
-
this.
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
...theme
|
|
394
|
+
const { prefix, components, brands } = options;
|
|
395
|
+
this.brand = new Brand({
|
|
396
|
+
prefix,
|
|
397
|
+
...brands
|
|
487
398
|
});
|
|
488
|
-
const colorKeys = this.theme.getColorKeys();
|
|
489
399
|
this.color = new Color({
|
|
490
|
-
prefix
|
|
491
|
-
colorKeys
|
|
400
|
+
prefix
|
|
492
401
|
});
|
|
493
402
|
this.elevation = new Elevation();
|
|
494
403
|
this.button = new Button({
|
|
495
|
-
prefix
|
|
496
|
-
colorKeys,
|
|
404
|
+
prefix,
|
|
497
405
|
...components?.button
|
|
498
406
|
});
|
|
499
407
|
this.overlay = new Overlay({
|
|
500
|
-
prefix
|
|
408
|
+
prefix,
|
|
501
409
|
...components?.overlay
|
|
502
410
|
});
|
|
503
411
|
}
|
|
@@ -505,15 +413,22 @@ class VinicuncaConfig {
|
|
|
505
413
|
return {
|
|
506
414
|
name: "unocss-preset-vinicunca",
|
|
507
415
|
layers: {
|
|
508
|
-
preflight: -
|
|
509
|
-
vinicunca: -
|
|
416
|
+
preflight: -3,
|
|
417
|
+
vinicunca: -2,
|
|
510
418
|
default: 0,
|
|
511
419
|
variants: 1
|
|
512
420
|
},
|
|
513
|
-
prefix: this.prefix,
|
|
514
421
|
preflights: this.definePreflights(),
|
|
515
422
|
rules: this.defineRules(),
|
|
516
|
-
shortcuts: this.defineShortcuts()
|
|
423
|
+
shortcuts: this.defineShortcuts(),
|
|
424
|
+
theme: {
|
|
425
|
+
letterSpacing: {
|
|
426
|
+
button: "0.0892857143em"
|
|
427
|
+
},
|
|
428
|
+
textIndent: {
|
|
429
|
+
button: "0.0892857143em"
|
|
430
|
+
}
|
|
431
|
+
}
|
|
517
432
|
};
|
|
518
433
|
}
|
|
519
434
|
getTransformer() {
|
|
@@ -521,29 +436,23 @@ class VinicuncaConfig {
|
|
|
521
436
|
name: "vinicunca-transformers",
|
|
522
437
|
enforce: "pre",
|
|
523
438
|
transform: (str) => {
|
|
524
|
-
|
|
525
|
-
content = this.button.transformClass(content);
|
|
526
|
-
str.overwrite(0, str.length(), content);
|
|
439
|
+
this.button.transfromClasses(str);
|
|
527
440
|
}
|
|
528
441
|
};
|
|
529
442
|
}
|
|
530
443
|
definePreflights() {
|
|
531
444
|
return [
|
|
532
|
-
this.
|
|
533
|
-
this.overlay.getPreflight()
|
|
445
|
+
this.brand.getPreflight()
|
|
534
446
|
];
|
|
535
447
|
}
|
|
536
448
|
defineRules() {
|
|
537
449
|
return [
|
|
538
|
-
this.theme.getRules(),
|
|
539
450
|
this.color.getRules(),
|
|
540
|
-
this.elevation.getRules()
|
|
541
|
-
this.button.getRules()
|
|
451
|
+
this.elevation.getRules()
|
|
542
452
|
].flat(1);
|
|
543
453
|
}
|
|
544
454
|
defineShortcuts() {
|
|
545
455
|
return [
|
|
546
|
-
...this.button.getShortcuts(),
|
|
547
456
|
...this.overlay.getShortcuts()
|
|
548
457
|
];
|
|
549
458
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { DeepPartial, Preset, SourceCodeTransformer } from '@unocss/core';
|
|
2
2
|
|
|
3
|
-
interface
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
interface CoreOptions {
|
|
4
|
+
prefix?: string;
|
|
5
|
+
classBase?: string;
|
|
6
|
+
classProps?: Record<string, Record<string, string>>;
|
|
6
7
|
}
|
|
7
8
|
|
|
8
9
|
interface OverlayOptions {
|
|
@@ -58,16 +59,15 @@ interface ThemePreset {
|
|
|
58
59
|
|
|
59
60
|
interface IConfigVinicunca {
|
|
60
61
|
prefix?: string;
|
|
61
|
-
|
|
62
|
+
brands?: ThemePreset;
|
|
62
63
|
components?: {
|
|
63
|
-
button?:
|
|
64
|
+
button?: CoreOptions;
|
|
64
65
|
overlay?: OverlayOptions;
|
|
65
66
|
};
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
declare class VinicuncaConfig {
|
|
69
|
-
private
|
|
70
|
-
private theme;
|
|
70
|
+
private brand;
|
|
71
71
|
private color;
|
|
72
72
|
private elevation;
|
|
73
73
|
private button;
|
package/dist/index.mjs
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import { toKebabCase, convertToUnit,
|
|
1
|
+
import { toKebabCase, convertToUnit, parseColor, getLuma, mergeDeep, APCAContrast } from '@vinicunca/js-utilities';
|
|
2
2
|
import { entriesToCss } from '@unocss/core';
|
|
3
|
-
import { parseColor } from '@unocss/preset-mini';
|
|
4
|
-
import { entriesToCss as entriesToCss$1 } from 'unocss';
|
|
5
3
|
|
|
6
4
|
const DEFAULT_PREFIX = "vin-";
|
|
7
5
|
class PresetCore {
|
|
8
6
|
constructor(options) {
|
|
9
|
-
this.prefix = options.prefix ??
|
|
10
|
-
this.
|
|
7
|
+
this.prefix = options.prefix ?? DEFAULT_PREFIX;
|
|
8
|
+
this.classBase = options.classBase ?? "";
|
|
9
|
+
this.classProps = options.classProps ?? {};
|
|
11
10
|
}
|
|
12
11
|
genVariable(key = "") {
|
|
13
12
|
return `--${this.prefix}${key}`;
|
|
@@ -19,14 +18,12 @@ class PresetCore {
|
|
|
19
18
|
return prev;
|
|
20
19
|
}, {});
|
|
21
20
|
}
|
|
22
|
-
getColorKeys() {
|
|
23
|
-
return Array.from(new Set(this.colorKeys));
|
|
24
|
-
}
|
|
25
21
|
}
|
|
26
22
|
|
|
27
23
|
class Color extends PresetCore {
|
|
28
24
|
constructor(options) {
|
|
29
25
|
super(options);
|
|
26
|
+
this.varTextOpacity = "--un-text-opacity";
|
|
30
27
|
}
|
|
31
28
|
getRules() {
|
|
32
29
|
return [
|
|
@@ -36,17 +33,14 @@ class Color extends PresetCore {
|
|
|
36
33
|
}
|
|
37
34
|
getTextRule() {
|
|
38
35
|
return [
|
|
39
|
-
/^text-(?<body>(?:on-)?(?<color>.+))/,
|
|
36
|
+
/^text-brand-(?<body>(?:on-)?(?<color>.+))/,
|
|
40
37
|
({ groups }) => {
|
|
41
38
|
const { body, color } = groups;
|
|
42
|
-
if (!this.getColorKeys().includes(color)) {
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
39
|
const colorBody = /^on-[a-z]/.test(body) ? `on-${color}` : color;
|
|
46
40
|
const colorVar = this.genVariable(`theme-${colorBody}`);
|
|
47
41
|
return {
|
|
48
|
-
|
|
49
|
-
|
|
42
|
+
[this.varTextOpacity]: 1,
|
|
43
|
+
color: `rgba(var(${colorVar}), var(${this.varTextOpacity}))`
|
|
50
44
|
};
|
|
51
45
|
},
|
|
52
46
|
{ layer: "vinicunca" }
|
|
@@ -54,18 +48,15 @@ class Color extends PresetCore {
|
|
|
54
48
|
}
|
|
55
49
|
getBgRule() {
|
|
56
50
|
return [
|
|
57
|
-
/^bg-(.+)$/,
|
|
51
|
+
/^bg-brand-(.+)$/,
|
|
58
52
|
([, body]) => {
|
|
59
|
-
if (!this.colorKeys.includes(body)) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
53
|
const bgColorVar = this.genVariable(`theme-${body}`);
|
|
63
54
|
const colorVar = this.genVariable(`theme-on-${body}`);
|
|
64
55
|
return {
|
|
65
|
-
|
|
56
|
+
[this.varTextOpacity]: 1,
|
|
66
57
|
"--un-bg-opacity": 1,
|
|
67
58
|
"background-color": `rgba(var(${bgColorVar}),var(--un-bg-opacity))`,
|
|
68
|
-
"color": `rgba(var(${colorVar}), var(
|
|
59
|
+
"color": `rgba(var(${colorVar}), var(${this.varTextOpacity}))`
|
|
69
60
|
};
|
|
70
61
|
},
|
|
71
62
|
{ layer: "vinicunca" }
|
|
@@ -141,7 +132,6 @@ const DEFAULT_THEME = {
|
|
|
141
132
|
dark: false,
|
|
142
133
|
colors: {
|
|
143
134
|
"background": "#FFFFFF",
|
|
144
|
-
"invert": "#000000",
|
|
145
135
|
"surface": "#FFFFFF",
|
|
146
136
|
"surface-variant": "#424242",
|
|
147
137
|
"on-surface-variant": "#EEEEEE",
|
|
@@ -154,24 +144,23 @@ const DEFAULT_THEME = {
|
|
|
154
144
|
},
|
|
155
145
|
variables: {
|
|
156
146
|
"border-color": "#000000",
|
|
157
|
-
"border
|
|
158
|
-
"high-emphasis
|
|
159
|
-
"medium-emphasis
|
|
160
|
-
"disabled
|
|
161
|
-
"idle
|
|
162
|
-
"hover
|
|
163
|
-
"focus
|
|
164
|
-
"selected
|
|
165
|
-
"activated
|
|
166
|
-
"pressed
|
|
167
|
-
"dragged
|
|
147
|
+
"opacity-border": 0.12,
|
|
148
|
+
"opacity-high-emphasis": 0.87,
|
|
149
|
+
"opacity-medium-emphasis": 0.6,
|
|
150
|
+
"opacity-disabled": 0.38,
|
|
151
|
+
"opacity-idle": 0.04,
|
|
152
|
+
"opacity-hover": 0.04,
|
|
153
|
+
"opacity-focus": 0.12,
|
|
154
|
+
"opacity-selected": 0.08,
|
|
155
|
+
"opacity-activated": 0.12,
|
|
156
|
+
"opacity-pressed": 0.12,
|
|
157
|
+
"opacity-dragged": 0.08
|
|
168
158
|
}
|
|
169
159
|
},
|
|
170
160
|
dark: {
|
|
171
161
|
dark: true,
|
|
172
162
|
colors: {
|
|
173
163
|
"background": "#121212",
|
|
174
|
-
"invert": "#FFFFFF",
|
|
175
164
|
"surface": "#212121",
|
|
176
165
|
"surface-variant": "#BDBDBD",
|
|
177
166
|
"on-surface-variant": "#424242",
|
|
@@ -184,17 +173,17 @@ const DEFAULT_THEME = {
|
|
|
184
173
|
},
|
|
185
174
|
variables: {
|
|
186
175
|
"border-color": "#FFFFFF",
|
|
187
|
-
"border
|
|
188
|
-
"high-emphasis
|
|
189
|
-
"medium-emphasis
|
|
190
|
-
"disabled
|
|
191
|
-
"idle
|
|
192
|
-
"hover
|
|
193
|
-
"focus
|
|
194
|
-
"selected
|
|
195
|
-
"activated
|
|
196
|
-
"pressed
|
|
197
|
-
"dragged
|
|
176
|
+
"opacity-border": 0.12,
|
|
177
|
+
"opacity-high-emphasis": 0.87,
|
|
178
|
+
"opacity-medium-emphasis": 0.6,
|
|
179
|
+
"opacity-disabled": 0.38,
|
|
180
|
+
"opacity-idle": 0.1,
|
|
181
|
+
"opacity-hover": 0.04,
|
|
182
|
+
"opacity-focus": 0.12,
|
|
183
|
+
"opacity-selected": 0.08,
|
|
184
|
+
"opacity-activated": 0.12,
|
|
185
|
+
"opacity-pressed": 0.16,
|
|
186
|
+
"opacity-dragged": 0.08
|
|
198
187
|
}
|
|
199
188
|
}
|
|
200
189
|
};
|
|
@@ -203,98 +192,7 @@ function createCssSelector({ selector, content }) {
|
|
|
203
192
|
return `${selector} { ${content.join(" ")} }`;
|
|
204
193
|
}
|
|
205
194
|
|
|
206
|
-
|
|
207
|
-
const theme = {};
|
|
208
|
-
for (const color of Object.keys(colors)) {
|
|
209
|
-
let colorKey = color;
|
|
210
|
-
if (/^on-[a-z]/.test(color)) {
|
|
211
|
-
colorKey = toCamelCase(color);
|
|
212
|
-
}
|
|
213
|
-
const data = parseColor(color, {
|
|
214
|
-
colors: {
|
|
215
|
-
[colorKey]: colors[color]
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
|
-
if (data?.cssColor?.components) {
|
|
219
|
-
const colorValue = data.cssColor.components.join(",");
|
|
220
|
-
theme[color] = colorValue;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
return theme;
|
|
224
|
-
}
|
|
225
|
-
function colorToInt(color) {
|
|
226
|
-
let rgb;
|
|
227
|
-
if (typeof color === "number") {
|
|
228
|
-
rgb = color;
|
|
229
|
-
} else if (typeof color === "string") {
|
|
230
|
-
let c = color.startsWith("#") ? color.substring(1) : color;
|
|
231
|
-
if (c.length === 3) {
|
|
232
|
-
c = c.split("").map((char) => char + char).join("");
|
|
233
|
-
}
|
|
234
|
-
if (c.length !== 6 && c.length !== 8) {
|
|
235
|
-
console.warn(`'${color}' is not a valid rgb color`);
|
|
236
|
-
}
|
|
237
|
-
rgb = parseInt(c, 16);
|
|
238
|
-
} else {
|
|
239
|
-
throw new TypeError(`Colors can only be numbers or strings, recieved ${color == null ? color : color.constructor.name} instead`);
|
|
240
|
-
}
|
|
241
|
-
if (rgb < 0) {
|
|
242
|
-
console.warn(`Colors cannot be negative: '${color}'`);
|
|
243
|
-
rgb = 0;
|
|
244
|
-
} else if (rgb > 4294967295 || isNaN(rgb)) {
|
|
245
|
-
console.warn(`'${color}' is not a valid rgb color`);
|
|
246
|
-
rgb = 16777215;
|
|
247
|
-
}
|
|
248
|
-
return rgb;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
const mainTRC = 2.4;
|
|
252
|
-
const Rco = 0.2126729;
|
|
253
|
-
const Gco = 0.7151522;
|
|
254
|
-
const Bco = 0.072175;
|
|
255
|
-
const normBG = 0.55;
|
|
256
|
-
const normTXT = 0.58;
|
|
257
|
-
const revTXT = 0.57;
|
|
258
|
-
const revBG = 0.62;
|
|
259
|
-
const blkThrs = 0.03;
|
|
260
|
-
const blkClmp = 1.45;
|
|
261
|
-
const deltaYmin = 5e-4;
|
|
262
|
-
const scaleBoW = 1.25;
|
|
263
|
-
const scaleWoB = 1.25;
|
|
264
|
-
const loConThresh = 0.078;
|
|
265
|
-
const loConFactor = 12.82051282051282;
|
|
266
|
-
const loConOffset = 0.06;
|
|
267
|
-
const loClip = 1e-3;
|
|
268
|
-
function APCAcontrast(text, background) {
|
|
269
|
-
const Rtxt = ((text >> 16 & 255) / 255) ** mainTRC;
|
|
270
|
-
const Gtxt = ((text >> 8 & 255) / 255) ** mainTRC;
|
|
271
|
-
const Btxt = ((text >> 0 & 255) / 255) ** mainTRC;
|
|
272
|
-
const Rbg = ((background >> 16 & 255) / 255) ** mainTRC;
|
|
273
|
-
const Gbg = ((background >> 8 & 255) / 255) ** mainTRC;
|
|
274
|
-
const Bbg = ((background >> 0 & 255) / 255) ** mainTRC;
|
|
275
|
-
let Ytxt = Rtxt * Rco + Gtxt * Gco + Btxt * Bco;
|
|
276
|
-
let Ybg = Rbg * Rco + Gbg * Gco + Bbg * Bco;
|
|
277
|
-
if (Ytxt <= blkThrs) {
|
|
278
|
-
Ytxt += (blkThrs - Ytxt) ** blkClmp;
|
|
279
|
-
}
|
|
280
|
-
if (Ybg <= blkThrs) {
|
|
281
|
-
Ybg += (blkThrs - Ybg) ** blkClmp;
|
|
282
|
-
}
|
|
283
|
-
if (Math.abs(Ybg - Ytxt) < deltaYmin) {
|
|
284
|
-
return 0;
|
|
285
|
-
}
|
|
286
|
-
let outputContrast;
|
|
287
|
-
if (Ybg > Ytxt) {
|
|
288
|
-
const SAPC = (Ybg ** normBG - Ytxt ** normTXT) * scaleBoW;
|
|
289
|
-
outputContrast = SAPC < loClip ? 0 : SAPC < loConThresh ? SAPC - SAPC * loConFactor * loConOffset : SAPC - loConOffset;
|
|
290
|
-
} else {
|
|
291
|
-
const SAPC = (Ybg ** revBG - Ytxt ** revTXT) * scaleWoB;
|
|
292
|
-
outputContrast = SAPC > -loClip ? 0 : SAPC > -loConThresh ? SAPC - SAPC * loConFactor * loConOffset : SAPC + loConOffset;
|
|
293
|
-
}
|
|
294
|
-
return outputContrast * 100;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
class Theme extends PresetCore {
|
|
195
|
+
class Brand extends PresetCore {
|
|
298
196
|
constructor(options) {
|
|
299
197
|
super(options);
|
|
300
198
|
const parsedOptions = this.parseThemeOptions(options?.themes);
|
|
@@ -307,18 +205,39 @@ class Theme extends PresetCore {
|
|
|
307
205
|
getCSS: () => {
|
|
308
206
|
const lines = [];
|
|
309
207
|
lines.push(createCssSelector({
|
|
310
|
-
selector: "root
|
|
208
|
+
selector: ":root",
|
|
311
209
|
content: [
|
|
312
210
|
entriesToCss(Object.entries(this.remapVariables({ tokens: this.preflights })))
|
|
313
211
|
]
|
|
314
212
|
}));
|
|
315
|
-
|
|
213
|
+
lines.push(createCssSelector({
|
|
214
|
+
selector: ":root",
|
|
215
|
+
content: this.genCssVariables(this.themes.light)
|
|
216
|
+
}));
|
|
217
|
+
return lines.join("\n");
|
|
316
218
|
}
|
|
317
219
|
};
|
|
318
220
|
}
|
|
319
|
-
|
|
221
|
+
genCssVariables(theme) {
|
|
222
|
+
const lightOverlay = theme.dark ? 2 : 1;
|
|
223
|
+
const darkOverlay = theme.dark ? 1 : 2;
|
|
224
|
+
const themeVariables = {};
|
|
225
|
+
for (const [key, value] of Object.entries(theme.colors)) {
|
|
226
|
+
const rgb = parseColor(value);
|
|
227
|
+
themeVariables[key] = `${rgb.r},${rgb.g},${rgb.b}`;
|
|
228
|
+
if (!key.startsWith("on-")) {
|
|
229
|
+
themeVariables[`${key}-overlay-multiplier`] = (getLuma(value) > 0.18 ? lightOverlay : darkOverlay).toString();
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
const variables = {};
|
|
233
|
+
for (const [key, value] of Object.entries(theme.variables)) {
|
|
234
|
+
const color = typeof value === "string" && value.startsWith("#") ? parseColor(value) : void 0;
|
|
235
|
+
const rgb = color ? `${color.r},${color.g},${color.b}` : void 0;
|
|
236
|
+
variables[key] = `${rgb ?? value}`;
|
|
237
|
+
}
|
|
320
238
|
return [
|
|
321
|
-
this.
|
|
239
|
+
entriesToCss(Object.entries(this.remapVariables({ tokens: themeVariables, key: "theme-" }))),
|
|
240
|
+
entriesToCss(Object.entries(this.remapVariables({ tokens: variables })))
|
|
322
241
|
];
|
|
323
242
|
}
|
|
324
243
|
parseThemeOptions(options) {
|
|
@@ -344,102 +263,93 @@ class Theme extends PresetCore {
|
|
|
344
263
|
continue;
|
|
345
264
|
}
|
|
346
265
|
const onColor = `on-${color}`;
|
|
347
|
-
const colorValue =
|
|
348
|
-
const blackContrast = Math.abs(
|
|
349
|
-
const whiteContrast = Math.abs(
|
|
266
|
+
const colorValue = parseColor(theme.colors[color]);
|
|
267
|
+
const blackContrast = Math.abs(APCAContrast(parseColor(0), colorValue));
|
|
268
|
+
const whiteContrast = Math.abs(APCAContrast(parseColor(16777215), colorValue));
|
|
350
269
|
theme.colors[onColor] = whiteContrast > Math.min(blackContrast, 50) ? "#fff" : "#000";
|
|
351
|
-
this.colorKeys.push(color);
|
|
352
270
|
}
|
|
353
271
|
}
|
|
354
272
|
return acc;
|
|
355
273
|
}
|
|
356
|
-
getVariablesRule() {
|
|
357
|
-
return [
|
|
358
|
-
new RegExp(`^theme-(?<name>${Object.keys(this.themes).join("|")})$`),
|
|
359
|
-
({ groups }) => {
|
|
360
|
-
if (!groups?.name) {
|
|
361
|
-
return {};
|
|
362
|
-
}
|
|
363
|
-
const themeName = this.themes[groups.name];
|
|
364
|
-
const themeColors = themeName.colors ?? {};
|
|
365
|
-
const rgbs = generateRGBs(themeColors);
|
|
366
|
-
return {
|
|
367
|
-
"color-scheme": themeName.dark ? "dark" : "light",
|
|
368
|
-
...this.remapVariables({ tokens: rgbs, key: "theme-" }),
|
|
369
|
-
...this.remapVariables({ tokens: themeName.variables })
|
|
370
|
-
};
|
|
371
|
-
},
|
|
372
|
-
{ layer: "vinicunca" }
|
|
373
|
-
];
|
|
374
|
-
}
|
|
375
274
|
}
|
|
376
275
|
|
|
377
276
|
class Button extends PresetCore {
|
|
378
277
|
constructor(options) {
|
|
379
278
|
super(options);
|
|
380
|
-
this.
|
|
381
|
-
this.
|
|
279
|
+
this.regexCache = {};
|
|
280
|
+
this.classPropsKeys = Object.keys(this.classProps);
|
|
281
|
+
this.regexes = {
|
|
282
|
+
core: new RegExp(`(?<!--)((?:${this.prefix}button)+?)(?:--\\[((?:[\\w\\s-])+?)\\](?!\\s*?=>))?`, "gm")
|
|
283
|
+
};
|
|
284
|
+
this.classPropsKeys.forEach((key) => {
|
|
285
|
+
this.regexes[key] = new RegExp(`${key}-(${Object.keys(this.classProps[key]).join("|")})`, "g");
|
|
286
|
+
});
|
|
382
287
|
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
288
|
+
makeRegexClass(key) {
|
|
289
|
+
if (!this.regexCache[key]) {
|
|
290
|
+
this.regexCache[key] = this.regexes[key];
|
|
291
|
+
}
|
|
292
|
+
this.regexCache[key].lastIndex = 0;
|
|
293
|
+
return this.regexCache[key];
|
|
294
|
+
}
|
|
295
|
+
parseButtonClasses(str) {
|
|
296
|
+
const regexCore = this.makeRegexClass("core");
|
|
297
|
+
let hasChanged = false;
|
|
298
|
+
let content = str.toString();
|
|
299
|
+
let depth = 5;
|
|
300
|
+
do {
|
|
301
|
+
const before = content;
|
|
302
|
+
content = content.replace(
|
|
303
|
+
regexCore,
|
|
304
|
+
(_from, _pre, body) => {
|
|
305
|
+
const results = [this.classBase];
|
|
306
|
+
if (body) {
|
|
307
|
+
const bodyContent = body.split(/\s/g).filter(Boolean);
|
|
308
|
+
this.classPropsKeys.forEach((propKey) => {
|
|
309
|
+
const propRegex = this.makeRegexClass(propKey);
|
|
310
|
+
const defaultValue = this.classProps[propKey].default || "";
|
|
311
|
+
let hasProp = true;
|
|
312
|
+
if (bodyContent.length) {
|
|
313
|
+
for (let idx = 0; idx < bodyContent.length; idx++) {
|
|
314
|
+
const propBody = bodyContent[idx];
|
|
315
|
+
const match = propRegex.exec(propBody);
|
|
316
|
+
if (match) {
|
|
317
|
+
const [, key] = match;
|
|
318
|
+
results.push(this.classProps[propKey][key]);
|
|
319
|
+
bodyContent.splice(idx, 1);
|
|
320
|
+
hasProp = true;
|
|
321
|
+
break;
|
|
322
|
+
}
|
|
323
|
+
hasProp = false;
|
|
324
|
+
}
|
|
325
|
+
if (!hasProp) {
|
|
326
|
+
results.push(defaultValue);
|
|
327
|
+
}
|
|
328
|
+
} else {
|
|
329
|
+
results.push(defaultValue);
|
|
330
|
+
}
|
|
331
|
+
});
|
|
401
332
|
} else {
|
|
402
|
-
results.push(
|
|
333
|
+
results.push(
|
|
334
|
+
...this.classPropsKeys.map(
|
|
335
|
+
(key) => this.classProps[key].default || ""
|
|
336
|
+
)
|
|
337
|
+
);
|
|
403
338
|
}
|
|
404
|
-
|
|
405
|
-
results.push(`hover:${this.prefix}text-on-invert`);
|
|
406
|
-
results.push(`hover:before:${this.prefix}bg-invert`);
|
|
339
|
+
return results.join(" ").replace(/(\r\n|\n|\r)/gm, " ");
|
|
407
340
|
}
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
341
|
+
);
|
|
342
|
+
hasChanged = content !== before;
|
|
343
|
+
depth -= 1;
|
|
344
|
+
} while (hasChanged && depth);
|
|
345
|
+
return {
|
|
346
|
+
expanded: content.replace(/\s+/gm, " "),
|
|
347
|
+
hasChanged
|
|
348
|
+
};
|
|
411
349
|
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
getShortcuts() {
|
|
416
|
-
return [
|
|
417
|
-
[
|
|
418
|
-
/^button$/,
|
|
419
|
-
() => {
|
|
420
|
-
const size = this.sizes.default ?? "";
|
|
421
|
-
const variant = this.variants.default ?? "";
|
|
422
|
-
return `${size} ${variant}`;
|
|
423
|
-
},
|
|
424
|
-
{ layer: "vinicunca" }
|
|
425
|
-
],
|
|
426
|
-
[
|
|
427
|
-
new RegExp(`^button--size-(?<size>${Object.keys(this.sizes).join("|")})?$`),
|
|
428
|
-
({ groups }) => {
|
|
429
|
-
const size = groups?.size || "default";
|
|
430
|
-
return this.sizes[size] ?? "";
|
|
431
|
-
},
|
|
432
|
-
{ layer: "vinicunca" }
|
|
433
|
-
],
|
|
434
|
-
[
|
|
435
|
-
new RegExp(`^button--variant-(?<variant>${Object.keys(this.variants).join("|")})?$`),
|
|
436
|
-
({ groups }) => {
|
|
437
|
-
const variant = groups?.variant || "elevated";
|
|
438
|
-
return this.variants[variant] ?? "";
|
|
439
|
-
},
|
|
440
|
-
{ layer: "variants" }
|
|
441
|
-
]
|
|
442
|
-
];
|
|
350
|
+
transfromClasses(str) {
|
|
351
|
+
const { expanded } = this.parseButtonClasses(str.toString());
|
|
352
|
+
return str.length() ? str.overwrite(0, str.length(), expanded) : str;
|
|
443
353
|
}
|
|
444
354
|
}
|
|
445
355
|
|
|
@@ -456,7 +366,7 @@ class Overlay extends PresetCore {
|
|
|
456
366
|
lines.push(createCssSelector({
|
|
457
367
|
selector: `html.${this.scrollBlockedClass.name}`,
|
|
458
368
|
content: [
|
|
459
|
-
entriesToCss
|
|
369
|
+
entriesToCss(Object.entries(this.scrollBlockedClass.html))
|
|
460
370
|
]
|
|
461
371
|
}));
|
|
462
372
|
return lines.join("");
|
|
@@ -477,25 +387,21 @@ class Overlay extends PresetCore {
|
|
|
477
387
|
|
|
478
388
|
class VinicuncaConfig {
|
|
479
389
|
constructor(options) {
|
|
480
|
-
const { prefix, components,
|
|
481
|
-
this.
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
...theme
|
|
390
|
+
const { prefix, components, brands } = options;
|
|
391
|
+
this.brand = new Brand({
|
|
392
|
+
prefix,
|
|
393
|
+
...brands
|
|
485
394
|
});
|
|
486
|
-
const colorKeys = this.theme.getColorKeys();
|
|
487
395
|
this.color = new Color({
|
|
488
|
-
prefix
|
|
489
|
-
colorKeys
|
|
396
|
+
prefix
|
|
490
397
|
});
|
|
491
398
|
this.elevation = new Elevation();
|
|
492
399
|
this.button = new Button({
|
|
493
|
-
prefix
|
|
494
|
-
colorKeys,
|
|
400
|
+
prefix,
|
|
495
401
|
...components?.button
|
|
496
402
|
});
|
|
497
403
|
this.overlay = new Overlay({
|
|
498
|
-
prefix
|
|
404
|
+
prefix,
|
|
499
405
|
...components?.overlay
|
|
500
406
|
});
|
|
501
407
|
}
|
|
@@ -503,15 +409,22 @@ class VinicuncaConfig {
|
|
|
503
409
|
return {
|
|
504
410
|
name: "unocss-preset-vinicunca",
|
|
505
411
|
layers: {
|
|
506
|
-
preflight: -
|
|
507
|
-
vinicunca: -
|
|
412
|
+
preflight: -3,
|
|
413
|
+
vinicunca: -2,
|
|
508
414
|
default: 0,
|
|
509
415
|
variants: 1
|
|
510
416
|
},
|
|
511
|
-
prefix: this.prefix,
|
|
512
417
|
preflights: this.definePreflights(),
|
|
513
418
|
rules: this.defineRules(),
|
|
514
|
-
shortcuts: this.defineShortcuts()
|
|
419
|
+
shortcuts: this.defineShortcuts(),
|
|
420
|
+
theme: {
|
|
421
|
+
letterSpacing: {
|
|
422
|
+
button: "0.0892857143em"
|
|
423
|
+
},
|
|
424
|
+
textIndent: {
|
|
425
|
+
button: "0.0892857143em"
|
|
426
|
+
}
|
|
427
|
+
}
|
|
515
428
|
};
|
|
516
429
|
}
|
|
517
430
|
getTransformer() {
|
|
@@ -519,29 +432,23 @@ class VinicuncaConfig {
|
|
|
519
432
|
name: "vinicunca-transformers",
|
|
520
433
|
enforce: "pre",
|
|
521
434
|
transform: (str) => {
|
|
522
|
-
|
|
523
|
-
content = this.button.transformClass(content);
|
|
524
|
-
str.overwrite(0, str.length(), content);
|
|
435
|
+
this.button.transfromClasses(str);
|
|
525
436
|
}
|
|
526
437
|
};
|
|
527
438
|
}
|
|
528
439
|
definePreflights() {
|
|
529
440
|
return [
|
|
530
|
-
this.
|
|
531
|
-
this.overlay.getPreflight()
|
|
441
|
+
this.brand.getPreflight()
|
|
532
442
|
];
|
|
533
443
|
}
|
|
534
444
|
defineRules() {
|
|
535
445
|
return [
|
|
536
|
-
this.theme.getRules(),
|
|
537
446
|
this.color.getRules(),
|
|
538
|
-
this.elevation.getRules()
|
|
539
|
-
this.button.getRules()
|
|
447
|
+
this.elevation.getRules()
|
|
540
448
|
].flat(1);
|
|
541
449
|
}
|
|
542
450
|
defineShortcuts() {
|
|
543
451
|
return [
|
|
544
|
-
...this.button.getShortcuts(),
|
|
545
452
|
...this.overlay.getShortcuts()
|
|
546
453
|
];
|
|
547
454
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vinicunca/unocss-preset",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"packageManager": "pnpm@7.15.2",
|
|
5
5
|
"description": "UnoCSS custom preset",
|
|
6
6
|
"author": "praburangki<https://github.com/praburangki>",
|
|
@@ -46,27 +46,27 @@
|
|
|
46
46
|
"styles"
|
|
47
47
|
],
|
|
48
48
|
"peerDependencies": {
|
|
49
|
-
"
|
|
50
|
-
"
|
|
49
|
+
"@vinicunca/js-utilities": "*",
|
|
50
|
+
"unocss": "*"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@commitlint/cli": "^17.4.2",
|
|
54
54
|
"@commitlint/config-conventional": "^17.4.2",
|
|
55
|
-
"@vinicunca/eslint-config": "^1.
|
|
56
|
-
"@vinicunca/js-utilities": "^
|
|
57
|
-
"bumpp": "^
|
|
55
|
+
"@vinicunca/eslint-config": "^1.7.1",
|
|
56
|
+
"@vinicunca/js-utilities": "^3.0.0",
|
|
57
|
+
"bumpp": "^9.1.0",
|
|
58
58
|
"commitizen": "^4.2.6",
|
|
59
59
|
"conventional-changelog-cli": "^2.2.2",
|
|
60
60
|
"cz-customizable": "^7.0.0",
|
|
61
|
-
"eslint": "^8.
|
|
62
|
-
"eslint-define-config": "^1.
|
|
61
|
+
"eslint": "^8.37.0",
|
|
62
|
+
"eslint-define-config": "^1.17.0",
|
|
63
63
|
"husky": "^8.0.3",
|
|
64
64
|
"is-ci": "^3.0.1",
|
|
65
|
-
"lint-staged": "^13.
|
|
66
|
-
"typescript": "^
|
|
67
|
-
"unbuild": "^
|
|
68
|
-
"unocss": "^0.
|
|
69
|
-
"vitest": "^0.
|
|
65
|
+
"lint-staged": "^13.2.0",
|
|
66
|
+
"typescript": "^5.0.3",
|
|
67
|
+
"unbuild": "^0.8.11",
|
|
68
|
+
"unocss": "^0.50.6",
|
|
69
|
+
"vitest": "^0.29.8"
|
|
70
70
|
},
|
|
71
71
|
"publishConfig": {
|
|
72
72
|
"access": "public"
|