rnwind 0.0.4 → 0.0.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.
Files changed (127) hide show
  1. package/lib/cjs/core/normalize-classname.cjs +25 -0
  2. package/lib/cjs/core/normalize-classname.cjs.map +1 -0
  3. package/lib/cjs/core/normalize-classname.d.ts +10 -0
  4. package/lib/cjs/core/style-builder/build-style.cjs +258 -58
  5. package/lib/cjs/core/style-builder/build-style.cjs.map +1 -1
  6. package/lib/cjs/core/style-builder/build-style.d.ts +6 -1
  7. package/lib/cjs/core/style-builder/union-builder.cjs +37 -3
  8. package/lib/cjs/core/style-builder/union-builder.cjs.map +1 -1
  9. package/lib/cjs/core/style-builder/union-builder.d.ts +21 -1
  10. package/lib/cjs/metro/dts.cjs +7 -16
  11. package/lib/cjs/metro/dts.cjs.map +1 -1
  12. package/lib/cjs/metro/dts.d.ts +2 -4
  13. package/lib/cjs/metro/state.cjs +30 -78
  14. package/lib/cjs/metro/state.cjs.map +1 -1
  15. package/lib/cjs/metro/state.d.ts +8 -25
  16. package/lib/cjs/metro/transformer.cjs +193 -34
  17. package/lib/cjs/metro/transformer.cjs.map +1 -1
  18. package/lib/cjs/metro/with-config.cjs +2 -2
  19. package/lib/cjs/metro/with-config.cjs.map +1 -1
  20. package/lib/cjs/metro/with-config.d.ts +11 -26
  21. package/lib/cjs/metro/wrap-imports.cjs +273 -0
  22. package/lib/cjs/metro/wrap-imports.cjs.map +1 -0
  23. package/lib/cjs/metro/wrap-imports.d.ts +26 -0
  24. package/lib/cjs/runtime/components/rnwind-provider.cjs +0 -17
  25. package/lib/cjs/runtime/components/rnwind-provider.cjs.map +1 -1
  26. package/lib/cjs/runtime/components/rnwind-provider.d.ts +0 -14
  27. package/lib/cjs/runtime/hooks/use-css.cjs +16 -10
  28. package/lib/cjs/runtime/hooks/use-css.cjs.map +1 -1
  29. package/lib/cjs/runtime/hooks/use-css.d.ts +15 -9
  30. package/lib/cjs/runtime/index.cjs +11 -13
  31. package/lib/cjs/runtime/index.cjs.map +1 -1
  32. package/lib/cjs/runtime/index.d.ts +4 -9
  33. package/lib/cjs/runtime/lookup-css.cjs +10 -0
  34. package/lib/cjs/runtime/lookup-css.cjs.map +1 -1
  35. package/lib/cjs/runtime/lookup-css.d.ts +7 -0
  36. package/lib/cjs/runtime/resolve.cjs +400 -0
  37. package/lib/cjs/runtime/resolve.cjs.map +1 -0
  38. package/lib/cjs/runtime/resolve.d.ts +66 -0
  39. package/lib/cjs/runtime/wrap.cjs +254 -0
  40. package/lib/cjs/runtime/wrap.cjs.map +1 -0
  41. package/lib/cjs/runtime/wrap.d.ts +37 -0
  42. package/lib/cjs/testing/index.cjs +81 -50
  43. package/lib/cjs/testing/index.cjs.map +1 -1
  44. package/lib/esm/core/normalize-classname.d.ts +10 -0
  45. package/lib/esm/core/normalize-classname.mjs +23 -0
  46. package/lib/esm/core/normalize-classname.mjs.map +1 -0
  47. package/lib/esm/core/style-builder/build-style.d.ts +6 -1
  48. package/lib/esm/core/style-builder/build-style.mjs +258 -58
  49. package/lib/esm/core/style-builder/build-style.mjs.map +1 -1
  50. package/lib/esm/core/style-builder/union-builder.d.ts +21 -1
  51. package/lib/esm/core/style-builder/union-builder.mjs +37 -3
  52. package/lib/esm/core/style-builder/union-builder.mjs.map +1 -1
  53. package/lib/esm/metro/dts.d.ts +2 -4
  54. package/lib/esm/metro/dts.mjs +7 -16
  55. package/lib/esm/metro/dts.mjs.map +1 -1
  56. package/lib/esm/metro/state.d.ts +8 -25
  57. package/lib/esm/metro/state.mjs +30 -76
  58. package/lib/esm/metro/state.mjs.map +1 -1
  59. package/lib/esm/metro/transformer.mjs +194 -35
  60. package/lib/esm/metro/transformer.mjs.map +1 -1
  61. package/lib/esm/metro/with-config.d.ts +11 -26
  62. package/lib/esm/metro/with-config.mjs +2 -2
  63. package/lib/esm/metro/with-config.mjs.map +1 -1
  64. package/lib/esm/metro/wrap-imports.d.ts +26 -0
  65. package/lib/esm/metro/wrap-imports.mjs +250 -0
  66. package/lib/esm/metro/wrap-imports.mjs.map +1 -0
  67. package/lib/esm/runtime/components/rnwind-provider.d.ts +0 -14
  68. package/lib/esm/runtime/components/rnwind-provider.mjs +1 -17
  69. package/lib/esm/runtime/components/rnwind-provider.mjs.map +1 -1
  70. package/lib/esm/runtime/hooks/use-css.d.ts +15 -9
  71. package/lib/esm/runtime/hooks/use-css.mjs +16 -10
  72. package/lib/esm/runtime/hooks/use-css.mjs.map +1 -1
  73. package/lib/esm/runtime/index.d.ts +4 -9
  74. package/lib/esm/runtime/index.mjs +4 -4
  75. package/lib/esm/runtime/index.mjs.map +1 -1
  76. package/lib/esm/runtime/lookup-css.d.ts +7 -0
  77. package/lib/esm/runtime/lookup-css.mjs +10 -1
  78. package/lib/esm/runtime/lookup-css.mjs.map +1 -1
  79. package/lib/esm/runtime/resolve.d.ts +66 -0
  80. package/lib/esm/runtime/resolve.mjs +393 -0
  81. package/lib/esm/runtime/resolve.mjs.map +1 -0
  82. package/lib/esm/runtime/wrap.d.ts +37 -0
  83. package/lib/esm/runtime/wrap.mjs +251 -0
  84. package/lib/esm/runtime/wrap.mjs.map +1 -0
  85. package/lib/esm/testing/index.mjs +84 -53
  86. package/lib/esm/testing/index.mjs.map +1 -1
  87. package/package.json +2 -1
  88. package/src/core/normalize-classname.ts +19 -0
  89. package/src/core/style-builder/build-style.ts +286 -55
  90. package/src/core/style-builder/union-builder.ts +36 -3
  91. package/src/metro/dts.ts +7 -19
  92. package/src/metro/state.ts +29 -74
  93. package/src/metro/transformer.ts +190 -34
  94. package/src/metro/with-config.ts +13 -28
  95. package/src/metro/wrap-imports.ts +260 -0
  96. package/src/runtime/components/rnwind-provider.tsx +0 -17
  97. package/src/runtime/hooks/use-css.ts +17 -11
  98. package/src/runtime/index.ts +3 -26
  99. package/src/runtime/lookup-css.ts +10 -0
  100. package/src/runtime/resolve.ts +438 -0
  101. package/src/runtime/wrap.tsx +267 -0
  102. package/src/testing/index.ts +106 -56
  103. package/lib/cjs/core/parser/text-truncate.cjs +0 -78
  104. package/lib/cjs/core/parser/text-truncate.cjs.map +0 -1
  105. package/lib/cjs/metro/transform-ast.cjs +0 -1472
  106. package/lib/cjs/metro/transform-ast.cjs.map +0 -1
  107. package/lib/cjs/metro/transform-ast.d.ts +0 -88
  108. package/lib/cjs/runtime/haptics.cjs +0 -113
  109. package/lib/cjs/runtime/haptics.cjs.map +0 -1
  110. package/lib/cjs/runtime/haptics.d.ts +0 -48
  111. package/lib/cjs/runtime/interactive-box.cjs +0 -35
  112. package/lib/cjs/runtime/interactive-box.cjs.map +0 -1
  113. package/lib/cjs/runtime/interactive-box.d.ts +0 -40
  114. package/lib/esm/core/parser/text-truncate.mjs +0 -75
  115. package/lib/esm/core/parser/text-truncate.mjs.map +0 -1
  116. package/lib/esm/metro/transform-ast.d.ts +0 -88
  117. package/lib/esm/metro/transform-ast.mjs +0 -1451
  118. package/lib/esm/metro/transform-ast.mjs.map +0 -1
  119. package/lib/esm/runtime/haptics.d.ts +0 -48
  120. package/lib/esm/runtime/haptics.mjs +0 -110
  121. package/lib/esm/runtime/haptics.mjs.map +0 -1
  122. package/lib/esm/runtime/interactive-box.d.ts +0 -40
  123. package/lib/esm/runtime/interactive-box.mjs +0 -33
  124. package/lib/esm/runtime/interactive-box.mjs.map +0 -1
  125. package/src/metro/transform-ast.ts +0 -1729
  126. package/src/runtime/haptics.ts +0 -120
  127. 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 { lookupCss } from '../lookup-css'
2
+ import { resolve } from '../resolve'
3
3
 
4
4
  /**
5
- * Convenience hook: `useRnwind()` + `lookupCss()` rolled into one. Use
6
- * inside any component that wants the resolved style array without
7
- * threading the rnwind context manually. JSX-heavy components should
8
- * still call `useRnwind()` once and pass it to `lookupCss(...)` per
9
- * element so React only does a single context read per render.
10
- * @param className Raw className string or transformer-hoisted atom-name array.
11
- * @param userStyle Optional caller-supplied style appended last.
12
- * @returns Frozen style array for React Native's `style` prop.
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 | readonly string[] | null, userStyle?: unknown): readonly unknown[] {
15
- return lookupCss(className, useRnwind(), userStyle)
20
+ export function useCss(className?: string | null, userStyle?: unknown): unknown {
21
+ return resolve(className, useRnwind(), userStyle).style
16
22
  }
@@ -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.