Skip to content

Commit 56f7782

Browse files
authored
feat: custom css functions (#44)
1 parent fda0aea commit 56f7782

File tree

10 files changed

+75
-9
lines changed

10 files changed

+75
-9
lines changed

packages/uniwind/specs/mocks.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ export const UniwindRuntimeMock = {
88
},
99
colorScheme: ColorScheme.Light,
1010
orientation: Orientation.Portrait,
11-
rem: 16,
1211
rtl: false,
1312
currentThemeName: ColorScheme.Light,
1413
insets: {
@@ -18,4 +17,7 @@ export const UniwindRuntimeMock = {
1817
right: 0,
1918
},
2019
colorMix,
20+
fontScale: (value: number) => value * 1,
21+
cubicBezier: () => '',
22+
lightDark: (light: string) => light,
2123
}

packages/uniwind/specs/utils.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export const getStyleSheetsFromCandidates = async <T extends string>(...candidat
1515
candidates,
1616
platform: Platform.iOS,
1717
cssPath: testCSSPath,
18+
themes: ['light', 'dark'],
1819
})
1920

2021
new Function(virtualJS)()
@@ -52,11 +53,14 @@ export const injectMocks = () => {
5253
addChangeListener: () => {},
5354
},
5455
PixelRatio: {
55-
getFontScale: () => UniwindRuntimeMock.rem,
56+
getFontScale: () => 1,
5657
},
5758
I18nManager: {
5859
isRTL: UniwindRuntimeMock.rtl,
5960
},
61+
StyleSheet: {
62+
hairlineWidth: 1,
63+
},
6064
}))
6165
// @ts-expect-error Mock __DEV__
6266
globalThis.__DEV__ = true

packages/uniwind/src/core/native/runtime.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Appearance, Dimensions, I18nManager, PixelRatio } from 'react-native'
1+
import { Appearance, Dimensions, I18nManager, PixelRatio, StyleSheet } from 'react-native'
22
import { ColorScheme, Orientation } from '../../types'
33
import type { UniwindRuntime as UniwindRuntimeType } from '../types'
44
import { colorMix, lightDark } from './native-utils'
@@ -14,7 +14,8 @@ export const UniwindRuntime = {
1414
colorScheme: initialColorScheme,
1515
currentThemeName: initialColorScheme,
1616
orientation: window.width > window.height ? Orientation.Landscape : Orientation.Portrait,
17-
rem: PixelRatio.getFontScale() * 16,
17+
fontScale: value => value * PixelRatio.getFontScale(),
18+
hairlineWidth: StyleSheet.hairlineWidth,
1819
rtl: I18nManager.isRTL,
1920
insets: {
2021
top: 0,
@@ -23,6 +24,7 @@ export const UniwindRuntime = {
2324
right: 0,
2425
},
2526
colorMix,
27+
pixelRatio: value => value * PixelRatio.get(),
2628
cubicBezier: () => '',
2729
lightDark: () => '',
2830
} as UniwindRuntimeType

packages/uniwind/src/core/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,15 @@ export type UniwindRuntime = {
3434
colorScheme: ColorScheme
3535
currentThemeName: ThemeName
3636
rtl: boolean
37-
rem: number
3837
insets: {
3938
top: number
4039
bottom: number
4140
left: number
4241
right: number
4342
}
43+
hairlineWidth: number
44+
pixelRatio: (value: number) => number
45+
fontScale: (value: number) => number
4446
colorMix: (color: string, mixColor: string, weight: number) => string
4547
cubicBezier: (x1: number, y1: number, x2: number, y2: number) => string
4648
lightDark: (light: string, dark: string) => string

packages/uniwind/src/metro/compileVirtual.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { compile } from '@tailwindcss/node'
2+
import { polyfillWeb } from './polyfillWeb'
23
import { ProcessorBuilder } from './processor'
34
import { addMetaToStylesTemplate, serializeStylesheet } from './stylesheet'
45
import { Platform } from './types'
@@ -19,7 +20,7 @@ export const compileVirtual = async ({ candidates, css, cssPath, platform, theme
1920
const tailwindCSS = compiler.build(candidates)
2021

2122
if (platform === Platform.Web) {
22-
return tailwindCSS
23+
return polyfillWeb(tailwindCSS)
2324
}
2425

2526
const Processor = new ProcessorBuilder(themes)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { TokenOrValue, transform } from 'lightningcss'
2+
3+
const ONE_PX = { type: 'token', value: { type: 'dimension', unit: 'px', value: 1 } } satisfies TokenOrValue
4+
5+
export const polyfillWeb = (css: string) => {
6+
const result = transform({
7+
code: Buffer.from(css),
8+
filename: 'uniwind.css',
9+
visitor: {
10+
Function: {
11+
pixelRatio: fn => {
12+
return {
13+
type: 'function',
14+
value: {
15+
name: 'calc',
16+
arguments: [
17+
fn.arguments.at(0) ?? ONE_PX,
18+
{ type: 'token', value: { type: 'delim', value: '*' } },
19+
ONE_PX,
20+
],
21+
},
22+
} satisfies TokenOrValue
23+
},
24+
fontScale: fn => {
25+
return {
26+
type: 'function',
27+
value: {
28+
name: 'calc',
29+
arguments: [
30+
fn.arguments.at(0) ?? ONE_PX,
31+
{ type: 'token', value: { type: 'delim', value: '*' } },
32+
{ type: 'token', value: { type: 'dimension', value: 1, unit: 'rem' } },
33+
],
34+
},
35+
} satisfies TokenOrValue
36+
},
37+
hairlineWidth: () => ONE_PX,
38+
},
39+
},
40+
})
41+
42+
return result.code.toString()
43+
}

packages/uniwind/src/metro/processor/functions.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,18 @@ export class Functions {
105105
return `${fn.name}(${this.Processor.CSS.processValue(fn.arguments)})`
106106
}
107107

108+
if (fn.name === 'hairlineWidth') {
109+
return 'rt.hairlineWidth'
110+
}
111+
112+
if (fn.name === 'pixelRatio') {
113+
return `rt.pixelRatio( ${this.Processor.CSS.processValue(fn.arguments)} )`
114+
}
115+
116+
if (fn.name === 'fontScale') {
117+
return `rt.fontScale( ${this.Processor.CSS.processValue(fn.arguments)} )`
118+
}
119+
108120
this.logger.error(`Unsupported function - ${fn.name}`)
109121

110122
return fn.name

packages/uniwind/src/metro/processor/processor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { Var } from './var'
1010
export class ProcessorBuilder {
1111
stylesheets = {} as Record<string, Array<any>>
1212
vars = {
13-
'--uniwind-em': 'rt.rem * 1',
13+
'--uniwind-em': 16,
1414
} as Record<string, any>
1515
CSS = new CSS(this)
1616
RN = new RN(this)

packages/uniwind/src/metro/processor/units.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export class Units {
2121
case 'vh':
2222
return `rt.screen.height * ${length.value / 100}`
2323
case 'rem':
24-
return `rt.rem * ${length.value}`
24+
return length.value * 16
2525
case 'em':
2626
return `this[\`--uniwind-em\`] * ${length.value}`
2727
default:

packages/uniwind/src/metro/stylesheet/addMetaToStylesTemplate.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export const addMetaToStylesTemplate = (Processor: ProcessorBuilder, currentPlat
7575
dependencies.push(StyleDependency.Insets)
7676
}
7777

78-
if (stringifiedEntries.includes('rt.rem')) {
78+
if (stringifiedEntries.includes('rt.fontScale')) {
7979
dependencies.push(StyleDependency.FontScale)
8080
}
8181

0 commit comments

Comments
 (0)