@unocss/core 0.58.4 → 0.58.6

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
@@ -226,6 +226,14 @@ class TwoKeyMap {
226
226
  }
227
227
  }
228
228
  class BetterMap extends Map {
229
+ getFallback(key, fallback) {
230
+ const v = this.get(key);
231
+ if (v === void 0) {
232
+ this.set(key, fallback);
233
+ return fallback;
234
+ }
235
+ return v;
236
+ }
229
237
  map(mapFn) {
230
238
  const result = [];
231
239
  this.forEach((v, k) => {
@@ -233,6 +241,13 @@ class BetterMap extends Map {
233
241
  });
234
242
  return result;
235
243
  }
244
+ flatMap(mapFn) {
245
+ const result = [];
246
+ this.forEach((v, k) => {
247
+ result.push(...mapFn(v, k));
248
+ });
249
+ return result;
250
+ }
236
251
  }
237
252
 
238
253
  var __defProp$1 = Object.defineProperty;
@@ -590,7 +605,7 @@ function definePreset(preset) {
590
605
  return preset;
591
606
  }
592
607
 
593
- const version = "0.58.4";
608
+ const version = "0.58.6";
594
609
 
595
610
  var __defProp = Object.defineProperty;
596
611
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -697,6 +712,7 @@ class UnoGenerator {
697
712
  minify = false,
698
713
  extendedInfo = false
699
714
  } = options;
715
+ const outputCssLayers = this.config.outputToCssLayers;
700
716
  const tokens = isString(input) ? await this.applyExtractors(
701
717
  input,
702
718
  id,
@@ -764,7 +780,7 @@ class UnoGenerator {
764
780
  })();
765
781
  const layers = this.config.sortLayers(Array.from(layerSet).sort((a, b) => (this.config.layers[a] ?? 0) - (this.config.layers[b] ?? 0) || a.localeCompare(b)));
766
782
  const layerCache = {};
767
- const getLayer = (layer) => {
783
+ const getLayer = (layer = LAYER_DEFAULT) => {
768
784
  if (layerCache[layer])
769
785
  return layerCache[layer];
770
786
  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]) => {
@@ -803,6 +819,14 @@ class UnoGenerator {
803
819
  if (preflights) {
804
820
  css = [preflightsMap[layer], css].filter(Boolean).join(nl);
805
821
  }
822
+ if (outputCssLayers && css) {
823
+ let cssLayer = typeof outputCssLayers === "object" ? outputCssLayers.cssLayerName?.(layer) : void 0;
824
+ if (cssLayer !== null) {
825
+ if (!cssLayer)
826
+ cssLayer = layer;
827
+ css = `@layer ${cssLayer}{${nl}${css}${nl}}`;
828
+ }
829
+ }
806
830
  const layerMark = minify ? "" : `/* layer: ${layer} */${nl}`;
807
831
  return layerCache[layer] = css ? layerMark + css : "";
808
832
  };
@@ -1034,7 +1058,7 @@ class UnoGenerator {
1034
1058
  ];
1035
1059
  }
1036
1060
  async stringifyShortcuts(parent, context, expanded, meta = { layer: this.config.shortcutsLayer }) {
1037
- const selectorMap = new TwoKeyMap();
1061
+ const layerMap = new BetterMap();
1038
1062
  const parsed = (await Promise.all(uniq(expanded).map(async (i) => {
1039
1063
  const result = isString(i) ? await this.parseUtil(i, context, true, meta.prefix) : [[Number.POSITIVE_INFINITY, "{inline}", normalizeCSSEntries(i), void 0, []]];
1040
1064
  if (!result && this.config.warn)
@@ -1048,30 +1072,33 @@ class UnoGenerator {
1048
1072
  rawStringifiedUtil.push([item[0], void 0, item[1], void 0, item[2], context, void 0]);
1049
1073
  continue;
1050
1074
  }
1051
- const { selector, entries, parent: parent2, sort, noMerge } = this.applyVariants(item, [...item[4], ...parentVariants], raw);
1075
+ const { selector, entries, parent: parent2, sort, noMerge, layer } = this.applyVariants(item, [...item[4], ...parentVariants], raw);
1076
+ const selectorMap = layerMap.getFallback(layer ?? meta.layer, new TwoKeyMap());
1052
1077
  const mapItem = selectorMap.getFallback(selector, parent2, [[], item[0]]);
1053
1078
  mapItem[0].push([entries, !!(noMerge ?? item[3]?.noMerge), sort ?? 0]);
1054
1079
  }
1055
- return rawStringifiedUtil.concat(selectorMap.map(([e2, index], selector, joinedParents) => {
1056
- const stringify = (flatten, noMerge, entrySortPair) => {
1057
- const maxSort = Math.max(...entrySortPair.map((e3) => e3[1]));
1058
- const entriesList = entrySortPair.map((e3) => e3[0]);
1059
- return (flatten ? [entriesList.flat(1)] : entriesList).map((entries) => {
1060
- const body = entriesToCss(entries);
1061
- if (body)
1062
- return [index, selector, body, joinedParents, { ...meta, noMerge, sort: maxSort }, context, void 0];
1063
- return void 0;
1064
- });
1065
- };
1066
- const merges = [
1067
- [e2.filter(([, noMerge]) => noMerge).map(([entries, , sort]) => [entries, sort]), true],
1068
- [e2.filter(([, noMerge]) => !noMerge).map(([entries, , sort]) => [entries, sort]), false]
1069
- ];
1070
- return merges.map(([e3, noMerge]) => [
1071
- ...stringify(false, noMerge, e3.filter(([entries]) => entries.some((entry) => entry[0] === CONTROL_SHORTCUT_NO_MERGE))),
1072
- ...stringify(true, noMerge, e3.filter(([entries]) => entries.every((entry) => entry[0] !== CONTROL_SHORTCUT_NO_MERGE)))
1073
- ]);
1074
- }).flat(2).filter(Boolean));
1080
+ return rawStringifiedUtil.concat(layerMap.flatMap(
1081
+ (selectorMap, layer) => selectorMap.map(([e2, index], selector, joinedParents) => {
1082
+ const stringify = (flatten, noMerge, entrySortPair) => {
1083
+ const maxSort = Math.max(...entrySortPair.map((e3) => e3[1]));
1084
+ const entriesList = entrySortPair.map((e3) => e3[0]);
1085
+ return (flatten ? [entriesList.flat(1)] : entriesList).map((entries) => {
1086
+ const body = entriesToCss(entries);
1087
+ if (body)
1088
+ return [index, selector, body, joinedParents, { ...meta, noMerge, sort: maxSort, layer }, context, void 0];
1089
+ return void 0;
1090
+ });
1091
+ };
1092
+ const merges = [
1093
+ [e2.filter(([, noMerge]) => noMerge).map(([entries, , sort]) => [entries, sort]), true],
1094
+ [e2.filter(([, noMerge]) => !noMerge).map(([entries, , sort]) => [entries, sort]), false]
1095
+ ];
1096
+ return merges.map(([e3, noMerge]) => [
1097
+ ...stringify(false, noMerge, e3.filter(([entries]) => entries.some((entry) => entry[0] === CONTROL_SHORTCUT_NO_MERGE))),
1098
+ ...stringify(true, noMerge, e3.filter(([entries]) => entries.every((entry) => entry[0] !== CONTROL_SHORTCUT_NO_MERGE)))
1099
+ ]);
1100
+ }).flat(2).filter(Boolean)
1101
+ ));
1075
1102
  }
1076
1103
  isBlocked(raw) {
1077
1104
  return !raw || this.config.blocklist.some((e2) => typeof e2 === "function" ? e2(raw) : isString(e2) ? e2 === raw : e2.test(raw));
package/dist/index.d.cts CHANGED
@@ -98,7 +98,9 @@ declare class TwoKeyMap<K1, K2, V> {
98
98
  map<T>(fn: (v: V, k1: K1, k2: K2) => T): T[];
99
99
  }
100
100
  declare class BetterMap<K, V> extends Map<K, V> {
101
+ getFallback(key: K, fallback: V): V;
101
102
  map<R>(mapFn: (value: V, key: K) => R): R[];
103
+ flatMap<R extends readonly unknown[]>(mapFn: (value: V, key: K) => R): R[number][];
102
104
  }
103
105
 
104
106
  declare class CountableSet<K> extends Set<K> {
@@ -296,7 +298,7 @@ interface Extractor {
296
298
  *
297
299
  * Return `undefined` to skip this extractor.
298
300
  */
299
- extract?(ctx: ExtractorContext): Awaitable<Set<string> | CountableSet<string> | string[] | undefined | void>;
301
+ extract?: (ctx: ExtractorContext) => Awaitable<Set<string> | CountableSet<string> | string[] | undefined | void>;
300
302
  }
301
303
  interface RuleMeta {
302
304
  /**
@@ -520,6 +522,10 @@ interface ConfigBase<Theme extends object = object> {
520
522
  * Layer orders. Default to 0.
521
523
  */
522
524
  layers?: Record<string, number>;
525
+ /**
526
+ * Output the internal layers as CSS Cascade Layers.
527
+ */
528
+ outputToCssLayers?: boolean | OutputCssLayersOptions;
523
529
  /**
524
530
  * Custom function to sort layers.
525
531
  */
@@ -578,6 +584,14 @@ interface ConfigBase<Theme extends object = object> {
578
584
  */
579
585
  details?: boolean;
580
586
  }
587
+ interface OutputCssLayersOptions {
588
+ /**
589
+ * Specify the css layer that the internal layer should be output to.
590
+ *
591
+ * Return `null` to specify that the layer should not be output to any css layer.
592
+ */
593
+ cssLayerName?: (internalLayer: string) => string | undefined | null;
594
+ }
581
595
  type AutoCompleteTemplate = string;
582
596
  type AutoCompleteFunction = (input: string) => Awaitable<string[]>;
583
597
  interface AutoCompleteExtractorContext {
@@ -702,7 +716,7 @@ interface UnocssPluginContext<Config extends UserConfig = UserConfig> {
702
716
  /**
703
717
  * Await all pending tasks
704
718
  */
705
- flushTasks(): Promise<any>;
719
+ flushTasks: () => Promise<any>;
706
720
  filter: (code: string, id: string) => boolean;
707
721
  extract: (code: string, id?: string) => Promise<void>;
708
722
  reloadConfig: () => Promise<LoadConfigResult<Config>>;
@@ -869,8 +883,8 @@ interface ResolvedConfig<Theme extends object = object> extends Omit<RequiredByK
869
883
  interface GenerateResult<T = Set<string>> {
870
884
  css: string;
871
885
  layers: string[];
872
- getLayer(name?: string): string | undefined;
873
- getLayers(includes?: string[], excludes?: string[]): string;
886
+ getLayer: (name?: string) => string | undefined;
887
+ getLayers: (includes?: string[], excludes?: string[]) => string;
874
888
  matched: T;
875
889
  }
876
890
  type VariantMatchedResult<Theme extends object = object> = readonly [
@@ -981,4 +995,4 @@ declare function mergeConfigs<Theme extends object = object>(configs: UserConfig
981
995
  declare function definePreset<Options extends object | undefined = undefined, Theme extends object = object>(preset: PresetFactory<Theme, Options>): PresetFactory<Theme, Options>;
982
996
  declare function definePreset<Theme extends object = object>(preset: Preset<Theme>): Preset<Theme>;
983
997
 
984
- export { type ArgumentType, type Arrayable, type AutoCompleteExtractor, type AutoCompleteExtractorContext, type AutoCompleteExtractorResult, type AutoCompleteFunction, type AutoCompleteTemplate, type Awaitable, BetterMap, type BlocklistRule, CONTROL_SHORTCUT_NO_MERGE, type CSSColorValue, type CSSEntries, type CSSObject, type CSSValue, type CSSValues, type CliEntryItem, type CliOptions, type ConfigBase, type ContentOptions, CountableSet, type DeepPartial, type DynamicMatcher, type DynamicRule, type DynamicShortcut, type DynamicShortcutMatcher, type ExtendedTokenInfo, type Extractor, type ExtractorContext, type FilterPattern, type FlatObjectTuple, type GenerateOptions, type GenerateResult, type GeneratorOptions, type HighlightAnnotation, type ParsedColorValue, type ParsedUtil, type PartialByKeys, type PluginOptions, type Postprocessor, type Preflight, type PreflightContext, type PreparedRule, type Preprocessor, type Preset, type PresetFactory, type PresetOptions, type PresetOrFactory, type RGBAColorValue, type RawUtil, type Replacement, type RequiredByKey, type ResolvedConfig, type RestArgs, type Rule, type RuleContext, type RuleMeta, type Shift, type Shortcut, type ShortcutValue, type SourceCodeTransformer, type SourceCodeTransformerEnforce, type SourceMap, type StaticRule, type StaticShortcut, type StaticShortcutMap, type StringifiedUtil, type SuggestResult, type ThemeExtender, type ToArray, TwoKeyMap, UnoGenerator, type UnocssPluginContext, type UserConfig, type UserConfigDefaults, type UserOnlyOptions, type UserShortcuts, type UtilObject, type Variant, type VariantContext, type VariantFunction, type VariantHandler, type VariantHandlerContext, type VariantMatchedResult, type VariantObject, attributifyRE, clearIdenticalEntries, clone, collapseVariantGroup, createGenerator, cssIdRE, defaultSplitRE, definePreset, e, entriesToCss, escapeRegExp, escapeSelector, expandVariantGroup, extractorSplit as extractorDefault, extractorSplit, hasScopePlaceholder, isAttributifySelector, isCountableSet, isObject, isRawUtil, isStaticRule, isStaticShortcut, isString, isValidSelector, makeRegexClassGroup, mergeConfigs, mergeDeep, noop, normalizeCSSEntries, normalizeCSSValues, normalizeVariant, notNull, parseVariantGroup, regexScopePlaceholder, resolveConfig, resolvePreset, resolvePresets, resolveShortcuts, splitWithVariantGroupRE, toArray, toEscapedSelector, uniq, uniqueBy, validateFilterRE, warnOnce, withLayer };
998
+ export { type ArgumentType, type Arrayable, type AutoCompleteExtractor, type AutoCompleteExtractorContext, type AutoCompleteExtractorResult, type AutoCompleteFunction, type AutoCompleteTemplate, type Awaitable, BetterMap, type BlocklistRule, CONTROL_SHORTCUT_NO_MERGE, type CSSColorValue, type CSSEntries, type CSSObject, type CSSValue, type CSSValues, type CliEntryItem, type CliOptions, type ConfigBase, type ContentOptions, CountableSet, type DeepPartial, type DynamicMatcher, type DynamicRule, type DynamicShortcut, type DynamicShortcutMatcher, type ExtendedTokenInfo, type Extractor, type ExtractorContext, type FilterPattern, type FlatObjectTuple, type GenerateOptions, type GenerateResult, type GeneratorOptions, type HighlightAnnotation, type OutputCssLayersOptions, type ParsedColorValue, type ParsedUtil, type PartialByKeys, type PluginOptions, type Postprocessor, type Preflight, type PreflightContext, type PreparedRule, type Preprocessor, type Preset, type PresetFactory, type PresetOptions, type PresetOrFactory, type RGBAColorValue, type RawUtil, type Replacement, type RequiredByKey, type ResolvedConfig, type RestArgs, type Rule, type RuleContext, type RuleMeta, type Shift, type Shortcut, type ShortcutValue, type SourceCodeTransformer, type SourceCodeTransformerEnforce, type SourceMap, type StaticRule, type StaticShortcut, type StaticShortcutMap, type StringifiedUtil, type SuggestResult, type ThemeExtender, type ToArray, TwoKeyMap, UnoGenerator, type UnocssPluginContext, type UserConfig, type UserConfigDefaults, type UserOnlyOptions, type UserShortcuts, type UtilObject, type Variant, type VariantContext, type VariantFunction, type VariantHandler, type VariantHandlerContext, type VariantMatchedResult, type VariantObject, attributifyRE, clearIdenticalEntries, clone, collapseVariantGroup, createGenerator, cssIdRE, defaultSplitRE, definePreset, e, entriesToCss, escapeRegExp, escapeSelector, expandVariantGroup, extractorSplit as extractorDefault, extractorSplit, hasScopePlaceholder, isAttributifySelector, isCountableSet, isObject, isRawUtil, isStaticRule, isStaticShortcut, isString, isValidSelector, makeRegexClassGroup, mergeConfigs, mergeDeep, noop, normalizeCSSEntries, normalizeCSSValues, normalizeVariant, notNull, parseVariantGroup, regexScopePlaceholder, resolveConfig, resolvePreset, resolvePresets, resolveShortcuts, splitWithVariantGroupRE, toArray, toEscapedSelector, uniq, uniqueBy, validateFilterRE, warnOnce, withLayer };
package/dist/index.d.mts CHANGED
@@ -98,7 +98,9 @@ declare class TwoKeyMap<K1, K2, V> {
98
98
  map<T>(fn: (v: V, k1: K1, k2: K2) => T): T[];
99
99
  }
100
100
  declare class BetterMap<K, V> extends Map<K, V> {
101
+ getFallback(key: K, fallback: V): V;
101
102
  map<R>(mapFn: (value: V, key: K) => R): R[];
103
+ flatMap<R extends readonly unknown[]>(mapFn: (value: V, key: K) => R): R[number][];
102
104
  }
103
105
 
104
106
  declare class CountableSet<K> extends Set<K> {
@@ -296,7 +298,7 @@ interface Extractor {
296
298
  *
297
299
  * Return `undefined` to skip this extractor.
298
300
  */
299
- extract?(ctx: ExtractorContext): Awaitable<Set<string> | CountableSet<string> | string[] | undefined | void>;
301
+ extract?: (ctx: ExtractorContext) => Awaitable<Set<string> | CountableSet<string> | string[] | undefined | void>;
300
302
  }
301
303
  interface RuleMeta {
302
304
  /**
@@ -520,6 +522,10 @@ interface ConfigBase<Theme extends object = object> {
520
522
  * Layer orders. Default to 0.
521
523
  */
522
524
  layers?: Record<string, number>;
525
+ /**
526
+ * Output the internal layers as CSS Cascade Layers.
527
+ */
528
+ outputToCssLayers?: boolean | OutputCssLayersOptions;
523
529
  /**
524
530
  * Custom function to sort layers.
525
531
  */
@@ -578,6 +584,14 @@ interface ConfigBase<Theme extends object = object> {
578
584
  */
579
585
  details?: boolean;
580
586
  }
587
+ interface OutputCssLayersOptions {
588
+ /**
589
+ * Specify the css layer that the internal layer should be output to.
590
+ *
591
+ * Return `null` to specify that the layer should not be output to any css layer.
592
+ */
593
+ cssLayerName?: (internalLayer: string) => string | undefined | null;
594
+ }
581
595
  type AutoCompleteTemplate = string;
582
596
  type AutoCompleteFunction = (input: string) => Awaitable<string[]>;
583
597
  interface AutoCompleteExtractorContext {
@@ -702,7 +716,7 @@ interface UnocssPluginContext<Config extends UserConfig = UserConfig> {
702
716
  /**
703
717
  * Await all pending tasks
704
718
  */
705
- flushTasks(): Promise<any>;
719
+ flushTasks: () => Promise<any>;
706
720
  filter: (code: string, id: string) => boolean;
707
721
  extract: (code: string, id?: string) => Promise<void>;
708
722
  reloadConfig: () => Promise<LoadConfigResult<Config>>;
@@ -869,8 +883,8 @@ interface ResolvedConfig<Theme extends object = object> extends Omit<RequiredByK
869
883
  interface GenerateResult<T = Set<string>> {
870
884
  css: string;
871
885
  layers: string[];
872
- getLayer(name?: string): string | undefined;
873
- getLayers(includes?: string[], excludes?: string[]): string;
886
+ getLayer: (name?: string) => string | undefined;
887
+ getLayers: (includes?: string[], excludes?: string[]) => string;
874
888
  matched: T;
875
889
  }
876
890
  type VariantMatchedResult<Theme extends object = object> = readonly [
@@ -981,4 +995,4 @@ declare function mergeConfigs<Theme extends object = object>(configs: UserConfig
981
995
  declare function definePreset<Options extends object | undefined = undefined, Theme extends object = object>(preset: PresetFactory<Theme, Options>): PresetFactory<Theme, Options>;
982
996
  declare function definePreset<Theme extends object = object>(preset: Preset<Theme>): Preset<Theme>;
983
997
 
984
- export { type ArgumentType, type Arrayable, type AutoCompleteExtractor, type AutoCompleteExtractorContext, type AutoCompleteExtractorResult, type AutoCompleteFunction, type AutoCompleteTemplate, type Awaitable, BetterMap, type BlocklistRule, CONTROL_SHORTCUT_NO_MERGE, type CSSColorValue, type CSSEntries, type CSSObject, type CSSValue, type CSSValues, type CliEntryItem, type CliOptions, type ConfigBase, type ContentOptions, CountableSet, type DeepPartial, type DynamicMatcher, type DynamicRule, type DynamicShortcut, type DynamicShortcutMatcher, type ExtendedTokenInfo, type Extractor, type ExtractorContext, type FilterPattern, type FlatObjectTuple, type GenerateOptions, type GenerateResult, type GeneratorOptions, type HighlightAnnotation, type ParsedColorValue, type ParsedUtil, type PartialByKeys, type PluginOptions, type Postprocessor, type Preflight, type PreflightContext, type PreparedRule, type Preprocessor, type Preset, type PresetFactory, type PresetOptions, type PresetOrFactory, type RGBAColorValue, type RawUtil, type Replacement, type RequiredByKey, type ResolvedConfig, type RestArgs, type Rule, type RuleContext, type RuleMeta, type Shift, type Shortcut, type ShortcutValue, type SourceCodeTransformer, type SourceCodeTransformerEnforce, type SourceMap, type StaticRule, type StaticShortcut, type StaticShortcutMap, type StringifiedUtil, type SuggestResult, type ThemeExtender, type ToArray, TwoKeyMap, UnoGenerator, type UnocssPluginContext, type UserConfig, type UserConfigDefaults, type UserOnlyOptions, type UserShortcuts, type UtilObject, type Variant, type VariantContext, type VariantFunction, type VariantHandler, type VariantHandlerContext, type VariantMatchedResult, type VariantObject, attributifyRE, clearIdenticalEntries, clone, collapseVariantGroup, createGenerator, cssIdRE, defaultSplitRE, definePreset, e, entriesToCss, escapeRegExp, escapeSelector, expandVariantGroup, extractorSplit as extractorDefault, extractorSplit, hasScopePlaceholder, isAttributifySelector, isCountableSet, isObject, isRawUtil, isStaticRule, isStaticShortcut, isString, isValidSelector, makeRegexClassGroup, mergeConfigs, mergeDeep, noop, normalizeCSSEntries, normalizeCSSValues, normalizeVariant, notNull, parseVariantGroup, regexScopePlaceholder, resolveConfig, resolvePreset, resolvePresets, resolveShortcuts, splitWithVariantGroupRE, toArray, toEscapedSelector, uniq, uniqueBy, validateFilterRE, warnOnce, withLayer };
998
+ export { type ArgumentType, type Arrayable, type AutoCompleteExtractor, type AutoCompleteExtractorContext, type AutoCompleteExtractorResult, type AutoCompleteFunction, type AutoCompleteTemplate, type Awaitable, BetterMap, type BlocklistRule, CONTROL_SHORTCUT_NO_MERGE, type CSSColorValue, type CSSEntries, type CSSObject, type CSSValue, type CSSValues, type CliEntryItem, type CliOptions, type ConfigBase, type ContentOptions, CountableSet, type DeepPartial, type DynamicMatcher, type DynamicRule, type DynamicShortcut, type DynamicShortcutMatcher, type ExtendedTokenInfo, type Extractor, type ExtractorContext, type FilterPattern, type FlatObjectTuple, type GenerateOptions, type GenerateResult, type GeneratorOptions, type HighlightAnnotation, type OutputCssLayersOptions, type ParsedColorValue, type ParsedUtil, type PartialByKeys, type PluginOptions, type Postprocessor, type Preflight, type PreflightContext, type PreparedRule, type Preprocessor, type Preset, type PresetFactory, type PresetOptions, type PresetOrFactory, type RGBAColorValue, type RawUtil, type Replacement, type RequiredByKey, type ResolvedConfig, type RestArgs, type Rule, type RuleContext, type RuleMeta, type Shift, type Shortcut, type ShortcutValue, type SourceCodeTransformer, type SourceCodeTransformerEnforce, type SourceMap, type StaticRule, type StaticShortcut, type StaticShortcutMap, type StringifiedUtil, type SuggestResult, type ThemeExtender, type ToArray, TwoKeyMap, UnoGenerator, type UnocssPluginContext, type UserConfig, type UserConfigDefaults, type UserOnlyOptions, type UserShortcuts, type UtilObject, type Variant, type VariantContext, type VariantFunction, type VariantHandler, type VariantHandlerContext, type VariantMatchedResult, type VariantObject, attributifyRE, clearIdenticalEntries, clone, collapseVariantGroup, createGenerator, cssIdRE, defaultSplitRE, definePreset, e, entriesToCss, escapeRegExp, escapeSelector, expandVariantGroup, extractorSplit as extractorDefault, extractorSplit, hasScopePlaceholder, isAttributifySelector, isCountableSet, isObject, isRawUtil, isStaticRule, isStaticShortcut, isString, isValidSelector, makeRegexClassGroup, mergeConfigs, mergeDeep, noop, normalizeCSSEntries, normalizeCSSValues, normalizeVariant, notNull, parseVariantGroup, regexScopePlaceholder, resolveConfig, resolvePreset, resolvePresets, resolveShortcuts, splitWithVariantGroupRE, toArray, toEscapedSelector, uniq, uniqueBy, validateFilterRE, warnOnce, withLayer };
package/dist/index.d.ts CHANGED
@@ -98,7 +98,9 @@ declare class TwoKeyMap<K1, K2, V> {
98
98
  map<T>(fn: (v: V, k1: K1, k2: K2) => T): T[];
99
99
  }
100
100
  declare class BetterMap<K, V> extends Map<K, V> {
101
+ getFallback(key: K, fallback: V): V;
101
102
  map<R>(mapFn: (value: V, key: K) => R): R[];
103
+ flatMap<R extends readonly unknown[]>(mapFn: (value: V, key: K) => R): R[number][];
102
104
  }
103
105
 
104
106
  declare class CountableSet<K> extends Set<K> {
@@ -296,7 +298,7 @@ interface Extractor {
296
298
  *
297
299
  * Return `undefined` to skip this extractor.
298
300
  */
299
- extract?(ctx: ExtractorContext): Awaitable<Set<string> | CountableSet<string> | string[] | undefined | void>;
301
+ extract?: (ctx: ExtractorContext) => Awaitable<Set<string> | CountableSet<string> | string[] | undefined | void>;
300
302
  }
301
303
  interface RuleMeta {
302
304
  /**
@@ -520,6 +522,10 @@ interface ConfigBase<Theme extends object = object> {
520
522
  * Layer orders. Default to 0.
521
523
  */
522
524
  layers?: Record<string, number>;
525
+ /**
526
+ * Output the internal layers as CSS Cascade Layers.
527
+ */
528
+ outputToCssLayers?: boolean | OutputCssLayersOptions;
523
529
  /**
524
530
  * Custom function to sort layers.
525
531
  */
@@ -578,6 +584,14 @@ interface ConfigBase<Theme extends object = object> {
578
584
  */
579
585
  details?: boolean;
580
586
  }
587
+ interface OutputCssLayersOptions {
588
+ /**
589
+ * Specify the css layer that the internal layer should be output to.
590
+ *
591
+ * Return `null` to specify that the layer should not be output to any css layer.
592
+ */
593
+ cssLayerName?: (internalLayer: string) => string | undefined | null;
594
+ }
581
595
  type AutoCompleteTemplate = string;
582
596
  type AutoCompleteFunction = (input: string) => Awaitable<string[]>;
583
597
  interface AutoCompleteExtractorContext {
@@ -702,7 +716,7 @@ interface UnocssPluginContext<Config extends UserConfig = UserConfig> {
702
716
  /**
703
717
  * Await all pending tasks
704
718
  */
705
- flushTasks(): Promise<any>;
719
+ flushTasks: () => Promise<any>;
706
720
  filter: (code: string, id: string) => boolean;
707
721
  extract: (code: string, id?: string) => Promise<void>;
708
722
  reloadConfig: () => Promise<LoadConfigResult<Config>>;
@@ -869,8 +883,8 @@ interface ResolvedConfig<Theme extends object = object> extends Omit<RequiredByK
869
883
  interface GenerateResult<T = Set<string>> {
870
884
  css: string;
871
885
  layers: string[];
872
- getLayer(name?: string): string | undefined;
873
- getLayers(includes?: string[], excludes?: string[]): string;
886
+ getLayer: (name?: string) => string | undefined;
887
+ getLayers: (includes?: string[], excludes?: string[]) => string;
874
888
  matched: T;
875
889
  }
876
890
  type VariantMatchedResult<Theme extends object = object> = readonly [
@@ -981,4 +995,4 @@ declare function mergeConfigs<Theme extends object = object>(configs: UserConfig
981
995
  declare function definePreset<Options extends object | undefined = undefined, Theme extends object = object>(preset: PresetFactory<Theme, Options>): PresetFactory<Theme, Options>;
982
996
  declare function definePreset<Theme extends object = object>(preset: Preset<Theme>): Preset<Theme>;
983
997
 
984
- export { type ArgumentType, type Arrayable, type AutoCompleteExtractor, type AutoCompleteExtractorContext, type AutoCompleteExtractorResult, type AutoCompleteFunction, type AutoCompleteTemplate, type Awaitable, BetterMap, type BlocklistRule, CONTROL_SHORTCUT_NO_MERGE, type CSSColorValue, type CSSEntries, type CSSObject, type CSSValue, type CSSValues, type CliEntryItem, type CliOptions, type ConfigBase, type ContentOptions, CountableSet, type DeepPartial, type DynamicMatcher, type DynamicRule, type DynamicShortcut, type DynamicShortcutMatcher, type ExtendedTokenInfo, type Extractor, type ExtractorContext, type FilterPattern, type FlatObjectTuple, type GenerateOptions, type GenerateResult, type GeneratorOptions, type HighlightAnnotation, type ParsedColorValue, type ParsedUtil, type PartialByKeys, type PluginOptions, type Postprocessor, type Preflight, type PreflightContext, type PreparedRule, type Preprocessor, type Preset, type PresetFactory, type PresetOptions, type PresetOrFactory, type RGBAColorValue, type RawUtil, type Replacement, type RequiredByKey, type ResolvedConfig, type RestArgs, type Rule, type RuleContext, type RuleMeta, type Shift, type Shortcut, type ShortcutValue, type SourceCodeTransformer, type SourceCodeTransformerEnforce, type SourceMap, type StaticRule, type StaticShortcut, type StaticShortcutMap, type StringifiedUtil, type SuggestResult, type ThemeExtender, type ToArray, TwoKeyMap, UnoGenerator, type UnocssPluginContext, type UserConfig, type UserConfigDefaults, type UserOnlyOptions, type UserShortcuts, type UtilObject, type Variant, type VariantContext, type VariantFunction, type VariantHandler, type VariantHandlerContext, type VariantMatchedResult, type VariantObject, attributifyRE, clearIdenticalEntries, clone, collapseVariantGroup, createGenerator, cssIdRE, defaultSplitRE, definePreset, e, entriesToCss, escapeRegExp, escapeSelector, expandVariantGroup, extractorSplit as extractorDefault, extractorSplit, hasScopePlaceholder, isAttributifySelector, isCountableSet, isObject, isRawUtil, isStaticRule, isStaticShortcut, isString, isValidSelector, makeRegexClassGroup, mergeConfigs, mergeDeep, noop, normalizeCSSEntries, normalizeCSSValues, normalizeVariant, notNull, parseVariantGroup, regexScopePlaceholder, resolveConfig, resolvePreset, resolvePresets, resolveShortcuts, splitWithVariantGroupRE, toArray, toEscapedSelector, uniq, uniqueBy, validateFilterRE, warnOnce, withLayer };
998
+ export { type ArgumentType, type Arrayable, type AutoCompleteExtractor, type AutoCompleteExtractorContext, type AutoCompleteExtractorResult, type AutoCompleteFunction, type AutoCompleteTemplate, type Awaitable, BetterMap, type BlocklistRule, CONTROL_SHORTCUT_NO_MERGE, type CSSColorValue, type CSSEntries, type CSSObject, type CSSValue, type CSSValues, type CliEntryItem, type CliOptions, type ConfigBase, type ContentOptions, CountableSet, type DeepPartial, type DynamicMatcher, type DynamicRule, type DynamicShortcut, type DynamicShortcutMatcher, type ExtendedTokenInfo, type Extractor, type ExtractorContext, type FilterPattern, type FlatObjectTuple, type GenerateOptions, type GenerateResult, type GeneratorOptions, type HighlightAnnotation, type OutputCssLayersOptions, type ParsedColorValue, type ParsedUtil, type PartialByKeys, type PluginOptions, type Postprocessor, type Preflight, type PreflightContext, type PreparedRule, type Preprocessor, type Preset, type PresetFactory, type PresetOptions, type PresetOrFactory, type RGBAColorValue, type RawUtil, type Replacement, type RequiredByKey, type ResolvedConfig, type RestArgs, type Rule, type RuleContext, type RuleMeta, type Shift, type Shortcut, type ShortcutValue, type SourceCodeTransformer, type SourceCodeTransformerEnforce, type SourceMap, type StaticRule, type StaticShortcut, type StaticShortcutMap, type StringifiedUtil, type SuggestResult, type ThemeExtender, type ToArray, TwoKeyMap, UnoGenerator, type UnocssPluginContext, type UserConfig, type UserConfigDefaults, type UserOnlyOptions, type UserShortcuts, type UtilObject, type Variant, type VariantContext, type VariantFunction, type VariantHandler, type VariantHandlerContext, type VariantMatchedResult, type VariantObject, attributifyRE, clearIdenticalEntries, clone, collapseVariantGroup, createGenerator, cssIdRE, defaultSplitRE, definePreset, e, entriesToCss, escapeRegExp, escapeSelector, expandVariantGroup, extractorSplit as extractorDefault, extractorSplit, hasScopePlaceholder, isAttributifySelector, isCountableSet, isObject, isRawUtil, isStaticRule, isStaticShortcut, isString, isValidSelector, makeRegexClassGroup, mergeConfigs, mergeDeep, noop, normalizeCSSEntries, normalizeCSSValues, normalizeVariant, notNull, parseVariantGroup, regexScopePlaceholder, resolveConfig, resolvePreset, resolvePresets, resolveShortcuts, splitWithVariantGroupRE, toArray, toEscapedSelector, uniq, uniqueBy, validateFilterRE, warnOnce, withLayer };
package/dist/index.mjs CHANGED
@@ -224,6 +224,14 @@ class TwoKeyMap {
224
224
  }
225
225
  }
226
226
  class BetterMap extends Map {
227
+ getFallback(key, fallback) {
228
+ const v = this.get(key);
229
+ if (v === void 0) {
230
+ this.set(key, fallback);
231
+ return fallback;
232
+ }
233
+ return v;
234
+ }
227
235
  map(mapFn) {
228
236
  const result = [];
229
237
  this.forEach((v, k) => {
@@ -231,6 +239,13 @@ class BetterMap extends Map {
231
239
  });
232
240
  return result;
233
241
  }
242
+ flatMap(mapFn) {
243
+ const result = [];
244
+ this.forEach((v, k) => {
245
+ result.push(...mapFn(v, k));
246
+ });
247
+ return result;
248
+ }
234
249
  }
235
250
 
236
251
  var __defProp$1 = Object.defineProperty;
@@ -588,7 +603,7 @@ function definePreset(preset) {
588
603
  return preset;
589
604
  }
590
605
 
591
- const version = "0.58.4";
606
+ const version = "0.58.6";
592
607
 
593
608
  var __defProp = Object.defineProperty;
594
609
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -695,6 +710,7 @@ class UnoGenerator {
695
710
  minify = false,
696
711
  extendedInfo = false
697
712
  } = options;
713
+ const outputCssLayers = this.config.outputToCssLayers;
698
714
  const tokens = isString(input) ? await this.applyExtractors(
699
715
  input,
700
716
  id,
@@ -762,7 +778,7 @@ class UnoGenerator {
762
778
  })();
763
779
  const layers = this.config.sortLayers(Array.from(layerSet).sort((a, b) => (this.config.layers[a] ?? 0) - (this.config.layers[b] ?? 0) || a.localeCompare(b)));
764
780
  const layerCache = {};
765
- const getLayer = (layer) => {
781
+ const getLayer = (layer = LAYER_DEFAULT) => {
766
782
  if (layerCache[layer])
767
783
  return layerCache[layer];
768
784
  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]) => {
@@ -801,6 +817,14 @@ class UnoGenerator {
801
817
  if (preflights) {
802
818
  css = [preflightsMap[layer], css].filter(Boolean).join(nl);
803
819
  }
820
+ if (outputCssLayers && css) {
821
+ let cssLayer = typeof outputCssLayers === "object" ? outputCssLayers.cssLayerName?.(layer) : void 0;
822
+ if (cssLayer !== null) {
823
+ if (!cssLayer)
824
+ cssLayer = layer;
825
+ css = `@layer ${cssLayer}{${nl}${css}${nl}}`;
826
+ }
827
+ }
804
828
  const layerMark = minify ? "" : `/* layer: ${layer} */${nl}`;
805
829
  return layerCache[layer] = css ? layerMark + css : "";
806
830
  };
@@ -1032,7 +1056,7 @@ class UnoGenerator {
1032
1056
  ];
1033
1057
  }
1034
1058
  async stringifyShortcuts(parent, context, expanded, meta = { layer: this.config.shortcutsLayer }) {
1035
- const selectorMap = new TwoKeyMap();
1059
+ const layerMap = new BetterMap();
1036
1060
  const parsed = (await Promise.all(uniq(expanded).map(async (i) => {
1037
1061
  const result = isString(i) ? await this.parseUtil(i, context, true, meta.prefix) : [[Number.POSITIVE_INFINITY, "{inline}", normalizeCSSEntries(i), void 0, []]];
1038
1062
  if (!result && this.config.warn)
@@ -1046,30 +1070,33 @@ class UnoGenerator {
1046
1070
  rawStringifiedUtil.push([item[0], void 0, item[1], void 0, item[2], context, void 0]);
1047
1071
  continue;
1048
1072
  }
1049
- const { selector, entries, parent: parent2, sort, noMerge } = this.applyVariants(item, [...item[4], ...parentVariants], raw);
1073
+ const { selector, entries, parent: parent2, sort, noMerge, layer } = this.applyVariants(item, [...item[4], ...parentVariants], raw);
1074
+ const selectorMap = layerMap.getFallback(layer ?? meta.layer, new TwoKeyMap());
1050
1075
  const mapItem = selectorMap.getFallback(selector, parent2, [[], item[0]]);
1051
1076
  mapItem[0].push([entries, !!(noMerge ?? item[3]?.noMerge), sort ?? 0]);
1052
1077
  }
1053
- return rawStringifiedUtil.concat(selectorMap.map(([e2, index], selector, joinedParents) => {
1054
- const stringify = (flatten, noMerge, entrySortPair) => {
1055
- const maxSort = Math.max(...entrySortPair.map((e3) => e3[1]));
1056
- const entriesList = entrySortPair.map((e3) => e3[0]);
1057
- return (flatten ? [entriesList.flat(1)] : entriesList).map((entries) => {
1058
- const body = entriesToCss(entries);
1059
- if (body)
1060
- return [index, selector, body, joinedParents, { ...meta, noMerge, sort: maxSort }, context, void 0];
1061
- return void 0;
1062
- });
1063
- };
1064
- const merges = [
1065
- [e2.filter(([, noMerge]) => noMerge).map(([entries, , sort]) => [entries, sort]), true],
1066
- [e2.filter(([, noMerge]) => !noMerge).map(([entries, , sort]) => [entries, sort]), false]
1067
- ];
1068
- return merges.map(([e3, noMerge]) => [
1069
- ...stringify(false, noMerge, e3.filter(([entries]) => entries.some((entry) => entry[0] === CONTROL_SHORTCUT_NO_MERGE))),
1070
- ...stringify(true, noMerge, e3.filter(([entries]) => entries.every((entry) => entry[0] !== CONTROL_SHORTCUT_NO_MERGE)))
1071
- ]);
1072
- }).flat(2).filter(Boolean));
1078
+ return rawStringifiedUtil.concat(layerMap.flatMap(
1079
+ (selectorMap, layer) => selectorMap.map(([e2, index], selector, joinedParents) => {
1080
+ const stringify = (flatten, noMerge, entrySortPair) => {
1081
+ const maxSort = Math.max(...entrySortPair.map((e3) => e3[1]));
1082
+ const entriesList = entrySortPair.map((e3) => e3[0]);
1083
+ return (flatten ? [entriesList.flat(1)] : entriesList).map((entries) => {
1084
+ const body = entriesToCss(entries);
1085
+ if (body)
1086
+ return [index, selector, body, joinedParents, { ...meta, noMerge, sort: maxSort, layer }, context, void 0];
1087
+ return void 0;
1088
+ });
1089
+ };
1090
+ const merges = [
1091
+ [e2.filter(([, noMerge]) => noMerge).map(([entries, , sort]) => [entries, sort]), true],
1092
+ [e2.filter(([, noMerge]) => !noMerge).map(([entries, , sort]) => [entries, sort]), false]
1093
+ ];
1094
+ return merges.map(([e3, noMerge]) => [
1095
+ ...stringify(false, noMerge, e3.filter(([entries]) => entries.some((entry) => entry[0] === CONTROL_SHORTCUT_NO_MERGE))),
1096
+ ...stringify(true, noMerge, e3.filter(([entries]) => entries.every((entry) => entry[0] !== CONTROL_SHORTCUT_NO_MERGE)))
1097
+ ]);
1098
+ }).flat(2).filter(Boolean)
1099
+ ));
1073
1100
  }
1074
1101
  isBlocked(raw) {
1075
1102
  return !raw || this.config.blocklist.some((e2) => typeof e2 === "function" ? e2(raw) : isString(e2) ? e2 === raw : e2.test(raw));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unocss/core",
3
- "version": "0.58.4",
3
+ "version": "0.58.6",
4
4
  "description": "The instant on-demand Atomic CSS engine.",
5
5
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
6
6
  "license": "MIT",
@@ -37,7 +37,7 @@
37
37
  "dist"
38
38
  ],
39
39
  "devDependencies": {
40
- "magic-string": "^0.30.5",
40
+ "magic-string": "^0.30.8",
41
41
  "unconfig": "^0.3.11"
42
42
  },
43
43
  "scripts": {