Skip to content

Commit 08be1e8

Browse files
committed
fix(preset-uno): transform base racing
1 parent 177bb68 commit 08be1e8

12 files changed

Lines changed: 66 additions & 46 deletions

File tree

packages/core/src/generator/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,11 +262,11 @@ export class UnoGenerator {
262262
}
263263

264264
applyVariants(parsed: ParsedUtil, variantHandlers = parsed[4], raw = parsed[1]) {
265+
const entries = variantHandlers.reduce((p, v) => v.body?.(p) || p, parsed[2])
265266
return [
266267
// selector
267-
variantHandlers.reduce((p, v) => v.selector?.(p) || p, toEscapedSelector(raw)),
268-
// entries
269-
variantHandlers.reduce((p, v) => v.body?.(p) || p, parsed[2]),
268+
variantHandlers.reduce((p, v) => v.selector?.(p, entries) || p, toEscapedSelector(raw)),
269+
entries,
270270
// parent
271271
variantHandlers.reduce((p: string | undefined, v) => Array.isArray(v.parent) ? v.parent[0] : v.parent || p, undefined),
272272
] as const

packages/core/src/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export interface VariantHandler {
9999
/**
100100
* Rewrite the output selector. Often be used to append pesudo classes or parents.
101101
*/
102-
selector?: (input: string) => string | undefined
102+
selector?: (input: string, body: CSSEntries) => string | undefined
103103
/**
104104
* Rewrite the output css body. The input come in [key,value][] pairs.
105105
*/

packages/core/src/utils/object.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ export function normalizeCSSValues(obj: CSSValues): CSSEntries[] {
1919

2020
export function clearIdenticalEntries(entry: CSSEntries): CSSEntries {
2121
return entry.filter(([k, v], idx) => {
22+
// remove control keys
23+
if (k.startsWith('$$'))
24+
return false
25+
// remove identical entries
2226
for (let i = idx - 1; i >= 0; i--) {
2327
if (entry[i][0] === k && entry[i][1] === v)
2428
return false

packages/preset-uno/src/rules/default.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { bgColors, opacity, textColors, textDecorationColors, textStrokeColors,
66
import { bgAttachments, bgBlendModes, bgClips, bgGradients, bgImages, bgOrigins, bgPositions, bgSizes, bgRepeats } from './background'
77
import { filters } from './filters'
88
import { flex } from './flex'
9-
import { fonts, leadings, tabSizes, textDecorationLengths, textDecorationOffsets, textIndents, textShadows, textStrokeWidths, trackings, wordSpacings } from './typography'
9+
import { fonts, fontVariantNumeric, leadings, tabSizes, textDecorationLengths, textDecorationOffsets, textIndents, textShadows, textStrokeWidths, trackings, wordSpacings } from './typography'
1010
import { gaps } from './gap'
1111
import { grids } from './grid'
1212
import { overflows } from './layout'
@@ -15,7 +15,7 @@ import { rings } from './ring'
1515
import { mixBlendModes, boxShadows } from './shadow'
1616
import { sizes, aspectRatio } from './size'
1717
import { paddings, margins } from './spacing'
18-
import { appearances, breaks, cursors, displays, pointerEvents, resizes, screenReadersAccess, textDecorations, textOverflows, textTransforms, userSelects, whitespaces, fontStyles, fontVariantNumeric, fontSmoothings, hyphens, textDecorationStyles, writingModes, writingOrientations, isolations, contents } from './static'
18+
import { appearances, breaks, cursors, displays, pointerEvents, resizes, screenReadersAccess, textDecorations, textOverflows, textTransforms, userSelects, whitespaces, fontStyles, fontSmoothings, hyphens, textDecorationStyles, writingModes, writingOrientations, isolations, contents } from './static'
1919
import { tables } from './table'
2020
import { transforms } from './transform'
2121
import { listStyle, caretColors, boxDecorationBreaks, caretOpacity, imageRenderings, appearance, placeholder, overscrolls, outline } from './behaviors'

packages/preset-uno/src/rules/filters.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Rule, toArray, RuleContext, CSSValues } from '@unocss/core'
22
import { Theme } from '../theme'
33
import { handler as h } from '../utils'
4+
import { CONTROL_BYPASS_PSEUDO } from '../variants/pseudo'
45

56
const varEmpty = 'var(--un-empty,/*!*/ /*!*/)'
67
const filterContnet = 'var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia) var(--un-drop-shadow)'
@@ -16,6 +17,7 @@ const filterBase = {
1617
'--un-sepia': varEmpty,
1718
'--un-drop-shadow': varEmpty,
1819
'filter': filterContnet,
20+
[CONTROL_BYPASS_PSEUDO]: '',
1921
}
2022

2123
const backdropFilterContent = 'var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-saturate) var(--un-backdrop-sepia)'
@@ -31,6 +33,7 @@ const backdropFilterBase = {
3133
'--un-backdrop-sepia': varEmpty,
3234
'-webkit-backdrop-filter': backdropFilterContent,
3335
'backdrop-filter': backdropFilterContent,
36+
[CONTROL_BYPASS_PSEUDO]: '',
3437
}
3538

3639
const percentWithDefault = (defaultValue = '1') => (str?: string) => {

packages/preset-uno/src/rules/static.ts

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Rule } from '@unocss/core'
22

3-
const varEmpty = 'var(--un-empty,/*!*/ /*!*/)'
3+
export const varEmpty = 'var(--un-empty,/*!*/ /*!*/)'
44

55
// display table included on table.ts
66
export const displays: Rule[] = [
@@ -90,27 +90,6 @@ export const fontStyles: Rule[] = [
9090
['not-italic', { 'font-style': 'normal' }],
9191
]
9292

93-
const fontVariantNumericBase = {
94-
'--un-ordinal': varEmpty,
95-
'--un-slashed-zero': varEmpty,
96-
'--un-numeric-figure': varEmpty,
97-
'--un-numeric-spacing': varEmpty,
98-
'--un-numeric-fraction': varEmpty,
99-
'font-variant-numeric': 'var(--un-ordinal) var(--un-slashed-zero) var(--un-numeric-figure) var(--un-numeric-spacing) var(--un-numeric-fraction)',
100-
}
101-
102-
export const fontVariantNumeric: Rule[] = [
103-
[/^ordinal$/, () => [fontVariantNumericBase, { '--un-ordinal': 'ordinal' }]],
104-
[/^slashed-zero$/, () => [fontVariantNumericBase, { '--un-slashed-zero': 'slashed-zero' }]],
105-
[/^lining-nums$/, () => [fontVariantNumericBase, { '--un-numeric-figure': 'lining-nums' }]],
106-
[/^oldstyle-nums$/, () => [fontVariantNumericBase, { '--un-numeric-figure': 'oldstyle-nums' }]],
107-
[/^proportional-nums$/, () => [fontVariantNumericBase, { '--un-numeric-spacing': 'proportional-nums' }]],
108-
[/^tabular-nums$/, () => [fontVariantNumericBase, { '--un-numeric-spacing': 'tabular-nums' }]],
109-
[/^diagonal-fractions$/, () => [fontVariantNumericBase, { '--un-numeric-fraction': 'diagonal-fractions' }]],
110-
[/^stacked-fractions$/, () => [fontVariantNumericBase, { '--un-numeric-fraction': 'stacked-fractions' }]],
111-
['normal-nums', { 'font-variant-numeric': 'normal' }],
112-
]
113-
11493
export const fontSmoothings: Rule[] = [
11594
['antialiased', {
11695
'-webkit-font-smoothing': 'antialiased',

packages/preset-uno/src/rules/transform.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Rule, CSSValues } from '@unocss/core'
22
import { xyzMap, handler as h } from '../utils'
3+
import { CONTROL_BYPASS_PSEUDO } from '../variants/pseudo'
34

45
const transformBase = {
56
'--un-rotate': 0,
@@ -12,6 +13,7 @@ const transformBase = {
1213
'--un-translate-y': 0,
1314
'--un-translate-z': 0,
1415
'transform': 'rotate(var(--un-rotate)) scaleX(var(--un-scale-x)) scaleY(var(--un-scale-y)) scaleZ(var(--un-scale-z)) skewX(var(--un-skew-x)) skewY(var(--un-skew-y)) translateX(var(--un-translate-x)) translateY(var(--un-translate-y)) translateZ(var(--un-translate-z))',
16+
[CONTROL_BYPASS_PSEUDO]: '',
1517
}
1618

1719
export const transforms: Rule[] = [

packages/preset-uno/src/rules/typography.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { toArray, Rule } from '@unocss/core'
22
import { Theme } from '../theme'
33
import { handler as h } from '../utils'
4+
import { CONTROL_BYPASS_PSEUDO } from '../variants/pseudo'
5+
import { varEmpty } from './static'
46

57
export const fontsFamilies: Rule<Theme>[] = [
68
[/^font-(\w+)$/, ([, d], { theme }) => {
@@ -125,6 +127,28 @@ export const textShadows: Rule<Theme>[] = [
125127
}],
126128
]
127129

130+
const fontVariantNumericBase = {
131+
'--un-ordinal': varEmpty,
132+
'--un-slashed-zero': varEmpty,
133+
'--un-numeric-figure': varEmpty,
134+
'--un-numeric-spacing': varEmpty,
135+
'--un-numeric-fraction': varEmpty,
136+
'font-variant-numeric': 'var(--un-ordinal) var(--un-slashed-zero) var(--un-numeric-figure) var(--un-numeric-spacing) var(--un-numeric-fraction)',
137+
[CONTROL_BYPASS_PSEUDO]: '',
138+
}
139+
140+
export const fontVariantNumeric: Rule[] = [
141+
[/^ordinal$/, () => [fontVariantNumericBase, { '--un-ordinal': 'ordinal' }]],
142+
[/^slashed-zero$/, () => [fontVariantNumericBase, { '--un-slashed-zero': 'slashed-zero' }]],
143+
[/^lining-nums$/, () => [fontVariantNumericBase, { '--un-numeric-figure': 'lining-nums' }]],
144+
[/^oldstyle-nums$/, () => [fontVariantNumericBase, { '--un-numeric-figure': 'oldstyle-nums' }]],
145+
[/^proportional-nums$/, () => [fontVariantNumericBase, { '--un-numeric-spacing': 'proportional-nums' }]],
146+
[/^tabular-nums$/, () => [fontVariantNumericBase, { '--un-numeric-spacing': 'tabular-nums' }]],
147+
[/^diagonal-fractions$/, () => [fontVariantNumericBase, { '--un-numeric-fraction': 'diagonal-fractions' }]],
148+
[/^stacked-fractions$/, () => [fontVariantNumericBase, { '--un-numeric-fraction': 'stacked-fractions' }]],
149+
['normal-nums', { 'font-variant-numeric': 'normal' }],
150+
]
151+
128152
export const fonts = [
129153
fontsFamilies,
130154
fontSizes,

packages/preset-uno/src/theme/font.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
// port form Tailwind CSS and Windi CSS
2-
// TODO: add more details
3-
41
import { Theme } from './types'
52

63
export const fontFamily = {

packages/preset-uno/src/variants/pseudo.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import { toArray, VariantFunction, VariantObject } from '@unocss/core'
1+
import { CSSEntries, toArray, VariantFunction, VariantObject } from '@unocss/core'
2+
3+
export const CONTROL_BYPASS_PSEUDO = '$$no-pseudo'
24

35
export const PseudoClasses: Record<string, string | undefined> = Object.fromEntries([
46
'active',
@@ -56,19 +58,23 @@ export const variantPseudoElements: VariantFunction = (input: string) => {
5658
if (match) {
5759
return {
5860
matcher: input.slice(match[1].length + 1),
59-
selector: input => `${input}::${match[1]}`,
61+
selector: (s, body) => shouldAdd(body) && `${s}::${match[1]}`,
6062
}
6163
}
6264
}
6365

66+
function shouldAdd(entires: CSSEntries) {
67+
return !entires.find(i => i[0] === CONTROL_BYPASS_PSEUDO) || undefined
68+
}
69+
6470
export const variantPseudoClasses: VariantObject = {
6571
match: (input: string) => {
6672
let match = input.match(PseudoClassesRE)
6773
if (match) {
6874
const pseudo = PseudoClasses[match[1]] || match[1]
6975
return {
7076
matcher: input.slice(match[1].length + 1),
71-
selector: input => `${input}:${pseudo}`,
77+
selector: (s, body) => shouldAdd(body) && `${s}:${pseudo}`,
7278
}
7379
}
7480

@@ -77,7 +83,7 @@ export const variantPseudoClasses: VariantObject = {
7783
const pseudo = PseudoClasses[match[1]] || match[1]
7884
return {
7985
matcher: input.slice(match[1].length + 5),
80-
selector: input => `${input}:not(:${pseudo})`,
86+
selector: (s, body) => shouldAdd(body) && `${s}:not(:${pseudo})`,
8187
}
8288
}
8389

@@ -86,7 +92,7 @@ export const variantPseudoClasses: VariantObject = {
8692
const pseudo = PseudoClasses[match[1]] || match[1]
8793
return {
8894
matcher: input.slice(match[1].length + 7),
89-
selector: s => s.includes('.group:')
95+
selector: (s, body) => shouldAdd(body) && s.includes('.group:')
9096
? s.replace(/\.group:/, `.group:${pseudo}:`)
9197
: `.group:${pseudo} ${s}`,
9298
}
@@ -97,7 +103,7 @@ export const variantPseudoClasses: VariantObject = {
97103
const pseudo = PseudoClasses[match[1]] || match[1]
98104
return {
99105
matcher: input.slice(match[1].length + 6),
100-
selector: s => s.includes('.peer:')
106+
selector: (s, body) => shouldAdd(body) && s.includes('.peer:')
101107
? s.replace(/\.peer:/, `.peer:${pseudo}:`)
102108
: `.peer:${pseudo} ~ ${s}`,
103109
}

0 commit comments

Comments
 (0)