Skip to content

Commit 5b67c04

Browse files
zyyvCopilot
andauthored
feat(core): add noScope key determines whether to wrap the selector (#5130)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent dc1cb1a commit 5b67c04

File tree

5 files changed

+81
-46
lines changed

5 files changed

+81
-46
lines changed

packages-engine/core/src/generator.ts

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { createNanoEvents } from './utils/events'
88
export const symbols: ControlSymbols = {
99
shortcutsNoMerge: '$$symbol-shortcut-no-merge' as unknown as ControlSymbols['shortcutsNoMerge'],
1010
noMerge: '$$symbol-no-merge' as unknown as ControlSymbols['noMerge'],
11+
noScope: '$$symbol-no-scope' as unknown as ControlSymbols['noScope'],
1112
variants: '$$symbol-variants' as unknown as ControlSymbols['variants'],
1213
parent: '$$symbol-parent' as unknown as ControlSymbols['parent'],
1314
selector: '$$symbol-selector' as unknown as ControlSymbols['selector'],
@@ -323,7 +324,7 @@ class UnoGeneratorInternal<Theme extends object = object> {
323324
|| 0
324325
})
325326
.map(([, selector, body, , meta, , variantNoMerge]) => {
326-
const scopedSelector = selector ? applyScope(selector, scope) : selector
327+
const scopedSelector = (selector && !meta?.noScope) ? applyScope(selector, scope) : selector
327328
return [
328329
[[scopedSelector ?? '', meta?.sort ?? 0]],
329330
body,
@@ -701,50 +702,49 @@ class UnoGeneratorInternal<Theme extends object = object> {
701702
// Extract variants from special symbols
702703
let variants = context.variantHandlers
703704
let entryMeta = meta
704-
for (const entry of css) {
705-
if (entry[0] === symbols.variants) {
706-
if (typeof entry[1] === 'function') {
707-
variants = entry[1](variants) || variants
708-
}
709-
else {
710-
variants = [
711-
...toArray(entry[1]),
712-
...variants,
713-
]
714-
}
715-
}
716-
else if (entry[0] === symbols.parent) {
717-
variants = [
718-
{ parent: entry[1] },
719-
...variants,
720-
]
721-
}
722-
else if (entry[0] === symbols.selector) {
723-
variants = [
724-
{ selector: entry[1] },
725-
...variants,
726-
]
727-
}
728-
else if (entry[0] === symbols.layer) {
729-
variants = [
730-
{ layer: entry[1] },
731-
...variants,
732-
]
733-
}
734-
else if (entry[0] === symbols.sort) {
735-
entryMeta = {
736-
...entryMeta,
737-
sort: entry[1],
738-
}
739-
}
740-
else if (entry[0] === symbols.noMerge) {
741-
entryMeta = {
742-
...entryMeta,
743-
noMerge: entry[1],
744-
}
705+
const setVariant = (variant: (typeof variants)[number]) => {
706+
variants = [variant, ...variants]
707+
}
708+
const setMeta = (partial: Partial<RuleMeta>) => {
709+
entryMeta = {
710+
...entryMeta,
711+
...partial,
745712
}
746-
else if (entry[0] === symbols.body) {
747-
(entry as unknown as CSSEntry)[0] = VirtualKey
713+
}
714+
for (const entry of css) {
715+
switch (entry[0]) {
716+
case symbols.variants:
717+
if (typeof entry[1] === 'function') {
718+
variants = entry[1](variants) || variants
719+
}
720+
else {
721+
variants = [
722+
...toArray(entry[1]),
723+
...variants,
724+
]
725+
}
726+
break
727+
case symbols.parent:
728+
setVariant({ parent: entry[1] })
729+
break
730+
case symbols.selector:
731+
setVariant({ selector: entry[1] })
732+
break
733+
case symbols.layer:
734+
setVariant({ layer: entry[1] })
735+
break
736+
case symbols.sort:
737+
setMeta({ sort: entry[1] })
738+
break
739+
case symbols.noMerge:
740+
setMeta({ noMerge: entry[1] })
741+
break
742+
case symbols.noScope:
743+
setMeta({ noScope: entry[1] })
744+
break
745+
case symbols.body:
746+
(entry as unknown as CSSEntry)[0] = VirtualKey
747+
break
748748
}
749749
}
750750

packages-engine/core/src/types.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ export interface RuleContext<Theme extends object = object> {
8080

8181
declare const SymbolShortcutsNoMerge: unique symbol
8282
declare const SymbolNoMerge: unique symbol
83+
declare const SymbolNoScope: unique symbol
8384
declare const SymbolVariants: unique symbol
8485
declare const SymbolParent: unique symbol
8586
declare const SymbolSelector: unique symbol
@@ -96,6 +97,10 @@ export interface ControlSymbols {
9697
* Prevent merging in rules
9798
*/
9899
noMerge: typeof SymbolNoMerge
100+
/**
101+
* Prevent applying the `scope` option to this rule/selector
102+
*/
103+
noScope: typeof SymbolNoScope
99104
/**
100105
* Additional variants applied to this rule
101106
*/
@@ -125,6 +130,7 @@ export interface ControlSymbols {
125130
export interface ControlSymbolsValue {
126131
[SymbolShortcutsNoMerge]: true
127132
[SymbolNoMerge]: true
133+
[SymbolNoScope]: true
128134
[SymbolVariants]: VariantHandler[] | ((handlers: VariantHandler[]) => VariantHandler[])
129135
[SymbolParent]: string
130136
[SymbolSelector]: (selector: string) => string
@@ -199,6 +205,12 @@ export interface RuleMeta {
199205
*/
200206
noMerge?: boolean
201207

208+
/**
209+
* Option to not apply scope to this selector.
210+
* @default false
211+
*/
212+
noScope?: boolean
213+
202214
/**
203215
* Fine tune sort
204216
*/

packages-engine/core/test/__snapshots__/extended-info.test.ts.snap

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Map {
3434
"body": "$$symbol-body",
3535
"layer": "$$symbol-layer",
3636
"noMerge": "$$symbol-no-merge",
37+
"noScope": "$$symbol-no-scope",
3738
"parent": "$$symbol-parent",
3839
"selector": "$$symbol-selector",
3940
"shortcutsNoMerge": "$$symbol-shortcut-no-merge",
@@ -86,6 +87,7 @@ Map {
8687
"body": "$$symbol-body",
8788
"layer": "$$symbol-layer",
8889
"noMerge": "$$symbol-no-merge",
90+
"noScope": "$$symbol-no-scope",
8991
"parent": "$$symbol-parent",
9092
"selector": "$$symbol-selector",
9193
"shortcutsNoMerge": "$$symbol-shortcut-no-merge",
@@ -136,6 +138,7 @@ Map {
136138
"body": "$$symbol-body",
137139
"layer": "$$symbol-layer",
138140
"noMerge": "$$symbol-no-merge",
141+
"noScope": "$$symbol-no-scope",
139142
"parent": "$$symbol-parent",
140143
"selector": "$$symbol-selector",
141144
"shortcutsNoMerge": "$$symbol-shortcut-no-merge",

packages-engine/core/test/scope.test.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { createGenerator } from '@unocss/core'
2-
import presetUno from '@unocss/preset-uno'
2+
import presetWind3 from '@unocss/preset-wind3'
3+
import presetWind4 from '@unocss/preset-wind4'
34
import { expect, it } from 'vitest'
45

56
export const fixture = new Set([
@@ -19,11 +20,29 @@ export const fixture = new Set([
1920

2021
const uno = await createGenerator({
2122
presets: [
22-
presetUno(),
23+
presetWind3(),
2324
],
2425
})
2526

2627
it('scope', async () => {
2728
const { css } = await uno.generate(fixture, { scope: '.foo-scope', preflights: false })
2829
expect(css).toMatchSnapshot()
2930
})
31+
32+
it('scope with property layer', async () => {
33+
const uno = await createGenerator({
34+
presets: [
35+
presetWind4(),
36+
],
37+
})
38+
const { css } = await uno.generate('text-red', { scope: '.foo-scope', preflights: false })
39+
expect(css).toMatchInlineSnapshot(`
40+
"/* layer: properties */
41+
@property --un-text-opacity{syntax:"<percentage>";inherits:false;initial-value:100%;}
42+
/* layer: default */
43+
.foo-scope .text-red{color:color-mix(in srgb, var(--colors-red-DEFAULT) var(--un-text-opacity), transparent);}
44+
@supports (color: color-mix(in lab, red, red)){
45+
.foo-scope .text-red{color:color-mix(in oklab, var(--colors-red-DEFAULT) var(--un-text-opacity), transparent);}
46+
}"
47+
`)
48+
})

packages-presets/preset-wind4/src/utils/utilities.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ export function defineProperty(
395395
const value: CSSObjectInput = {
396396
[symbols.shortcutsNoMerge]: true,
397397
[symbols.noMerge]: true,
398+
[symbols.noScope]: true,
398399
[symbols.variants]: () => [
399400
{
400401
parent: '',

0 commit comments

Comments
 (0)