@ranimontagna/agent-toolkit 0.3.5 → 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.
Files changed (110) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/README.md +8 -8
  3. package/dist/src/installers/superpowers.js +23 -7
  4. package/dist/src/installers/superpowers.js.map +1 -1
  5. package/package.json +5 -5
  6. package/skills/backend/fastify-best-practices/NOTICE.md +1 -1
  7. package/skills/backend/fastify-best-practices/rules/authentication.md +13 -0
  8. package/skills/backend/fastify-best-practices/rules/configuration.md +9 -0
  9. package/skills/backend/fastify-best-practices/rules/content-type.md +16 -0
  10. package/skills/backend/fastify-best-practices/rules/cors-security.md +18 -0
  11. package/skills/backend/fastify-best-practices/rules/database.md +12 -0
  12. package/skills/backend/fastify-best-practices/rules/decorators.md +14 -0
  13. package/skills/backend/fastify-best-practices/rules/deployment.md +16 -0
  14. package/skills/backend/fastify-best-practices/rules/error-handling.md +16 -0
  15. package/skills/backend/fastify-best-practices/rules/hooks.md +20 -0
  16. package/skills/backend/fastify-best-practices/rules/http-proxy.md +11 -0
  17. package/skills/backend/fastify-best-practices/rules/logging.md +18 -0
  18. package/skills/backend/fastify-best-practices/rules/performance.md +20 -0
  19. package/skills/backend/fastify-best-practices/rules/plugins.md +14 -0
  20. package/skills/backend/fastify-best-practices/rules/routes.md +18 -0
  21. package/skills/backend/fastify-best-practices/rules/schemas.md +20 -0
  22. package/skills/backend/fastify-best-practices/rules/serialization.md +19 -0
  23. package/skills/backend/fastify-best-practices/rules/testing.md +17 -0
  24. package/skills/backend/fastify-best-practices/rules/typescript.md +15 -0
  25. package/skills/backend/fastify-best-practices/rules/websockets.md +15 -0
  26. package/skills/backend/go/golang-patterns/NOTICE.md +1 -1
  27. package/skills/backend/go/golang-patterns/SKILL.md +2 -1
  28. package/skills/devops/docker-patterns/NOTICE.md +1 -1
  29. package/skills/devops/docker-patterns/SKILL.md +3 -3
  30. package/skills/frontend/design/revenue-centric-design/NOTICE.md +1 -1
  31. package/skills/frontend/design/revenue-centric-design/SKILL.md +6 -4
  32. package/skills/frontend/design/revenue-centric-design/assets/1985681720104903142__1.jpg +0 -0
  33. package/skills/frontend/design/revenue-centric-design/assets/1999584679247134761__1.jpg +0 -0
  34. package/skills/frontend/design/revenue-centric-design/assets/2000930776636940333__1.jpg +0 -0
  35. package/skills/frontend/design/revenue-centric-design/assets/2018693884449009956__3.jpg +0 -0
  36. package/skills/frontend/design/revenue-centric-design/assets/2081714430811730162__1.jpg +0 -0
  37. package/skills/frontend/design/revenue-centric-design/assets/2092692547244007852__q__1.jpg +0 -0
  38. package/skills/frontend/design/revenue-centric-design/assets/2092692547244007852__q__2.jpg +0 -0
  39. package/skills/frontend/design/revenue-centric-design/assets/2092692547244007852__q__3.jpg +0 -0
  40. package/skills/frontend/design/revenue-centric-design/references/checkout-and-forms.md +39 -0
  41. package/skills/frontend/design/revenue-centric-design/references/churn-and-retention.md +25 -0
  42. package/skills/frontend/design/revenue-centric-design/references/conversion-and-landing-pages.md +52 -1
  43. package/skills/frontend/design/revenue-centric-design/references/dashboards-and-data-viz.md +23 -0
  44. package/skills/frontend/design/revenue-centric-design/references/metrics-and-experimentation.md +13 -0
  45. package/skills/frontend/design/revenue-centric-design/references/onboarding-and-activation.md +7 -1
  46. package/skills/frontend/design/revenue-centric-design/references/pricing-and-monetization.md +35 -8
  47. package/skills/frontend/design/revenue-centric-design/references/product-strategy-and-features.md +37 -0
  48. package/skills/frontend/design/revenue-centric-design/references/revenue-centric-design.md +2 -2
  49. package/skills/frontend/design/ui-ux-pro-max/NOTICE.md +6 -4
  50. package/skills/frontend/design/ui-ux-pro-max/SKILL.md +103 -573
  51. package/skills/frontend/design/ui-ux-pro-max/data/app-interface.csv +29 -27
  52. package/skills/frontend/design/ui-ux-pro-max/data/catalog-summary.json +78 -0
  53. package/skills/frontend/design/ui-ux-pro-max/data/charts.csv +26 -26
  54. package/skills/frontend/design/ui-ux-pro-max/data/colors.csv +191 -160
  55. package/skills/frontend/design/ui-ux-pro-max/data/data-provenance.json +1348 -0
  56. package/skills/frontend/design/ui-ux-pro-max/data/google-font-licenses.json +20185 -0
  57. package/skills/frontend/design/ui-ux-pro-max/data/google-fonts.csv +1934 -1923
  58. package/skills/frontend/design/ui-ux-pro-max/data/icons.csv +106 -106
  59. package/skills/frontend/design/ui-ux-pro-max/data/landing.csv +35 -35
  60. package/skills/frontend/design/ui-ux-pro-max/data/motion.csv +18 -0
  61. package/skills/frontend/design/ui-ux-pro-max/data/phosphor-icons-upstream.json +32582 -0
  62. package/skills/frontend/design/ui-ux-pro-max/data/products.csv +192 -161
  63. package/skills/frontend/design/ui-ux-pro-max/data/react-performance.csv +37 -37
  64. package/skills/frontend/design/ui-ux-pro-max/data/stacks/angular.csv +51 -51
  65. package/skills/frontend/design/ui-ux-pro-max/data/stacks/astro.csv +54 -54
  66. package/skills/frontend/design/ui-ux-pro-max/data/stacks/avalonia.csv +57 -0
  67. package/skills/frontend/design/ui-ux-pro-max/data/stacks/flutter.csv +53 -53
  68. package/skills/frontend/design/ui-ux-pro-max/data/stacks/html-tailwind.csv +60 -56
  69. package/skills/frontend/design/ui-ux-pro-max/data/stacks/javafx.csv +76 -0
  70. package/skills/frontend/design/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -53
  71. package/skills/frontend/design/ui-ux-pro-max/data/stacks/laravel.csv +51 -51
  72. package/skills/frontend/design/ui-ux-pro-max/data/stacks/nextjs.csv +62 -53
  73. package/skills/frontend/design/ui-ux-pro-max/data/stacks/nuxt-ui.csv +77 -51
  74. package/skills/frontend/design/ui-ux-pro-max/data/stacks/nuxtjs.csv +68 -59
  75. package/skills/frontend/design/ui-ux-pro-max/data/stacks/react-native.csv +52 -52
  76. package/skills/frontend/design/ui-ux-pro-max/data/stacks/react.csv +67 -54
  77. package/skills/frontend/design/ui-ux-pro-max/data/stacks/shadcn.csv +69 -61
  78. package/skills/frontend/design/ui-ux-pro-max/data/stacks/svelte.csv +56 -54
  79. package/skills/frontend/design/ui-ux-pro-max/data/stacks/swiftui.csv +51 -51
  80. package/skills/frontend/design/ui-ux-pro-max/data/stacks/threejs.csv +54 -54
  81. package/skills/frontend/design/ui-ux-pro-max/data/stacks/uno.csv +60 -0
  82. package/skills/frontend/design/ui-ux-pro-max/data/stacks/uwp.csv +56 -0
  83. package/skills/frontend/design/ui-ux-pro-max/data/stacks/vue.csv +50 -50
  84. package/skills/frontend/design/ui-ux-pro-max/data/stacks/winui.csv +60 -0
  85. package/skills/frontend/design/ui-ux-pro-max/data/stacks/wpf.csv +57 -0
  86. package/skills/frontend/design/ui-ux-pro-max/data/styles.csv +89 -85
  87. package/skills/frontend/design/ui-ux-pro-max/data/typography.csv +74 -73
  88. package/skills/frontend/design/ui-ux-pro-max/data/ui-reasoning.csv +193 -162
  89. package/skills/frontend/design/ui-ux-pro-max/data/ux-guidelines.csv +30 -10
  90. package/skills/frontend/design/ui-ux-pro-max/references/pro-rules.md +117 -0
  91. package/skills/frontend/design/ui-ux-pro-max/references/quick-reference.md +256 -0
  92. package/skills/frontend/design/ui-ux-pro-max/scripts/core.py +800 -69
  93. package/skills/frontend/design/ui-ux-pro-max/scripts/design_system.py +700 -180
  94. package/skills/frontend/design/ui-ux-pro-max/scripts/reasoning_contract.py +123 -0
  95. package/skills/frontend/design/ui-ux-pro-max/scripts/search.py +105 -42
  96. package/skills/frontend/design/ui-ux-pro-max/scripts/validate_data.py +1095 -0
  97. package/skills/frontend/react-native/react-native-unistyles-v3/NOTICE.md +1 -1
  98. package/skills/frontend/react-native/react-native-unistyles-v3/SKILL.md +33 -24
  99. package/skills/frontend/react-native/react-native-unistyles-v3/references/api-reference.md +135 -78
  100. package/skills/frontend/react-native/react-native-unistyles-v3/references/common-issues.md +48 -31
  101. package/skills/frontend/react-native/react-native-unistyles-v3/references/setup-guide.md +76 -34
  102. package/skills/frontend/react-native/react-native-unistyles-v3/references/styling-patterns.md +145 -52
  103. package/skills/frontend/react-native/react-native-unistyles-v3/references/third-party-integration.md +76 -27
  104. package/skills/media/brag-slim/NOTICE.md +3 -3
  105. package/skills/media/brag-slim/SKILL.md +4 -0
  106. package/tools.lock.json +20 -20
  107. package/skills/frontend/design/revenue-centric-design/assets/2018693884449009956__1.jpg +0 -0
  108. package/skills/frontend/design/ui-ux-pro-max/data/_sync_all.py +0 -414
  109. package/skills/frontend/design/ui-ux-pro-max/data/design.csv +0 -1776
  110. package/skills/frontend/design/ui-ux-pro-max/data/draft.csv +0 -1779
@@ -3,7 +3,7 @@
3
3
  This skill is copied from Jacek Pudysz's public `jpudysz/react-native-unistyles` repository.
4
4
 
5
5
  - Source: https://github.com/jpudysz/react-native-unistyles/tree/main/skills/react-native-unistyles-v3
6
- - Imported from commit: `8b5e9fd281a81bdfd87d4fe9e6a0b042c84c5c83`
6
+ - Imported from commit: `eef411b37335010860ed80f69aa674572b90e1bf`
7
7
  - Upstream skill name: `react-native-unistyles-v3`
8
8
  - License: MIT, as declared by the upstream README and `packages/unistyles/package.json`
9
9
  - Copyright: Copyright (c) 2026 Jacek Pudysz
@@ -12,12 +12,13 @@ You are assisting with React Native Unistyles v3 styling. v3 is a zero-re-render
12
12
 
13
13
  ## Prerequisites
14
14
 
15
- - React Native 0.78+ with **New Architecture mandatory** (default from RN 0.83+)
15
+ - React Native 0.81+ with **New Architecture mandatory** (enabled by default since RN 0.76, the only architecture since RN 0.82)
16
16
  - React 19+ (enforced at runtime)
17
- - `react-native-nitro-modules` (native bridge dependency)
18
- - `react-native-edge-to-edge` (required for Android edge-to-edge insets)
19
- - Expo SDK 53+ (if using Expo; **not compatible with Expo Go** — requires dev client or prebuild)
20
- - Xcode 16+ (iOS)
17
+ - `react-native-nitro-modules` (native bridge dependency; pin an exact version — Unistyles 3.4.0+ needs `>= 0.37.1`)
18
+ - iOS 15.1+, Android 7+
19
+ - `react-native-edge-to-edge` is optional since v3.1.0 (set `edgeToEdgeEnabled=true` in `android/gradle.properties` instead; Expo SDK 54+ enables it automatically)
20
+ - Expo SDK 54+ (if using Expo; **not compatible with Expo Go** — requires dev client or prebuild)
21
+ - Xcode 16.4+ (iOS, required by Nitro Modules)
21
22
 
22
23
  ## Workflow
23
24
 
@@ -62,8 +63,8 @@ StyleSheet.configure({
62
63
  settings: {
63
64
  initialTheme: 'light', // or: () => storage.getString('theme') ?? 'light'
64
65
  // adaptiveThemes: true, // auto-switch light/dark based on OS (mutually exclusive with initialTheme)
65
- // CSSVars: true, // use CSS custom properties on web
66
- // nativeBreakpointsMode: 'pixels' | 'points'
66
+ // CSSVars: true, // web: themes as CSS variables (default: true)
67
+ // nativeBreakpointsMode: 'pixels' | 'points' // default 'pixels' = compare against rt.screen (pt/dp)
67
68
  }
68
69
  })
69
70
  ```
@@ -90,12 +91,14 @@ const styles = StyleSheet.create(theme => ({
90
91
  }
91
92
  }))
92
93
 
93
- // In component — call useVariants BEFORE accessing styles
94
+ // In component — call useVariants BEFORE accessing styles (always pass an object, `{}` for defaults)
94
95
  styles.useVariants({ size: 'large', color: 'primary' })
95
96
  return <View style={styles.button} />
96
97
  ```
97
98
 
98
- ### withUnistyles — wrap third-party components (not React Native or Reanimated components)
99
+ ### withUnistyles — map theme/runtime to non-style props, or wrap views Unistyles can't bind to
100
+
101
+ React Native / Reanimated views that only take `style` need no wrapping. Use `withUnistyles` for props like `color`/`trackColor`, for `contentContainerStyle`, or for third-party views that don't expose a native ref.
99
102
 
100
103
  ```tsx
101
104
  import { withUnistyles } from 'react-native-unistyles'
@@ -107,17 +110,19 @@ const UniButton = withUnistyles(Button, (theme, rt) => ({
107
110
  }))
108
111
 
109
112
  // Usage: <UniButton title="Press me" />
113
+ // Per-instance mapping: <UniButton uniProps={theme => ({ color: isOn ? theme.colors.on : theme.colors.off })} />
110
114
  ```
111
115
 
112
116
  ## Critical Rules
113
117
 
114
118
  1. **NEVER spread styles** — `{...styles.x}` breaks C++ proxy binding. ALWAYS use array syntax: `[styles.x, styles.y]` or `[styles.x, { marginTop: 10 }]`
115
- 2. **NEVER re-export StyleSheet from barrel files** — the Babel plugin detects `StyleSheet.create` by import source. Re-exporting breaks detection.
116
- 3. **Babel plugin is REQUIRED** — add `['react-native-unistyles/plugin', { root: 'src' }]` to babel.config.js. Without it, styles won't be reactive.
119
+ 2. **NEVER re-export StyleSheet from barrel files** — import it directly from `react-native-unistyles`. Outside `root`, the Babel plugin only recognizes `StyleSheet.create` via that import (or `autoProcessImports`), so a re-export silently breaks detection.
120
+ 3. **Babel plugin is REQUIRED** — add `['react-native-unistyles/plugin', { root: 'src' }]` to babel.config.js (`root` is required; every file under it is processed). Re.Pack users use `RepackUnistylePlugin` from `react-native-unistyles/repack-plugin` instead. Without the plugin, styles won't be reactive.
117
121
  4. **Import StyleSheet from `react-native-unistyles` only** — it polyfills all RN StyleSheet APIs (`hairlineWidth`, `compose`, `flatten`, `absoluteFill`). Replace all `import { StyleSheet } from 'react-native'`.
118
- 5. **`styles.useVariants()` must be called before accessing variant-dependent styles** — treat it like a React hook (top of component).
119
- 6. **Prefer `StyleSheet.create(theme => ...)` over `useUnistyles()`** — theme functions cause zero re-renders; `useUnistyles()` re-renders on every theme/runtime change.
122
+ 5. **`styles.useVariants()` must be called before accessing variant-dependent styles** — treat it like a React hook (top of component). Always pass an object: `useVariants(undefined)` throws on native, use `{}` to select `default` variants.
123
+ 6. **Prefer `StyleSheet.create(theme => ...)` over `useUnistyles()`** — theme functions cause zero re-renders; `useUnistyles()` re-renders whenever a `theme`/`rt` value you *read* changes (never read `rt.insets.ime` there — it re-renders every keyboard frame).
120
124
  7. **`StyleSheet.configure()` must be called before any `StyleSheet.create()`** — typically in your app entry point, before any component renders.
125
+ 8. **Dynamic function arguments must be serializable** — Unistyles stores them in C++ and re-runs the function on theme/runtime changes. Functions are dropped; `Date`/`Map`/`Set`/class instances become plain objects. Pass primitives / plain objects (e.g. `date.getTime()`).
121
126
 
122
127
  ## Decision Trees
123
128
 
@@ -133,27 +138,31 @@ Need theme values as non-style props?
133
138
  └─ NO → Pass Unistyles styles via style prop directly
134
139
 
135
140
  Need theme/runtime in component logic (not just styles)?
136
- ├─ YES → useUnistyles() hook [causes re-renders]
141
+ ├─ YES → useUnistyles() hook [re-renders when read values change]
137
142
  └─ NO → Use StyleSheet.create with theme function
138
143
  ```
139
144
 
140
145
  ### Third-party component integration
141
146
 
142
147
  ```
143
- Does the component accept a `style` prop?
144
- ├─ YES → Pass Unistyles styles directly (Babel auto-processes standard RN views)
145
- │ If it's a custom native view → add to autoProcessPaths in Babel config
146
- ├─ NO → Does it accept theme-derived props (color, size, etc.)?
147
- │ ├─ YES → withUnistyles(Component, (theme, rt) => ({ prop: theme.value }))
148
- │ └─ NO → useUnistyles() as fallback
149
- └─ Component from node_modules not processed?
150
- → Add its path to autoProcessPaths or autoProcessImports in Babel plugin config
148
+ Passing a Unistyles style to `contentContainerStyle` (ScrollView/FlatList)?
149
+ ├─ YES → withUnistyles(ScrollView) — auto-maps style + contentContainerStyle
150
+ └─ NO → react-native / react-native-reanimated view with a `style` prop?
151
+ ├─ YES → Pass Unistyles styles directly (Babel swaps in ref-borrowing factories)
152
+ └─ NO → Third-party view built on RN components (in node_modules)?
153
+ ├─ YES → Add its path to autoProcessPaths (e.g. 'some-lib/src/components')
154
+ └─ Still not updating / needs theme-derived props (color, size, ...)?
155
+ ├─ YES → withUnistyles(Component, (theme, rt) => ({ prop: theme.value }))
156
+ └─ Last resort → useUnistyles() (re-renders the component)
157
+
158
+ Your own files outside `root` (monorepo package) not updating?
159
+ → autoProcessImports: ['@my-org/styles'] (force-processes any file importing it)
151
160
  ```
152
161
 
153
162
  ## Reference Files
154
163
 
155
- - **Setup, installation, Babel plugin, TypeScript, testing, Expo Router**: read [references/setup-guide.md](references/setup-guide.md)
164
+ - **Setup, installation, Babel plugin, Re.Pack, TypeScript, testing, Expo Router**: read [references/setup-guide.md](references/setup-guide.md)
156
165
  - **Complete API for every export**: read [references/api-reference.md](references/api-reference.md)
157
166
  - **Code patterns: themes, variants, breakpoints, web, SSR, Reanimated**: read [references/styling-patterns.md](references/styling-patterns.md)
158
- - **withUnistyles, autoProcessPaths, React Compiler, Reanimated, FlatList**: read [references/third-party-integration.md](references/third-party-integration.md)
167
+ - **withUnistyles, autoProcessPaths/Imports, React Compiler, Reanimated, edge-to-edge, frozen screens, FlatList**: read [references/third-party-integration.md](references/third-party-integration.md)
159
168
  - **Troubleshooting from 150+ GitHub issues with solutions**: read [references/common-issues.md](references/common-issues.md)
@@ -52,6 +52,10 @@ const styles = StyleSheet.create(theme => ({
52
52
  <View style={styles.box(200, true)} />
53
53
  ```
54
54
 
55
+ Arguments must be serializable (strings, numbers, booleans, `null`, `undefined`, plain arrays/objects): they're stored in C++ and the function is re-run natively on theme/runtime changes. Functions are dropped (shifting the remaining arguments); `Date`, `Map`, `Set` and class instances become plain objects.
56
+
57
+ `boxShadow` and `filter: [{ dropShadow }]` also accept CSS-like strings (e.g. `boxShadow: '0 2px 4px rgba(0, 0, 0, 0.2)'`), parsed on iOS/Android.
58
+
55
59
  ### StyleSheet.configure(config)
56
60
 
57
61
  One-time initialization. Must be called before any `StyleSheet.create()`.
@@ -61,21 +65,23 @@ StyleSheet.configure({
61
65
  themes?: { [name: string]: ThemeObject },
62
66
  breakpoints?: { [name: string]: number }, // first must be 0
63
67
  settings?: {
64
- initialTheme?: string | (() => string),
68
+ initialTheme?: string | (() => string), // mutually exclusive with adaptiveThemes: true
65
69
  adaptiveThemes?: boolean,
66
- CSSVars?: boolean,
67
- nativeBreakpointsMode?: 'pixels' | 'points',
70
+ CSSVars?: boolean, // web only, default true
71
+ nativeBreakpointsMode?: 'pixels' | 'points', // default 'pixels'
68
72
  }
69
73
  })
70
74
  ```
71
75
 
76
+ Unknown keys throw. `nativeBreakpointsMode: 'pixels'` compares breakpoints/`mq` against `UnistylesRuntime.screen` (points on iOS, dp on Android); `'points'` divides that by `pixelRatio` first.
77
+
72
78
  ### StyleSheet utilities
73
79
 
74
80
  | Property/Method | Description |
75
81
  |----------------|-------------|
76
- | `StyleSheet.hairlineWidth` | Thinnest visible line width (always `1` in v3) |
77
- | `StyleSheet.absoluteFill` | Shorthand for `{ position: 'absolute', left: 0, right: 0, top: 0, bottom: 0 }` |
78
- | `StyleSheet.absoluteFillObject` | Same object as `absoluteFill` |
82
+ | `StyleSheet.hairlineWidth` | Thinnest line the device can draw (computed from `pixelRatio` on native; always `1` on web) |
83
+ | `StyleSheet.absoluteFill` | Static `{ position: 'absolute', left: 0, right: 0, top: 0, bottom: 0 }` |
84
+ | `StyleSheet.absoluteFillObject` | Same static object as `absoluteFill` |
79
85
  | `StyleSheet.compose(a, b)` | Compose two styles |
80
86
  | `StyleSheet.flatten(style)` | Flatten a style array into a single object |
81
87
 
@@ -84,8 +90,12 @@ StyleSheet.configure({
84
90
  Subscribe to Unistyles dependency changes:
85
91
 
86
92
  ```tsx
93
+ import { StyleSheet, UnistyleDependency } from 'react-native-unistyles'
94
+
87
95
  const unsubscribe = StyleSheet.addChangeListener((dependencies: UnistyleDependency[]) => {
88
- // dependencies is an array of what changed (Theme, Breakpoints, Orientation, etc.)
96
+ if (dependencies.includes(UnistyleDependency.Theme)) {
97
+ // theme changed (or was updated with updateTheme)
98
+ }
89
99
  })
90
100
 
91
101
  // Later:
@@ -106,19 +116,19 @@ import { UnistylesRuntime } from 'react-native-unistyles'
106
116
 
107
117
  | Property | Type | Description |
108
118
  |----------|------|-------------|
109
- | `colorScheme` | `'light' \| 'dark' \| 'unspecified'` | OS color scheme |
110
- | `themeName` | `string \| undefined` | Current active theme name |
119
+ | `colorScheme` | `ColorScheme` (`'light' \| 'dark' \| 'unspecified'`) | OS color scheme |
120
+ | `themeName` | `string \| undefined` | Current theme name (inside a `ScopedTheme` during render: the scoped name) |
111
121
  | `breakpoint` | `string \| undefined` | Current active breakpoint name |
112
122
  | `hasAdaptiveThemes` | `boolean` | Whether adaptive themes are enabled |
113
- | `screen` | `{ width: number, height: number }` | Screen dimensions |
114
- | `insets` | `{ top, bottom, left, right, ime: number }` | Safe area insets + keyboard (ime) |
115
- | `orientation` | `'portrait' \| 'landscape'` | Current orientation |
123
+ | `screen` | `{ width: number, height: number }` | Screen dimensions (points on iOS, dp on Android; `window.innerWidth/innerHeight` on web) |
124
+ | `insets` | `{ top, bottom, left, right, ime: number }` | Safe area insets + keyboard (ime); all `0` on web |
125
+ | `orientation` | `Orientation` (`'portrait' \| 'landscape'`) | Current orientation |
116
126
  | `isPortrait` | `boolean` | Shorthand for portrait check |
117
127
  | `isLandscape` | `boolean` | Shorthand for landscape check |
118
128
  | `pixelRatio` | `number` | Device pixel ratio |
119
129
  | `fontScale` | `number` | User font scale preference |
120
- | `rtl` | `boolean` | Whether layout direction is RTL |
121
- | `contentSizeCategory` | `IOSContentSizeCategory \| AndroidContentSizeCategory` | Accessibility text size |
130
+ | `rtl` | `boolean` | Whether layout direction is RTL. Updates at runtime on Android (`I18nManager.forceRTL` / locale change) and web (`dir` on `<html>`); on iOS read at startup (restart required) |
131
+ | `contentSizeCategory` | `IOSContentSizeCategory \| AndroidContentSizeCategory \| WebContentSizeCategory` | Accessibility text size (`'web-unspecified'` on web) |
122
132
  | `breakpoints` | `UnistylesBreakpoints` | Registered breakpoints object |
123
133
 
124
134
  ### Sub-objects
@@ -126,18 +136,18 @@ import { UnistylesRuntime } from 'react-native-unistyles'
126
136
  | Property | Type | Description |
127
137
  |----------|------|-------------|
128
138
  | `statusBar` | `UnistylesStatusBar` | Status bar dimensions and controls |
129
- | `navigationBar` | `UnistylesNavigationBar` | Navigation bar dimensions and controls (Android) |
139
+ | `navigationBar` | `UnistylesNavigationBar` | Navigation bar dimensions and controls (Android only; `0` on iOS/web) |
130
140
 
131
141
  ### Methods
132
142
 
133
143
  ```tsx
134
- // Switch theme
144
+ // Switch theme (throws while adaptive themes are enabled)
135
145
  UnistylesRuntime.setTheme('dark')
136
146
 
137
- // Get theme object by name
147
+ // Get theme object by name (current theme if omitted)
138
148
  const darkTheme = UnistylesRuntime.getTheme('dark')
139
149
 
140
- // Update theme values at runtime (triggers re-style of affected components)
150
+ // Update theme values at runtime (re-styles affected views if it's the current theme)
141
151
  UnistylesRuntime.updateTheme('light', currentTheme => ({
142
152
  ...currentTheme,
143
153
  colors: { ...currentTheme.colors, primary: '#ff0000' }
@@ -146,10 +156,10 @@ UnistylesRuntime.updateTheme('light', currentTheme => ({
146
156
  // Enable/disable adaptive themes
147
157
  UnistylesRuntime.setAdaptiveThemes(true)
148
158
 
149
- // Set root view background color
159
+ // Set root view background color (any RN color; omit to reset to transparent; sets <html> background on web)
150
160
  UnistylesRuntime.setRootViewBackgroundColor('#ffffff')
151
161
 
152
- // Enable immersive mode (hide status bar + navigation bar)
162
+ // Immersive mode: Android hides status + navigation bars; iOS hides only the status bar (fade); no-op on web
153
163
  UnistylesRuntime.setImmersiveMode(true)
154
164
  ```
155
165
 
@@ -157,34 +167,43 @@ UnistylesRuntime.setImmersiveMode(true)
157
167
 
158
168
  ## StatusBar
159
169
 
170
+ Accessed via `UnistylesRuntime.statusBar`.
171
+
160
172
  ```tsx
161
- import { StatusBar } from 'react-native-unistyles'
173
+ UnistylesRuntime.statusBar
162
174
  ```
163
175
 
164
176
  | Property/Method | Type | Description |
165
177
  |----------------|------|-------------|
166
178
  | `width` | `number` | Status bar width |
167
179
  | `height` | `number` | Status bar height |
168
- | `setHidden(hidden, animation?)` | `(boolean, 'none' \| 'fade' \| 'slide') => void` | Show/hide status bar |
169
- | `setStyle(style, animated?)` | `('default' \| 'light' \| 'dark', boolean?) => void` | Set status bar style |
180
+ | `setHidden(hidden, animation?)` | `(boolean, 'none' \| 'fade' \| 'slide') => void` | Show/hide status bar (`animation` used on iOS) |
181
+ | `setStyle(style, animated?)` | `(StatusBarStyle, boolean?) => void` | Set content style: `StatusBarStyle.Default` / `.Light` / `.Dark` |
182
+
183
+ ```tsx
184
+ import { UnistylesRuntime, StatusBarStyle } from 'react-native-unistyles'
170
185
 
171
- Also accessible via `UnistylesRuntime.statusBar`.
186
+ UnistylesRuntime.statusBar.setStyle(StatusBarStyle.Light, true)
187
+ UnistylesRuntime.statusBar.setHidden(true, 'slide')
188
+ ```
189
+
190
+ On web, status/navigation bar dimensions are `0` and these setters do nothing.
172
191
 
173
192
  ---
174
193
 
175
194
  ## NavigationBar
176
195
 
196
+ Accessed via `UnistylesRuntime.navigationBar`.
197
+
177
198
  ```tsx
178
- import { NavigationBar } from 'react-native-unistyles'
199
+ UnistylesRuntime.navigationBar
179
200
  ```
180
201
 
181
202
  | Property/Method | Type | Description |
182
203
  |----------------|------|-------------|
183
- | `width` | `number` | Navigation bar width |
184
- | `height` | `number` | Navigation bar height |
185
- | `setHidden(hidden)` | `(boolean) => void` | Show/hide navigation bar (Android) |
186
-
187
- Also accessible via `UnistylesRuntime.navigationBar`.
204
+ | `width` | `number` | Navigation bar width (Android only, `0` on iOS) |
205
+ | `height` | `number` | Navigation bar height (Android only, `0` on iOS) |
206
+ | `setHidden(hidden)` | `(boolean) => void` | Show/hide navigation bar (Android only) |
188
207
 
189
208
  ---
190
209
 
@@ -213,17 +232,19 @@ mq.height(min?, max?).and.width(min?, max?) // returns symbol
213
232
  ```
214
233
 
215
234
  Parameters can be:
216
- - **Breakpoint names**: `'sm'`, `'md'`, `'lg'` (from registered breakpoints)
217
- - **Pixel values**: `320`, `768`, `1200`
218
- - **`null`/`undefined`**: unbounded (no min or no max)
235
+ - **Breakpoint names**: `'sm'`, `'md'`, `'lg'` (resolved to their values when `mq` is called — `StyleSheet.configure` must run first; unknown names resolve to `0`)
236
+ - **Numbers**: `320`, `768`, `1200` (same units as `UnistylesRuntime.screen`)
237
+ - **`null`/`undefined` min** → `0`; omitted max → unbounded
238
+
239
+ **Both bounds are inclusive.** Adjacent ranges like `(240, 380)` and `(380)` both match width `380`; on native the first matching query in the style object wins. Invalid ranges (`('xl', 'sm')`, `(500, 200)`) are ignored.
219
240
 
220
241
  ### Examples
221
242
 
222
243
  ```tsx
223
- mq.only.width('sm', 'md') // width between sm and md breakpoints
224
- mq.only.width(320, 768) // width between 320px and 768px
244
+ mq.only.width('sm', 'md') // sm <= width <= md
245
+ mq.only.width(320, 768) // 320 <= width <= 768
225
246
  mq.only.width('sm') // width >= sm (no max)
226
- mq.only.width(null, 600) // width <= 600px
247
+ mq.only.width(null, 600) // 0 <= width <= 600
227
248
  mq.width('sm', 'lg').and.height(400, 800) // combined width + height
228
249
  ```
229
250
 
@@ -250,19 +271,29 @@ const UniButton = withUnistyles(Button, (theme, rt) => ({
250
271
  }))
251
272
  ```
252
273
 
253
- ### With uniProps — dynamic mappings from component props
254
-
255
- The wrapped component receives additional `uniProps` that map to theme-derived values:
274
+ ### uniProps — per-instance mappings that can use component state
256
275
 
257
276
  ```tsx
258
- const UniIcon = withUnistyles(Icon, (theme) => ({
259
- // These become available as props on UniIcon
260
- }))
277
+ const UniSwitch = withUnistyles(Switch)
261
278
 
262
- // The style and contentContainerStyle props are auto-processed
263
- <UniIcon style={styles.icon} />
279
+ const MyComponent = ({ isDisabled }) => (
280
+ <UniSwitch
281
+ uniProps={(theme, rt) => ({
282
+ trackColor: { true: isDisabled ? theme.colors.disabled : theme.colors.primary }
283
+ })}
284
+ />
285
+ )
264
286
  ```
265
287
 
288
+ Priority: mappings < `uniProps` < inline props. Both mappings and `uniProps` may return a `key` (used as the React `key` to remount the component, `uniProps` wins). They can't return `style`/`contentContainerStyle` — pass those as regular props; they're auto-mapped:
289
+
290
+ ```tsx
291
+ const UniScrollView = withUnistyles(ScrollView)
292
+ <UniScrollView style={styles.scroll} contentContainerStyle={styles.content} />
293
+ ```
294
+
295
+ Re-renders: only when the dependencies it reads change — but on iOS/Android a wrapped component is always subscribed to theme changes. Reading `rt.insets.ime` re-renders on every keyboard animation frame. On web the component is wrapped in a `display: contents` `<div>`.
296
+
266
297
  ### Ref forwarding
267
298
 
268
299
  `withUnistyles` forwards refs automatically:
@@ -280,7 +311,7 @@ const ref = useRef<TextInput>(null)
280
311
 
281
312
  ## useUnistyles
282
313
 
283
- Hook that returns the current theme and mini runtime. **Causes re-renders** when theme or runtime values change.
314
+ Hook that returns the current theme and mini runtime. **Causes re-renders** of the whole component. Subscriptions are created on **property access**, not destructuring: reading any `theme.*` subscribes to theme changes, reading `rt.screen.width` subscribes to dimensions, `rt.insets.top` to insets, `rt.insets.ime` only to the keyboard (re-renders every animation frame — prefer `StyleSheet`). Respects the parent `ScopedTheme`.
284
315
 
285
316
  ```tsx
286
317
  import { useUnistyles } from 'react-native-unistyles'
@@ -310,12 +341,14 @@ import { Display, Hide, mq } from 'react-native-unistyles'
310
341
  <SidePanel />
311
342
  </Display>
312
343
 
313
- // Hide children when width < 768
314
- <Hide mq={mq.only.width(null, 768)}>
344
+ // Hide children when width <= 767 (bounds are inclusive)
345
+ <Hide mq={mq.only.width(null, 767)}>
315
346
  <MobileNav />
316
347
  </Hide>
317
348
  ```
318
349
 
350
+ These are plain conditional renders (no wrapper view); only `Display`/`Hide` re-renders when the query result changes.
351
+
319
352
  ---
320
353
 
321
354
  ## ScopedTheme
@@ -331,7 +364,7 @@ Props are **mutually exclusive** — use only one:
331
364
  | Prop | Type | Description |
332
365
  |------|------|-------------|
333
366
  | `name` | `keyof UnistylesThemes` | Force a specific theme |
334
- | `invertedAdaptive` | `boolean` | Use the opposite adaptive theme |
367
+ | `invertedAdaptive` | `boolean` | Use the opposite adaptive theme (no-op if adaptive themes are disabled) |
335
368
  | `reset` | `boolean` | Reset to the global theme (undo parent ScopedTheme) |
336
369
 
337
370
  ```tsx
@@ -351,6 +384,8 @@ Props are **mutually exclusive** — use only one:
351
384
  </ScopedTheme>
352
385
  ```
353
386
 
387
+ The scoped theme is only known during render (no React Context): `UnistylesRuntime.themeName`, `useUnistyles`, `withUnistyles` and `useAnimatedTheme` respect it inside the subtree. With `Suspense`, put `ScopedTheme` inside the suspending component.
388
+
354
389
  ---
355
390
 
356
391
  ## Types
@@ -373,6 +408,7 @@ const styles = StyleSheet.create(theme => ({
373
408
 
374
409
  type ButtonVariants = UnistylesVariants<typeof styles>
375
410
  // { size?: 'small' | 'large'; color?: 'primary' | 'secondary' }
411
+ // Options of the same group are merged across styles; boolean groups infer `boolean`
376
412
 
377
413
  type Props = { title: string } & ButtonVariants
378
414
 
@@ -386,16 +422,34 @@ const Button = ({ title, ...variants }: Props) => {
386
422
 
387
423
  The type of individual style entries in a Unistyles stylesheet.
388
424
 
389
- ### IOSContentSizeCategory / AndroidContentSizeCategory
425
+ ### UnistylesMiniRuntime
426
+
427
+ Type of the `rt` argument (in `StyleSheet.create`, `useUnistyles`, `withUnistyles`): `themeName`, `breakpoint`, `hasAdaptiveThemes`, `colorScheme`, `screen`, `contentSizeCategory`, `insets`, `pixelRatio`, `fontScale`, `rtl`, `statusBar`, `navigationBar`, `isPortrait`, `isLandscape`.
428
+
429
+ ```tsx
430
+ import type { UnistylesMiniRuntime } from 'react-native-unistyles'
431
+
432
+ const getHeaderHeight = (rt: UnistylesMiniRuntime) => rt.insets.top + 56
433
+ ```
434
+
435
+ ### Value enums: ColorScheme, Orientation, StatusBarStyle, content size categories
390
436
 
391
- Enums for accessibility text size categories:
437
+ These are **runtime values** (TS enums), not just types:
392
438
 
393
439
  ```tsx
394
- import type { IOSContentSizeCategory, AndroidContentSizeCategory } from 'react-native-unistyles'
440
+ import {
441
+ ColorScheme, // Light 'light', Dark 'dark', Unspecified 'unspecified'
442
+ Orientation, // Portrait 'portrait', Landscape 'landscape'
443
+ StatusBarStyle, // Default 'default', Light 'light', Dark 'dark'
444
+ IOSContentSizeCategory, // AccessibilityExtraExtraExtraLarge … AccessibilityMedium,
445
+ // ExtraExtraExtraLarge 'xxxLarge', ExtraExtraLarge 'xxLarge', ExtraLarge 'xLarge',
446
+ // Large, Medium, Small, ExtraSmall 'xSmall', Unspecified 'unspecified'
447
+ AndroidContentSizeCategory, // Small, Default, Large, ExtraLarge, Huge, ExtraHuge, ExtraExtraHuge
448
+ WebContentSizeCategory, // Unspecified 'web-unspecified'
449
+ UnistylesRuntime,
450
+ } from 'react-native-unistyles'
395
451
 
396
- // iOS values: 'accessibilityExtraExtraExtraLarge', 'xxxLarge', 'xxLarge', 'xLarge',
397
- // 'Large', 'Medium', 'Small', 'xSmall', 'unspecified'
398
- // Android values: 'Small', 'Default', 'Large', 'ExtraLarge', 'Huge', 'ExtraHuge', 'ExtraExtraHuge'
452
+ const isDark = UnistylesRuntime.colorScheme === ColorScheme.Dark
399
453
  ```
400
454
 
401
455
  ### UnistyleDependency
@@ -405,9 +459,11 @@ Enum for change listener dependencies:
405
459
  ```tsx
406
460
  import { UnistyleDependency } from 'react-native-unistyles'
407
461
 
408
- // Values: Theme, ThemeName, Breakpoints, ColorScheme, ContentSizeCategory,
409
- // Orientation, Insets, Ime, PixelRatio, FontScale, Rtl,
410
- // NavigationBar, StatusBar, Dimensions, AdaptiveThemes
462
+ // Values: Theme, ThemeName, AdaptiveThemes, Breakpoints, Variants, ColorScheme,
463
+ // Dimensions, Orientation, ContentSizeCategory, Insets, PixelRatio,
464
+ // FontScale, StatusBar, NavigationBar, Ime, Rtl
465
+ // Web emits only: Theme, ThemeName, AdaptiveThemes, Breakpoints, ColorScheme,
466
+ // Dimensions, Orientation, Rtl
411
467
  ```
412
468
 
413
469
  ---
@@ -415,16 +471,16 @@ import { UnistyleDependency } from 'react-native-unistyles'
415
471
  ## Web-Only Exports
416
472
 
417
473
  ```tsx
418
- import { getWebProps } from 'react-native-unistyles/web-only'
474
+ import { getWebProps } from 'react-native-unistyles/web'
419
475
  ```
420
476
 
421
- ### getWebProps(style)
477
+ ### getWebProps(style, forwardedRef?)
422
478
 
423
- For custom web components that don't support Unistyles' auto-processing:
479
+ For custom web (DOM) components. Returns `{ className, ref }` — spread both onto the element (the `ref` keeps the styles reactive; pass your forwarded ref as the 2nd argument to merge it). `className` includes any `_classNames`:
424
480
 
425
481
  ```tsx
426
- const { className, style: webStyle } = getWebProps(styles.container)
427
- return <div className={className} style={webStyle}>...</div>
482
+ const webProps = getWebProps([styles.container, customStyle], forwardedRef)
483
+ return <div {...webProps}>...</div>
428
484
  ```
429
485
 
430
486
  ---
@@ -437,7 +493,7 @@ import { useAnimatedTheme, useAnimatedVariantColor } from 'react-native-unistyle
437
493
 
438
494
  ### useAnimatedTheme()
439
495
 
440
- Returns a `SharedValue<Theme>` for use inside Reanimated worklets:
496
+ Returns a `SharedValue<Theme>` for use inside Reanimated worklets (no re-renders; follows the parent `ScopedTheme`):
441
497
 
442
498
  ```tsx
443
499
  const animatedTheme = useAnimatedTheme()
@@ -449,17 +505,20 @@ const animatedStyle = useAnimatedStyle(() => ({
449
505
 
450
506
  ### useAnimatedVariantColor(style, colorKey)
451
507
 
452
- Animate color transitions when variants change:
508
+ Returns a derived `SharedValue<string>` with the variant's current color (`colorKey` must contain `color`/`Color`; the style must have `variants`, otherwise it throws). Use it inside `useAnimatedStyle`:
453
509
 
454
510
  ```tsx
455
- const animatedColor = useAnimatedVariantColor(styles.button, 'backgroundColor')
511
+ const color = useAnimatedVariantColor(styles.button, 'backgroundColor')
512
+ const animatedStyle = useAnimatedStyle(() => ({
513
+ backgroundColor: withTiming(color.value, { duration: 500 }),
514
+ }))
456
515
  ```
457
516
 
458
517
  ---
459
518
 
460
519
  ## SSR Exports
461
520
 
462
- For server-side rendering with Next.js:
521
+ For server-side rendering with Next.js (also re-exported from the root, docs use the subpath):
463
522
 
464
523
  ```tsx
465
524
  import {
@@ -467,29 +526,27 @@ import {
467
526
  getServerUnistyles,
468
527
  hydrateServerUnistyles,
469
528
  resetServerUnistyles
470
- } from 'react-native-unistyles'
529
+ } from 'react-native-unistyles/server'
471
530
  ```
472
531
 
473
532
  | Function | Description |
474
533
  |----------|-------------|
475
- | `useServerUnistyles(settings?)` | React hook returning style elements for SSR (App Router) |
476
- | `getServerUnistyles(settings?)` | Returns React element with styles for SSR (Pages Router) |
477
- | `hydrateServerUnistyles()` | Call on client to hydrate server-rendered styles |
478
- | `resetServerUnistyles()` | Reset server styles between requests |
534
+ | `useServerUnistyles(settings?)` | App Router, in a `'use client'` component with `useServerInsertedHTML`. Returns the styles once per request on the server and resets the registry; on the client it hydrates automatically |
535
+ | `getServerUnistyles(settings?)` | Pages Router (`_document` `getInitialProps`). Returns `<style>`/`<script>` elements; throws on the client |
536
+ | `hydrateServerUnistyles()` | Pages Router: call on the client (in `useEffect`); throws on the server |
537
+ | `resetServerUnistyles()` | Pages Router: call after **every** request (clears CSS, cached stylesheets, listeners) |
479
538
 
480
- Settings: `{ includeRNWStyles?: boolean }`
539
+ Settings: `{ includeRNWStyles?: boolean }` (default `true`)
481
540
 
482
541
  ---
483
542
 
484
- ## Native Components
543
+ ## Native Components (Babel factories)
485
544
 
486
- Pre-styled components that work with Unistyles out of the box:
545
+ The Babel plugin rewrites `react-native` imports in processed files to ref-borrowing factories (no extra views, no styling of their own) so C++ can update the native views:
487
546
 
488
547
  ```tsx
548
+ // what the plugin generates — you don't write this yourself
489
549
  import { View } from 'react-native-unistyles/components/native/View'
490
- import { Text } from 'react-native-unistyles/components/native/Text'
491
- import { Pressable } from 'react-native-unistyles/components/native/Pressable'
492
- // etc.
493
550
  ```
494
551
 
495
- These are automatically created by the Babel plugin — you typically don't import them directly. They exist for edge cases where the plugin can't detect a component.
552
+ They are built with `createUnistylesElement(Component)` (exported from the root). On native, only the `style` prop is bound — use `withUnistyles` for `contentContainerStyle`.