@unocss/preset-mini 0.22.7 → 0.24.2

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.
@@ -37,12 +37,28 @@ const variantBreakpoints = (matcher, { theme }) => {
37
37
  }
38
38
  };
39
39
 
40
+ const scopeMatcher = (strict, name, template) => {
41
+ const re = strict ? new RegExp(`^${name}(?:-\\[(.+?)\\])[:-]`) : new RegExp(`^${name}(?:-\\[(.+?)\\])?[:-]`);
42
+ return (matcher) => {
43
+ const match = matcher.match(re);
44
+ if (match) {
45
+ return {
46
+ matcher: matcher.slice(match[0].length),
47
+ selector: (s) => template.replace("&&-s", s).replace("&&-c", match[1] ?? "*")
48
+ };
49
+ }
50
+ };
51
+ };
40
52
  const variantCombinators = [
41
- variants$1.variantMatcher("all", (input) => `${input} *`),
42
- variants$1.variantMatcher("children", (input) => `${input}>*`),
43
- variants$1.variantMatcher("next", (input) => `${input}+*`),
44
- variants$1.variantMatcher("sibling", (input) => `${input}+*`),
45
- variants$1.variantMatcher("siblings", (input) => `${input}~*`),
53
+ scopeMatcher(false, "all", "&&-s &&-c"),
54
+ scopeMatcher(false, "children", "&&-s>&&-c"),
55
+ scopeMatcher(false, "next", "&&-s+&&-c"),
56
+ scopeMatcher(false, "sibling", "&&-s+&&-c"),
57
+ scopeMatcher(false, "siblings", "&&-s~&&-c"),
58
+ scopeMatcher(true, "group", "&&-c &&-s"),
59
+ scopeMatcher(true, "parent", "&&-c>&&-s"),
60
+ scopeMatcher(true, "previous", "&&-c+&&-s"),
61
+ scopeMatcher(true, "peer", "&&-c~&&-s"),
46
62
  variants$1.variantMatcher("svg", (input) => `${input} svg`)
47
63
  ];
48
64
 
@@ -181,6 +197,10 @@ const PartClassesRE = /(part-\[(.+)]:)(.+)/;
181
197
  const PseudoElementsRE = new RegExp(`^(${PseudoElementsStr})[:-]`);
182
198
  const PseudoClassesRE = new RegExp(`^(${PseudoClassesStr})[:-]`);
183
199
  const PseudoClassFunctionsRE = new RegExp(`^(${PseudoClassFunctionsStr})-(${PseudoClassesStr})[:-]`);
200
+ const sortValue = (pseudo) => {
201
+ if (pseudo === "active")
202
+ return 1;
203
+ };
184
204
  const taggedPseudoClassMatcher = (tag, parent, combinator) => {
185
205
  const re = new RegExp(`^${tag}-((?:(${PseudoClassFunctionsStr})-)?(${PseudoClassesStr}))[:-]`);
186
206
  const rawRe = new RegExp(`^${core.escapeRegExp(parent)}:`);
@@ -191,8 +211,9 @@ const taggedPseudoClassMatcher = (tag, parent, combinator) => {
191
211
  if (match[2])
192
212
  pseudo = `:${match[2]}(${pseudo})`;
193
213
  return {
194
- matcher: input.slice(match[1].length + tag.length + 2),
195
- selector: (s) => rawRe.test(s) ? s.replace(rawRe, `${parent}${pseudo}:`) : `${parent}${pseudo}${combinator}${s}`
214
+ matcher: input.slice(match[0].length),
215
+ selector: (s) => rawRe.test(s) ? s.replace(rawRe, `${parent}${pseudo}:`) : `${parent}${pseudo}${combinator}${s}`,
216
+ sort: sortValue(match[3])
196
217
  };
197
218
  }
198
219
  };
@@ -202,7 +223,7 @@ const variantPseudoElements = (input) => {
202
223
  if (match) {
203
224
  const pseudo = PseudoElements[match[1]] || `::${match[1]}`;
204
225
  return {
205
- matcher: input.slice(match[1].length + 1),
226
+ matcher: input.slice(match[0].length),
206
227
  selector: (s) => `${s}${pseudo}`
207
228
  };
208
229
  }
@@ -213,8 +234,9 @@ const variantPseudoClasses = {
213
234
  if (match) {
214
235
  const pseudo = PseudoClasses[match[1]] || `:${match[1]}`;
215
236
  return {
216
- matcher: input.slice(match[1].length + 1),
217
- selector: (s) => `${s}${pseudo}`
237
+ matcher: input.slice(match[0].length),
238
+ selector: (s) => `${s}${pseudo}`,
239
+ sort: sortValue(match[1])
218
240
  };
219
241
  }
220
242
  },
@@ -227,7 +249,7 @@ const variantPseudoClassFunctions = {
227
249
  const fn = match[1];
228
250
  const pseudo = PseudoClasses[match[2]] || `:${match[2]}`;
229
251
  return {
230
- matcher: input.slice(match[1].length + match[2].length + 2),
252
+ matcher: input.slice(match[0].length),
231
253
  selector: (s) => `${s}:${fn}(${pseudo})`
232
254
  };
233
255
  }
@@ -248,6 +270,10 @@ const variantTaggedPseudoClasses = (options = {}) => {
248
270
  {
249
271
  match: taggedPseudoClassMatcher("parent", attributify ? '[parent=""]' : ".parent", ">"),
250
272
  multiPass: true
273
+ },
274
+ {
275
+ match: taggedPseudoClassMatcher("previous", attributify ? '[previous=""]' : ".previous", "+"),
276
+ multiPass: true
251
277
  }
252
278
  ];
253
279
  };
@@ -35,12 +35,28 @@ const variantBreakpoints = (matcher, { theme }) => {
35
35
  }
36
36
  };
37
37
 
38
+ const scopeMatcher = (strict, name, template) => {
39
+ const re = strict ? new RegExp(`^${name}(?:-\\[(.+?)\\])[:-]`) : new RegExp(`^${name}(?:-\\[(.+?)\\])?[:-]`);
40
+ return (matcher) => {
41
+ const match = matcher.match(re);
42
+ if (match) {
43
+ return {
44
+ matcher: matcher.slice(match[0].length),
45
+ selector: (s) => template.replace("&&-s", s).replace("&&-c", match[1] ?? "*")
46
+ };
47
+ }
48
+ };
49
+ };
38
50
  const variantCombinators = [
39
- variantMatcher("all", (input) => `${input} *`),
40
- variantMatcher("children", (input) => `${input}>*`),
41
- variantMatcher("next", (input) => `${input}+*`),
42
- variantMatcher("sibling", (input) => `${input}+*`),
43
- variantMatcher("siblings", (input) => `${input}~*`),
51
+ scopeMatcher(false, "all", "&&-s &&-c"),
52
+ scopeMatcher(false, "children", "&&-s>&&-c"),
53
+ scopeMatcher(false, "next", "&&-s+&&-c"),
54
+ scopeMatcher(false, "sibling", "&&-s+&&-c"),
55
+ scopeMatcher(false, "siblings", "&&-s~&&-c"),
56
+ scopeMatcher(true, "group", "&&-c &&-s"),
57
+ scopeMatcher(true, "parent", "&&-c>&&-s"),
58
+ scopeMatcher(true, "previous", "&&-c+&&-s"),
59
+ scopeMatcher(true, "peer", "&&-c~&&-s"),
44
60
  variantMatcher("svg", (input) => `${input} svg`)
45
61
  ];
46
62
 
@@ -179,6 +195,10 @@ const PartClassesRE = /(part-\[(.+)]:)(.+)/;
179
195
  const PseudoElementsRE = new RegExp(`^(${PseudoElementsStr})[:-]`);
180
196
  const PseudoClassesRE = new RegExp(`^(${PseudoClassesStr})[:-]`);
181
197
  const PseudoClassFunctionsRE = new RegExp(`^(${PseudoClassFunctionsStr})-(${PseudoClassesStr})[:-]`);
198
+ const sortValue = (pseudo) => {
199
+ if (pseudo === "active")
200
+ return 1;
201
+ };
182
202
  const taggedPseudoClassMatcher = (tag, parent, combinator) => {
183
203
  const re = new RegExp(`^${tag}-((?:(${PseudoClassFunctionsStr})-)?(${PseudoClassesStr}))[:-]`);
184
204
  const rawRe = new RegExp(`^${escapeRegExp(parent)}:`);
@@ -189,8 +209,9 @@ const taggedPseudoClassMatcher = (tag, parent, combinator) => {
189
209
  if (match[2])
190
210
  pseudo = `:${match[2]}(${pseudo})`;
191
211
  return {
192
- matcher: input.slice(match[1].length + tag.length + 2),
193
- selector: (s) => rawRe.test(s) ? s.replace(rawRe, `${parent}${pseudo}:`) : `${parent}${pseudo}${combinator}${s}`
212
+ matcher: input.slice(match[0].length),
213
+ selector: (s) => rawRe.test(s) ? s.replace(rawRe, `${parent}${pseudo}:`) : `${parent}${pseudo}${combinator}${s}`,
214
+ sort: sortValue(match[3])
194
215
  };
195
216
  }
196
217
  };
@@ -200,7 +221,7 @@ const variantPseudoElements = (input) => {
200
221
  if (match) {
201
222
  const pseudo = PseudoElements[match[1]] || `::${match[1]}`;
202
223
  return {
203
- matcher: input.slice(match[1].length + 1),
224
+ matcher: input.slice(match[0].length),
204
225
  selector: (s) => `${s}${pseudo}`
205
226
  };
206
227
  }
@@ -211,8 +232,9 @@ const variantPseudoClasses = {
211
232
  if (match) {
212
233
  const pseudo = PseudoClasses[match[1]] || `:${match[1]}`;
213
234
  return {
214
- matcher: input.slice(match[1].length + 1),
215
- selector: (s) => `${s}${pseudo}`
235
+ matcher: input.slice(match[0].length),
236
+ selector: (s) => `${s}${pseudo}`,
237
+ sort: sortValue(match[1])
216
238
  };
217
239
  }
218
240
  },
@@ -225,7 +247,7 @@ const variantPseudoClassFunctions = {
225
247
  const fn = match[1];
226
248
  const pseudo = PseudoClasses[match[2]] || `:${match[2]}`;
227
249
  return {
228
- matcher: input.slice(match[1].length + match[2].length + 2),
250
+ matcher: input.slice(match[0].length),
229
251
  selector: (s) => `${s}:${fn}(${pseudo})`
230
252
  };
231
253
  }
@@ -246,6 +268,10 @@ const variantTaggedPseudoClasses = (options = {}) => {
246
268
  {
247
269
  match: taggedPseudoClassMatcher("parent", attributify ? '[parent=""]' : ".parent", ">"),
248
270
  multiPass: true
271
+ },
272
+ {
273
+ match: taggedPseudoClassMatcher("previous", attributify ? '[previous=""]' : ".previous", "+"),
274
+ multiPass: true
249
275
  }
250
276
  ];
251
277
  };
@@ -2,6 +2,7 @@
2
2
 
3
3
  const core = require('@unocss/core');
4
4
 
5
+ const cssColorFunctions = ["hsl", "hsla", "hwb", "lab", "lch", "oklab", "oklch", "rgb", "rgba"];
5
6
  function hex2rgba(hex = "") {
6
7
  const color = parseHexColor(hex);
7
8
  if (color != null) {
@@ -11,41 +12,32 @@ function hex2rgba(hex = "") {
11
12
  return [...components, alpha];
12
13
  }
13
14
  }
14
- function parseHexColor(str) {
15
- const [, body] = str.match(/^#?([\da-f]+)$/i) || [];
16
- if (!body)
17
- return;
18
- switch (body.length) {
19
- case 3:
20
- case 4:
21
- const digits = Array.from(body, (s) => Number.parseInt(s, 16)).map((n) => n << 4 | n);
22
- return {
23
- type: "rgb",
24
- components: digits.slice(0, 3),
25
- alpha: body.length === 3 ? void 0 : Math.round(digits[3] / 255 * 100) / 100
26
- };
27
- case 6:
28
- case 8:
29
- const value = Number.parseInt(body, 16);
30
- return {
31
- type: "rgb",
32
- components: body.length === 6 ? [value >> 16 & 255, value >> 8 & 255, value & 255] : [value >> 24 & 255, value >> 16 & 255, value >> 8 & 255],
33
- alpha: body.length === 6 ? void 0 : Math.round((value & 255) / 255 * 100) / 100
34
- };
35
- }
36
- }
37
15
  function parseCssColor(str = "") {
38
16
  const color = parseColor$1(str);
39
17
  if (color == null)
40
18
  return;
41
19
  const { type: casedType, components, alpha } = color;
42
20
  const type = casedType.toLowerCase();
21
+ if (components.length === 0)
22
+ return;
43
23
  if (["rgba", "hsla"].includes(type) && alpha === void 0)
44
24
  return;
45
- if (["rgb", "hsl", "hwb", "lab", "lch", "oklab", "oklch"].includes(type) && components.length !== 3)
25
+ if (cssColorFunctions.includes(type) && components.length !== 3)
46
26
  return;
47
27
  return { type, components, alpha };
48
28
  }
29
+ function colorToString(color, alphaOverride) {
30
+ const { components } = color;
31
+ let { alpha, type } = color;
32
+ alpha = alphaOverride ?? alpha;
33
+ type = type.toLowerCase();
34
+ if (["hsla", "hsl", "rgba", "rgb"].includes(type))
35
+ return `${type.replace("a", "")}a(${components.join(",")}${alpha == null ? "" : `,${alpha}`})`;
36
+ alpha = alpha == null ? "" : ` / ${alpha}`;
37
+ if (cssColorFunctions.includes(type))
38
+ return `${type}(${components.join(" ")}${alpha})`;
39
+ return `color(${type} ${components.join(" ")}${alpha})`;
40
+ }
49
41
  function parseColor$1(str) {
50
42
  if (!str)
51
43
  return;
@@ -65,10 +57,32 @@ function parseColor$1(str) {
65
57
  if (color != null)
66
58
  return color;
67
59
  }
60
+ function parseHexColor(str) {
61
+ const [, body] = str.match(/^#?([\da-f]+)$/i) || [];
62
+ if (!body)
63
+ return;
64
+ switch (body.length) {
65
+ case 3:
66
+ case 4:
67
+ const digits = Array.from(body, (s) => Number.parseInt(s, 16)).map((n) => n << 4 | n);
68
+ return {
69
+ type: "rgb",
70
+ components: digits.slice(0, 3),
71
+ alpha: body.length === 3 ? void 0 : Math.round(digits[3] / 255 * 100) / 100
72
+ };
73
+ case 6:
74
+ case 8:
75
+ const value = Number.parseInt(body, 16);
76
+ return {
77
+ type: "rgb",
78
+ components: body.length === 6 ? [value >> 16 & 255, value >> 8 & 255, value & 255] : [value >> 24 & 255, value >> 16 & 255, value >> 8 & 255],
79
+ alpha: body.length === 6 ? void 0 : Math.round((value & 255) / 255 * 100) / 100
80
+ };
81
+ }
82
+ }
68
83
  function cssColorKeyword(str) {
69
84
  const color = {
70
- rebeccapurple: [102, 51, 153, 1],
71
- transparent: [0, 0, 0, 0]
85
+ rebeccapurple: [102, 51, 153, 1]
72
86
  }[str];
73
87
  if (color != null) {
74
88
  return {
@@ -78,54 +92,13 @@ function cssColorKeyword(str) {
78
92
  };
79
93
  }
80
94
  }
81
- function getComponent(separator, str) {
82
- const component = str.trim();
83
- if (component === "")
84
- return;
85
- const l = str.length;
86
- let parenthesis = 0;
87
- for (let i = 0; i < l; i++) {
88
- switch (str[i]) {
89
- case "(":
90
- parenthesis++;
91
- break;
92
- case ")":
93
- if (--parenthesis < 0)
94
- return;
95
- break;
96
- case separator:
97
- if (parenthesis === 0) {
98
- const component2 = str.slice(0, i).trim();
99
- if (component2 === "")
100
- return;
101
- return [
102
- str.slice(0, i).trim(),
103
- str.slice(i + 1).trim()
104
- ];
105
- }
106
- }
107
- }
108
- return [
109
- str.trim(),
110
- ""
111
- ];
112
- }
113
95
  function parseCssCommaColorFunction(color) {
114
96
  const match = color.match(/^(rgb|rgba|hsl|hsla)\((.+)\)$/i);
115
97
  if (!match)
116
98
  return;
117
99
  const [, type, componentString] = match;
118
- const components = [];
119
- let cs = componentString;
120
- for (let c = 5; c > 0 && cs !== ""; --c) {
121
- const componentValue = getComponent(",", cs);
122
- if (!componentValue)
123
- return;
124
- const [component, rest] = componentValue;
125
- components.push(component);
126
- cs = rest;
127
- }
128
- if ([3, 4].includes(components.length)) {
100
+ const components = getComponents(componentString, ",", 5);
101
+ if (components && [3, 4].includes(components.length)) {
129
102
  return {
130
103
  type,
131
104
  components: components.slice(0, 3),
@@ -133,8 +106,9 @@ function parseCssCommaColorFunction(color) {
133
106
  };
134
107
  }
135
108
  }
109
+ const cssColorFunctionsRe = new RegExp(`^(${cssColorFunctions.join("|")})\\((.+)\\)$`, "i");
136
110
  function parseCssSpaceColorFunction(color) {
137
- const match = color.match(/^(rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch)\((.+)\)$/i);
111
+ const match = color.match(cssColorFunctionsRe);
138
112
  if (!match)
139
113
  return;
140
114
  const [, fn, componentString] = match;
@@ -163,16 +137,9 @@ function parseCssColorFunction(color) {
163
137
  }
164
138
  }
165
139
  function parseCssSpaceColorValues(componentString) {
166
- let cs = componentString;
167
- const components = [];
168
- while (cs !== "") {
169
- const cc = getComponent(" ", cs);
170
- if (!cc)
171
- return;
172
- const [component, rest] = cc;
173
- components.push(component);
174
- cs = rest;
175
- }
140
+ const components = getComponents(componentString);
141
+ if (!components)
142
+ return;
176
143
  let totalComponents = components.length;
177
144
  if (components[totalComponents - 2] === "/") {
178
145
  return {
@@ -180,21 +147,14 @@ function parseCssSpaceColorValues(componentString) {
180
147
  alpha: components[totalComponents - 1]
181
148
  };
182
149
  }
183
- if (components[totalComponents - 2].endsWith("/") || components[totalComponents - 1].startsWith("/")) {
150
+ if (components[totalComponents - 2] != null && (components[totalComponents - 2].endsWith("/") || components[totalComponents - 1].startsWith("/"))) {
184
151
  const removed = components.splice(totalComponents - 2);
185
152
  components.push(removed.join(" "));
186
153
  --totalComponents;
187
154
  }
188
- cs = components[totalComponents - 1];
189
- const withAlpha = [];
190
- while (cs !== "") {
191
- const cc = getComponent("/", cs);
192
- if (!cc)
193
- return;
194
- const [component, rest] = cc;
195
- withAlpha.push(component);
196
- cs = rest;
197
- }
155
+ const withAlpha = getComponents(components[totalComponents - 1], "/", 3);
156
+ if (!withAlpha)
157
+ return;
198
158
  if (withAlpha.length === 1 || withAlpha[withAlpha.length - 1] === "")
199
159
  return { components };
200
160
  const alpha = withAlpha.pop();
@@ -204,6 +164,58 @@ function parseCssSpaceColorValues(componentString) {
204
164
  alpha
205
165
  };
206
166
  }
167
+ function getComponent(str, separator) {
168
+ str = str.trim();
169
+ if (str === "")
170
+ return;
171
+ const l = str.length;
172
+ let parenthesis = 0;
173
+ for (let i = 0; i < l; i++) {
174
+ switch (str[i]) {
175
+ case "(":
176
+ parenthesis++;
177
+ break;
178
+ case ")":
179
+ if (--parenthesis < 0)
180
+ return;
181
+ break;
182
+ case separator:
183
+ if (parenthesis === 0) {
184
+ const component = str.slice(0, i).trim();
185
+ if (component === "")
186
+ return;
187
+ return [
188
+ component,
189
+ str.slice(i + 1).trim()
190
+ ];
191
+ }
192
+ }
193
+ }
194
+ return [
195
+ str,
196
+ ""
197
+ ];
198
+ }
199
+ function getComponents(str, separator, limit) {
200
+ separator = separator ?? " ";
201
+ if (separator.length !== 1)
202
+ return;
203
+ limit = limit ?? 10;
204
+ const components = [];
205
+ let i = 0;
206
+ while (str !== "") {
207
+ if (++i > limit)
208
+ return;
209
+ const componentPair = getComponent(str, separator);
210
+ if (!componentPair)
211
+ return;
212
+ const [component, rest] = componentPair;
213
+ components.push(component);
214
+ str = rest;
215
+ }
216
+ if (components.length > 0)
217
+ return components;
218
+ }
207
219
 
208
220
  const directionMap = {
209
221
  "l": ["-left"],
@@ -509,54 +521,59 @@ const parseColor = (body, theme) => {
509
521
  else if (no && colorData)
510
522
  color = colorData[no];
511
523
  }
512
- const rgba = hex2rgba(color);
513
- const alpha = opacity ? opacity[0] === "[" ? handler.bracket.percent(opacity) : parseFloat(opacity) / 100 : rgba?.[3];
514
- const hasAlpha = alpha != null && !Number.isNaN(alpha);
515
- if (rgba) {
516
- if (hasAlpha) {
517
- rgba[3] = typeof alpha === "string" && !alpha.includes("%") ? parseFloat(alpha) : alpha;
518
- } else {
519
- rgba.splice(3);
520
- }
521
- }
522
524
  return {
523
525
  opacity,
524
526
  name,
525
527
  no,
526
528
  color,
527
- rgba,
528
- alpha: hasAlpha ? alpha : void 0
529
+ cssColor: parseCssColor(color),
530
+ alpha: handler.bracket.cssvar.percent(opacity ?? "")
529
531
  };
530
532
  };
531
533
  const colorResolver = (property, varName) => ([, body], { theme }) => {
532
534
  const data = parseColor(body, theme);
533
535
  if (!data)
534
536
  return;
535
- const { alpha, opacity, color, rgba } = data;
536
- if (!color)
537
- return;
538
- if (rgba) {
537
+ const { alpha, color, cssColor } = data;
538
+ if (cssColor) {
539
539
  if (alpha != null) {
540
540
  return {
541
- [property]: `rgba(${rgba.join(",")})`
541
+ [property]: colorToString(cssColor, alpha)
542
542
  };
543
543
  } else {
544
544
  return {
545
- [`--un-${varName}-opacity`]: (opacity && handler.cssvar(opacity)) ?? 1,
546
- [property]: `rgba(${rgba.join(",")},var(--un-${varName}-opacity))`
545
+ [`--un-${varName}-opacity`]: cssColor.alpha ?? 1,
546
+ [property]: colorToString(cssColor, `var(--un-${varName}-opacity)`)
547
547
  };
548
548
  }
549
- } else {
549
+ } else if (color) {
550
550
  return {
551
- [property]: color.replace("%alpha", `${alpha || 1}`)
551
+ [property]: color.replace("%alpha", `${alpha ?? 1}`)
552
552
  };
553
553
  }
554
554
  };
555
+ const colorableShadows = (shadows, colorVar) => {
556
+ const colored = [];
557
+ shadows = core.toArray(shadows);
558
+ for (let i = 0; i < shadows.length; i++) {
559
+ const components = getComponents(shadows[i], " ", 6);
560
+ if (!components || components.length < 3)
561
+ return shadows;
562
+ const color = parseCssColor(components.pop());
563
+ if (color == null)
564
+ return shadows;
565
+ colored.push(`${components.join(" ")} var(${colorVar}, ${colorToString(color)})`);
566
+ }
567
+ return colored;
568
+ };
555
569
 
556
570
  exports.colorResolver = colorResolver;
571
+ exports.colorToString = colorToString;
572
+ exports.colorableShadows = colorableShadows;
557
573
  exports.cornerMap = cornerMap;
558
574
  exports.directionMap = directionMap;
559
575
  exports.directionSize = directionSize;
576
+ exports.getComponents = getComponents;
560
577
  exports.h = h;
561
578
  exports.handler = handler;
562
579
  exports.hex2rgba = hex2rgba;