@ranimontagna/agent-toolkit 0.3.6 → 0.3.7
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/CHANGELOG.md +2 -0
- package/README.md +1 -1
- package/package.json +1 -1
- package/skills/backend/fastify-best-practices/NOTICE.md +1 -1
- package/skills/backend/fastify-best-practices/rules/authentication.md +13 -0
- package/skills/backend/fastify-best-practices/rules/configuration.md +9 -0
- package/skills/backend/fastify-best-practices/rules/content-type.md +16 -0
- package/skills/backend/fastify-best-practices/rules/cors-security.md +18 -0
- package/skills/backend/fastify-best-practices/rules/database.md +12 -0
- package/skills/backend/fastify-best-practices/rules/decorators.md +14 -0
- package/skills/backend/fastify-best-practices/rules/deployment.md +16 -0
- package/skills/backend/fastify-best-practices/rules/error-handling.md +16 -0
- package/skills/backend/fastify-best-practices/rules/hooks.md +20 -0
- package/skills/backend/fastify-best-practices/rules/http-proxy.md +11 -0
- package/skills/backend/fastify-best-practices/rules/logging.md +18 -0
- package/skills/backend/fastify-best-practices/rules/performance.md +20 -0
- package/skills/backend/fastify-best-practices/rules/plugins.md +14 -0
- package/skills/backend/fastify-best-practices/rules/routes.md +18 -0
- package/skills/backend/fastify-best-practices/rules/schemas.md +20 -0
- package/skills/backend/fastify-best-practices/rules/serialization.md +19 -0
- package/skills/backend/fastify-best-practices/rules/testing.md +17 -0
- package/skills/backend/fastify-best-practices/rules/typescript.md +15 -0
- package/skills/backend/fastify-best-practices/rules/websockets.md +15 -0
- package/skills/backend/go/golang-patterns/NOTICE.md +1 -1
- package/skills/backend/go/golang-patterns/SKILL.md +2 -1
- package/skills/devops/docker-patterns/NOTICE.md +1 -1
- package/skills/devops/docker-patterns/SKILL.md +3 -3
- package/skills/frontend/design/revenue-centric-design/NOTICE.md +1 -1
- package/skills/frontend/design/revenue-centric-design/SKILL.md +6 -4
- package/skills/frontend/design/revenue-centric-design/assets/1985681720104903142__1.jpg +0 -0
- package/skills/frontend/design/revenue-centric-design/assets/1999584679247134761__1.jpg +0 -0
- package/skills/frontend/design/revenue-centric-design/assets/2000930776636940333__1.jpg +0 -0
- package/skills/frontend/design/revenue-centric-design/assets/2018693884449009956__3.jpg +0 -0
- package/skills/frontend/design/revenue-centric-design/assets/2081714430811730162__1.jpg +0 -0
- package/skills/frontend/design/revenue-centric-design/assets/2092692547244007852__q__1.jpg +0 -0
- package/skills/frontend/design/revenue-centric-design/assets/2092692547244007852__q__2.jpg +0 -0
- package/skills/frontend/design/revenue-centric-design/assets/2092692547244007852__q__3.jpg +0 -0
- package/skills/frontend/design/revenue-centric-design/references/checkout-and-forms.md +39 -0
- package/skills/frontend/design/revenue-centric-design/references/churn-and-retention.md +25 -0
- package/skills/frontend/design/revenue-centric-design/references/conversion-and-landing-pages.md +52 -1
- package/skills/frontend/design/revenue-centric-design/references/dashboards-and-data-viz.md +23 -0
- package/skills/frontend/design/revenue-centric-design/references/metrics-and-experimentation.md +13 -0
- package/skills/frontend/design/revenue-centric-design/references/onboarding-and-activation.md +7 -1
- package/skills/frontend/design/revenue-centric-design/references/pricing-and-monetization.md +35 -8
- package/skills/frontend/design/revenue-centric-design/references/product-strategy-and-features.md +37 -0
- package/skills/frontend/design/revenue-centric-design/references/revenue-centric-design.md +2 -2
- package/skills/frontend/design/ui-ux-pro-max/NOTICE.md +6 -4
- package/skills/frontend/design/ui-ux-pro-max/SKILL.md +103 -573
- package/skills/frontend/design/ui-ux-pro-max/data/app-interface.csv +29 -27
- package/skills/frontend/design/ui-ux-pro-max/data/catalog-summary.json +78 -0
- package/skills/frontend/design/ui-ux-pro-max/data/charts.csv +26 -26
- package/skills/frontend/design/ui-ux-pro-max/data/colors.csv +191 -160
- package/skills/frontend/design/ui-ux-pro-max/data/data-provenance.json +1348 -0
- package/skills/frontend/design/ui-ux-pro-max/data/google-font-licenses.json +20185 -0
- package/skills/frontend/design/ui-ux-pro-max/data/google-fonts.csv +1934 -1923
- package/skills/frontend/design/ui-ux-pro-max/data/icons.csv +106 -106
- package/skills/frontend/design/ui-ux-pro-max/data/landing.csv +35 -35
- package/skills/frontend/design/ui-ux-pro-max/data/motion.csv +18 -0
- package/skills/frontend/design/ui-ux-pro-max/data/phosphor-icons-upstream.json +32582 -0
- package/skills/frontend/design/ui-ux-pro-max/data/products.csv +192 -161
- package/skills/frontend/design/ui-ux-pro-max/data/react-performance.csv +37 -37
- package/skills/frontend/design/ui-ux-pro-max/data/stacks/angular.csv +51 -51
- package/skills/frontend/design/ui-ux-pro-max/data/stacks/astro.csv +54 -54
- package/skills/frontend/design/ui-ux-pro-max/data/stacks/avalonia.csv +57 -0
- package/skills/frontend/design/ui-ux-pro-max/data/stacks/flutter.csv +53 -53
- package/skills/frontend/design/ui-ux-pro-max/data/stacks/html-tailwind.csv +60 -56
- package/skills/frontend/design/ui-ux-pro-max/data/stacks/javafx.csv +76 -0
- package/skills/frontend/design/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -53
- package/skills/frontend/design/ui-ux-pro-max/data/stacks/laravel.csv +51 -51
- package/skills/frontend/design/ui-ux-pro-max/data/stacks/nextjs.csv +62 -53
- package/skills/frontend/design/ui-ux-pro-max/data/stacks/nuxt-ui.csv +77 -51
- package/skills/frontend/design/ui-ux-pro-max/data/stacks/nuxtjs.csv +68 -59
- package/skills/frontend/design/ui-ux-pro-max/data/stacks/react-native.csv +52 -52
- package/skills/frontend/design/ui-ux-pro-max/data/stacks/react.csv +67 -54
- package/skills/frontend/design/ui-ux-pro-max/data/stacks/shadcn.csv +69 -61
- package/skills/frontend/design/ui-ux-pro-max/data/stacks/svelte.csv +56 -54
- package/skills/frontend/design/ui-ux-pro-max/data/stacks/swiftui.csv +51 -51
- package/skills/frontend/design/ui-ux-pro-max/data/stacks/threejs.csv +54 -54
- package/skills/frontend/design/ui-ux-pro-max/data/stacks/uno.csv +60 -0
- package/skills/frontend/design/ui-ux-pro-max/data/stacks/uwp.csv +56 -0
- package/skills/frontend/design/ui-ux-pro-max/data/stacks/vue.csv +50 -50
- package/skills/frontend/design/ui-ux-pro-max/data/stacks/winui.csv +60 -0
- package/skills/frontend/design/ui-ux-pro-max/data/stacks/wpf.csv +57 -0
- package/skills/frontend/design/ui-ux-pro-max/data/styles.csv +89 -85
- package/skills/frontend/design/ui-ux-pro-max/data/typography.csv +74 -73
- package/skills/frontend/design/ui-ux-pro-max/data/ui-reasoning.csv +193 -162
- package/skills/frontend/design/ui-ux-pro-max/data/ux-guidelines.csv +30 -10
- package/skills/frontend/design/ui-ux-pro-max/references/pro-rules.md +117 -0
- package/skills/frontend/design/ui-ux-pro-max/references/quick-reference.md +256 -0
- package/skills/frontend/design/ui-ux-pro-max/scripts/core.py +800 -69
- package/skills/frontend/design/ui-ux-pro-max/scripts/design_system.py +700 -180
- package/skills/frontend/design/ui-ux-pro-max/scripts/reasoning_contract.py +123 -0
- package/skills/frontend/design/ui-ux-pro-max/scripts/search.py +105 -42
- package/skills/frontend/design/ui-ux-pro-max/scripts/validate_data.py +1095 -0
- package/skills/frontend/react-native/react-native-unistyles-v3/NOTICE.md +1 -1
- package/skills/frontend/react-native/react-native-unistyles-v3/SKILL.md +33 -24
- package/skills/frontend/react-native/react-native-unistyles-v3/references/api-reference.md +135 -78
- package/skills/frontend/react-native/react-native-unistyles-v3/references/common-issues.md +48 -31
- package/skills/frontend/react-native/react-native-unistyles-v3/references/setup-guide.md +76 -34
- package/skills/frontend/react-native/react-native-unistyles-v3/references/styling-patterns.md +145 -52
- package/skills/frontend/react-native/react-native-unistyles-v3/references/third-party-integration.md +76 -27
- package/skills/media/brag-slim/NOTICE.md +3 -3
- package/skills/media/brag-slim/SKILL.md +4 -0
- package/skills/frontend/design/revenue-centric-design/assets/2018693884449009956__1.jpg +0 -0
- package/skills/frontend/design/ui-ux-pro-max/data/_sync_all.py +0 -414
- package/skills/frontend/design/ui-ux-pro-max/data/design.csv +0 -1776
- package/skills/frontend/design/ui-ux-pro-max/data/draft.csv +0 -1779
|
@@ -6,18 +6,18 @@ Curated from 150+ GitHub issues. Organized by category with symptoms, causes, an
|
|
|
6
6
|
|
|
7
7
|
## 1. Setup & Initialization
|
|
8
8
|
|
|
9
|
-
### "Unistyles was loaded but not configured" after hot reload
|
|
9
|
+
### "Unistyles was loaded, but it's not configured" after hot reload
|
|
10
10
|
|
|
11
11
|
**Symptoms:** Error appears after fast refresh / hot reload, not on cold start.
|
|
12
12
|
**Cause:** `StyleSheet.configure()` runs in a module scope that doesn't re-execute on HMR.
|
|
13
13
|
**Solution:** Ensure `StyleSheet.configure()` is imported in your entry point file. For Expo Router, follow the [Expo Router integration steps](setup-guide.md#expo-router-integration).
|
|
14
14
|
**Ref:** [#1098](https://github.com/jpudysz/react-native-unistyles/issues/1098)
|
|
15
15
|
|
|
16
|
-
### "Unistyles not
|
|
16
|
+
### "Unistyles was loaded, but it's not configured. Did you forget to call StyleSheet.configure?"
|
|
17
17
|
|
|
18
18
|
**Symptoms:** Crash on app start.
|
|
19
19
|
**Cause:** `StyleSheet.create()` is called before `StyleSheet.configure()`.
|
|
20
|
-
**Solution:** Move `StyleSheet.configure()` to your app's entry point, before any component imports that use `StyleSheet.create`.
|
|
20
|
+
**Solution:** Move `StyleSheet.configure()` to your app's entry point, before any component imports that use `StyleSheet.create`. With no themes/breakpoints, call `StyleSheet.configure({})`.
|
|
21
21
|
**Ref:** [#1010](https://github.com/jpudysz/react-native-unistyles/issues/1010)
|
|
22
22
|
|
|
23
23
|
### StyleSheet.configure timing with Expo Router
|
|
@@ -26,17 +26,17 @@ Curated from 150+ GitHub issues. Organized by category with symptoms, causes, an
|
|
|
26
26
|
**Cause:** Expo Router resolves routes before your config runs.
|
|
27
27
|
**Solution:**
|
|
28
28
|
1. Set `"main": "index.ts"` in package.json
|
|
29
|
-
2. Create `index.ts` with:
|
|
29
|
+
2. Create `index.ts` (or `index.js`) with:
|
|
30
30
|
```ts
|
|
31
|
-
import './unistyles' // configure first
|
|
32
31
|
import 'expo-router/entry'
|
|
32
|
+
import './unistyles' // your StyleSheet.configure() file
|
|
33
33
|
```
|
|
34
34
|
3. For static rendering, also import config in `app/+html.tsx`
|
|
35
35
|
|
|
36
36
|
### "Property value expected type of number but got null" for hasAdaptiveThemes
|
|
37
37
|
|
|
38
38
|
**Symptoms:** Runtime error mentioning `hasAdaptiveThemes` property.
|
|
39
|
-
**Cause:** `adaptiveThemes` set to `true` without both `light` and `dark` themes registered.
|
|
39
|
+
**Cause:** `adaptiveThemes` set to `true` without both `light` and `dark` themes registered (current versions throw "You're trying to enable adaptiveThemes, but you didn't register both 'light' and 'dark' themes").
|
|
40
40
|
**Solution:** Ensure themes object has keys named exactly `light` and `dark`:
|
|
41
41
|
```tsx
|
|
42
42
|
StyleSheet.configure({
|
|
@@ -46,14 +46,23 @@ StyleSheet.configure({
|
|
|
46
46
|
```
|
|
47
47
|
**Ref:** [#1040](https://github.com/jpudysz/react-native-unistyles/issues/1040)
|
|
48
48
|
|
|
49
|
+
### setTheme throws / initialTheme + adaptiveThemes error
|
|
50
|
+
|
|
51
|
+
**Cause:** `initialTheme` and `adaptiveThemes: true` are mutually exclusive, and `UnistylesRuntime.setTheme()` throws while adaptive themes are enabled.
|
|
52
|
+
**Solution:** Use one of the two settings. To switch manually at runtime, call `UnistylesRuntime.setAdaptiveThemes(false)` before `setTheme()`.
|
|
53
|
+
|
|
54
|
+
### Adaptive themes don't follow the OS
|
|
55
|
+
|
|
56
|
+
**Solution:** Check that Expo `app.json` has `userInterfaceStyle: "automatic"` (bare: `Info.plist` doesn't hardcode `UIUserInterfaceStyle`), and that you haven't forced a scheme with `Appearance.setColorScheme('light' | 'dark')` (use `'unspecified'` to reset). Requires iOS 15+ / Android 10+.
|
|
57
|
+
|
|
49
58
|
---
|
|
50
59
|
|
|
51
60
|
## 2. Style Spreading (Most Common Issue)
|
|
52
61
|
|
|
53
|
-
### "Style is not bound!" error
|
|
62
|
+
### "Style is not bound!" error / "we detected style object with 2 unistyles styles" warning
|
|
54
63
|
|
|
55
|
-
**Symptoms:** Runtime error "Style is not bound!" or styles
|
|
56
|
-
**Cause:** Spreading Unistyles styles with `{...styles.x}
|
|
64
|
+
**Symptoms:** Runtime error "Unistyles: Style is not bound!", a `__DEV__` warning about merged Unistyles styles, or styles that stop updating.
|
|
65
|
+
**Cause:** Spreading/merging Unistyles styles with `{...styles.x}` (or altering the hidden `unistyles_*` key). Each style carries C++ state — merging two into one object keeps only the first binding.
|
|
57
66
|
**Solution:** ALWAYS use array syntax:
|
|
58
67
|
```tsx
|
|
59
68
|
// WRONG
|
|
@@ -85,7 +94,7 @@ const animStyle = useAnimatedStyle(() => ({ ...styles.box }))
|
|
|
85
94
|
### Re-exporting StyleSheet from barrel files
|
|
86
95
|
|
|
87
96
|
**Symptoms:** Styles not reactive; theme changes have no effect.
|
|
88
|
-
**Cause:**
|
|
97
|
+
**Cause:** Outside `root`, the Babel plugin recognizes `StyleSheet.create` only when `StyleSheet` is imported from `react-native-unistyles` (or the file matches `autoProcessImports`). Re-exporting through a barrel file (e.g., `export { StyleSheet } from 'react-native-unistyles'` in `utils/index.ts`) breaks detection there. (Inside `root` a heuristic still catches stylesheet-shaped `.create()` calls, but don't rely on it.)
|
|
89
98
|
**Solution:** Always import directly:
|
|
90
99
|
```tsx
|
|
91
100
|
// WRONG
|
|
@@ -98,14 +107,14 @@ import { StyleSheet } from 'react-native-unistyles'
|
|
|
98
107
|
### Plugin interferes with other .create() calls
|
|
99
108
|
|
|
100
109
|
**Symptoms:** Other libraries' `.create()` calls break (e.g., Zustand, custom factories).
|
|
101
|
-
**Cause:**
|
|
102
|
-
**Solution:**
|
|
110
|
+
**Cause:** In processed files (under `root`, matching `autoProcessImports`, or importing `react-native-unistyles`), the plugin treats any `something.create(arg)` that *looks like* a stylesheet as one: a single object argument whose values are objects, or an arrow function with ≤ 2 params returning a non-empty object.
|
|
111
|
+
**Solution:** Change the call shape (e.g. pass an extra argument or a non-arrow factory), or move such factories to a file the plugin doesn't process. Use `debug: true` to see what the plugin detected.
|
|
103
112
|
**Ref:** [#993](https://github.com/jpudysz/react-native-unistyles/issues/993)
|
|
104
113
|
|
|
105
114
|
### Wrong root directory
|
|
106
115
|
|
|
107
116
|
**Symptoms:** Styles not reactive; Babel plugin appears to do nothing.
|
|
108
|
-
**Cause:** The `root` option
|
|
117
|
+
**Cause:** The `root` option is missing (the plugin throws), resolves to the project root (throws — it would include `node_modules`), or points to the wrong directory. It's resolved relative to Babel's `root` (project directory by default).
|
|
109
118
|
**Solution:** `root` must point to your **source code directory**, not the project root:
|
|
110
119
|
```js
|
|
111
120
|
// WRONG — root resolves to project root
|
|
@@ -119,13 +128,14 @@ import { StyleSheet } from 'react-native-unistyles'
|
|
|
119
128
|
|
|
120
129
|
### Files outside root not processed
|
|
121
130
|
|
|
122
|
-
**Symptoms:** Shared package
|
|
123
|
-
**Cause:**
|
|
124
|
-
**Solution:**
|
|
131
|
+
**Symptoms:** Shared package / library views not reactive.
|
|
132
|
+
**Cause:** Files outside `root` are only processed if they import `react-native-unistyles` (and contain a stylesheet), match `autoProcessImports`, or match `autoProcessPaths`. `node_modules` is ignored unless listed in `autoProcessPaths`.
|
|
133
|
+
**Solution:**
|
|
125
134
|
```js
|
|
126
135
|
['react-native-unistyles/plugin', {
|
|
127
136
|
root: 'src',
|
|
128
|
-
|
|
137
|
+
autoProcessImports: ['@my-org/styles'], // your monorepo files importing this are processed
|
|
138
|
+
autoProcessPaths: ['external-library/components'] // substring of the absolute path, NOT '../relative'
|
|
129
139
|
}]
|
|
130
140
|
```
|
|
131
141
|
|
|
@@ -133,6 +143,16 @@ import { StyleSheet } from 'react-native-unistyles'
|
|
|
133
143
|
|
|
134
144
|
## 4. Theme Updates Not Propagating
|
|
135
145
|
|
|
146
|
+
### Frozen / hidden screens show stale styles
|
|
147
|
+
|
|
148
|
+
**Symptoms:** After changing the theme (or rotating) while a screen is frozen (`freezeOnBlur`, react-navigation `inactiveBehavior` / `<Activity />`, `Suspense` fallback), the screen returns with old styles, or dynamic styles look wrong.
|
|
149
|
+
**Cause:** Bugs in re-linking frozen views, fixed in **3.4.0**; also non-serializable dynamic function arguments (functions are dropped, `Date`/class instances become `{}` when the function is re-run natively).
|
|
150
|
+
**Solution:** Upgrade to 3.4.0+, and pass only serializable values to dynamic functions. `useUnistyles`/`withUnistyles` components update only after the screen unfreezes (React blocks frozen trees).
|
|
151
|
+
|
|
152
|
+
### Component not updating at all
|
|
153
|
+
|
|
154
|
+
Check, in order: the file is processed by the Babel plugin (`debug: true`); the view is a React Native view (otherwise use `withUnistyles`); styles aren't spread; `contentContainerStyle` is passed through `withUnistyles`.
|
|
155
|
+
|
|
136
156
|
### Nested Text components + Reanimated conflict
|
|
137
157
|
|
|
138
158
|
**Symptoms:** Nested `<Text>` components don't update color when theme changes while using Reanimated.
|
|
@@ -202,7 +222,7 @@ const UniButton = withUnistyles(Button, (theme) => ({
|
|
|
202
222
|
### Keyboard inset lag with react-native-keyboard-controller
|
|
203
223
|
|
|
204
224
|
**Symptoms:** `rt.insets.ime` lags behind actual keyboard position.
|
|
205
|
-
**Cause:** Conflict between Unistyles' IME tracking and react-native-keyboard-controller.
|
|
225
|
+
**Cause:** Conflict between Unistyles' IME tracking and react-native-keyboard-controller. (Note: on Android, `ime` is the keyboard height minus the bottom inset and is only animated on Android 11+; Unistyles also guards `rt.insets.bottom` from being polluted by keyboard libraries.)
|
|
206
226
|
**Solution:** Use only one keyboard tracking solution. Prefer `rt.insets.ime` and remove `react-native-keyboard-controller`, or vice versa.
|
|
207
227
|
**Ref:** [#1065](https://github.com/jpudysz/react-native-unistyles/issues/1065)
|
|
208
228
|
|
|
@@ -234,15 +254,12 @@ npx react-native run-android
|
|
|
234
254
|
### SSR hydration mismatches
|
|
235
255
|
|
|
236
256
|
**Symptoms:** React hydration warnings on page load with SSR.
|
|
237
|
-
**Cause:** Server-rendered styles don't match client-side
|
|
238
|
-
**Solution:** Use the SSR utilities:
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
// Client: hydrate
|
|
244
|
-
hydrateServerUnistyles()
|
|
245
|
-
```
|
|
257
|
+
**Cause:** Server-rendered styles don't match client-side state, or (without adaptive themes) Unistyles adds the theme class to `<html>`.
|
|
258
|
+
**Solution:** Use the SSR utilities from `react-native-unistyles/server` (see [styling-patterns.md](styling-patterns.md#ssr-with-nextjs)):
|
|
259
|
+
- App Router: `useServerUnistyles()` inside a `'use client'` component with `useServerInsertedHTML` (hydrates automatically on the client)
|
|
260
|
+
- Pages Router: `getServerUnistyles()` + `resetServerUnistyles()` in `_document` `getInitialProps`, `hydrateServerUnistyles()` in a `useEffect` in `_app`
|
|
261
|
+
- Add `suppressHydrationWarning` (or the theme class) to `<html>`
|
|
262
|
+
- Styles leaking between requests (Pages Router) → you forgot `resetServerUnistyles()`
|
|
246
263
|
|
|
247
264
|
### Safari 16.3 and below not supported
|
|
248
265
|
|
|
@@ -255,7 +272,7 @@ hydrateServerUnistyles()
|
|
|
255
272
|
|
|
256
273
|
**Symptoms:** Animated.View doesn't receive Unistyles styles on web platform.
|
|
257
274
|
**Cause:** Reanimated's web implementation may not forward the style processing correctly.
|
|
258
|
-
**Solution:** Use `getWebProps` or apply styles differently on web.
|
|
275
|
+
**Solution:** Use `getWebProps` from `react-native-unistyles/web` (spread `{ className, ref }`) or apply styles differently on web.
|
|
259
276
|
**Ref:** [#1014](https://github.com/jpudysz/react-native-unistyles/issues/1014)
|
|
260
277
|
|
|
261
278
|
### Gap polyfill incorrect margins on SmartTV
|
|
@@ -335,9 +352,9 @@ plugins: [
|
|
|
335
352
|
|
|
336
353
|
### useUnistyles causes re-renders
|
|
337
354
|
|
|
338
|
-
**Symptoms:** Excessive re-renders, especially on theme/orientation changes.
|
|
339
|
-
**Cause:** `useUnistyles()`
|
|
340
|
-
**Solution:** Prefer `StyleSheet.create(theme => ...)` which uses zero-re-render C++ updates. Reserve `useUnistyles()` for cases where you need theme/runtime in JS logic.
|
|
355
|
+
**Symptoms:** Excessive re-renders, especially on theme/orientation/keyboard changes.
|
|
356
|
+
**Cause:** `useUnistyles()` re-renders the whole component when any value you **read** changes (subscriptions are created on property access, not destructuring). Reading `rt.insets.ime` re-renders on every keyboard animation frame.
|
|
357
|
+
**Solution:** Prefer `StyleSheet.create(theme => ...)` which uses zero-re-render C++ updates. Reserve `useUnistyles()` for cases where you need theme/runtime in JS logic, and read only what you need.
|
|
341
358
|
|
|
342
359
|
### Variant memory in long lists
|
|
343
360
|
|
|
@@ -3,11 +3,15 @@
|
|
|
3
3
|
## Installation
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
npm install react-native-unistyles react-native-nitro-modules
|
|
6
|
+
npm install react-native-unistyles react-native-nitro-modules@0.37.1
|
|
7
7
|
# or
|
|
8
|
-
yarn add react-native-unistyles react-native-nitro-modules
|
|
8
|
+
yarn add react-native-unistyles react-native-nitro-modules@0.37.1
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
Always pin an exact `react-native-nitro-modules` version that matches the compatibility table in the Unistyles README (Unistyles 3.4.0+ requires `>= 0.37.1`).
|
|
12
|
+
|
|
13
|
+
On Android, `react-native-edge-to-edge` is optional (since v3.1.0). Set `edgeToEdgeEnabled=true` in `android/gradle.properties` (Expo SDK 54+ does it automatically).
|
|
14
|
+
|
|
11
15
|
Then rebuild your native project:
|
|
12
16
|
```bash
|
|
13
17
|
npx pod-install # iOS
|
|
@@ -34,11 +38,13 @@ module.exports = {
|
|
|
34
38
|
|
|
35
39
|
| Option | Type | Description |
|
|
36
40
|
|--------|------|-------------|
|
|
37
|
-
| `root` | `string` | **Required
|
|
38
|
-
| `
|
|
39
|
-
| `
|
|
40
|
-
| `autoRemapImports` | `
|
|
41
|
-
| `debug` | `boolean` |
|
|
41
|
+
| `root` | `string` | **Required** (the plugin throws without it). Folder resolved relative to Babel's `root` (your project directory by default). **Every file under it is processed**, no matter what it imports. Must NOT resolve to the project root itself (`'.'`), as that would include `node_modules`. |
|
|
42
|
+
| `autoProcessImports` | `string[]` | Any file (outside `node_modules`) that imports one of these sources is processed like a `root` file (e.g., `['@my-org/styles']`). Use it for monorepo packages outside `root`. |
|
|
43
|
+
| `autoProcessPaths` | `string[]` | Path fragments (matched as a substring of the absolute file path, e.g. `'external-library/components'`) whose `react-native` imports are replaced with Unistyles ref-borrowing factories. Meant for 3rd party code in `node_modules`. `react-native-reanimated/src/component` and `react-native-reanimated/lib/module/component` are always included; your paths are added. |
|
|
44
|
+
| `autoRemapImports` | `Array<{ path: string, imports: Array<{ isDefault: boolean, name?: string, path: string, mapTo: string }> }>` | Advanced: remap non-standard imports (e.g. `react-native/Libraries/...`) in a `node_modules` library to Unistyles factories. |
|
|
45
|
+
| `debug` | `boolean` | Log detected style dependencies per file/style. Default: `false`. |
|
|
46
|
+
|
|
47
|
+
The plugin also throws on string refs (`ref="myView"`). Components swapped for ref-borrowing factories: `ActivityIndicator`, `View`, `Text`, `Image`, `ImageBackground`, `KeyboardAvoidingView`, `Pressable`, `ScrollView`, `FlatList`, `SectionList`, `Switch`, `TextInput`, `RefreshControl`, `TouchableHighlight`, `TouchableOpacity`, `VirtualizedList`, `Animated`, `SafeAreaView` (`Modal` and `TouchableWithoutFeedback` are not supported).
|
|
42
48
|
|
|
43
49
|
### Example: Monorepo with shared packages
|
|
44
50
|
|
|
@@ -48,13 +54,39 @@ module.exports = {
|
|
|
48
54
|
plugins: [
|
|
49
55
|
['react-native-unistyles/plugin', {
|
|
50
56
|
root: 'src',
|
|
51
|
-
|
|
52
|
-
autoProcessImports: ['@
|
|
57
|
+
// files outside `root` that import these sources are processed too
|
|
58
|
+
autoProcessImports: ['@my-org/styles', '@my-org/ui'],
|
|
59
|
+
// 3rd party components in node_modules built on react-native views
|
|
60
|
+
autoProcessPaths: ['external-library/components']
|
|
53
61
|
}]
|
|
54
62
|
]
|
|
55
63
|
}
|
|
56
64
|
```
|
|
57
65
|
|
|
66
|
+
Note: `autoProcessPaths` is a substring match against the absolute file path — relative paths like `'../shared-ui/src'` never match.
|
|
67
|
+
|
|
68
|
+
### Re.Pack
|
|
69
|
+
|
|
70
|
+
With Re.Pack, don't add the plugin to `babel.config.js`; use the Rspack plugin instead (it runs the same Babel plugin through a loader):
|
|
71
|
+
|
|
72
|
+
```js
|
|
73
|
+
// rspack.config.mjs
|
|
74
|
+
import * as Repack from '@callstack/repack'
|
|
75
|
+
import { RepackUnistylePlugin } from 'react-native-unistyles/repack-plugin'
|
|
76
|
+
|
|
77
|
+
export default {
|
|
78
|
+
plugins: [
|
|
79
|
+
new Repack.RepackPlugin(),
|
|
80
|
+
new RepackUnistylePlugin({
|
|
81
|
+
unistylesPluginOptions: { root: 'src' }, // same options as the Babel plugin, `root` required
|
|
82
|
+
// ruleExcludePaths: [...BASE_REPACK_EXCLUDE_PATHS, /my-lib/] // optional RegExp[]
|
|
83
|
+
})
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The loader needs `@babel/plugin-syntax-typescript` and `babel-plugin-syntax-hermes-parser` installed in your project.
|
|
89
|
+
|
|
58
90
|
### React Compiler ordering
|
|
59
91
|
|
|
60
92
|
If using React Compiler, the Unistyles plugin **MUST come BEFORE** React Compiler:
|
|
@@ -100,10 +132,12 @@ StyleSheet.configure({
|
|
|
100
132
|
|
|
101
133
|
| Setting | Type | Description |
|
|
102
134
|
|---------|------|-------------|
|
|
103
|
-
| `initialTheme` | `string \| () => string` | Theme to use on app start. Can be a function
|
|
104
|
-
| `adaptiveThemes` | `boolean` | Auto-switch between `light` and `dark` themes based on OS color scheme. Requires themes named exactly `light` and `dark`.
|
|
105
|
-
| `CSSVars` | `boolean` |
|
|
106
|
-
| `nativeBreakpointsMode` | `'pixels' \| 'points'` |
|
|
135
|
+
| `initialTheme` | `string \| () => string` | Theme to use on app start. Can be a synchronous function (e.g., reading from storage). Mutually exclusive with `adaptiveThemes: true` (throws). With 2+ themes and no `adaptiveThemes`, set it — otherwise no theme is selected. A single registered theme is selected automatically. |
|
|
136
|
+
| `adaptiveThemes` | `boolean` | Auto-switch between `light` and `dark` themes based on OS color scheme. Requires themes named exactly `light` and `dark`. While enabled, `UnistylesRuntime.setTheme()` throws — call `setAdaptiveThemes(false)` first. |
|
|
137
|
+
| `CSSVars` | `boolean` | Web only. Converts theme strings to CSS variables, so theme switching only swaps the `html` class (or relies on `prefers-color-scheme` with adaptive themes). Default: `true`. Disable when themes differ in non-string values (numbers, functions). |
|
|
138
|
+
| `nativeBreakpointsMode` | `'pixels' \| 'points'` | Default `'pixels'`: breakpoints are compared against `UnistylesRuntime.screen` (points on iOS, dp on Android). `'points'` additionally divides the screen size by `pixelRatio`. |
|
|
139
|
+
|
|
140
|
+
Any other key in `settings` (or in the config object) throws an error.
|
|
107
141
|
|
|
108
142
|
### Minimal configuration (no themes, no breakpoints)
|
|
109
143
|
|
|
@@ -120,7 +154,7 @@ Augment the Unistyles module to get type-safe themes and breakpoints:
|
|
|
120
154
|
```tsx
|
|
121
155
|
// unistyles.ts (or wherever you call StyleSheet.configure)
|
|
122
156
|
import { StyleSheet } from 'react-native-unistyles'
|
|
123
|
-
import { lightTheme } from './themes'
|
|
157
|
+
import { lightTheme, darkTheme } from './themes'
|
|
124
158
|
import { breakpoints } from './breakpoints'
|
|
125
159
|
|
|
126
160
|
type AppThemes = {
|
|
@@ -160,11 +194,15 @@ Expo Router resolves routes before Unistyles can initialize. Extra steps are nee
|
|
|
160
194
|
### 2. Create index.ts
|
|
161
195
|
|
|
162
196
|
```ts
|
|
163
|
-
// index.ts
|
|
164
|
-
import './unistyles' // your StyleSheet.configure() file
|
|
197
|
+
// index.ts (or index.js)
|
|
165
198
|
import 'expo-router/entry'
|
|
199
|
+
import './unistyles' // your StyleSheet.configure() file
|
|
166
200
|
```
|
|
167
201
|
|
|
202
|
+
This is the order used by the official docs and the repo's Expo example app. The key point is that the config file is imported from the custom entry, not from a route file.
|
|
203
|
+
|
|
204
|
+
Expo Router screens can be frozen when unfocused (`freezeOnBlur`) — Unistyles keeps their bindings and applies changes when they become visible again (fixes for stale styles landed in 3.4.0).
|
|
205
|
+
|
|
168
206
|
### 3. For static rendering (Expo SDK 52+)
|
|
169
207
|
|
|
170
208
|
Import your Unistyles config in `app/+html.tsx`:
|
|
@@ -193,25 +231,29 @@ export default function Root({ children }: PropsWithChildren) {
|
|
|
193
231
|
|
|
194
232
|
## Testing / Mocks Setup
|
|
195
233
|
|
|
196
|
-
The Babel plugin
|
|
197
|
-
|
|
198
|
-
```js
|
|
199
|
-
// jest.setup.js
|
|
200
|
-
require('react-native-unistyles/mocks')
|
|
201
|
-
require('./unistyles') // your StyleSheet.configure() call — provides theme data to mocks
|
|
202
|
-
```
|
|
234
|
+
The Babel plugin is a no-op when `NODE_ENV === 'test'` (Jest sets this by default). Add the mocks to Jest `setupFiles`, followed by your config file:
|
|
203
235
|
|
|
204
|
-
```
|
|
205
|
-
//
|
|
206
|
-
|
|
207
|
-
|
|
236
|
+
```json
|
|
237
|
+
// package.json
|
|
238
|
+
{
|
|
239
|
+
"jest": {
|
|
240
|
+
"preset": "jest-expo",
|
|
241
|
+
"setupFiles": [
|
|
242
|
+
"react-native-unistyles/mocks",
|
|
243
|
+
"./unistyles.ts"
|
|
244
|
+
]
|
|
245
|
+
}
|
|
208
246
|
}
|
|
209
247
|
```
|
|
210
248
|
|
|
211
|
-
The
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
- `useUnistyles
|
|
215
|
-
- `
|
|
216
|
-
- `
|
|
217
|
-
- `
|
|
249
|
+
The config file must come **after** the mocks (they stub `StyleSheet.configure`).
|
|
250
|
+
|
|
251
|
+
Mock behavior and limitations:
|
|
252
|
+
- `StyleSheet.create`, `useUnistyles` and `withUnistyles` always resolve with the **first** registered theme (`initialTheme` / `adaptiveThemes` are ignored)
|
|
253
|
+
- runtime values (`screen`, `insets`, `statusBar`, `navigationBar`) are `0`
|
|
254
|
+
- `variants` / `compoundVariants` are stripped and `useVariants` does nothing
|
|
255
|
+
- `Display`, `Hide` and `ScopedTheme` render nothing (`null`)
|
|
256
|
+
- `useAnimatedTheme` / `useAnimatedVariantColor` (from `react-native-unistyles/reanimated`) are mocked
|
|
257
|
+
- `createUnistylesElement`, `UnistyleDependency` and the SSR helpers are **not** mocked (`undefined`)
|
|
258
|
+
|
|
259
|
+
Don't unit-test how Unistyles resolves styles — use E2E tools (Maestro, Playwright) for that.
|