rnwind 0.0.4 → 0.0.5
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/lib/cjs/core/normalize-classname.cjs +25 -0
- package/lib/cjs/core/normalize-classname.cjs.map +1 -0
- package/lib/cjs/core/normalize-classname.d.ts +10 -0
- package/lib/cjs/core/style-builder/build-style.cjs +258 -58
- package/lib/cjs/core/style-builder/build-style.cjs.map +1 -1
- package/lib/cjs/core/style-builder/build-style.d.ts +6 -1
- package/lib/cjs/core/style-builder/union-builder.cjs +37 -3
- package/lib/cjs/core/style-builder/union-builder.cjs.map +1 -1
- package/lib/cjs/core/style-builder/union-builder.d.ts +21 -1
- package/lib/cjs/metro/dts.cjs +7 -16
- package/lib/cjs/metro/dts.cjs.map +1 -1
- package/lib/cjs/metro/dts.d.ts +2 -4
- package/lib/cjs/metro/state.cjs +30 -78
- package/lib/cjs/metro/state.cjs.map +1 -1
- package/lib/cjs/metro/state.d.ts +8 -25
- package/lib/cjs/metro/transformer.cjs +193 -34
- package/lib/cjs/metro/transformer.cjs.map +1 -1
- package/lib/cjs/metro/with-config.cjs +2 -2
- package/lib/cjs/metro/with-config.cjs.map +1 -1
- package/lib/cjs/metro/with-config.d.ts +11 -26
- package/lib/cjs/metro/wrap-imports.cjs +273 -0
- package/lib/cjs/metro/wrap-imports.cjs.map +1 -0
- package/lib/cjs/metro/wrap-imports.d.ts +26 -0
- package/lib/cjs/runtime/components/rnwind-provider.cjs +0 -17
- package/lib/cjs/runtime/components/rnwind-provider.cjs.map +1 -1
- package/lib/cjs/runtime/components/rnwind-provider.d.ts +0 -14
- package/lib/cjs/runtime/hooks/use-css.cjs +16 -10
- package/lib/cjs/runtime/hooks/use-css.cjs.map +1 -1
- package/lib/cjs/runtime/hooks/use-css.d.ts +15 -9
- package/lib/cjs/runtime/index.cjs +11 -13
- package/lib/cjs/runtime/index.cjs.map +1 -1
- package/lib/cjs/runtime/index.d.ts +4 -9
- package/lib/cjs/runtime/lookup-css.cjs +10 -0
- package/lib/cjs/runtime/lookup-css.cjs.map +1 -1
- package/lib/cjs/runtime/lookup-css.d.ts +7 -0
- package/lib/cjs/runtime/resolve.cjs +348 -0
- package/lib/cjs/runtime/resolve.cjs.map +1 -0
- package/lib/cjs/runtime/resolve.d.ts +61 -0
- package/lib/cjs/runtime/wrap.cjs +254 -0
- package/lib/cjs/runtime/wrap.cjs.map +1 -0
- package/lib/cjs/runtime/wrap.d.ts +37 -0
- package/lib/cjs/testing/index.cjs +81 -50
- package/lib/cjs/testing/index.cjs.map +1 -1
- package/lib/esm/core/normalize-classname.d.ts +10 -0
- package/lib/esm/core/normalize-classname.mjs +23 -0
- package/lib/esm/core/normalize-classname.mjs.map +1 -0
- package/lib/esm/core/style-builder/build-style.d.ts +6 -1
- package/lib/esm/core/style-builder/build-style.mjs +258 -58
- package/lib/esm/core/style-builder/build-style.mjs.map +1 -1
- package/lib/esm/core/style-builder/union-builder.d.ts +21 -1
- package/lib/esm/core/style-builder/union-builder.mjs +37 -3
- package/lib/esm/core/style-builder/union-builder.mjs.map +1 -1
- package/lib/esm/metro/dts.d.ts +2 -4
- package/lib/esm/metro/dts.mjs +7 -16
- package/lib/esm/metro/dts.mjs.map +1 -1
- package/lib/esm/metro/state.d.ts +8 -25
- package/lib/esm/metro/state.mjs +30 -76
- package/lib/esm/metro/state.mjs.map +1 -1
- package/lib/esm/metro/transformer.mjs +194 -35
- package/lib/esm/metro/transformer.mjs.map +1 -1
- package/lib/esm/metro/with-config.d.ts +11 -26
- package/lib/esm/metro/with-config.mjs +2 -2
- package/lib/esm/metro/with-config.mjs.map +1 -1
- package/lib/esm/metro/wrap-imports.d.ts +26 -0
- package/lib/esm/metro/wrap-imports.mjs +250 -0
- package/lib/esm/metro/wrap-imports.mjs.map +1 -0
- package/lib/esm/runtime/components/rnwind-provider.d.ts +0 -14
- package/lib/esm/runtime/components/rnwind-provider.mjs +1 -17
- package/lib/esm/runtime/components/rnwind-provider.mjs.map +1 -1
- package/lib/esm/runtime/hooks/use-css.d.ts +15 -9
- package/lib/esm/runtime/hooks/use-css.mjs +16 -10
- package/lib/esm/runtime/hooks/use-css.mjs.map +1 -1
- package/lib/esm/runtime/index.d.ts +4 -9
- package/lib/esm/runtime/index.mjs +4 -4
- package/lib/esm/runtime/index.mjs.map +1 -1
- package/lib/esm/runtime/lookup-css.d.ts +7 -0
- package/lib/esm/runtime/lookup-css.mjs +10 -1
- package/lib/esm/runtime/lookup-css.mjs.map +1 -1
- package/lib/esm/runtime/resolve.d.ts +61 -0
- package/lib/esm/runtime/resolve.mjs +341 -0
- package/lib/esm/runtime/resolve.mjs.map +1 -0
- package/lib/esm/runtime/wrap.d.ts +37 -0
- package/lib/esm/runtime/wrap.mjs +251 -0
- package/lib/esm/runtime/wrap.mjs.map +1 -0
- package/lib/esm/testing/index.mjs +84 -53
- package/lib/esm/testing/index.mjs.map +1 -1
- package/package.json +2 -1
- package/src/core/normalize-classname.ts +19 -0
- package/src/core/style-builder/build-style.ts +286 -55
- package/src/core/style-builder/union-builder.ts +36 -3
- package/src/metro/dts.ts +7 -19
- package/src/metro/state.ts +29 -74
- package/src/metro/transformer.ts +190 -34
- package/src/metro/with-config.ts +13 -28
- package/src/metro/wrap-imports.ts +260 -0
- package/src/runtime/components/rnwind-provider.tsx +0 -17
- package/src/runtime/hooks/use-css.ts +17 -11
- package/src/runtime/index.ts +3 -26
- package/src/runtime/lookup-css.ts +10 -0
- package/src/runtime/resolve.ts +381 -0
- package/src/runtime/wrap.tsx +267 -0
- package/src/testing/index.ts +106 -56
- package/lib/cjs/core/parser/text-truncate.cjs +0 -78
- package/lib/cjs/core/parser/text-truncate.cjs.map +0 -1
- package/lib/cjs/metro/transform-ast.cjs +0 -1472
- package/lib/cjs/metro/transform-ast.cjs.map +0 -1
- package/lib/cjs/metro/transform-ast.d.ts +0 -88
- package/lib/cjs/runtime/haptics.cjs +0 -113
- package/lib/cjs/runtime/haptics.cjs.map +0 -1
- package/lib/cjs/runtime/haptics.d.ts +0 -48
- package/lib/cjs/runtime/interactive-box.cjs +0 -35
- package/lib/cjs/runtime/interactive-box.cjs.map +0 -1
- package/lib/cjs/runtime/interactive-box.d.ts +0 -40
- package/lib/esm/core/parser/text-truncate.mjs +0 -75
- package/lib/esm/core/parser/text-truncate.mjs.map +0 -1
- package/lib/esm/metro/transform-ast.d.ts +0 -88
- package/lib/esm/metro/transform-ast.mjs +0 -1451
- package/lib/esm/metro/transform-ast.mjs.map +0 -1
- package/lib/esm/runtime/haptics.d.ts +0 -48
- package/lib/esm/runtime/haptics.mjs +0 -110
- package/lib/esm/runtime/haptics.mjs.map +0 -1
- package/lib/esm/runtime/interactive-box.d.ts +0 -40
- package/lib/esm/runtime/interactive-box.mjs +0 -33
- package/lib/esm/runtime/interactive-box.mjs.map +0 -1
- package/src/metro/transform-ast.ts +0 -1729
- package/src/runtime/haptics.ts +0 -120
- package/src/runtime/interactive-box.tsx +0 -57
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import * as t from '@babel/types'
|
|
2
|
+
import type { File } from '@babel/types'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Build-time import rewrite. For every `import { View } from
|
|
6
|
+
* 'react-native'` (and the other configured modules) it aliases the
|
|
7
|
+
* original export and binds a `wrap()`-ed component in its place:
|
|
8
|
+
*
|
|
9
|
+
* ```
|
|
10
|
+
* import { View, StyleSheet } from 'react-native'
|
|
11
|
+
* ⇩
|
|
12
|
+
* import { View as _rnw0, StyleSheet } from 'react-native'
|
|
13
|
+
* import { wrap as _rnwWrap } from 'rnwind'
|
|
14
|
+
* const View = _rnwWrap(_rnw0)
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* Now `<View className="…">` resolves className → style at render via the
|
|
18
|
+
* wrapper — no matter how className arrived (literal, `{...rest}` spread,
|
|
19
|
+
* forwarded through custom layers). Non-component exports (`StyleSheet`)
|
|
20
|
+
* are left untouched.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/** Local binding the injected `wrap` import is aliased to. */
|
|
24
|
+
const WRAP_LOCAL = '_rnwWrap'
|
|
25
|
+
/** Local binding the injected `wrapNamespace` import is aliased to. */
|
|
26
|
+
const WRAP_NS_LOCAL = '_rnwWrapNs'
|
|
27
|
+
/** Module the wrapper is imported from. */
|
|
28
|
+
const RUNTIME_MODULE = 'rnwind'
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Wrap-modules whose DEFAULT export is a component NAMESPACE accessed via
|
|
32
|
+
* member expressions (`Animated.View`), not a single component. Their
|
|
33
|
+
* default import is bound through `wrapNamespace` (a Proxy that wraps each
|
|
34
|
+
* accessed component member) instead of `wrap`. Every other default import
|
|
35
|
+
* is treated as a plain component.
|
|
36
|
+
*/
|
|
37
|
+
const NAMESPACE_DEFAULT_MODULES: ReadonlySet<string> = new Set(['react-native-reanimated'])
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* react-native mixes styleable components with utilities (`StyleSheet`,
|
|
41
|
+
* `Platform`, …). Only these named exports are wrapped; everything else
|
|
42
|
+
* passes through. Other ecosystem modules export components only and use
|
|
43
|
+
* the `'all'` policy instead.
|
|
44
|
+
*/
|
|
45
|
+
const REACT_NATIVE_COMPONENTS: ReadonlySet<string> = new Set([
|
|
46
|
+
'View',
|
|
47
|
+
'Text',
|
|
48
|
+
'TextInput',
|
|
49
|
+
'Pressable',
|
|
50
|
+
'ScrollView',
|
|
51
|
+
'Image',
|
|
52
|
+
'ImageBackground',
|
|
53
|
+
'FlatList',
|
|
54
|
+
'SectionList',
|
|
55
|
+
'VirtualizedList',
|
|
56
|
+
'KeyboardAvoidingView',
|
|
57
|
+
'SafeAreaView',
|
|
58
|
+
'Modal',
|
|
59
|
+
'Switch',
|
|
60
|
+
'RefreshControl',
|
|
61
|
+
'ActivityIndicator',
|
|
62
|
+
'TouchableOpacity',
|
|
63
|
+
'TouchableHighlight',
|
|
64
|
+
'TouchableWithoutFeedback',
|
|
65
|
+
'TouchableNativeFeedback',
|
|
66
|
+
'Button',
|
|
67
|
+
'StatusBar',
|
|
68
|
+
])
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Named exports that LOOK like components (PascalCase) under an `'all'`
|
|
72
|
+
* policy but aren't — React contexts, gesture-handler enums/namespaces,
|
|
73
|
+
* etc. Wrapping these would turn `Gesture.Pan()` / `State.ACTIVE` /
|
|
74
|
+
* `<XContext.Provider>` into a `wrap()`-ed component and break them.
|
|
75
|
+
* Names ending in `Context` are excluded separately.
|
|
76
|
+
*/
|
|
77
|
+
const NON_COMPONENT_EXPORTS: ReadonlySet<string> = new Set([
|
|
78
|
+
'Gesture',
|
|
79
|
+
'GestureObjects',
|
|
80
|
+
'State',
|
|
81
|
+
'Directions',
|
|
82
|
+
'Extrapolation',
|
|
83
|
+
'Extrapolate',
|
|
84
|
+
'Easing',
|
|
85
|
+
'ReduceMotion',
|
|
86
|
+
'KeyframeRegistry',
|
|
87
|
+
])
|
|
88
|
+
|
|
89
|
+
/** Per-module policy: an explicit allow-list, or `'all'` named exports. */
|
|
90
|
+
export type WrapPolicy = 'all' | ReadonlySet<string>
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Default module → wrap policy. react-native is allow-listed (mixed
|
|
94
|
+
* exports); the rest are component-only packages → `'all'`. Only modules
|
|
95
|
+
* the project has installed are ever hit (you can't import from a missing
|
|
96
|
+
* package), so listing optional peers is free.
|
|
97
|
+
*/
|
|
98
|
+
export const DEFAULT_WRAP_MODULES: ReadonlyMap<string, WrapPolicy> = new Map<string, WrapPolicy>([
|
|
99
|
+
['react-native', REACT_NATIVE_COMPONENTS],
|
|
100
|
+
['react-native-reanimated', 'all'],
|
|
101
|
+
['react-native-svg', 'all'],
|
|
102
|
+
['react-native-gesture-handler', 'all'],
|
|
103
|
+
['react-native-safe-area-context', 'all'],
|
|
104
|
+
['expo-linear-gradient', 'all'],
|
|
105
|
+
['expo-image', 'all'],
|
|
106
|
+
['expo-blur', 'all'],
|
|
107
|
+
['expo-symbols', 'all'],
|
|
108
|
+
['@shopify/flash-list', 'all'],
|
|
109
|
+
['@shopify/react-native-skia', 'all'],
|
|
110
|
+
['lottie-react-native', 'all'],
|
|
111
|
+
])
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Whether a named import from a wrap-module should be wrapped.
|
|
115
|
+
*
|
|
116
|
+
* Explicit allow-lists (react-native) match by exact name. The `'all'`
|
|
117
|
+
* policy wraps only component-style names — PascalCase, not a React
|
|
118
|
+
* context (`*Context`), and not a known non-component export. This is
|
|
119
|
+
* what stops `useSafeAreaInsets` (a hook) from being wrapped into a
|
|
120
|
+
* component and crashing when called.
|
|
121
|
+
* @param policy The module's wrap policy.
|
|
122
|
+
* @param importedName The exported name being imported.
|
|
123
|
+
* @returns True when the name is a component to wrap.
|
|
124
|
+
*/
|
|
125
|
+
function shouldWrap(policy: WrapPolicy, importedName: string): boolean {
|
|
126
|
+
if (policy !== 'all') return policy.has(importedName)
|
|
127
|
+
if (!/^[A-Z]/.test(importedName)) return false
|
|
128
|
+
if (importedName.endsWith('Context')) return false
|
|
129
|
+
return !NON_COMPONENT_EXPORTS.has(importedName)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Merge user-supplied wrap modules onto the defaults — a bare module name
|
|
134
|
+
* adopts the `'all'` policy.
|
|
135
|
+
* @param extra User module specifiers (or undefined).
|
|
136
|
+
* @returns Effective module → policy map.
|
|
137
|
+
*/
|
|
138
|
+
export function buildWrapModules(extra?: readonly string[]): ReadonlyMap<string, WrapPolicy> {
|
|
139
|
+
if (!extra || extra.length === 0) return DEFAULT_WRAP_MODULES
|
|
140
|
+
const merged = new Map<string, WrapPolicy>(DEFAULT_WRAP_MODULES)
|
|
141
|
+
for (const moduleName of extra) if (!merged.has(moduleName)) merged.set(moduleName, 'all')
|
|
142
|
+
return merged
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* The `imported` name of an import specifier (`import { a as b }` → `'a'`).
|
|
147
|
+
* @param specifier Named import specifier.
|
|
148
|
+
* @returns The exported name.
|
|
149
|
+
*/
|
|
150
|
+
function importedNameOf(specifier: t.ImportSpecifier): string {
|
|
151
|
+
return t.isIdentifier(specifier.imported) ? specifier.imported.name : specifier.imported.value
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Build `const Local = <wrapper>(alias)` and rebind the specifier's local
|
|
156
|
+
* to `alias` in place.
|
|
157
|
+
* @param specifier The import specifier to rebind.
|
|
158
|
+
* @param alias The `_rnwN` alias to bind the original import to.
|
|
159
|
+
* @param wrapper The runtime helper local (`_rnwWrap` / `_rnwWrapNs`).
|
|
160
|
+
* @returns The wrap declaration.
|
|
161
|
+
*/
|
|
162
|
+
function makeWrapDecl(
|
|
163
|
+
specifier: t.ImportSpecifier | t.ImportDefaultSpecifier | t.ImportNamespaceSpecifier,
|
|
164
|
+
alias: string,
|
|
165
|
+
wrapper: string,
|
|
166
|
+
): t.VariableDeclaration {
|
|
167
|
+
const { name: localName } = specifier.local
|
|
168
|
+
specifier.local = t.identifier(alias)
|
|
169
|
+
return t.variableDeclaration('const', [
|
|
170
|
+
t.variableDeclarator(t.identifier(localName), t.callExpression(t.identifier(wrapper), [t.identifier(alias)])),
|
|
171
|
+
])
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Rewrite one import declaration's wrappable specifiers, aliasing each to
|
|
176
|
+
* `_rnw<N>` in place:
|
|
177
|
+
* - named (`{ View }`) → `const View = wrap(_rnwN)` (per policy),
|
|
178
|
+
* - namespace (`* as Animated`) → `const Animated = wrapNamespace(_rnwN)`,
|
|
179
|
+
* - default → `wrapNamespace` for {@link NAMESPACE_DEFAULT_MODULES}
|
|
180
|
+
* (reanimated's `Animated`), else `wrap` (a plain default component).
|
|
181
|
+
* @param node Import declaration to inspect.
|
|
182
|
+
* @param policy The module's wrap policy.
|
|
183
|
+
* @param counter Next alias index (caller-threaded for uniqueness).
|
|
184
|
+
* @returns New wrap declarations, advanced counter, and whether any
|
|
185
|
+
* binding used `wrapNamespace`.
|
|
186
|
+
*/
|
|
187
|
+
function wrapSpecifiers(
|
|
188
|
+
node: t.ImportDeclaration,
|
|
189
|
+
policy: WrapPolicy,
|
|
190
|
+
counter: number,
|
|
191
|
+
): { decls: t.VariableDeclaration[]; counter: number; usesNamespace: boolean } {
|
|
192
|
+
const decls: t.VariableDeclaration[] = []
|
|
193
|
+
const moduleName = node.source.value
|
|
194
|
+
let next = counter
|
|
195
|
+
let usesNamespace = false
|
|
196
|
+
for (const specifier of node.specifiers) {
|
|
197
|
+
if (t.isImportSpecifier(specifier)) {
|
|
198
|
+
if (!shouldWrap(policy, importedNameOf(specifier))) continue
|
|
199
|
+
decls.push(makeWrapDecl(specifier, `_rnw${next}`, WRAP_LOCAL))
|
|
200
|
+
next += 1
|
|
201
|
+
continue
|
|
202
|
+
}
|
|
203
|
+
const isNamespace = t.isImportNamespaceSpecifier(specifier) || NAMESPACE_DEFAULT_MODULES.has(moduleName)
|
|
204
|
+
const wrapper = isNamespace ? WRAP_NS_LOCAL : WRAP_LOCAL
|
|
205
|
+
decls.push(makeWrapDecl(specifier, `_rnw${next}`, wrapper))
|
|
206
|
+
next += 1
|
|
207
|
+
if (isNamespace) usesNamespace = true
|
|
208
|
+
}
|
|
209
|
+
return { decls, counter: next, usesNamespace }
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Insert the `wrap` import at the top and the `const X = wrap(_rnwN)`
|
|
214
|
+
* declarations AFTER every import. The consts reference the aliased
|
|
215
|
+
* binding `_rnwN`, and in Metro's real transform (CommonJS interop + the
|
|
216
|
+
* reanimated worklets plugin) a const placed above its source import
|
|
217
|
+
* evaluates before the binding initialises → `ReferenceError: _rnw0
|
|
218
|
+
* doesn't exist`. ESM-only hoisting would mask this; the bundle does not.
|
|
219
|
+
* @param ast Parsed Babel file (mutated).
|
|
220
|
+
* @param wrapDecls The wrap declarations to place.
|
|
221
|
+
* @param usesNamespace Whether any binding used `wrapNamespace`.
|
|
222
|
+
*/
|
|
223
|
+
function placeWrapDecls(ast: File, wrapDecls: readonly t.VariableDeclaration[], usesNamespace: boolean): void {
|
|
224
|
+
const specifiers = [t.importSpecifier(t.identifier(WRAP_LOCAL), t.identifier('wrap'))]
|
|
225
|
+
if (usesNamespace) specifiers.push(t.importSpecifier(t.identifier(WRAP_NS_LOCAL), t.identifier('wrapNamespace')))
|
|
226
|
+
ast.program.body.unshift(t.importDeclaration(specifiers, t.stringLiteral(RUNTIME_MODULE)))
|
|
227
|
+
let afterImports = 0
|
|
228
|
+
for (let index = 0; index < ast.program.body.length; index += 1) {
|
|
229
|
+
if (t.isImportDeclaration(ast.program.body[index])) afterImports = index + 1
|
|
230
|
+
}
|
|
231
|
+
ast.program.body.splice(afterImports, 0, ...wrapDecls)
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Rewrite component imports from the configured wrap-modules into
|
|
236
|
+
* `wrap()`-ed bindings, in place. Injects the `wrap` import once when any
|
|
237
|
+
* binding was rewritten.
|
|
238
|
+
* @param ast Parsed Babel file (mutated).
|
|
239
|
+
* @param modules Effective module → policy map.
|
|
240
|
+
* @returns True when at least one import was wrapped.
|
|
241
|
+
*/
|
|
242
|
+
export function rewriteWrapImports(ast: File, modules: ReadonlyMap<string, WrapPolicy>): boolean {
|
|
243
|
+
const wrapDecls: t.VariableDeclaration[] = []
|
|
244
|
+
let counter = 0
|
|
245
|
+
let usesNamespace = false
|
|
246
|
+
|
|
247
|
+
for (const node of ast.program.body) {
|
|
248
|
+
if (!t.isImportDeclaration(node)) continue
|
|
249
|
+
const policy = modules.get(node.source.value)
|
|
250
|
+
if (!policy) continue
|
|
251
|
+
const { decls, counter: nextCounter, usesNamespace: ns } = wrapSpecifiers(node, policy, counter)
|
|
252
|
+
counter = nextCounter
|
|
253
|
+
usesNamespace = usesNamespace || ns
|
|
254
|
+
wrapDecls.push(...decls)
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (wrapDecls.length === 0) return false
|
|
258
|
+
placeWrapDecls(ast, wrapDecls, usesNamespace)
|
|
259
|
+
return true
|
|
260
|
+
}
|
|
@@ -96,23 +96,6 @@ export function useRnwind(): RnwindState {
|
|
|
96
96
|
return useContext(RnwindContext)
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
/**
|
|
100
|
-
* Internal context hook the babel transformer injects at the top of
|
|
101
|
-
* every rewritten component as `const _t = useR_()`. Same body as the
|
|
102
|
-
* public {@link useRnwind} — exposed under a `use*`-prefixed name so
|
|
103
|
-
* react-refresh's babel plugin (which only tracks call-sites whose
|
|
104
|
-
* identifier matches `^use[A-Z]`) folds it into each component's
|
|
105
|
-
* fast-refresh signature. Without that prefix the signature stayed
|
|
106
|
-
* stable across transformer changes; HMR then preserved fiber state
|
|
107
|
-
* while the rendered hook list shifted, surfacing as "change in the
|
|
108
|
-
* order of Hooks" runtime errors. Trailing underscore keeps it
|
|
109
|
-
* visually distinct from the user-facing `useRnwind`.
|
|
110
|
-
* @returns Active rnwind state.
|
|
111
|
-
*/
|
|
112
|
-
export function useR_(): RnwindState {
|
|
113
|
-
return useContext(RnwindContext)
|
|
114
|
-
}
|
|
115
|
-
|
|
116
99
|
/**
|
|
117
100
|
* Provider for rnwind's full runtime state. fontScale + windowWidth
|
|
118
101
|
* come from `useWindowDimensions()` so they react to OS-level
|
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
import { useRnwind } from '../components/rnwind-provider'
|
|
2
|
-
import {
|
|
2
|
+
import { resolve } from '../resolve'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
5
|
+
* Resolve a className to a React Native `style` value against the active
|
|
6
|
+
* rnwind context (scheme, insets, fontScale, breakpoint). Molecule-fast:
|
|
7
|
+
* a literal className the scanner saw returns a pre-merged object by
|
|
8
|
+
* reference; anything else falls back to per-atom resolution. The escape
|
|
9
|
+
* hatch for custom components that hold a `className` prop:
|
|
10
|
+
*
|
|
11
|
+
* ```tsx
|
|
12
|
+
* function Card({ className, style, ...rest }) {
|
|
13
|
+
* return <RNView style={useCss(className, style)} {...rest} />
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
* @param className Raw className string.
|
|
17
|
+
* @param userStyle Optional caller-supplied style appended last (wins).
|
|
18
|
+
* @returns RN `style` value (a single object or an array).
|
|
13
19
|
*/
|
|
14
|
-
export function useCss(className?: string |
|
|
15
|
-
return
|
|
20
|
+
export function useCss(className?: string | null, userStyle?: unknown): unknown {
|
|
21
|
+
return resolve(className, useRnwind(), userStyle).style
|
|
16
22
|
}
|
package/src/runtime/index.ts
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
1
|
export {
|
|
6
2
|
lookupCss,
|
|
7
3
|
registerAtoms,
|
|
@@ -10,36 +6,17 @@ export {
|
|
|
10
6
|
setWindowHeightProvider,
|
|
11
7
|
getBreakpoints,
|
|
12
8
|
activeBreakpointFor,
|
|
13
|
-
lookupCss as _l,
|
|
14
9
|
} from './lookup-css'
|
|
15
|
-
export { useR_ } from './components/rnwind-provider'
|
|
16
10
|
export type { HoistedClassName, InteractState, LookupInsets, SafeMarkerSpec } from './lookup-css'
|
|
11
|
+
export { wrap, wrapNamespace } from './wrap'
|
|
12
|
+
export { resolve, registerMolecules, registerGradients, registerHaptics } from './resolve'
|
|
13
|
+
export type { ResolvedCss } from './resolve'
|
|
17
14
|
export { useCss } from './hooks/use-css'
|
|
18
15
|
export { useInteract } from './hooks/use-interact'
|
|
19
16
|
export type { UseInteractResult } from './hooks/use-interact'
|
|
20
17
|
export { chainPress, chainFocus } from './chain-handlers'
|
|
21
|
-
export { InteractiveBox, InteractiveBox as _ib } from './interactive-box'
|
|
22
|
-
export type { InteractiveBoxProps, InteractiveSpec } from './interactive-box'
|
|
23
18
|
export { RnwindProvider, useRnwind } from './components/rnwind-provider'
|
|
24
19
|
export type { RnwindProviderProps, RnwindState, Insets } from './components/rnwind-provider'
|
|
25
|
-
export { useMountHaptic, triggerHaptic, triggerHaptic as _ht, useMountHaptic as _hm } from './haptics'
|
|
26
|
-
|
|
27
|
-
// ──────────────────────────────────────────────────────────────────────
|
|
28
|
-
// Internal aliases the babel transformer uses. Underscore-prefixed so
|
|
29
|
-
// user code (which imports the public names above) can never collide
|
|
30
|
-
// with what we inject at JSX sites — even if the user shadows
|
|
31
|
-
// `lookupCss` / `useHaptics` / `InteractiveBox` with a local symbol,
|
|
32
|
-
// the transformer's emitted code still references the private alias.
|
|
33
|
-
// Don't import these in app code.
|
|
34
|
-
// ──────────────────────────────────────────────────────────────────────
|
|
35
|
-
/** @internal */
|
|
36
|
-
|
|
37
|
-
/** @internal */
|
|
38
|
-
|
|
39
|
-
/** @internal */
|
|
40
|
-
|
|
41
|
-
/** @internal */
|
|
42
|
-
|
|
43
20
|
export type { HapticRequest, HapticTrigger, OnHaptics } from '../core/parser/haptics'
|
|
44
21
|
export type { AsLinearGradientProps, LinearGradientPoint } from './gradient-types'
|
|
45
22
|
export type { ThemeTable, ThemeTables } from '../core/types'
|
|
@@ -496,6 +496,16 @@ export function registerAtoms(scheme: string, atoms: Record<string, unknown>): v
|
|
|
496
496
|
atomVersion += 1
|
|
497
497
|
}
|
|
498
498
|
|
|
499
|
+
/**
|
|
500
|
+
* Current registry version — bumps on every `registerAtoms` /
|
|
501
|
+
* `registerBreakpoints`. The molecule resolver folds it into its cache
|
|
502
|
+
* key so an HMR atom reload invalidates derived results.
|
|
503
|
+
* @returns Monotonic version counter.
|
|
504
|
+
*/
|
|
505
|
+
export function getStyleVersion(): number {
|
|
506
|
+
return atomVersion
|
|
507
|
+
}
|
|
508
|
+
|
|
499
509
|
/**
|
|
500
510
|
* Register the responsive-breakpoint table the manifest module emits at
|
|
501
511
|
* load time. Replaces the prior table — calling with `{}` clears it.
|