@unocss/core 0.21.0 → 0.22.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/index.cjs CHANGED
@@ -93,6 +93,32 @@ function mergeDeep(original, patch) {
93
93
  }
94
94
  return output;
95
95
  }
96
+ function clone(val) {
97
+ let k, out, tmp;
98
+ if (Array.isArray(val)) {
99
+ out = Array(k = val.length);
100
+ while (k--)
101
+ out[k] = (tmp = val[k]) && typeof tmp === "object" ? clone(tmp) : tmp;
102
+ return out;
103
+ }
104
+ if (Object.prototype.toString.call(val) === "[object Object]") {
105
+ out = {};
106
+ for (k in val) {
107
+ if (k === "__proto__") {
108
+ Object.defineProperty(out, k, {
109
+ value: clone(val[k]),
110
+ configurable: true,
111
+ enumerable: true,
112
+ writable: true
113
+ });
114
+ } else {
115
+ out[k] = (tmp = val[k]) && typeof tmp === "object" ? clone(tmp) : tmp;
116
+ }
117
+ }
118
+ return out;
119
+ }
120
+ return val;
121
+ }
96
122
  function isStaticRule(rule) {
97
123
  return typeof rule[0] === "string";
98
124
  }
@@ -135,6 +161,7 @@ function hex2rgba(hex = "") {
135
161
 
136
162
  const attributifyRE = /^\[(.+?)~?="(.*)"\]$/;
137
163
  const validateFilterRE = /(?!\d|-{2}|-\d)[a-zA-Z0-9\u00A0-\uFFFF-_:%-?]/;
164
+ const CONTROL_SHORTCUT_NO_MERGE = "$$shortcut-no-merge";
138
165
  function isAttributifySelector(selector) {
139
166
  return selector.match(attributifyRE);
140
167
  }
@@ -332,10 +359,11 @@ function resolveConfig(userConfig = {}, defaults = {}) {
332
359
  delete rules[i];
333
360
  }
334
361
  });
335
- const theme = [
362
+ const theme = clone([
336
363
  ...sortedPresets.map((p) => p.theme || {}),
337
364
  config.theme || {}
338
- ].reduce((a, p) => mergeDeep(a, p), {});
365
+ ].reduce((a, p) => mergeDeep(a, p), {}));
366
+ mergePresets("extendTheme").forEach((extendTheme) => extendTheme(theme));
339
367
  return {
340
368
  mergeSelectors: true,
341
369
  warn: true,
@@ -360,7 +388,7 @@ function resolveConfig(userConfig = {}, defaults = {}) {
360
388
  };
361
389
  }
362
390
 
363
- const version = "0.21.0";
391
+ const version = "0.22.1";
364
392
 
365
393
  class UnoGenerator {
366
394
  constructor(userConfig = {}, defaults = {}) {
@@ -472,33 +500,38 @@ class UnoGenerator {
472
500
  }
473
501
  const layerCache = {};
474
502
  const layers = this.config.sortLayers(Array.from(layerSet).sort((a, b) => (this.config.layers[a] ?? 0) - (this.config.layers[b] ?? 0) || a.localeCompare(b)));
503
+ let preflightsMap = {};
504
+ if (preflights) {
505
+ preflightsMap = Object.fromEntries(await Promise.all(layers.map(async (layer) => {
506
+ const preflights2 = await Promise.all(this.config.preflights.filter((i) => (i.layer || "default") === layer).map(async (i) => await i.getCSS()));
507
+ const css = preflights2.filter(Boolean).join(nl);
508
+ return [layer, css];
509
+ })));
510
+ }
475
511
  const getLayer = (layer) => {
476
512
  if (layerCache[layer])
477
513
  return layerCache[layer];
478
514
  let css = Array.from(sheet).sort((a, b) => (this.parentOrders.get(a[0]) ?? 0) - (this.parentOrders.get(b[0]) ?? 0) || a[0]?.localeCompare(b[0] || "") || 0).map(([parent, items]) => {
479
515
  const size = items.length;
480
- const sorted = items.filter((i) => (i[4]?.layer || "default") === layer).sort((a, b) => a[0] - b[0] || a[1]?.localeCompare(b[1] || "") || 0).map((a) => [a[1] ? applyScope(a[1], scope) : a[1], a[2]]);
516
+ const sorted = items.filter((i) => (i[4]?.layer || "default") === layer).sort((a, b) => a[0] - b[0] || a[1]?.localeCompare(b[1] || "") || 0).map((a) => [a[1] ? applyScope(a[1], scope) : a[1], a[2], !!a[4]?.noMerge]).map((a) => [a[0] == null ? a[0] : [a[0]], a[1], a[2]]);
481
517
  if (!sorted.length)
482
518
  return void 0;
483
- const rules = sorted.reverse().map(([selector, body], idx) => {
519
+ const rules = sorted.reverse().map(([selector, body, noMerge], idx) => {
484
520
  if (selector && this.config.mergeSelectors) {
485
521
  for (let i = idx + 1; i < size; i++) {
486
522
  const current = sorted[i];
487
- if (current && current[0] && current[1] === body) {
488
- current[0] = `${current[0]},${nl}${selector}`;
523
+ if (!noMerge && current && current[0] && current[1] === body) {
524
+ current[0].push(...selector);
489
525
  return null;
490
526
  }
491
527
  }
492
528
  }
493
- return selector ? `${selector}{${body}}` : body;
529
+ return selector ? `${[...new Set(selector)].join(`,${nl}`)}{${body}}` : body;
494
530
  }).filter(Boolean).reverse().join(nl);
495
531
  return parent ? `${parent}{${nl}${rules}${nl}}` : rules;
496
532
  }).filter(Boolean).join(nl);
497
533
  if (preflights) {
498
- css = [
499
- ...this.config.preflights.filter((i) => (i.layer || "default") === layer).map((i) => i.getCSS()).filter(Boolean),
500
- css
501
- ].join(nl);
534
+ css = [preflightsMap[layer], css].filter(Boolean).join(nl);
502
535
  }
503
536
  return layerCache[layer] = !minify && css ? `/* layer: ${layer} */${nl}${css}` : css;
504
537
  };
@@ -657,16 +690,18 @@ class UnoGenerator {
657
690
  continue;
658
691
  const { selector, entries, parent: parent2 } = this.applyVariants(item, [...item[4], ...parentVariants], raw);
659
692
  const mapItem = selectorMap.getFallback(selector, parent2, [[], item[0]]);
660
- mapItem[0].push(...entries);
661
- if (item[0] > mapItem[1])
662
- mapItem[1] = item[0];
693
+ mapItem[0].push(entries);
663
694
  }
664
- return selectorMap.map(([entries, index], selector, mediaQuery) => {
665
- const body = entriesToCss(entries);
666
- if (body)
667
- return [index, selector, body, mediaQuery, meta];
668
- return void 0;
669
- }).filter(Boolean);
695
+ return selectorMap.map(([e2, index], selector, mediaQuery) => {
696
+ const split = e2.filter((entries) => entries.some((entry) => entry[0] === CONTROL_SHORTCUT_NO_MERGE));
697
+ const rest = e2.filter((entries) => entries.every((entry) => entry[0] !== CONTROL_SHORTCUT_NO_MERGE));
698
+ return [...split, rest.flat(1)].map((entries) => {
699
+ const body = entriesToCss(entries);
700
+ if (body)
701
+ return [index, selector, body, mediaQuery, meta];
702
+ return void 0;
703
+ });
704
+ }).flat(1).filter(Boolean);
670
705
  }
671
706
  isBlocked(raw) {
672
707
  return !raw || this.config.blocklist.some((e2) => typeof e2 === "string" ? e2 === raw : e2.test(raw));
@@ -683,18 +718,20 @@ function applyScope(css, scope) {
683
718
  else
684
719
  return scope ? `${scope} ${css}` : css;
685
720
  }
721
+ const attributifyRe = /^\[(.+?)(~?=)"(.*)"\]$/;
686
722
  function toEscapedSelector(raw) {
687
- if (raw.startsWith("["))
688
- return raw.replace(/^\[(.+?)(~?=)"(.*)"\]$/, (_, n, s, i) => `[${e(n)}${s}"${e(i)}"]`);
689
- else
690
- return `.${e(raw)}`;
723
+ if (raw.startsWith("[") && attributifyRe.test(raw))
724
+ return raw.replace(attributifyRe, (_, n, s, i) => `[${e(n)}${s}"${e(i)}"]`);
725
+ return `.${e(raw)}`;
691
726
  }
692
727
 
693
728
  exports.BetterMap = BetterMap;
729
+ exports.CONTROL_SHORTCUT_NO_MERGE = CONTROL_SHORTCUT_NO_MERGE;
694
730
  exports.TwoKeyMap = TwoKeyMap;
695
731
  exports.UnoGenerator = UnoGenerator;
696
732
  exports.attributifyRE = attributifyRE;
697
733
  exports.clearIdenticalEntries = clearIdenticalEntries;
734
+ exports.clone = clone;
698
735
  exports.createGenerator = createGenerator;
699
736
  exports.createValueHandler = createValueHandler;
700
737
  exports.e = e;
package/dist/index.d.ts CHANGED
@@ -23,6 +23,7 @@ declare function createGenerator(config?: UserConfig, defaults?: UserConfigDefau
23
23
  declare const hasScopePlaceholder: (css: string) => RegExpMatchArray | null;
24
24
 
25
25
  declare type Awaitable<T> = T | Promise<T>;
26
+ declare type Arrayable<T> = T | T[];
26
27
  declare type ArgumentType<T> = T extends ((...args: infer A) => any) ? A : never;
27
28
  declare type Shift<T> = T extends [_: any, ...args: infer A] ? A : never;
28
29
  declare type RestArgs<T> = Shift<ArgumentType<T>>;
@@ -37,7 +38,7 @@ declare type RequiredByKey<T, K extends keyof T = keyof T> = FlatObjectTuple<Req
37
38
  declare type CSSObject = Record<string, string | number | undefined>;
38
39
  declare type CSSEntries = [string, string | number | undefined][];
39
40
  declare type RGBAColorValue = [number, number, number, number] | [number, number, number];
40
- declare type ParsedColorValue = {
41
+ interface ParsedColorValue {
41
42
  /**
42
43
  * Parsed color value.
43
44
  */
@@ -62,7 +63,7 @@ declare type ParsedColorValue = {
62
63
  * Parsed rgba's alpha value.
63
64
  */
64
65
  alpha?: number | string;
65
- };
66
+ }
66
67
  declare type PresetOptions = Record<string, any>;
67
68
  interface RuleContext<Theme extends {} = {}> {
68
69
  /**
@@ -122,6 +123,11 @@ interface RuleMeta {
122
123
  * @default 'default'
123
124
  */
124
125
  layer?: string;
126
+ /**
127
+ * Option to not merge this selector even if the body are the same.
128
+ * @default false
129
+ */
130
+ noMerge?: boolean;
125
131
  /**
126
132
  * Internal rules will only be matched for shortcuts but not the user code.
127
133
  * @default false
@@ -141,7 +147,7 @@ declare type UserShortcuts<Theme extends {} = {}> = StaticShortcutMap | (StaticS
141
147
  declare type Shortcut<Theme extends {} = {}> = StaticShortcut | DynamicShortcut<Theme>;
142
148
  declare type FilterPattern = ReadonlyArray<string | RegExp> | string | RegExp | null;
143
149
  interface Preflight {
144
- getCSS: () => string | undefined;
150
+ getCSS: () => Promise<string | undefined> | string | undefined;
145
151
  layer?: string;
146
152
  }
147
153
  declare type BlocklistRule = string | RegExp;
@@ -168,7 +174,7 @@ interface VariantHandler {
168
174
  order?: number;
169
175
  }
170
176
  declare type VariantFunction<Theme extends {} = {}> = (matcher: string, context: Readonly<VariantContext<Theme>>) => string | VariantHandler | undefined;
171
- declare type VariantObject<Theme extends {} = {}> = {
177
+ interface VariantObject<Theme extends {} = {}> {
172
178
  /**
173
179
  * The entry function to match and rewrite the selector for futher processing.
174
180
  */
@@ -179,10 +185,11 @@ declare type VariantObject<Theme extends {} = {}> = {
179
185
  * @default false
180
186
  */
181
187
  multiPass?: boolean;
182
- };
188
+ }
183
189
  declare type Variant<Theme extends {} = {}> = VariantFunction<Theme> | VariantObject<Theme>;
184
190
  declare type Preprocessor = (matcher: string) => string | undefined;
185
191
  declare type Postprocessor = (util: UtilObject) => void;
192
+ declare type ThemeExtender<T> = (theme: T) => void;
186
193
  interface ConfigBase<Theme extends {} = {}> {
187
194
  /**
188
195
  * Rules to generate CSS utilities
@@ -231,11 +238,15 @@ interface ConfigBase<Theme extends {} = {}> {
231
238
  /**
232
239
  * Preprocess the incoming utilities, return falsy value to exclude
233
240
  */
234
- preprocess?: Preprocessor | Preprocessor[];
241
+ preprocess?: Arrayable<Preprocessor>;
235
242
  /**
236
243
  * Process the generate utils object
237
244
  */
238
- postprocess?: Postprocessor | Postprocessor[];
245
+ postprocess?: Arrayable<Postprocessor>;
246
+ /**
247
+ * Custom functions to extend the theme object
248
+ */
249
+ extendTheme?: Arrayable<ThemeExtender<Theme>>;
239
250
  }
240
251
  interface Preset<Theme extends {} = {}> extends ConfigBase<Theme> {
241
252
  name: string;
@@ -392,6 +403,7 @@ declare function clearIdenticalEntries(entry: CSSEntries): CSSEntries;
392
403
  declare function entriesToCss(arr?: CSSEntries): string;
393
404
  declare function isObject(item: any): item is Record<string, any>;
394
405
  declare function mergeDeep<T>(original: T, patch: DeepPartial<T>): T;
406
+ declare function clone<T>(val: T): T;
395
407
  declare function isStaticRule(rule: Rule): rule is StaticRule;
396
408
  declare function isStaticShortcut(sc: Shortcut): sc is StaticShortcut;
397
409
 
@@ -403,6 +415,7 @@ declare function hex2rgba(hex?: string): RGBAColorValue | undefined;
403
415
 
404
416
  declare const attributifyRE: RegExp;
405
417
  declare const validateFilterRE: RegExp;
418
+ declare const CONTROL_SHORTCUT_NO_MERGE = "$$shortcut-no-merge";
406
419
  declare function isAttributifySelector(selector: string): RegExpMatchArray | null;
407
420
  declare function isValidSelector(selector?: string): selector is string;
408
421
  declare function normalizeVariant(variant: Variant): VariantObject;
@@ -445,4 +458,4 @@ declare const extractorSplit: Extractor;
445
458
 
446
459
  declare const extractorSvelte: Extractor;
447
460
 
448
- export { ArgumentType, Awaitable, BetterMap, BlocklistRule, CSSEntries, CSSObject, CSSValues, ConfigBase, DeepPartial, DynamicMatcher, DynamicRule, DynamicShortcut, DynamicShortcutMatcher, Extractor, ExtractorContext, FilterPattern, FlatObjectTuple, GenerateOptions, GenerateResult, GeneratorOptions, ParsedColorValue, ParsedUtil, PartialByKeys, PluginOptions, Postprocessor, Preflight, Preprocessor, Preset, PresetOptions, RGBAColorValue, RawUtil, RequiredByKey, ResolvedConfig, RestArgs, Rule, RuleContext, RuleMeta, Shift, Shortcut, StaticRule, StaticShortcut, StaticShortcutMap, StringifiedUtil, TwoKeyMap, UnoGenerator, UserConfig, UserConfigDefaults, UserOnlyOptions, UserShortcuts, UtilObject, ValueHandler, ValueHandlerCallback, Variant, VariantContext, VariantFunction, VariantHandler, VariantMatchedResult, VariantObject, attributifyRE, clearIdenticalEntries, createGenerator, createValueHandler, e, entriesToCss, escapeRegExp, escapeSelector, expandVariantGroup, extractorSplit, extractorSvelte, hasScopePlaceholder, hex2rgba, isAttributifySelector, isObject, isRawUtil, isStaticRule, isStaticShortcut, isValidSelector, mergeDeep, mergeSet, normalizeCSSEntries, normalizeCSSValues, normalizeVariant, notNull, regexClassGroup, toArray, uniq, validateFilterRE, warnOnce, withLayer };
461
+ export { ArgumentType, Arrayable, Awaitable, BetterMap, BlocklistRule, CONTROL_SHORTCUT_NO_MERGE, CSSEntries, CSSObject, CSSValues, ConfigBase, DeepPartial, DynamicMatcher, DynamicRule, DynamicShortcut, DynamicShortcutMatcher, Extractor, ExtractorContext, FilterPattern, FlatObjectTuple, GenerateOptions, GenerateResult, GeneratorOptions, ParsedColorValue, ParsedUtil, PartialByKeys, PluginOptions, Postprocessor, Preflight, Preprocessor, Preset, PresetOptions, RGBAColorValue, RawUtil, RequiredByKey, ResolvedConfig, RestArgs, Rule, RuleContext, RuleMeta, Shift, Shortcut, StaticRule, StaticShortcut, StaticShortcutMap, StringifiedUtil, ThemeExtender, TwoKeyMap, UnoGenerator, UserConfig, UserConfigDefaults, UserOnlyOptions, UserShortcuts, UtilObject, ValueHandler, ValueHandlerCallback, Variant, VariantContext, VariantFunction, VariantHandler, VariantMatchedResult, VariantObject, attributifyRE, clearIdenticalEntries, clone, createGenerator, createValueHandler, e, entriesToCss, escapeRegExp, escapeSelector, expandVariantGroup, extractorSplit, extractorSvelte, hasScopePlaceholder, hex2rgba, isAttributifySelector, isObject, isRawUtil, isStaticRule, isStaticShortcut, isValidSelector, mergeDeep, mergeSet, normalizeCSSEntries, normalizeCSSValues, normalizeVariant, notNull, regexClassGroup, toArray, uniq, validateFilterRE, warnOnce, withLayer };
package/dist/index.mjs CHANGED
@@ -89,6 +89,32 @@ function mergeDeep(original, patch) {
89
89
  }
90
90
  return output;
91
91
  }
92
+ function clone(val) {
93
+ let k, out, tmp;
94
+ if (Array.isArray(val)) {
95
+ out = Array(k = val.length);
96
+ while (k--)
97
+ out[k] = (tmp = val[k]) && typeof tmp === "object" ? clone(tmp) : tmp;
98
+ return out;
99
+ }
100
+ if (Object.prototype.toString.call(val) === "[object Object]") {
101
+ out = {};
102
+ for (k in val) {
103
+ if (k === "__proto__") {
104
+ Object.defineProperty(out, k, {
105
+ value: clone(val[k]),
106
+ configurable: true,
107
+ enumerable: true,
108
+ writable: true
109
+ });
110
+ } else {
111
+ out[k] = (tmp = val[k]) && typeof tmp === "object" ? clone(tmp) : tmp;
112
+ }
113
+ }
114
+ return out;
115
+ }
116
+ return val;
117
+ }
92
118
  function isStaticRule(rule) {
93
119
  return typeof rule[0] === "string";
94
120
  }
@@ -131,6 +157,7 @@ function hex2rgba(hex = "") {
131
157
 
132
158
  const attributifyRE = /^\[(.+?)~?="(.*)"\]$/;
133
159
  const validateFilterRE = /(?!\d|-{2}|-\d)[a-zA-Z0-9\u00A0-\uFFFF-_:%-?]/;
160
+ const CONTROL_SHORTCUT_NO_MERGE = "$$shortcut-no-merge";
134
161
  function isAttributifySelector(selector) {
135
162
  return selector.match(attributifyRE);
136
163
  }
@@ -328,10 +355,11 @@ function resolveConfig(userConfig = {}, defaults = {}) {
328
355
  delete rules[i];
329
356
  }
330
357
  });
331
- const theme = [
358
+ const theme = clone([
332
359
  ...sortedPresets.map((p) => p.theme || {}),
333
360
  config.theme || {}
334
- ].reduce((a, p) => mergeDeep(a, p), {});
361
+ ].reduce((a, p) => mergeDeep(a, p), {}));
362
+ mergePresets("extendTheme").forEach((extendTheme) => extendTheme(theme));
335
363
  return {
336
364
  mergeSelectors: true,
337
365
  warn: true,
@@ -356,7 +384,7 @@ function resolveConfig(userConfig = {}, defaults = {}) {
356
384
  };
357
385
  }
358
386
 
359
- const version = "0.21.0";
387
+ const version = "0.22.1";
360
388
 
361
389
  class UnoGenerator {
362
390
  constructor(userConfig = {}, defaults = {}) {
@@ -468,33 +496,38 @@ class UnoGenerator {
468
496
  }
469
497
  const layerCache = {};
470
498
  const layers = this.config.sortLayers(Array.from(layerSet).sort((a, b) => (this.config.layers[a] ?? 0) - (this.config.layers[b] ?? 0) || a.localeCompare(b)));
499
+ let preflightsMap = {};
500
+ if (preflights) {
501
+ preflightsMap = Object.fromEntries(await Promise.all(layers.map(async (layer) => {
502
+ const preflights2 = await Promise.all(this.config.preflights.filter((i) => (i.layer || "default") === layer).map(async (i) => await i.getCSS()));
503
+ const css = preflights2.filter(Boolean).join(nl);
504
+ return [layer, css];
505
+ })));
506
+ }
471
507
  const getLayer = (layer) => {
472
508
  if (layerCache[layer])
473
509
  return layerCache[layer];
474
510
  let css = Array.from(sheet).sort((a, b) => (this.parentOrders.get(a[0]) ?? 0) - (this.parentOrders.get(b[0]) ?? 0) || a[0]?.localeCompare(b[0] || "") || 0).map(([parent, items]) => {
475
511
  const size = items.length;
476
- const sorted = items.filter((i) => (i[4]?.layer || "default") === layer).sort((a, b) => a[0] - b[0] || a[1]?.localeCompare(b[1] || "") || 0).map((a) => [a[1] ? applyScope(a[1], scope) : a[1], a[2]]);
512
+ const sorted = items.filter((i) => (i[4]?.layer || "default") === layer).sort((a, b) => a[0] - b[0] || a[1]?.localeCompare(b[1] || "") || 0).map((a) => [a[1] ? applyScope(a[1], scope) : a[1], a[2], !!a[4]?.noMerge]).map((a) => [a[0] == null ? a[0] : [a[0]], a[1], a[2]]);
477
513
  if (!sorted.length)
478
514
  return void 0;
479
- const rules = sorted.reverse().map(([selector, body], idx) => {
515
+ const rules = sorted.reverse().map(([selector, body, noMerge], idx) => {
480
516
  if (selector && this.config.mergeSelectors) {
481
517
  for (let i = idx + 1; i < size; i++) {
482
518
  const current = sorted[i];
483
- if (current && current[0] && current[1] === body) {
484
- current[0] = `${current[0]},${nl}${selector}`;
519
+ if (!noMerge && current && current[0] && current[1] === body) {
520
+ current[0].push(...selector);
485
521
  return null;
486
522
  }
487
523
  }
488
524
  }
489
- return selector ? `${selector}{${body}}` : body;
525
+ return selector ? `${[...new Set(selector)].join(`,${nl}`)}{${body}}` : body;
490
526
  }).filter(Boolean).reverse().join(nl);
491
527
  return parent ? `${parent}{${nl}${rules}${nl}}` : rules;
492
528
  }).filter(Boolean).join(nl);
493
529
  if (preflights) {
494
- css = [
495
- ...this.config.preflights.filter((i) => (i.layer || "default") === layer).map((i) => i.getCSS()).filter(Boolean),
496
- css
497
- ].join(nl);
530
+ css = [preflightsMap[layer], css].filter(Boolean).join(nl);
498
531
  }
499
532
  return layerCache[layer] = !minify && css ? `/* layer: ${layer} */${nl}${css}` : css;
500
533
  };
@@ -653,16 +686,18 @@ class UnoGenerator {
653
686
  continue;
654
687
  const { selector, entries, parent: parent2 } = this.applyVariants(item, [...item[4], ...parentVariants], raw);
655
688
  const mapItem = selectorMap.getFallback(selector, parent2, [[], item[0]]);
656
- mapItem[0].push(...entries);
657
- if (item[0] > mapItem[1])
658
- mapItem[1] = item[0];
689
+ mapItem[0].push(entries);
659
690
  }
660
- return selectorMap.map(([entries, index], selector, mediaQuery) => {
661
- const body = entriesToCss(entries);
662
- if (body)
663
- return [index, selector, body, mediaQuery, meta];
664
- return void 0;
665
- }).filter(Boolean);
691
+ return selectorMap.map(([e2, index], selector, mediaQuery) => {
692
+ const split = e2.filter((entries) => entries.some((entry) => entry[0] === CONTROL_SHORTCUT_NO_MERGE));
693
+ const rest = e2.filter((entries) => entries.every((entry) => entry[0] !== CONTROL_SHORTCUT_NO_MERGE));
694
+ return [...split, rest.flat(1)].map((entries) => {
695
+ const body = entriesToCss(entries);
696
+ if (body)
697
+ return [index, selector, body, mediaQuery, meta];
698
+ return void 0;
699
+ });
700
+ }).flat(1).filter(Boolean);
666
701
  }
667
702
  isBlocked(raw) {
668
703
  return !raw || this.config.blocklist.some((e2) => typeof e2 === "string" ? e2 === raw : e2.test(raw));
@@ -679,11 +714,11 @@ function applyScope(css, scope) {
679
714
  else
680
715
  return scope ? `${scope} ${css}` : css;
681
716
  }
717
+ const attributifyRe = /^\[(.+?)(~?=)"(.*)"\]$/;
682
718
  function toEscapedSelector(raw) {
683
- if (raw.startsWith("["))
684
- return raw.replace(/^\[(.+?)(~?=)"(.*)"\]$/, (_, n, s, i) => `[${e(n)}${s}"${e(i)}"]`);
685
- else
686
- return `.${e(raw)}`;
719
+ if (raw.startsWith("[") && attributifyRe.test(raw))
720
+ return raw.replace(attributifyRe, (_, n, s, i) => `[${e(n)}${s}"${e(i)}"]`);
721
+ return `.${e(raw)}`;
687
722
  }
688
723
 
689
- export { BetterMap, TwoKeyMap, UnoGenerator, attributifyRE, clearIdenticalEntries, createGenerator, createValueHandler, e, entriesToCss, escapeRegExp, escapeSelector, expandVariantGroup, extractorSplit, extractorSvelte, hasScopePlaceholder, hex2rgba, isAttributifySelector, isObject, isRawUtil, isStaticRule, isStaticShortcut, isValidSelector, mergeDeep, mergeSet, normalizeCSSEntries, normalizeCSSValues, normalizeVariant, notNull, regexClassGroup, toArray, uniq, validateFilterRE, warnOnce, withLayer };
724
+ export { BetterMap, CONTROL_SHORTCUT_NO_MERGE, TwoKeyMap, UnoGenerator, attributifyRE, clearIdenticalEntries, clone, createGenerator, createValueHandler, e, entriesToCss, escapeRegExp, escapeSelector, expandVariantGroup, extractorSplit, extractorSvelte, hasScopePlaceholder, hex2rgba, isAttributifySelector, isObject, isRawUtil, isStaticRule, isStaticShortcut, isValidSelector, mergeDeep, mergeSet, normalizeCSSEntries, normalizeCSSValues, normalizeVariant, notNull, regexClassGroup, toArray, uniq, validateFilterRE, warnOnce, withLayer };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unocss/core",
3
- "version": "0.21.0",
3
+ "version": "0.22.1",
4
4
  "description": "The instant on-demand Atomic CSS engine.",
5
5
  "keywords": [
6
6
  "unocss",