@unocss/core 0.38.0 → 0.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -40,6 +40,8 @@ function escapeSelector(str) {
40
40
  const e = escapeSelector;
41
41
 
42
42
  function normalizeCSSEntries(obj) {
43
+ if (typeof obj === "string")
44
+ return obj;
43
45
  return (!Array.isArray(obj) ? Object.entries(obj) : obj).filter((i) => i[1] != null);
44
46
  }
45
47
  function normalizeCSSValues(obj) {
@@ -458,7 +460,7 @@ function resolveConfig(userConfig = {}, defaults = {}) {
458
460
  };
459
461
  }
460
462
 
461
- const version = "0.38.0";
463
+ const version = "0.39.0";
462
464
 
463
465
  class UnoGenerator {
464
466
  constructor(userConfig = {}, defaults = {}) {
@@ -563,7 +565,8 @@ class UnoGenerator {
563
565
  const layerSet = /* @__PURE__ */ new Set(["default"]);
564
566
  const matched = /* @__PURE__ */ new Set();
565
567
  const sheet = /* @__PURE__ */ new Map();
566
- await Promise.all(Array.from(tokens).map(async (raw) => {
568
+ let preflightsMap = {};
569
+ const tokenPromises = Array.from(tokens).map(async (raw) => {
567
570
  if (matched.has(raw))
568
571
  return;
569
572
  const payload = await this.parseToken(raw);
@@ -572,52 +575,68 @@ class UnoGenerator {
572
575
  matched.add(raw);
573
576
  for (const item of payload) {
574
577
  const parent = item[3] || "";
578
+ const layer = item[4]?.layer;
575
579
  if (!sheet.has(parent))
576
580
  sheet.set(parent, []);
577
581
  sheet.get(parent).push(item);
578
- if (item[4]?.layer)
579
- layerSet.add(item[4].layer);
582
+ if (layer)
583
+ layerSet.add(layer);
580
584
  }
581
- }));
582
- if (preflights) {
583
- this.config.preflights.forEach((i) => {
584
- if (i.layer)
585
- layerSet.add(i.layer);
586
- });
587
- }
588
- const layerCache = {};
589
- const layers = this.config.sortLayers(Array.from(layerSet).sort((a, b) => (this.config.layers[a] ?? 0) - (this.config.layers[b] ?? 0) || a.localeCompare(b)));
590
- let preflightsMap = {};
591
- if (preflights) {
585
+ });
586
+ const preflightPromise = (async () => {
587
+ if (!preflights)
588
+ return;
592
589
  const preflightContext = {
593
590
  generator: this,
594
591
  theme: this.config.theme
595
592
  };
596
- preflightsMap = Object.fromEntries(await Promise.all(layers.map(async (layer) => {
593
+ const preflightLayerSet = /* @__PURE__ */ new Set(["default"]);
594
+ this.config.preflights.forEach(({ layer }) => {
595
+ if (layer) {
596
+ layerSet.add(layer);
597
+ preflightLayerSet.add(layer);
598
+ }
599
+ });
600
+ preflightsMap = Object.fromEntries(await Promise.all(Array.from(preflightLayerSet).map(async (layer) => {
597
601
  const preflights2 = await Promise.all(this.config.preflights.filter((i) => (i.layer || "default") === layer).map(async (i) => await i.getCSS(preflightContext)));
598
602
  const css = preflights2.filter(Boolean).join(nl);
599
603
  return [layer, css];
600
604
  })));
601
- }
605
+ })();
606
+ await Promise.all([
607
+ ...tokenPromises,
608
+ preflightPromise
609
+ ]);
610
+ const layers = this.config.sortLayers(Array.from(layerSet).sort((a, b) => (this.config.layers[a] ?? 0) - (this.config.layers[b] ?? 0) || a.localeCompare(b)));
611
+ const layerCache = {};
602
612
  const getLayer = (layer) => {
603
613
  if (layerCache[layer])
604
614
  return layerCache[layer];
605
615
  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]) => {
606
616
  const size = items.length;
607
- const sorted = items.filter((i) => (i[4]?.layer || "default") === layer).sort((a, b) => a[0] - b[0] || (a[4]?.sort || 0) - (b[4]?.sort || 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]]);
617
+ const sorted = items.filter((i) => (i[4]?.layer || "default") === layer).sort((a, b) => a[0] - b[0] || (a[4]?.sort || 0) - (b[4]?.sort || 0) || a[1]?.localeCompare(b[1] || "") || a[2]?.localeCompare(b[2] || "") || 0).map(([, selector, body, , meta]) => {
618
+ const scopedSelector = selector ? applyScope(selector, scope) : selector;
619
+ return [
620
+ [[scopedSelector ?? "", meta?.sort ?? 0]],
621
+ body,
622
+ !!meta?.noMerge
623
+ ];
624
+ });
608
625
  if (!sorted.length)
609
626
  return void 0;
610
- const rules = sorted.reverse().map(([selector, body, noMerge], idx) => {
611
- if (!noMerge && selector && this.config.mergeSelectors) {
627
+ const rules = sorted.reverse().map(([selectorSortPair, body, noMerge], idx) => {
628
+ if (!noMerge && this.config.mergeSelectors) {
612
629
  for (let i = idx + 1; i < size; i++) {
613
630
  const current = sorted[i];
614
- if (current && !current[2] && current[0] && current[1] === body) {
615
- current[0].push(...selector);
631
+ if (current && !current[2] && (selectorSortPair && current[0] || selectorSortPair == null && current[0] == null) && current[1] === body) {
632
+ if (selectorSortPair && current[0])
633
+ current[0].push(...selectorSortPair);
616
634
  return null;
617
635
  }
618
636
  }
619
637
  }
620
- return selector ? `${[...new Set(selector)].join(`,${nl}`)}{${body}}` : body;
638
+ const selectors = selectorSortPair ? [...new Set(selectorSortPair.sort((a, b) => a[1] - b[1] || a[0]?.localeCompare(b[0] || "") || 0).map((pair) => pair[0]).filter(Boolean))] : [];
639
+ return selectors.length ? `${selectors.join(`,${nl}`)}{${body}}` : body;
621
640
  }).filter(Boolean).reverse().join(nl);
622
641
  return parent ? `${parent}{${nl}${rules}${nl}}` : rules;
623
642
  }).filter(Boolean).join(nl);
@@ -676,22 +695,34 @@ class UnoGenerator {
676
695
  }
677
696
  applyVariants(parsed, variantHandlers = parsed[4], raw = parsed[1]) {
678
697
  const handlers = [...variantHandlers].sort((a, b) => (a.order || 0) - (b.order || 0));
679
- const entries = handlers.reduce((p, v) => v.body?.(p) || p, parsed[2]);
680
- const selector = handlers.reduce((p, v) => v.selector?.(p, entries) || p, toEscapedSelector(raw));
698
+ let entries = parsed[2];
699
+ let selector = toEscapedSelector(raw);
700
+ let parent;
701
+ let layer;
702
+ let sort;
703
+ handlers.forEach((v) => {
704
+ entries = v.body?.(entries) || entries;
705
+ selector = v.selector?.(selector, entries) || selector;
706
+ parent = Array.isArray(v.parent) ? v.parent[0] : v.parent || parent;
707
+ layer = v.layer || layer;
708
+ sort = v.sort || sort;
709
+ });
681
710
  const obj = {
682
711
  selector: movePseudoElementsEnd(selector),
683
712
  entries,
684
- parent: handlers.reduce((p, v) => Array.isArray(v.parent) ? v.parent[0] : v.parent || p, void 0),
685
- layer: handlers.reduce((p, v) => v.layer || p, void 0),
686
- sort: handlers.reduce((p, v) => v.sort || p, void 0)
713
+ parent,
714
+ layer,
715
+ sort
687
716
  };
688
717
  for (const p of this.config.postprocess)
689
718
  p(obj);
690
719
  return obj;
691
720
  }
692
721
  constructCustomCSS(context, body, overrideSelector) {
693
- body = normalizeCSSEntries(body);
694
- const { selector, entries, parent } = this.applyVariants([0, overrideSelector || context.rawSelector, body, void 0, context.variantHandlers]);
722
+ const normalizedBody = normalizeCSSEntries(body);
723
+ if (typeof normalizedBody === "string")
724
+ return normalizedBody;
725
+ const { selector, entries, parent } = this.applyVariants([0, overrideSelector || context.rawSelector, normalizedBody, void 0, context.variantHandlers]);
695
726
  const cssBody = `${selector}{${entriesToCss(entries)}}`;
696
727
  if (parent)
697
728
  return `${parent}{${cssBody}}`;
@@ -707,7 +738,13 @@ class UnoGenerator {
707
738
  if (staticMatch) {
708
739
  if (staticMatch[1] && (internal || !staticMatch[2]?.internal)) {
709
740
  recordRule(staticMatch[3]);
710
- return [[staticMatch[0], raw, normalizeCSSEntries(staticMatch[1]), staticMatch[2], variantHandlers]];
741
+ const index = staticMatch[0];
742
+ const entry = normalizeCSSEntries(staticMatch[1]);
743
+ const meta = staticMatch[2];
744
+ if (typeof entry === "string")
745
+ return [[index, entry, meta]];
746
+ else
747
+ return [[index, raw, entry, meta, variantHandlers]];
711
748
  }
712
749
  }
713
750
  context.variantHandlers = variantHandlers;
@@ -726,11 +763,15 @@ class UnoGenerator {
726
763
  if (!result)
727
764
  continue;
728
765
  recordRule(rule);
729
- if (typeof result === "string")
730
- return [[i, result, meta]];
731
766
  const entries = normalizeCSSValues(result).filter((i2) => i2.length);
732
- if (entries.length)
733
- return entries.map((e2) => [i, raw, e2, meta, variantHandlers]);
767
+ if (entries.length) {
768
+ return entries.map((e2) => {
769
+ if (typeof e2 === "string")
770
+ return [i, e2, meta];
771
+ else
772
+ return [i, raw, e2, meta, variantHandlers];
773
+ });
774
+ }
734
775
  }
735
776
  }
736
777
  stringifyUtil(parsed, context) {
package/dist/index.d.ts CHANGED
@@ -71,7 +71,7 @@ declare class UnoGenerator {
71
71
  matchVariants(raw: string, current?: string): VariantMatchedResult;
72
72
  applyVariants(parsed: ParsedUtil, variantHandlers?: VariantHandler[], raw?: string): UtilObject;
73
73
  constructCustomCSS(context: Readonly<RuleContext>, body: CSSObject | CSSEntries, overrideSelector?: string): string;
74
- parseUtil(input: string | VariantMatchedResult, context: RuleContext, internal?: boolean): Promise<ParsedUtil[] | RawUtil[] | undefined>;
74
+ parseUtil(input: string | VariantMatchedResult, context: RuleContext, internal?: boolean): Promise<(ParsedUtil | RawUtil)[] | undefined>;
75
75
  stringifyUtil(parsed?: ParsedUtil | RawUtil, context?: RuleContext): StringifiedUtil | undefined;
76
76
  expandShortcut(processed: string, context: RuleContext, depth?: number): [string[], RuleMeta | undefined] | undefined;
77
77
  stringifyShortcuts(parent: VariantMatchedResult, context: RuleContext, expanded: string[], meta?: RuleMeta): Promise<StringifiedUtil[] | undefined>;
@@ -90,8 +90,8 @@ declare function escapeRegExp(string: string): string;
90
90
  declare function escapeSelector(str: string): string;
91
91
  declare const e: typeof escapeSelector;
92
92
 
93
- declare function normalizeCSSEntries(obj: CSSEntries | CSSObject): CSSEntries;
94
- declare function normalizeCSSValues(obj: CSSValues): CSSEntries[];
93
+ declare function normalizeCSSEntries(obj: string | CSSEntries | CSSObject): string | CSSEntries;
94
+ declare function normalizeCSSValues(obj: CSSValue | string | (CSSValue | string)[]): (string | CSSEntries)[];
95
95
  declare function clearIdenticalEntries(entry: CSSEntries): CSSEntries;
96
96
  declare function entriesToCss(arr?: CSSEntries): string;
97
97
  declare function isObject(item: any): item is Record<string, any>;
@@ -315,8 +315,9 @@ interface RuleMeta {
315
315
  */
316
316
  internal?: boolean;
317
317
  }
318
- declare type CSSValues = CSSObject | CSSEntries | (CSSObject | CSSEntries)[];
319
- declare type DynamicMatcher<Theme extends {} = {}> = ((match: RegExpMatchArray, context: Readonly<RuleContext<Theme>>) => Awaitable<CSSValues | string | undefined>);
318
+ declare type CSSValue = CSSObject | CSSEntries;
319
+ declare type CSSValues = CSSValue | CSSValue[];
320
+ declare type DynamicMatcher<Theme extends {} = {}> = ((match: RegExpMatchArray, context: Readonly<RuleContext<Theme>>) => Awaitable<CSSValue | string | (CSSValue | string)[] | undefined>);
320
321
  declare type DynamicRule<Theme extends {} = {}> = [RegExp, DynamicMatcher<Theme>] | [RegExp, DynamicMatcher<Theme>, RuleMeta];
321
322
  declare type StaticRule = [string, CSSObject | CSSEntries] | [string, CSSObject | CSSEntries, RuleMeta];
322
323
  declare type Rule<Theme extends {} = {}> = DynamicRule<Theme> | StaticRule;
@@ -565,7 +566,9 @@ interface UserOnlyOptions<Theme extends {} = {}> {
565
566
  interface UnocssPluginContext<Config extends UserConfig = UserConfig> {
566
567
  ready: Promise<LoadConfigResult<Config>>;
567
568
  uno: UnoGenerator;
569
+ /** All tokens scanned */
568
570
  tokens: Set<string>;
571
+ /** Map for all module's raw content */
569
572
  modules: BetterMap<string, string>;
570
573
  filter: (code: string, id: string) => boolean;
571
574
  extract: (code: string, id?: string) => Promise<void>;
@@ -686,6 +689,11 @@ declare type StringifiedUtil = readonly [
686
689
  meta: RuleMeta | undefined,
687
690
  context: RuleContext | undefined
688
691
  ];
692
+ declare type PreparedRule = readonly [
693
+ selector: [string, number][],
694
+ body: string,
695
+ noMerge: boolean
696
+ ];
689
697
  interface UtilObject {
690
698
  selector: string;
691
699
  entries: CSSEntries;
@@ -723,4 +731,4 @@ declare const extractorSplit: Extractor;
723
731
 
724
732
  declare const extractorSvelte: Extractor;
725
733
 
726
- export { ArgumentType, Arrayable, AutoCompleteExtractor, AutoCompleteExtractorContext, AutoCompleteExtractorResult, AutoCompleteFunction, AutoCompleteTemplate, Awaitable, BetterMap, BlocklistRule, CONTROL_SHORTCUT_NO_MERGE, CSSColorValue, CSSEntries, CSSObject, CSSValues, ConfigBase, DeepPartial, DetailString, DynamicMatcher, DynamicRule, DynamicShortcut, DynamicShortcutMatcher, ExtractStringOptions, Extractor, ExtractorContext, FilterPattern, FlatObjectTuple, GenerateOptions, GenerateResult, GeneratorOptions, ParsedColorValue, ParsedUtil, PartialByKeys, PluginOptions, Postprocessor, Preflight, PreflightContext, Preprocessor, Preset, PresetOptions, RGBAColorValue, Range, RawUtil, Replacement, RequiredByKey, ResolvedConfig, RestArgs, Rule, RuleContext, RuleMeta, Shift, Shortcut, SourceCodeTransformer, SourceMap, StaticRule, StaticShortcut, StaticShortcutMap, StringifiedUtil, SuggestResult, ThemeExtender, TransformResult, TwoKeyMap, UnoGenerator, UnocssPluginContext, UserConfig, UserConfigDefaults, UserOnlyOptions, UserShortcuts, UtilObject, ValueHandler, ValueHandlerCallback, Variant, VariantContext, VariantFunction, VariantHandler, VariantMatchedResult, VariantObject, attributifyRE, clearIdenticalEntries, clone, createGenerator, createValueHandler, cssIdRE, e, entriesToCss, escapeRegExp, escapeSelector, expandVariantGroup, extractQuoted, extractorSplit, extractorSvelte, hasScopePlaceholder, isAttributifySelector, isObject, isRawUtil, isStaticRule, isStaticShortcut, isValidSelector, matchingPair, mergeDeep, mergeSet, movePseudoElementsEnd, noop, normalizeCSSEntries, normalizeCSSValues, normalizeVariant, notNull, regexClassGroup, regexScopePlaceholder, toArray, toEscapedSelector, uniq, validateFilterRE, warnOnce, withLayer };
734
+ export { ArgumentType, Arrayable, AutoCompleteExtractor, AutoCompleteExtractorContext, AutoCompleteExtractorResult, AutoCompleteFunction, AutoCompleteTemplate, Awaitable, BetterMap, BlocklistRule, CONTROL_SHORTCUT_NO_MERGE, CSSColorValue, CSSEntries, CSSObject, CSSValue, CSSValues, ConfigBase, DeepPartial, DetailString, DynamicMatcher, DynamicRule, DynamicShortcut, DynamicShortcutMatcher, ExtractStringOptions, Extractor, ExtractorContext, FilterPattern, FlatObjectTuple, GenerateOptions, GenerateResult, GeneratorOptions, ParsedColorValue, ParsedUtil, PartialByKeys, PluginOptions, Postprocessor, Preflight, PreflightContext, PreparedRule, Preprocessor, Preset, PresetOptions, RGBAColorValue, Range, RawUtil, Replacement, RequiredByKey, ResolvedConfig, RestArgs, Rule, RuleContext, RuleMeta, Shift, Shortcut, SourceCodeTransformer, SourceMap, StaticRule, StaticShortcut, StaticShortcutMap, StringifiedUtil, SuggestResult, ThemeExtender, TransformResult, TwoKeyMap, UnoGenerator, UnocssPluginContext, UserConfig, UserConfigDefaults, UserOnlyOptions, UserShortcuts, UtilObject, ValueHandler, ValueHandlerCallback, Variant, VariantContext, VariantFunction, VariantHandler, VariantMatchedResult, VariantObject, attributifyRE, clearIdenticalEntries, clone, createGenerator, createValueHandler, cssIdRE, e, entriesToCss, escapeRegExp, escapeSelector, expandVariantGroup, extractQuoted, extractorSplit, extractorSvelte, hasScopePlaceholder, isAttributifySelector, isObject, isRawUtil, isStaticRule, isStaticShortcut, isValidSelector, matchingPair, mergeDeep, mergeSet, movePseudoElementsEnd, noop, normalizeCSSEntries, normalizeCSSValues, normalizeVariant, notNull, regexClassGroup, regexScopePlaceholder, toArray, toEscapedSelector, uniq, validateFilterRE, warnOnce, withLayer };
package/dist/index.mjs CHANGED
@@ -36,6 +36,8 @@ function escapeSelector(str) {
36
36
  const e = escapeSelector;
37
37
 
38
38
  function normalizeCSSEntries(obj) {
39
+ if (typeof obj === "string")
40
+ return obj;
39
41
  return (!Array.isArray(obj) ? Object.entries(obj) : obj).filter((i) => i[1] != null);
40
42
  }
41
43
  function normalizeCSSValues(obj) {
@@ -454,7 +456,7 @@ function resolveConfig(userConfig = {}, defaults = {}) {
454
456
  };
455
457
  }
456
458
 
457
- const version = "0.38.0";
459
+ const version = "0.39.0";
458
460
 
459
461
  class UnoGenerator {
460
462
  constructor(userConfig = {}, defaults = {}) {
@@ -559,7 +561,8 @@ class UnoGenerator {
559
561
  const layerSet = /* @__PURE__ */ new Set(["default"]);
560
562
  const matched = /* @__PURE__ */ new Set();
561
563
  const sheet = /* @__PURE__ */ new Map();
562
- await Promise.all(Array.from(tokens).map(async (raw) => {
564
+ let preflightsMap = {};
565
+ const tokenPromises = Array.from(tokens).map(async (raw) => {
563
566
  if (matched.has(raw))
564
567
  return;
565
568
  const payload = await this.parseToken(raw);
@@ -568,52 +571,68 @@ class UnoGenerator {
568
571
  matched.add(raw);
569
572
  for (const item of payload) {
570
573
  const parent = item[3] || "";
574
+ const layer = item[4]?.layer;
571
575
  if (!sheet.has(parent))
572
576
  sheet.set(parent, []);
573
577
  sheet.get(parent).push(item);
574
- if (item[4]?.layer)
575
- layerSet.add(item[4].layer);
578
+ if (layer)
579
+ layerSet.add(layer);
576
580
  }
577
- }));
578
- if (preflights) {
579
- this.config.preflights.forEach((i) => {
580
- if (i.layer)
581
- layerSet.add(i.layer);
582
- });
583
- }
584
- const layerCache = {};
585
- const layers = this.config.sortLayers(Array.from(layerSet).sort((a, b) => (this.config.layers[a] ?? 0) - (this.config.layers[b] ?? 0) || a.localeCompare(b)));
586
- let preflightsMap = {};
587
- if (preflights) {
581
+ });
582
+ const preflightPromise = (async () => {
583
+ if (!preflights)
584
+ return;
588
585
  const preflightContext = {
589
586
  generator: this,
590
587
  theme: this.config.theme
591
588
  };
592
- preflightsMap = Object.fromEntries(await Promise.all(layers.map(async (layer) => {
589
+ const preflightLayerSet = /* @__PURE__ */ new Set(["default"]);
590
+ this.config.preflights.forEach(({ layer }) => {
591
+ if (layer) {
592
+ layerSet.add(layer);
593
+ preflightLayerSet.add(layer);
594
+ }
595
+ });
596
+ preflightsMap = Object.fromEntries(await Promise.all(Array.from(preflightLayerSet).map(async (layer) => {
593
597
  const preflights2 = await Promise.all(this.config.preflights.filter((i) => (i.layer || "default") === layer).map(async (i) => await i.getCSS(preflightContext)));
594
598
  const css = preflights2.filter(Boolean).join(nl);
595
599
  return [layer, css];
596
600
  })));
597
- }
601
+ })();
602
+ await Promise.all([
603
+ ...tokenPromises,
604
+ preflightPromise
605
+ ]);
606
+ const layers = this.config.sortLayers(Array.from(layerSet).sort((a, b) => (this.config.layers[a] ?? 0) - (this.config.layers[b] ?? 0) || a.localeCompare(b)));
607
+ const layerCache = {};
598
608
  const getLayer = (layer) => {
599
609
  if (layerCache[layer])
600
610
  return layerCache[layer];
601
611
  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]) => {
602
612
  const size = items.length;
603
- const sorted = items.filter((i) => (i[4]?.layer || "default") === layer).sort((a, b) => a[0] - b[0] || (a[4]?.sort || 0) - (b[4]?.sort || 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]]);
613
+ const sorted = items.filter((i) => (i[4]?.layer || "default") === layer).sort((a, b) => a[0] - b[0] || (a[4]?.sort || 0) - (b[4]?.sort || 0) || a[1]?.localeCompare(b[1] || "") || a[2]?.localeCompare(b[2] || "") || 0).map(([, selector, body, , meta]) => {
614
+ const scopedSelector = selector ? applyScope(selector, scope) : selector;
615
+ return [
616
+ [[scopedSelector ?? "", meta?.sort ?? 0]],
617
+ body,
618
+ !!meta?.noMerge
619
+ ];
620
+ });
604
621
  if (!sorted.length)
605
622
  return void 0;
606
- const rules = sorted.reverse().map(([selector, body, noMerge], idx) => {
607
- if (!noMerge && selector && this.config.mergeSelectors) {
623
+ const rules = sorted.reverse().map(([selectorSortPair, body, noMerge], idx) => {
624
+ if (!noMerge && this.config.mergeSelectors) {
608
625
  for (let i = idx + 1; i < size; i++) {
609
626
  const current = sorted[i];
610
- if (current && !current[2] && current[0] && current[1] === body) {
611
- current[0].push(...selector);
627
+ if (current && !current[2] && (selectorSortPair && current[0] || selectorSortPair == null && current[0] == null) && current[1] === body) {
628
+ if (selectorSortPair && current[0])
629
+ current[0].push(...selectorSortPair);
612
630
  return null;
613
631
  }
614
632
  }
615
633
  }
616
- return selector ? `${[...new Set(selector)].join(`,${nl}`)}{${body}}` : body;
634
+ const selectors = selectorSortPair ? [...new Set(selectorSortPair.sort((a, b) => a[1] - b[1] || a[0]?.localeCompare(b[0] || "") || 0).map((pair) => pair[0]).filter(Boolean))] : [];
635
+ return selectors.length ? `${selectors.join(`,${nl}`)}{${body}}` : body;
617
636
  }).filter(Boolean).reverse().join(nl);
618
637
  return parent ? `${parent}{${nl}${rules}${nl}}` : rules;
619
638
  }).filter(Boolean).join(nl);
@@ -672,22 +691,34 @@ class UnoGenerator {
672
691
  }
673
692
  applyVariants(parsed, variantHandlers = parsed[4], raw = parsed[1]) {
674
693
  const handlers = [...variantHandlers].sort((a, b) => (a.order || 0) - (b.order || 0));
675
- const entries = handlers.reduce((p, v) => v.body?.(p) || p, parsed[2]);
676
- const selector = handlers.reduce((p, v) => v.selector?.(p, entries) || p, toEscapedSelector(raw));
694
+ let entries = parsed[2];
695
+ let selector = toEscapedSelector(raw);
696
+ let parent;
697
+ let layer;
698
+ let sort;
699
+ handlers.forEach((v) => {
700
+ entries = v.body?.(entries) || entries;
701
+ selector = v.selector?.(selector, entries) || selector;
702
+ parent = Array.isArray(v.parent) ? v.parent[0] : v.parent || parent;
703
+ layer = v.layer || layer;
704
+ sort = v.sort || sort;
705
+ });
677
706
  const obj = {
678
707
  selector: movePseudoElementsEnd(selector),
679
708
  entries,
680
- parent: handlers.reduce((p, v) => Array.isArray(v.parent) ? v.parent[0] : v.parent || p, void 0),
681
- layer: handlers.reduce((p, v) => v.layer || p, void 0),
682
- sort: handlers.reduce((p, v) => v.sort || p, void 0)
709
+ parent,
710
+ layer,
711
+ sort
683
712
  };
684
713
  for (const p of this.config.postprocess)
685
714
  p(obj);
686
715
  return obj;
687
716
  }
688
717
  constructCustomCSS(context, body, overrideSelector) {
689
- body = normalizeCSSEntries(body);
690
- const { selector, entries, parent } = this.applyVariants([0, overrideSelector || context.rawSelector, body, void 0, context.variantHandlers]);
718
+ const normalizedBody = normalizeCSSEntries(body);
719
+ if (typeof normalizedBody === "string")
720
+ return normalizedBody;
721
+ const { selector, entries, parent } = this.applyVariants([0, overrideSelector || context.rawSelector, normalizedBody, void 0, context.variantHandlers]);
691
722
  const cssBody = `${selector}{${entriesToCss(entries)}}`;
692
723
  if (parent)
693
724
  return `${parent}{${cssBody}}`;
@@ -703,7 +734,13 @@ class UnoGenerator {
703
734
  if (staticMatch) {
704
735
  if (staticMatch[1] && (internal || !staticMatch[2]?.internal)) {
705
736
  recordRule(staticMatch[3]);
706
- return [[staticMatch[0], raw, normalizeCSSEntries(staticMatch[1]), staticMatch[2], variantHandlers]];
737
+ const index = staticMatch[0];
738
+ const entry = normalizeCSSEntries(staticMatch[1]);
739
+ const meta = staticMatch[2];
740
+ if (typeof entry === "string")
741
+ return [[index, entry, meta]];
742
+ else
743
+ return [[index, raw, entry, meta, variantHandlers]];
707
744
  }
708
745
  }
709
746
  context.variantHandlers = variantHandlers;
@@ -722,11 +759,15 @@ class UnoGenerator {
722
759
  if (!result)
723
760
  continue;
724
761
  recordRule(rule);
725
- if (typeof result === "string")
726
- return [[i, result, meta]];
727
762
  const entries = normalizeCSSValues(result).filter((i2) => i2.length);
728
- if (entries.length)
729
- return entries.map((e2) => [i, raw, e2, meta, variantHandlers]);
763
+ if (entries.length) {
764
+ return entries.map((e2) => {
765
+ if (typeof e2 === "string")
766
+ return [i, e2, meta];
767
+ else
768
+ return [i, raw, e2, meta, variantHandlers];
769
+ });
770
+ }
730
771
  }
731
772
  }
732
773
  stringifyUtil(parsed, context) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unocss/core",
3
- "version": "0.38.0",
3
+ "version": "0.39.0",
4
4
  "description": "The instant on-demand Atomic CSS engine.",
5
5
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
6
6
  "license": "MIT",