@unocss/core 0.13.0 → 0.14.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.
package/dist/index.d.ts CHANGED
@@ -13,7 +13,7 @@ declare class UnoGenerator {
13
13
  matchVariants(raw: string, current?: string): VariantMatchedResult;
14
14
  applyVariants(parsed: ParsedUtil, variantHandlers?: VariantHandler[], raw?: string): readonly [string, CSSEntries, string | undefined];
15
15
  constructCustomCSS(context: Readonly<RuleContext>, body: CSSObject | CSSEntries, overrideSelector?: string): string;
16
- parseUtil(input: string | VariantMatchedResult, context: RuleContext, internal?: boolean): Promise<ParsedUtil | RawUtil | undefined>;
16
+ parseUtil(input: string | VariantMatchedResult, context: RuleContext, internal?: boolean): Promise<ParsedUtil[] | RawUtil[] | undefined>;
17
17
  stringifyUtil(parsed?: ParsedUtil | RawUtil): StringifiedUtil | undefined;
18
18
  expandShortcut(processed: string, context: RuleContext, depth?: number): [string[], RuleMeta | undefined] | undefined;
19
19
  stringifyShortcuts(parent: VariantMatchedResult, context: RuleContext, expanded: string[], meta?: RuleMeta): Promise<StringifiedUtil[] | undefined>;
@@ -33,6 +33,7 @@ declare type FlatObjectTuple<T> = {
33
33
  [K in keyof T]: T[K];
34
34
  };
35
35
  declare type PartialByKeys<T, K extends keyof T = keyof T> = FlatObjectTuple<Partial<Pick<T, Extract<keyof T, K>>> & Omit<T, K>>;
36
+ declare type RequiredByKey<T, K extends keyof T = keyof T> = FlatObjectTuple<Required<Pick<T, Extract<keyof T, K>>> & Omit<T, K>>;
36
37
  declare type CSSObject = Record<string, string | number | undefined>;
37
38
  declare type CSSEntries = [string, string | number | undefined][];
38
39
  interface RuleContext<Theme extends {} = {}> {
@@ -85,7 +86,8 @@ interface RuleMeta {
85
86
  */
86
87
  internal?: boolean;
87
88
  }
88
- declare type DynamicMatcher<Theme extends {} = {}> = ((match: string[], context: Readonly<RuleContext<Theme>>) => Awaitable<CSSObject | CSSEntries | string | undefined>);
89
+ declare type CSSValues = CSSObject | CSSEntries | (CSSObject | CSSEntries)[];
90
+ declare type DynamicMatcher<Theme extends {} = {}> = ((match: string[], context: Readonly<RuleContext<Theme>>) => Awaitable<CSSValues | string | undefined>);
89
91
  declare type DynamicRule<Theme extends {} = {}> = [RegExp, DynamicMatcher<Theme>] | [RegExp, DynamicMatcher<Theme>, RuleMeta];
90
92
  declare type StaticRule = [string, CSSObject | CSSEntries] | [string, CSSObject | CSSEntries, RuleMeta];
91
93
  declare type Rule<Theme extends {} = {}> = DynamicRule<Theme> | StaticRule;
@@ -95,6 +97,7 @@ declare type StaticShortcutMap = Record<string, string | string[]>;
95
97
  declare type DynamicShortcut<Theme extends {} = {}> = [RegExp, DynamicShortcutMatcher<Theme>] | [RegExp, DynamicShortcutMatcher<Theme>, RuleMeta];
96
98
  declare type UserShortcuts<Theme extends {} = {}> = StaticShortcutMap | (StaticShortcut | DynamicShortcut<Theme> | StaticShortcutMap)[];
97
99
  declare type Shortcut<Theme extends {} = {}> = StaticShortcut | DynamicShortcut<Theme>;
100
+ declare type FilterPattern = ReadonlyArray<string | RegExp> | string | RegExp | null;
98
101
  interface Preflight {
99
102
  getCSS: () => string | undefined;
100
103
  layer?: string;
@@ -108,7 +111,7 @@ interface VariantHandler {
108
111
  /**
109
112
  * Rewrite the output selector. Often be used to append pesudo classes or parents.
110
113
  */
111
- selector?: (input: string) => string | undefined;
114
+ selector?: (input: string, body: CSSEntries) => string | undefined;
112
115
  /**
113
116
  * Rewrite the output css body. The input come in [key,value][] pairs.
114
117
  */
@@ -226,11 +229,34 @@ interface UserOnlyOptions<Theme extends {} = {}> {
226
229
  */
227
230
  envMode?: 'dev' | 'build';
228
231
  }
229
- interface UserConfig<Theme extends {} = {}> extends ConfigBase<Theme>, UserOnlyOptions<Theme>, GeneratorOptions {
232
+ /**
233
+ * For other modules to aggregate the options
234
+ */
235
+ interface PluginOptions {
236
+ /**
237
+ * Load from configs files
238
+ *
239
+ * set `false` to disable
240
+ */
241
+ configFile?: string | false;
242
+ /**
243
+ * List of files that will also triggers config reloads
244
+ */
245
+ configDeps?: string[];
246
+ /**
247
+ * Patterns that filter the files being extracted.
248
+ */
249
+ include?: FilterPattern;
250
+ /**
251
+ * Patterns that filter the files NOT being extracted.
252
+ */
253
+ exclude?: FilterPattern;
254
+ }
255
+ interface UserConfig<Theme extends {} = {}> extends ConfigBase<Theme>, UserOnlyOptions<Theme>, GeneratorOptions, PluginOptions {
230
256
  }
231
257
  interface UserConfigDefaults<Theme extends {} = {}> extends ConfigBase<Theme>, UserOnlyOptions<Theme> {
232
258
  }
233
- interface ResolvedConfig extends Omit<PartialByKeys<Required<UserConfig>, 'preprocess'>, 'rules' | 'shortcuts'> {
259
+ interface ResolvedConfig extends Omit<RequiredByKey<UserConfig, 'mergeSelectors' | 'theme' | 'rules' | 'variants' | 'layers' | 'extractors' | 'blocklist' | 'safelist' | 'preflights' | 'sortLayers'>, 'rules' | 'shortcuts'> {
234
260
  shortcuts: Shortcut[];
235
261
  variants: VariantObject[];
236
262
  rulesSize: number;
@@ -301,6 +327,9 @@ declare function escapeRegExp(string: string): string;
301
327
  declare function escapeSelector(str: string): string;
302
328
  declare const e: typeof escapeSelector;
303
329
 
330
+ declare function normalizeCSSEntries(obj: CSSEntries | CSSObject): CSSEntries;
331
+ declare function normalizeCSSValues(obj: CSSValues): CSSEntries[];
332
+ declare function clearIdenticalEntries(entry: CSSEntries): CSSEntries;
304
333
  declare function entriesToCss(arr?: CSSEntries): string;
305
334
  declare function isObject(item: any): item is Record<string, any>;
306
335
  declare function mergeDeep<T>(original: T, patch: DeepPartial<T>): T;
@@ -319,6 +348,7 @@ declare function isAttributifySelector(selector: string): RegExpMatchArray | nul
319
348
  declare function isValidSelector(selector?: string): selector is string;
320
349
  declare function normalizeVariant(variant: Variant): VariantObject;
321
350
  declare function isRawUtil(util: ParsedUtil | RawUtil | StringifiedUtil): util is RawUtil;
351
+ declare function notNull<T>(value: T | null | undefined): value is T;
322
352
 
323
353
  declare class TwoKeyMap<K1, K2, V> {
324
354
  _map: Map<K1, Map<K2, V>>;
@@ -343,4 +373,4 @@ declare function warnOnce(msg: string): void;
343
373
 
344
374
  declare const extractorSplit: Extractor;
345
375
 
346
- export { ArgumentType, Awaitable, BetterMap, BlocklistRule, CSSEntries, CSSObject, ConfigBase, DeepPartial, DynamicMatcher, DynamicRule, DynamicShortcut, DynamicShortcutMatcher, Extractor, ExtractorContext, FlatObjectTuple, GenerateOptions, GenerateResult, GeneratorOptions, ParsedUtil, PartialByKeys, Preflight, Preset, RawUtil, ResolvedConfig, RestArgs, Rule, RuleContext, RuleMeta, Shift, Shortcut, StaticRule, StaticShortcut, StaticShortcutMap, StringifiedUtil, TwoKeyMap, UnoGenerator, UserConfig, UserConfigDefaults, UserOnlyOptions, UserShortcuts, Variant, VariantFunction, VariantHandler, VariantMatchedResult, VariantObject, attributifyRE, createGenerator, e, entriesToCss, escapeRegExp, escapeSelector, expandVariantGroup, extractorSplit, hasScopePlaceholder, hex2rgba, isAttributifySelector, isObject, isRawUtil, isStaticRule, isStaticShortcut, isValidSelector, mergeDeep, mergeSet, normalizeVariant, regexClassGroup, toArray, uniq, validateFilterRE, warnOnce, withLayer };
376
+ export { ArgumentType, Awaitable, BetterMap, BlocklistRule, CSSEntries, CSSObject, CSSValues, ConfigBase, DeepPartial, DynamicMatcher, DynamicRule, DynamicShortcut, DynamicShortcutMatcher, Extractor, ExtractorContext, FilterPattern, FlatObjectTuple, GenerateOptions, GenerateResult, GeneratorOptions, ParsedUtil, PartialByKeys, PluginOptions, Preflight, Preset, RawUtil, RequiredByKey, ResolvedConfig, RestArgs, Rule, RuleContext, RuleMeta, Shift, Shortcut, StaticRule, StaticShortcut, StaticShortcutMap, StringifiedUtil, TwoKeyMap, UnoGenerator, UserConfig, UserConfigDefaults, UserOnlyOptions, UserShortcuts, Variant, VariantFunction, VariantHandler, VariantMatchedResult, VariantObject, attributifyRE, clearIdenticalEntries, createGenerator, e, entriesToCss, escapeRegExp, escapeSelector, expandVariantGroup, extractorSplit, hasScopePlaceholder, hex2rgba, isAttributifySelector, isObject, isRawUtil, isStaticRule, isStaticShortcut, isValidSelector, mergeDeep, mergeSet, normalizeCSSEntries, normalizeCSSValues, normalizeVariant, notNull, regexClassGroup, toArray, uniq, validateFilterRE, warnOnce, withLayer };
package/dist/index.js CHANGED
@@ -12,6 +12,7 @@ __export(exports, {
12
12
  TwoKeyMap: () => TwoKeyMap,
13
13
  UnoGenerator: () => UnoGenerator,
14
14
  attributifyRE: () => attributifyRE,
15
+ clearIdenticalEntries: () => clearIdenticalEntries,
15
16
  createGenerator: () => createGenerator,
16
17
  e: () => e,
17
18
  entriesToCss: () => entriesToCss,
@@ -29,7 +30,10 @@ __export(exports, {
29
30
  isValidSelector: () => isValidSelector,
30
31
  mergeDeep: () => mergeDeep,
31
32
  mergeSet: () => mergeSet,
33
+ normalizeCSSEntries: () => normalizeCSSEntries,
34
+ normalizeCSSValues: () => normalizeCSSValues,
32
35
  normalizeVariant: () => normalizeVariant,
36
+ notNull: () => notNull,
33
37
  regexClassGroup: () => regexClassGroup,
34
38
  toArray: () => toArray,
35
39
  uniq: () => uniq,
@@ -77,10 +81,34 @@ function escapeSelector(str) {
77
81
  var e = escapeSelector;
78
82
 
79
83
  // src/utils/object.ts
84
+ function normalizeCSSEntries(obj) {
85
+ return (!Array.isArray(obj) ? Object.entries(obj) : obj).filter((i) => i[1] != null);
86
+ }
87
+ function normalizeCSSValues(obj) {
88
+ if (Array.isArray(obj)) {
89
+ if (obj.find((i) => !Array.isArray(i) || Array.isArray(i[0])))
90
+ return obj.map((i) => normalizeCSSEntries(i));
91
+ else
92
+ return [obj];
93
+ } else {
94
+ return [normalizeCSSEntries(obj)];
95
+ }
96
+ }
97
+ function clearIdenticalEntries(entry) {
98
+ return entry.filter(([k, v], idx) => {
99
+ if (k.startsWith("$$"))
100
+ return false;
101
+ for (let i = idx - 1; i >= 0; i--) {
102
+ if (entry[i][0] === k && entry[i][1] === v)
103
+ return false;
104
+ }
105
+ return true;
106
+ });
107
+ }
80
108
  function entriesToCss(arr) {
81
109
  if (arr == null)
82
110
  return "";
83
- return arr.map(([key, value]) => value != null ? `${key}:${value};` : void 0).filter(Boolean).join("");
111
+ return clearIdenticalEntries(arr).map(([key, value]) => value != null ? `${key}:${value};` : void 0).filter(Boolean).join("");
84
112
  }
85
113
  function isObject(item) {
86
114
  return item && typeof item === "object" && !Array.isArray(item);
@@ -164,6 +192,9 @@ function normalizeVariant(variant) {
164
192
  function isRawUtil(util) {
165
193
  return util.length === 3;
166
194
  }
195
+ function notNull(value) {
196
+ return value != null;
197
+ }
167
198
 
168
199
  // src/utils/map.ts
169
200
  var TwoKeyMap = class {
@@ -336,7 +367,7 @@ function resolveConfig(userConfig = {}, defaults = {}) {
336
367
  }
337
368
 
338
369
  // package.json
339
- var version = "0.13.0";
370
+ var version = "0.14.2";
340
371
 
341
372
  // src/generator/index.ts
342
373
  var UnoGenerator = class {
@@ -406,6 +437,7 @@ var UnoGenerator = class {
406
437
  this._cache.set(raw, null);
407
438
  };
408
439
  await Promise.all(Array.from(tokens).map(async (raw) => {
440
+ var _a;
409
441
  if (matched.has(raw) || this.blocked.has(raw))
410
442
  return;
411
443
  if (this._cache.has(raw)) {
@@ -436,9 +468,9 @@ var UnoGenerator = class {
436
468
  if (utils == null ? void 0 : utils.length)
437
469
  return hit(raw, utils);
438
470
  } else {
439
- const util = this.stringifyUtil(await this.parseUtil(applied, context));
440
- if (util)
441
- return hit(raw, [util]);
471
+ const utils = (_a = await this.parseUtil(applied, context)) == null ? void 0 : _a.map((i) => this.stringifyUtil(i)).filter(notNull);
472
+ if (utils == null ? void 0 : utils.length)
473
+ return hit(raw, utils);
442
474
  }
443
475
  this._cache.set(raw, null);
444
476
  }));
@@ -467,18 +499,18 @@ var UnoGenerator = class {
467
499
  }).map((a) => [a[1] ? applyScope(a[1], scope) : a[1], a[2]]);
468
500
  if (!sorted.length)
469
501
  return void 0;
470
- const rules = sorted.map(([selector, body], idx) => {
502
+ const rules = sorted.reverse().map(([selector, body], idx) => {
471
503
  if (selector && this.config.mergeSelectors) {
472
- for (let i = size - 1; i > idx; i--) {
504
+ for (let i = idx + 1; i < size; i++) {
473
505
  const current = sorted[i];
474
506
  if (current && current[0] && current[1] === body) {
475
- current[0] = `${selector},${current[0]}`;
507
+ current[0] = `${current[0]},${selector}`;
476
508
  return null;
477
509
  }
478
510
  }
479
511
  }
480
512
  return selector ? `${selector}{${body}}` : body;
481
- }).filter(Boolean).join(nl);
513
+ }).filter(Boolean).reverse().join(nl);
482
514
  return parent ? `${parent}{${nl}${rules}${nl}}` : rules;
483
515
  }).filter(Boolean).join(nl);
484
516
  if (preflights) {
@@ -535,20 +567,21 @@ var UnoGenerator = class {
535
567
  return [raw, processed, handlers];
536
568
  }
537
569
  applyVariants(parsed, variantHandlers = parsed[4], raw = parsed[1]) {
570
+ const entries = variantHandlers.reduce((p, v) => {
571
+ var _a;
572
+ return ((_a = v.body) == null ? void 0 : _a.call(v, p)) || p;
573
+ }, parsed[2]);
538
574
  return [
539
575
  variantHandlers.reduce((p, v) => {
540
576
  var _a;
541
- return ((_a = v.selector) == null ? void 0 : _a.call(v, p)) || p;
577
+ return ((_a = v.selector) == null ? void 0 : _a.call(v, p, entries)) || p;
542
578
  }, toEscapedSelector(raw)),
543
- variantHandlers.reduce((p, v) => {
544
- var _a;
545
- return ((_a = v.body) == null ? void 0 : _a.call(v, p)) || p;
546
- }, parsed[2]),
579
+ entries,
547
580
  variantHandlers.reduce((p, v) => Array.isArray(v.parent) ? v.parent[0] : v.parent || p, void 0)
548
581
  ];
549
582
  }
550
583
  constructCustomCSS(context, body, overrideSelector) {
551
- body = normalizeEntries(body);
584
+ body = normalizeCSSEntries(body);
552
585
  const [selector, entries, mediaQuery] = this.applyVariants([0, overrideSelector || context.rawSelector, body, void 0, context.variantHandlers]);
553
586
  const cssBody = `${selector}{${entriesToCss(entries)}}`;
554
587
  if (mediaQuery)
@@ -561,7 +594,7 @@ var UnoGenerator = class {
561
594
  const staticMatch = this.config.rulesStaticMap[processed];
562
595
  if (staticMatch) {
563
596
  if (staticMatch[1] && (internal || !((_a = staticMatch[2]) == null ? void 0 : _a.internal)))
564
- return [staticMatch[0], raw, normalizeEntries(staticMatch[1]), staticMatch[2], variantHandlers];
597
+ return [[staticMatch[0], raw, normalizeCSSEntries(staticMatch[1]), staticMatch[2], variantHandlers]];
565
598
  }
566
599
  context.variantHandlers = variantHandlers;
567
600
  const { rulesDynamic, rulesSize } = this.config;
@@ -579,10 +612,10 @@ var UnoGenerator = class {
579
612
  if (!result)
580
613
  continue;
581
614
  if (typeof result === "string")
582
- return [i, result, meta];
583
- const entries = normalizeEntries(result).filter((i2) => i2[1] != null);
615
+ return [[i, result, meta]];
616
+ const entries = normalizeCSSValues(result).filter((i2) => i2.length);
584
617
  if (entries.length)
585
- return [i, raw, entries, meta, variantHandlers];
618
+ return entries.map((e2) => [i, raw, e2, meta, variantHandlers]);
586
619
  }
587
620
  }
588
621
  stringifyUtil(parsed) {
@@ -636,8 +669,8 @@ var UnoGenerator = class {
636
669
  const result = await this.parseUtil(i, context, true);
637
670
  if (!result)
638
671
  warnOnce(`unmatched utility "${i}" in shortcut "${parent[1]}"`);
639
- return result;
640
- }))).filter(Boolean).sort((a, b) => a[0] - b[0]);
672
+ return result || [];
673
+ }))).flat(1).filter(Boolean).sort((a, b) => a[0] - b[0]);
641
674
  const [raw, , parentVariants] = parent;
642
675
  for (const item of parsed) {
643
676
  if (isRawUtil(item))
@@ -676,15 +709,13 @@ function toEscapedSelector(raw) {
676
709
  else
677
710
  return `.${e(raw)}`;
678
711
  }
679
- function normalizeEntries(obj) {
680
- return !Array.isArray(obj) ? Object.entries(obj) : obj;
681
- }
682
712
  // Annotate the CommonJS export names for ESM import in node:
683
713
  0 && (module.exports = {
684
714
  BetterMap,
685
715
  TwoKeyMap,
686
716
  UnoGenerator,
687
717
  attributifyRE,
718
+ clearIdenticalEntries,
688
719
  createGenerator,
689
720
  e,
690
721
  entriesToCss,
@@ -702,7 +733,10 @@ function normalizeEntries(obj) {
702
733
  isValidSelector,
703
734
  mergeDeep,
704
735
  mergeSet,
736
+ normalizeCSSEntries,
737
+ normalizeCSSValues,
705
738
  normalizeVariant,
739
+ notNull,
706
740
  regexClassGroup,
707
741
  toArray,
708
742
  uniq,
package/dist/index.mjs CHANGED
@@ -37,10 +37,34 @@ function escapeSelector(str) {
37
37
  var e = escapeSelector;
38
38
 
39
39
  // src/utils/object.ts
40
+ function normalizeCSSEntries(obj) {
41
+ return (!Array.isArray(obj) ? Object.entries(obj) : obj).filter((i) => i[1] != null);
42
+ }
43
+ function normalizeCSSValues(obj) {
44
+ if (Array.isArray(obj)) {
45
+ if (obj.find((i) => !Array.isArray(i) || Array.isArray(i[0])))
46
+ return obj.map((i) => normalizeCSSEntries(i));
47
+ else
48
+ return [obj];
49
+ } else {
50
+ return [normalizeCSSEntries(obj)];
51
+ }
52
+ }
53
+ function clearIdenticalEntries(entry) {
54
+ return entry.filter(([k, v], idx) => {
55
+ if (k.startsWith("$$"))
56
+ return false;
57
+ for (let i = idx - 1; i >= 0; i--) {
58
+ if (entry[i][0] === k && entry[i][1] === v)
59
+ return false;
60
+ }
61
+ return true;
62
+ });
63
+ }
40
64
  function entriesToCss(arr) {
41
65
  if (arr == null)
42
66
  return "";
43
- return arr.map(([key, value]) => value != null ? `${key}:${value};` : void 0).filter(Boolean).join("");
67
+ return clearIdenticalEntries(arr).map(([key, value]) => value != null ? `${key}:${value};` : void 0).filter(Boolean).join("");
44
68
  }
45
69
  function isObject(item) {
46
70
  return item && typeof item === "object" && !Array.isArray(item);
@@ -124,6 +148,9 @@ function normalizeVariant(variant) {
124
148
  function isRawUtil(util) {
125
149
  return util.length === 3;
126
150
  }
151
+ function notNull(value) {
152
+ return value != null;
153
+ }
127
154
 
128
155
  // src/utils/map.ts
129
156
  var TwoKeyMap = class {
@@ -296,7 +323,7 @@ function resolveConfig(userConfig = {}, defaults = {}) {
296
323
  }
297
324
 
298
325
  // package.json
299
- var version = "0.13.0";
326
+ var version = "0.14.2";
300
327
 
301
328
  // src/generator/index.ts
302
329
  var UnoGenerator = class {
@@ -366,6 +393,7 @@ var UnoGenerator = class {
366
393
  this._cache.set(raw, null);
367
394
  };
368
395
  await Promise.all(Array.from(tokens).map(async (raw) => {
396
+ var _a;
369
397
  if (matched.has(raw) || this.blocked.has(raw))
370
398
  return;
371
399
  if (this._cache.has(raw)) {
@@ -396,9 +424,9 @@ var UnoGenerator = class {
396
424
  if (utils == null ? void 0 : utils.length)
397
425
  return hit(raw, utils);
398
426
  } else {
399
- const util = this.stringifyUtil(await this.parseUtil(applied, context));
400
- if (util)
401
- return hit(raw, [util]);
427
+ const utils = (_a = await this.parseUtil(applied, context)) == null ? void 0 : _a.map((i) => this.stringifyUtil(i)).filter(notNull);
428
+ if (utils == null ? void 0 : utils.length)
429
+ return hit(raw, utils);
402
430
  }
403
431
  this._cache.set(raw, null);
404
432
  }));
@@ -427,18 +455,18 @@ var UnoGenerator = class {
427
455
  }).map((a) => [a[1] ? applyScope(a[1], scope) : a[1], a[2]]);
428
456
  if (!sorted.length)
429
457
  return void 0;
430
- const rules = sorted.map(([selector, body], idx) => {
458
+ const rules = sorted.reverse().map(([selector, body], idx) => {
431
459
  if (selector && this.config.mergeSelectors) {
432
- for (let i = size - 1; i > idx; i--) {
460
+ for (let i = idx + 1; i < size; i++) {
433
461
  const current = sorted[i];
434
462
  if (current && current[0] && current[1] === body) {
435
- current[0] = `${selector},${current[0]}`;
463
+ current[0] = `${current[0]},${selector}`;
436
464
  return null;
437
465
  }
438
466
  }
439
467
  }
440
468
  return selector ? `${selector}{${body}}` : body;
441
- }).filter(Boolean).join(nl);
469
+ }).filter(Boolean).reverse().join(nl);
442
470
  return parent ? `${parent}{${nl}${rules}${nl}}` : rules;
443
471
  }).filter(Boolean).join(nl);
444
472
  if (preflights) {
@@ -495,20 +523,21 @@ var UnoGenerator = class {
495
523
  return [raw, processed, handlers];
496
524
  }
497
525
  applyVariants(parsed, variantHandlers = parsed[4], raw = parsed[1]) {
526
+ const entries = variantHandlers.reduce((p, v) => {
527
+ var _a;
528
+ return ((_a = v.body) == null ? void 0 : _a.call(v, p)) || p;
529
+ }, parsed[2]);
498
530
  return [
499
531
  variantHandlers.reduce((p, v) => {
500
532
  var _a;
501
- return ((_a = v.selector) == null ? void 0 : _a.call(v, p)) || p;
533
+ return ((_a = v.selector) == null ? void 0 : _a.call(v, p, entries)) || p;
502
534
  }, toEscapedSelector(raw)),
503
- variantHandlers.reduce((p, v) => {
504
- var _a;
505
- return ((_a = v.body) == null ? void 0 : _a.call(v, p)) || p;
506
- }, parsed[2]),
535
+ entries,
507
536
  variantHandlers.reduce((p, v) => Array.isArray(v.parent) ? v.parent[0] : v.parent || p, void 0)
508
537
  ];
509
538
  }
510
539
  constructCustomCSS(context, body, overrideSelector) {
511
- body = normalizeEntries(body);
540
+ body = normalizeCSSEntries(body);
512
541
  const [selector, entries, mediaQuery] = this.applyVariants([0, overrideSelector || context.rawSelector, body, void 0, context.variantHandlers]);
513
542
  const cssBody = `${selector}{${entriesToCss(entries)}}`;
514
543
  if (mediaQuery)
@@ -521,7 +550,7 @@ var UnoGenerator = class {
521
550
  const staticMatch = this.config.rulesStaticMap[processed];
522
551
  if (staticMatch) {
523
552
  if (staticMatch[1] && (internal || !((_a = staticMatch[2]) == null ? void 0 : _a.internal)))
524
- return [staticMatch[0], raw, normalizeEntries(staticMatch[1]), staticMatch[2], variantHandlers];
553
+ return [[staticMatch[0], raw, normalizeCSSEntries(staticMatch[1]), staticMatch[2], variantHandlers]];
525
554
  }
526
555
  context.variantHandlers = variantHandlers;
527
556
  const { rulesDynamic, rulesSize } = this.config;
@@ -539,10 +568,10 @@ var UnoGenerator = class {
539
568
  if (!result)
540
569
  continue;
541
570
  if (typeof result === "string")
542
- return [i, result, meta];
543
- const entries = normalizeEntries(result).filter((i2) => i2[1] != null);
571
+ return [[i, result, meta]];
572
+ const entries = normalizeCSSValues(result).filter((i2) => i2.length);
544
573
  if (entries.length)
545
- return [i, raw, entries, meta, variantHandlers];
574
+ return entries.map((e2) => [i, raw, e2, meta, variantHandlers]);
546
575
  }
547
576
  }
548
577
  stringifyUtil(parsed) {
@@ -596,8 +625,8 @@ var UnoGenerator = class {
596
625
  const result = await this.parseUtil(i, context, true);
597
626
  if (!result)
598
627
  warnOnce(`unmatched utility "${i}" in shortcut "${parent[1]}"`);
599
- return result;
600
- }))).filter(Boolean).sort((a, b) => a[0] - b[0]);
628
+ return result || [];
629
+ }))).flat(1).filter(Boolean).sort((a, b) => a[0] - b[0]);
601
630
  const [raw, , parentVariants] = parent;
602
631
  for (const item of parsed) {
603
632
  if (isRawUtil(item))
@@ -636,14 +665,12 @@ function toEscapedSelector(raw) {
636
665
  else
637
666
  return `.${e(raw)}`;
638
667
  }
639
- function normalizeEntries(obj) {
640
- return !Array.isArray(obj) ? Object.entries(obj) : obj;
641
- }
642
668
  export {
643
669
  BetterMap,
644
670
  TwoKeyMap,
645
671
  UnoGenerator,
646
672
  attributifyRE,
673
+ clearIdenticalEntries,
647
674
  createGenerator,
648
675
  e,
649
676
  entriesToCss,
@@ -661,7 +688,10 @@ export {
661
688
  isValidSelector,
662
689
  mergeDeep,
663
690
  mergeSet,
691
+ normalizeCSSEntries,
692
+ normalizeCSSValues,
664
693
  normalizeVariant,
694
+ notNull,
665
695
  regexClassGroup,
666
696
  toArray,
667
697
  uniq,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unocss/core",
3
- "version": "0.13.0",
3
+ "version": "0.14.2",
4
4
  "description": "The instant on-demand Atomic CSS engine.",
5
5
  "keywords": [
6
6
  "unocss",