@codyswann/lisa 2.110.1 → 2.112.0

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 (193) hide show
  1. package/package.json +1 -1
  2. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  3. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  4. package/plugins/lisa/commands/repair-intake.md +2 -2
  5. package/plugins/lisa/rules/config-resolution.md +2 -2
  6. package/plugins/lisa/skills/repair-intake/SKILL.md +86 -9
  7. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  8. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  9. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  10. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  11. package/plugins/lisa-expo/.mcp.json +3 -3
  12. package/plugins/lisa-expo/THIRD-PARTY-NOTICES.md +57 -0
  13. package/plugins/lisa-expo/commands/e2e-coverage-gaps.md +7 -0
  14. package/plugins/lisa-expo/commands/exploratory-qa.md +2 -2
  15. package/plugins/lisa-expo/skills/add-app-clip/SKILL.md +280 -0
  16. package/plugins/lisa-expo/skills/add-app-clip/agents/openai.yaml +4 -0
  17. package/plugins/lisa-expo/skills/add-app-clip/references/native-module.md +96 -0
  18. package/plugins/lisa-expo/skills/building-native-ui/SKILL.md +321 -0
  19. package/plugins/lisa-expo/skills/building-native-ui/agents/openai.yaml +4 -0
  20. package/plugins/lisa-expo/skills/building-native-ui/references/animations.md +220 -0
  21. package/plugins/lisa-expo/skills/building-native-ui/references/controls.md +272 -0
  22. package/plugins/lisa-expo/skills/building-native-ui/references/form-sheet.md +253 -0
  23. package/plugins/lisa-expo/skills/building-native-ui/references/gradients.md +106 -0
  24. package/plugins/lisa-expo/skills/building-native-ui/references/icons.md +213 -0
  25. package/plugins/lisa-expo/skills/building-native-ui/references/media.md +198 -0
  26. package/plugins/lisa-expo/skills/building-native-ui/references/route-structure.md +229 -0
  27. package/plugins/lisa-expo/skills/building-native-ui/references/search.md +248 -0
  28. package/plugins/lisa-expo/skills/building-native-ui/references/storage.md +121 -0
  29. package/plugins/lisa-expo/skills/building-native-ui/references/tabs.md +433 -0
  30. package/plugins/lisa-expo/skills/building-native-ui/references/toolbar-and-headers.md +284 -0
  31. package/plugins/lisa-expo/skills/building-native-ui/references/visual-effects.md +197 -0
  32. package/plugins/lisa-expo/skills/building-native-ui/references/webgpu-three.md +605 -0
  33. package/plugins/lisa-expo/skills/building-native-ui/references/zoom-transitions.md +158 -0
  34. package/plugins/lisa-expo/skills/e2e-coverage-gaps/SKILL.md +105 -0
  35. package/plugins/lisa-expo/skills/e2e-coverage-gaps/agents/openai.yaml +4 -0
  36. package/plugins/lisa-expo/skills/eas-update-insights/SKILL.md +228 -0
  37. package/plugins/lisa-expo/skills/eas-update-insights/agents/openai.yaml +4 -0
  38. package/plugins/lisa-expo/skills/eas-update-insights/references/channel-insights-schema.md +47 -0
  39. package/plugins/lisa-expo/skills/eas-update-insights/references/update-insights-schema.md +69 -0
  40. package/plugins/lisa-expo/skills/exploratory-qa/SKILL.md +100 -93
  41. package/plugins/lisa-expo/skills/exploratory-qa/agents/openai.yaml +2 -2
  42. package/plugins/lisa-expo/skills/expo-api-routes/SKILL.md +369 -0
  43. package/plugins/lisa-expo/skills/expo-api-routes/agents/openai.yaml +4 -0
  44. package/plugins/lisa-expo/skills/expo-brownfield/SKILL.md +54 -0
  45. package/plugins/lisa-expo/skills/expo-brownfield/agents/openai.yaml +4 -0
  46. package/plugins/lisa-expo/skills/expo-brownfield/references/brownfield-integrated.md +526 -0
  47. package/plugins/lisa-expo/skills/expo-brownfield/references/brownfield-isolated.md +402 -0
  48. package/plugins/lisa-expo/skills/expo-brownfield/references/comparison.md +63 -0
  49. package/plugins/lisa-expo/skills/expo-brownfield/references/troubleshooting.md +88 -0
  50. package/plugins/lisa-expo/skills/expo-cicd-workflows/SKILL.md +92 -0
  51. package/plugins/lisa-expo/skills/expo-cicd-workflows/agents/openai.yaml +4 -0
  52. package/plugins/lisa-expo/skills/expo-cicd-workflows/scripts/fetch.js +113 -0
  53. package/plugins/lisa-expo/skills/expo-cicd-workflows/scripts/package.json +11 -0
  54. package/plugins/lisa-expo/skills/expo-cicd-workflows/scripts/validate.js +85 -0
  55. package/plugins/lisa-expo/skills/expo-deployment/SKILL.md +190 -0
  56. package/plugins/lisa-expo/skills/expo-deployment/agents/openai.yaml +4 -0
  57. package/plugins/lisa-expo/skills/expo-deployment/references/app-store-metadata.md +479 -0
  58. package/plugins/lisa-expo/skills/expo-deployment/references/ios-app-store.md +355 -0
  59. package/plugins/lisa-expo/skills/expo-deployment/references/play-store.md +246 -0
  60. package/plugins/lisa-expo/skills/expo-deployment/references/testflight.md +58 -0
  61. package/plugins/lisa-expo/skills/expo-deployment/references/workflows.md +200 -0
  62. package/plugins/lisa-expo/skills/expo-dev-client/SKILL.md +164 -0
  63. package/plugins/lisa-expo/skills/expo-dev-client/agents/openai.yaml +4 -0
  64. package/plugins/lisa-expo/skills/expo-module/SKILL.md +141 -0
  65. package/plugins/lisa-expo/skills/expo-module/agents/openai.yaml +4 -0
  66. package/plugins/lisa-expo/skills/expo-module/references/config-plugin.md +90 -0
  67. package/plugins/lisa-expo/skills/expo-module/references/create-expo-module.md +206 -0
  68. package/plugins/lisa-expo/skills/expo-module/references/lifecycle.md +127 -0
  69. package/plugins/lisa-expo/skills/expo-module/references/module-config.md +48 -0
  70. package/plugins/lisa-expo/skills/expo-module/references/native-module.md +286 -0
  71. package/plugins/lisa-expo/skills/expo-module/references/native-view.md +171 -0
  72. package/plugins/lisa-expo/skills/expo-tailwind-setup/SKILL.md +480 -0
  73. package/plugins/lisa-expo/skills/expo-tailwind-setup/agents/openai.yaml +4 -0
  74. package/plugins/lisa-expo/skills/expo-ui-jetpack-compose/SKILL.md +40 -0
  75. package/plugins/lisa-expo/skills/expo-ui-jetpack-compose/agents/openai.yaml +4 -0
  76. package/plugins/lisa-expo/skills/expo-ui-swift-ui/SKILL.md +39 -0
  77. package/plugins/lisa-expo/skills/expo-ui-swift-ui/agents/openai.yaml +4 -0
  78. package/plugins/lisa-expo/skills/native-data-fetching/SKILL.md +507 -0
  79. package/plugins/lisa-expo/skills/native-data-fetching/agents/openai.yaml +4 -0
  80. package/plugins/lisa-expo/skills/native-data-fetching/references/expo-router-loaders.md +344 -0
  81. package/plugins/lisa-expo/skills/upgrading-expo/SKILL.md +134 -0
  82. package/plugins/lisa-expo/skills/upgrading-expo/agents/openai.yaml +4 -0
  83. package/plugins/lisa-expo/skills/upgrading-expo/references/expo-av-to-audio.md +132 -0
  84. package/plugins/lisa-expo/skills/upgrading-expo/references/expo-av-to-video.md +160 -0
  85. package/plugins/lisa-expo/skills/upgrading-expo/references/native-tabs.md +124 -0
  86. package/plugins/lisa-expo/skills/upgrading-expo/references/new-architecture.md +79 -0
  87. package/plugins/lisa-expo/skills/upgrading-expo/references/react-19.md +79 -0
  88. package/plugins/lisa-expo/skills/upgrading-expo/references/react-compiler.md +59 -0
  89. package/plugins/lisa-expo/skills/upgrading-expo/references/react-navigation-to-expo-router.md +61 -0
  90. package/plugins/lisa-expo/skills/use-dom/SKILL.md +417 -0
  91. package/plugins/lisa-expo/skills/use-dom/agents/openai.yaml +4 -0
  92. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  93. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  94. package/plugins/lisa-harper-fabric/commands/e2e-coverage-gaps.md +7 -0
  95. package/plugins/lisa-harper-fabric/commands/exploratory-qa.md +2 -2
  96. package/plugins/lisa-harper-fabric/skills/e2e-coverage-gaps/SKILL.md +105 -0
  97. package/plugins/lisa-harper-fabric/skills/e2e-coverage-gaps/agents/openai.yaml +4 -0
  98. package/plugins/lisa-harper-fabric/skills/exploratory-qa/SKILL.md +100 -93
  99. package/plugins/lisa-harper-fabric/skills/exploratory-qa/agents/openai.yaml +2 -2
  100. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  101. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  102. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  103. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  104. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  105. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  106. package/plugins/lisa-rails/commands/e2e-coverage-gaps.md +7 -0
  107. package/plugins/lisa-rails/commands/exploratory-qa.md +2 -2
  108. package/plugins/lisa-rails/skills/e2e-coverage-gaps/SKILL.md +105 -0
  109. package/plugins/lisa-rails/skills/e2e-coverage-gaps/agents/openai.yaml +4 -0
  110. package/plugins/lisa-rails/skills/exploratory-qa/SKILL.md +100 -93
  111. package/plugins/lisa-rails/skills/exploratory-qa/agents/openai.yaml +2 -2
  112. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  113. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  114. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  115. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  116. package/plugins/lisa-wiki/templates/llm-wiki-contract.md +12 -0
  117. package/plugins/src/base/commands/repair-intake.md +2 -2
  118. package/plugins/src/base/rules/config-resolution.md +2 -2
  119. package/plugins/src/base/skills/repair-intake/SKILL.md +86 -9
  120. package/plugins/src/expo/.mcp.json +3 -3
  121. package/plugins/src/expo/THIRD-PARTY-NOTICES.md +57 -0
  122. package/plugins/src/expo/commands/e2e-coverage-gaps.md +7 -0
  123. package/plugins/src/expo/commands/exploratory-qa.md +2 -2
  124. package/plugins/src/expo/skills/add-app-clip/SKILL.md +280 -0
  125. package/plugins/src/expo/skills/add-app-clip/references/native-module.md +96 -0
  126. package/plugins/src/expo/skills/building-native-ui/SKILL.md +321 -0
  127. package/plugins/src/expo/skills/building-native-ui/references/animations.md +220 -0
  128. package/plugins/src/expo/skills/building-native-ui/references/controls.md +272 -0
  129. package/plugins/src/expo/skills/building-native-ui/references/form-sheet.md +253 -0
  130. package/plugins/src/expo/skills/building-native-ui/references/gradients.md +106 -0
  131. package/plugins/src/expo/skills/building-native-ui/references/icons.md +213 -0
  132. package/plugins/src/expo/skills/building-native-ui/references/media.md +198 -0
  133. package/plugins/src/expo/skills/building-native-ui/references/route-structure.md +229 -0
  134. package/plugins/src/expo/skills/building-native-ui/references/search.md +248 -0
  135. package/plugins/src/expo/skills/building-native-ui/references/storage.md +121 -0
  136. package/plugins/src/expo/skills/building-native-ui/references/tabs.md +433 -0
  137. package/plugins/src/expo/skills/building-native-ui/references/toolbar-and-headers.md +284 -0
  138. package/plugins/src/expo/skills/building-native-ui/references/visual-effects.md +197 -0
  139. package/plugins/src/expo/skills/building-native-ui/references/webgpu-three.md +605 -0
  140. package/plugins/src/expo/skills/building-native-ui/references/zoom-transitions.md +158 -0
  141. package/plugins/src/expo/skills/e2e-coverage-gaps/SKILL.md +105 -0
  142. package/plugins/src/expo/skills/eas-update-insights/SKILL.md +228 -0
  143. package/plugins/src/expo/skills/eas-update-insights/references/channel-insights-schema.md +47 -0
  144. package/plugins/src/expo/skills/eas-update-insights/references/update-insights-schema.md +69 -0
  145. package/plugins/src/expo/skills/exploratory-qa/SKILL.md +100 -93
  146. package/plugins/src/expo/skills/expo-api-routes/SKILL.md +369 -0
  147. package/plugins/src/expo/skills/expo-brownfield/SKILL.md +54 -0
  148. package/plugins/src/expo/skills/expo-brownfield/references/brownfield-integrated.md +526 -0
  149. package/plugins/src/expo/skills/expo-brownfield/references/brownfield-isolated.md +402 -0
  150. package/plugins/src/expo/skills/expo-brownfield/references/comparison.md +63 -0
  151. package/plugins/src/expo/skills/expo-brownfield/references/troubleshooting.md +88 -0
  152. package/plugins/src/expo/skills/expo-cicd-workflows/SKILL.md +92 -0
  153. package/plugins/src/expo/skills/expo-cicd-workflows/scripts/fetch.js +113 -0
  154. package/plugins/src/expo/skills/expo-cicd-workflows/scripts/package.json +11 -0
  155. package/plugins/src/expo/skills/expo-cicd-workflows/scripts/validate.js +85 -0
  156. package/plugins/src/expo/skills/expo-deployment/SKILL.md +190 -0
  157. package/plugins/src/expo/skills/expo-deployment/references/app-store-metadata.md +479 -0
  158. package/plugins/src/expo/skills/expo-deployment/references/ios-app-store.md +355 -0
  159. package/plugins/src/expo/skills/expo-deployment/references/play-store.md +246 -0
  160. package/plugins/src/expo/skills/expo-deployment/references/testflight.md +58 -0
  161. package/plugins/src/expo/skills/expo-deployment/references/workflows.md +200 -0
  162. package/plugins/src/expo/skills/expo-dev-client/SKILL.md +164 -0
  163. package/plugins/src/expo/skills/expo-module/SKILL.md +141 -0
  164. package/plugins/src/expo/skills/expo-module/references/config-plugin.md +90 -0
  165. package/plugins/src/expo/skills/expo-module/references/create-expo-module.md +206 -0
  166. package/plugins/src/expo/skills/expo-module/references/lifecycle.md +127 -0
  167. package/plugins/src/expo/skills/expo-module/references/module-config.md +48 -0
  168. package/plugins/src/expo/skills/expo-module/references/native-module.md +286 -0
  169. package/plugins/src/expo/skills/expo-module/references/native-view.md +171 -0
  170. package/plugins/src/expo/skills/expo-tailwind-setup/SKILL.md +480 -0
  171. package/plugins/src/expo/skills/expo-ui-jetpack-compose/SKILL.md +40 -0
  172. package/plugins/src/expo/skills/expo-ui-swift-ui/SKILL.md +39 -0
  173. package/plugins/src/expo/skills/native-data-fetching/SKILL.md +507 -0
  174. package/plugins/src/expo/skills/native-data-fetching/references/expo-router-loaders.md +344 -0
  175. package/plugins/src/expo/skills/upgrading-expo/SKILL.md +134 -0
  176. package/plugins/src/expo/skills/upgrading-expo/references/expo-av-to-audio.md +132 -0
  177. package/plugins/src/expo/skills/upgrading-expo/references/expo-av-to-video.md +160 -0
  178. package/plugins/src/expo/skills/upgrading-expo/references/native-tabs.md +124 -0
  179. package/plugins/src/expo/skills/upgrading-expo/references/new-architecture.md +79 -0
  180. package/plugins/src/expo/skills/upgrading-expo/references/react-19.md +79 -0
  181. package/plugins/src/expo/skills/upgrading-expo/references/react-compiler.md +59 -0
  182. package/plugins/src/expo/skills/upgrading-expo/references/react-navigation-to-expo-router.md +61 -0
  183. package/plugins/src/expo/skills/use-dom/SKILL.md +417 -0
  184. package/plugins/src/harper-fabric/commands/e2e-coverage-gaps.md +7 -0
  185. package/plugins/src/harper-fabric/commands/exploratory-qa.md +2 -2
  186. package/plugins/src/harper-fabric/skills/e2e-coverage-gaps/SKILL.md +105 -0
  187. package/plugins/src/harper-fabric/skills/exploratory-qa/SKILL.md +100 -93
  188. package/plugins/src/rails/commands/e2e-coverage-gaps.md +7 -0
  189. package/plugins/src/rails/commands/exploratory-qa.md +2 -2
  190. package/plugins/src/rails/skills/e2e-coverage-gaps/SKILL.md +105 -0
  191. package/plugins/src/rails/skills/exploratory-qa/SKILL.md +100 -93
  192. package/plugins/src/wiki/templates/llm-wiki-contract.md +12 -0
  193. package/scripts/generate-codex-plugin-artifacts.mjs +7 -2
@@ -0,0 +1,171 @@
1
+ # Native View Reference
2
+
3
+ Native views let you render platform UI components (UIView on iOS, Android View on Android) as React components.
4
+
5
+ ## Defining a View
6
+
7
+ **Swift:**
8
+
9
+ ```swift
10
+ public class MyViewModule: Module {
11
+ public func definition() -> ModuleDefinition {
12
+ Name("MyView")
13
+
14
+ View(MyNativeView.self) {
15
+ Prop("title") { (view: MyNativeView, title: String) in
16
+ view.titleLabel.text = title
17
+ }
18
+
19
+ Events("onPress", "onLoad")
20
+
21
+ AsyncFunction("reset") { (view: MyNativeView) in
22
+ view.reset()
23
+ }
24
+ }
25
+ }
26
+ }
27
+
28
+ class MyNativeView: ExpoView {
29
+ let titleLabel = UILabel()
30
+
31
+ required init(appContext: AppContext) {
32
+ super.init(appContext: appContext)
33
+ clipsToBounds = true
34
+ addSubview(titleLabel)
35
+ }
36
+
37
+ override func layoutSubviews() {
38
+ super.layoutSubviews()
39
+ titleLabel.frame = bounds
40
+ }
41
+ }
42
+ ```
43
+
44
+ **Kotlin:**
45
+
46
+ ```kotlin
47
+ class MyViewModule : Module() {
48
+ override fun definition() = ModuleDefinition {
49
+ Name("MyView")
50
+
51
+ View(MyNativeView::class) {
52
+ Prop("title") { view: MyNativeView, title: String ->
53
+ view.titleView.text = title
54
+ }
55
+
56
+ Events("onPress", "onLoad")
57
+
58
+ AsyncFunction("reset") { view: MyNativeView ->
59
+ view.reset()
60
+ }
61
+ }
62
+ }
63
+ }
64
+
65
+ class MyNativeView(context: Context, appContext: AppContext) : ExpoView(context, appContext) {
66
+ val titleView = TextView(context).also {
67
+ addView(it, LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT))
68
+ }
69
+ }
70
+ ```
71
+
72
+ **TypeScript:**
73
+
74
+ ```typescript
75
+ import { requireNativeView } from "expo";
76
+
77
+ export type MyViewProps = {
78
+ title?: string;
79
+ onPress?: (event: { nativeEvent: { x: number; y: number } }) => void;
80
+ onLoad?: () => void;
81
+ } & ViewProps;
82
+
83
+ const NativeView = requireNativeView<MyViewProps>("MyView");
84
+
85
+ export function MyView(props: MyViewProps) {
86
+ return <NativeView {...props} />;
87
+ }
88
+ ```
89
+
90
+ ## View Event Dispatching
91
+
92
+ **Swift:**
93
+
94
+ ```swift
95
+ class MyNativeView: ExpoView {
96
+ let onPress = EventDispatcher()
97
+
98
+ func handleTap(at point: CGPoint) {
99
+ onPress(["x": point.x, "y": point.y])
100
+ }
101
+ }
102
+ ```
103
+
104
+ **Kotlin:**
105
+
106
+ ```kotlin
107
+ class MyNativeView(context: Context, appContext: AppContext) : ExpoView(context, appContext) {
108
+ private val onPress by EventDispatcher()
109
+
110
+ fun handleTap(x: Float, y: Float) {
111
+ onPress(mapOf("x" to x, "y" to y))
112
+ }
113
+ }
114
+ ```
115
+
116
+ ## View Lifecycle
117
+
118
+ ```swift
119
+ // Called after all props have been set
120
+ OnViewDidUpdateProps { (view: MyNativeView) in
121
+ view.applyChanges()
122
+ }
123
+ ```
124
+
125
+ ```kotlin
126
+ // Android only - called when view is no longer used
127
+ OnViewDestroys { view: MyNativeView ->
128
+ view.cleanup()
129
+ }
130
+ ```
131
+
132
+ ## AsyncFunction on Views
133
+
134
+ Functions defined inside `View` are accessible via React ref:
135
+
136
+ ```typescript
137
+ const ref = useRef<MyView>(null);
138
+ // Call native function
139
+ await ref.current?.reset();
140
+ ```
141
+
142
+ ## PropGroup (Android)
143
+
144
+ Batch-register multiple props with shared setter logic:
145
+
146
+ ```kotlin
147
+ View(MyNativeView::class) {
148
+ PropGroup("border", "width" to Float::class, "color" to Int::class) { view, index, value ->
149
+ when (index) {
150
+ 0 -> view.borderWidth = value as Float
151
+ 1 -> view.borderColor = value as Int
152
+ }
153
+ }
154
+ }
155
+ ```
156
+
157
+ ## GroupView (Android)
158
+
159
+ Enable view group functionality for managing child views:
160
+
161
+ ```kotlin
162
+ View(MyContainerView::class) {
163
+ GroupView {
164
+ AddChildView { parent, child, index -> parent.addView(child, index) }
165
+ GetChildCount { parent -> parent.childCount }
166
+ GetChildViewAt { parent, index -> parent.getChildAt(index) }
167
+ RemoveChildView { parent, child -> parent.removeView(child) }
168
+ RemoveChildViewAt { parent, index -> parent.removeViewAt(index) }
169
+ }
170
+ }
171
+ ```
@@ -0,0 +1,480 @@
1
+ ---
2
+ name: expo-tailwind-setup
3
+ description: Set up Tailwind CSS v4 in Expo with react-native-css and NativeWind v5 for universal styling
4
+ version: 1.0.0
5
+ license: MIT
6
+ ---
7
+
8
+ # Tailwind CSS Setup for Expo with react-native-css
9
+
10
+ This guide covers setting up Tailwind CSS v4 in Expo using react-native-css and NativeWind v5 for universal styling across iOS, Android, and Web.
11
+
12
+ ## Overview
13
+
14
+ This setup uses:
15
+
16
+ - **Tailwind CSS v4** - Modern CSS-first configuration
17
+ - **react-native-css** - CSS runtime for React Native
18
+ - **NativeWind v5** - Metro transformer for Tailwind in React Native
19
+ - **@tailwindcss/postcss** - PostCSS plugin for Tailwind v4
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ # Install dependencies
25
+ npx expo install tailwindcss@^4 nativewind@5.0.0-preview.2 react-native-css@0.0.0-nightly.5ce6396 @tailwindcss/postcss tailwind-merge clsx
26
+ ```
27
+
28
+ Add resolutions for lightningcss compatibility:
29
+
30
+ ```json
31
+ // package.json
32
+ {
33
+ "resolutions": {
34
+ "lightningcss": "1.30.1"
35
+ }
36
+ }
37
+ ```
38
+
39
+ - autoprefixer is not needed in Expo because of lightningcss
40
+ - postcss is included in expo by default
41
+
42
+ ## Configuration Files
43
+
44
+ ### Metro Config
45
+
46
+ Create or update `metro.config.js`:
47
+
48
+ ```js
49
+ // metro.config.js
50
+ const { getDefaultConfig } = require("expo/metro-config");
51
+ const { withNativewind } = require("nativewind/metro");
52
+
53
+ /** @type {import('expo/metro-config').MetroConfig} */
54
+ const config = getDefaultConfig(__dirname);
55
+
56
+ module.exports = withNativewind(config, {
57
+ // inline variables break PlatformColor in CSS variables
58
+ inlineVariables: false,
59
+ // We add className support manually
60
+ globalClassNamePolyfill: false,
61
+ });
62
+ ```
63
+
64
+ ### PostCSS Config
65
+
66
+ Create `postcss.config.mjs`:
67
+
68
+ ```js
69
+ // postcss.config.mjs
70
+ export default {
71
+ plugins: {
72
+ "@tailwindcss/postcss": {},
73
+ },
74
+ };
75
+ ```
76
+
77
+ ### Global CSS
78
+
79
+ Create `src/global.css`:
80
+
81
+ ```css
82
+ @import "tailwindcss/theme.css" layer(theme);
83
+ @import "tailwindcss/preflight.css" layer(base);
84
+ @import "tailwindcss/utilities.css";
85
+
86
+ /* Platform-specific font families */
87
+ @media android {
88
+ :root {
89
+ --font-mono: monospace;
90
+ --font-rounded: normal;
91
+ --font-serif: serif;
92
+ --font-sans: normal;
93
+ }
94
+ }
95
+
96
+ @media ios {
97
+ :root {
98
+ --font-mono: ui-monospace;
99
+ --font-serif: ui-serif;
100
+ --font-sans: system-ui;
101
+ --font-rounded: ui-rounded;
102
+ }
103
+ }
104
+ ```
105
+
106
+ ## IMPORTANT: No Babel Config Needed
107
+
108
+ With Tailwind v4 and NativeWind v5, you do NOT need a babel.config.js for Tailwind. Remove any NativeWind babel presets if present:
109
+
110
+ ```js
111
+ // DELETE babel.config.js if it only contains NativeWind config
112
+ // The following is NO LONGER needed:
113
+ // module.exports = function (api) {
114
+ // api.cache(true);
115
+ // return {
116
+ // presets: [
117
+ // ["babel-preset-expo", { jsxImportSource: "nativewind" }],
118
+ // "nativewind/babel",
119
+ // ],
120
+ // };
121
+ // };
122
+ ```
123
+
124
+ ## CSS Component Wrappers
125
+
126
+ Since react-native-css requires explicit CSS element wrapping, create reusable components:
127
+
128
+ ### Main Components (`src/tw/index.tsx`)
129
+
130
+ ```tsx
131
+ import {
132
+ useCssElement,
133
+ useNativeVariable as useFunctionalVariable,
134
+ } from "react-native-css";
135
+
136
+ import { Link as RouterLink } from "expo-router";
137
+ import Animated from "react-native-reanimated";
138
+ import React from "react";
139
+ import {
140
+ View as RNView,
141
+ Text as RNText,
142
+ Pressable as RNPressable,
143
+ ScrollView as RNScrollView,
144
+ TouchableHighlight as RNTouchableHighlight,
145
+ TextInput as RNTextInput,
146
+ StyleSheet,
147
+ } from "react-native";
148
+
149
+ // CSS-enabled Link
150
+ export const Link = (
151
+ props: React.ComponentProps<typeof RouterLink> & { className?: string }
152
+ ) => {
153
+ return useCssElement(RouterLink, props, { className: "style" });
154
+ };
155
+
156
+ Link.Trigger = RouterLink.Trigger;
157
+ Link.Menu = RouterLink.Menu;
158
+ Link.MenuAction = RouterLink.MenuAction;
159
+ Link.Preview = RouterLink.Preview;
160
+
161
+ // CSS Variable hook
162
+ export const useCSSVariable =
163
+ process.env.EXPO_OS !== "web"
164
+ ? useFunctionalVariable
165
+ : (variable: string) => `var(${variable})`;
166
+
167
+ // View
168
+ export type ViewProps = React.ComponentProps<typeof RNView> & {
169
+ className?: string;
170
+ };
171
+
172
+ export const View = (props: ViewProps) => {
173
+ return useCssElement(RNView, props, { className: "style" });
174
+ };
175
+ View.displayName = "CSS(View)";
176
+
177
+ // Text
178
+ export const Text = (
179
+ props: React.ComponentProps<typeof RNText> & { className?: string }
180
+ ) => {
181
+ return useCssElement(RNText, props, { className: "style" });
182
+ };
183
+ Text.displayName = "CSS(Text)";
184
+
185
+ // ScrollView
186
+ export const ScrollView = (
187
+ props: React.ComponentProps<typeof RNScrollView> & {
188
+ className?: string;
189
+ contentContainerClassName?: string;
190
+ }
191
+ ) => {
192
+ return useCssElement(RNScrollView, props, {
193
+ className: "style",
194
+ contentContainerClassName: "contentContainerStyle",
195
+ });
196
+ };
197
+ ScrollView.displayName = "CSS(ScrollView)";
198
+
199
+ // Pressable
200
+ export const Pressable = (
201
+ props: React.ComponentProps<typeof RNPressable> & { className?: string }
202
+ ) => {
203
+ return useCssElement(RNPressable, props, { className: "style" });
204
+ };
205
+ Pressable.displayName = "CSS(Pressable)";
206
+
207
+ // TextInput
208
+ export const TextInput = (
209
+ props: React.ComponentProps<typeof RNTextInput> & { className?: string }
210
+ ) => {
211
+ return useCssElement(RNTextInput, props, { className: "style" });
212
+ };
213
+ TextInput.displayName = "CSS(TextInput)";
214
+
215
+ // AnimatedScrollView
216
+ export const AnimatedScrollView = (
217
+ props: React.ComponentProps<typeof Animated.ScrollView> & {
218
+ className?: string;
219
+ contentClassName?: string;
220
+ contentContainerClassName?: string;
221
+ }
222
+ ) => {
223
+ return useCssElement(Animated.ScrollView, props, {
224
+ className: "style",
225
+ contentClassName: "contentContainerStyle",
226
+ contentContainerClassName: "contentContainerStyle",
227
+ });
228
+ };
229
+
230
+ // TouchableHighlight with underlayColor extraction
231
+ function XXTouchableHighlight(
232
+ props: React.ComponentProps<typeof RNTouchableHighlight>
233
+ ) {
234
+ const { underlayColor, ...style } = StyleSheet.flatten(props.style) || {};
235
+ return (
236
+ <RNTouchableHighlight
237
+ underlayColor={underlayColor}
238
+ {...props}
239
+ style={style}
240
+ />
241
+ );
242
+ }
243
+
244
+ export const TouchableHighlight = (
245
+ props: React.ComponentProps<typeof RNTouchableHighlight>
246
+ ) => {
247
+ return useCssElement(XXTouchableHighlight, props, { className: "style" });
248
+ };
249
+ TouchableHighlight.displayName = "CSS(TouchableHighlight)";
250
+ ```
251
+
252
+ ### Image Component (`src/tw/image.tsx`)
253
+
254
+ ```tsx
255
+ import { useCssElement } from "react-native-css";
256
+ import React from "react";
257
+ import { StyleSheet } from "react-native";
258
+ import Animated from "react-native-reanimated";
259
+ import { Image as RNImage } from "expo-image";
260
+
261
+ const AnimatedExpoImage = Animated.createAnimatedComponent(RNImage);
262
+
263
+ export type ImageProps = React.ComponentProps<typeof Image>;
264
+
265
+ function CSSImage(props: React.ComponentProps<typeof AnimatedExpoImage>) {
266
+ // @ts-expect-error: Remap objectFit style to contentFit property
267
+ const { objectFit, objectPosition, ...style } =
268
+ StyleSheet.flatten(props.style) || {};
269
+
270
+ return (
271
+ <AnimatedExpoImage
272
+ contentFit={objectFit}
273
+ contentPosition={objectPosition}
274
+ {...props}
275
+ source={
276
+ typeof props.source === "string" ? { uri: props.source } : props.source
277
+ }
278
+ // @ts-expect-error: Style is remapped above
279
+ style={style}
280
+ />
281
+ );
282
+ }
283
+
284
+ export const Image = (
285
+ props: React.ComponentProps<typeof CSSImage> & { className?: string }
286
+ ) => {
287
+ return useCssElement(CSSImage, props, { className: "style" });
288
+ };
289
+
290
+ Image.displayName = "CSS(Image)";
291
+ ```
292
+
293
+ ### Animated Components (`src/tw/animated.tsx`)
294
+
295
+ ```tsx
296
+ import * as TW from "./index";
297
+ import RNAnimated from "react-native-reanimated";
298
+
299
+ export const Animated = {
300
+ ...RNAnimated,
301
+ View: RNAnimated.createAnimatedComponent(TW.View),
302
+ };
303
+ ```
304
+
305
+ ## Usage
306
+
307
+ Import CSS-wrapped components from your tw directory:
308
+
309
+ ```tsx
310
+ import { View, Text, ScrollView, Image } from "@/tw";
311
+
312
+ export default function MyScreen() {
313
+ return (
314
+ <ScrollView className="flex-1 bg-white">
315
+ <View className="p-4 gap-4">
316
+ <Text className="text-xl font-bold text-gray-900">Hello Tailwind!</Text>
317
+ <Image
318
+ className="w-full h-48 rounded-lg object-cover"
319
+ source={{ uri: "https://example.com/image.jpg" }}
320
+ />
321
+ </View>
322
+ </ScrollView>
323
+ );
324
+ }
325
+ ```
326
+
327
+ ## Custom Theme Variables
328
+
329
+ Add custom theme variables in your global.css using `@theme`:
330
+
331
+ ```css
332
+ @layer theme {
333
+ @theme {
334
+ /* Custom fonts */
335
+ --font-rounded: "SF Pro Rounded", sans-serif;
336
+
337
+ /* Custom line heights */
338
+ --text-xs--line-height: calc(1em / 0.75);
339
+ --text-sm--line-height: calc(1.25em / 0.875);
340
+ --text-base--line-height: calc(1.5em / 1);
341
+
342
+ /* Custom leading scales */
343
+ --leading-tight: 1.25em;
344
+ --leading-snug: 1.375em;
345
+ --leading-normal: 1.5em;
346
+ }
347
+ }
348
+ ```
349
+
350
+ ## Platform-Specific Styles
351
+
352
+ Use platform media queries for platform-specific styling:
353
+
354
+ ```css
355
+ @media ios {
356
+ :root {
357
+ --font-sans: system-ui;
358
+ --font-rounded: ui-rounded;
359
+ }
360
+ }
361
+
362
+ @media android {
363
+ :root {
364
+ --font-sans: normal;
365
+ --font-rounded: normal;
366
+ }
367
+ }
368
+ ```
369
+
370
+ ## Apple System Colors with CSS Variables
371
+
372
+ Create a CSS file for Apple semantic colors:
373
+
374
+ ```css
375
+ /* src/css/sf.css */
376
+ @layer base {
377
+ html {
378
+ color-scheme: light;
379
+ }
380
+ }
381
+
382
+ :root {
383
+ /* Accent colors with light/dark mode */
384
+ --sf-blue: light-dark(rgb(0 122 255), rgb(10 132 255));
385
+ --sf-green: light-dark(rgb(52 199 89), rgb(48 209 89));
386
+ --sf-red: light-dark(rgb(255 59 48), rgb(255 69 58));
387
+
388
+ /* Gray scales */
389
+ --sf-gray: light-dark(rgb(142 142 147), rgb(142 142 147));
390
+ --sf-gray-2: light-dark(rgb(174 174 178), rgb(99 99 102));
391
+
392
+ /* Text colors */
393
+ --sf-text: light-dark(rgb(0 0 0), rgb(255 255 255));
394
+ --sf-text-2: light-dark(rgb(60 60 67 / 0.6), rgb(235 235 245 / 0.6));
395
+
396
+ /* Background colors */
397
+ --sf-bg: light-dark(rgb(255 255 255), rgb(0 0 0));
398
+ --sf-bg-2: light-dark(rgb(242 242 247), rgb(28 28 30));
399
+ }
400
+
401
+ /* iOS native colors via platformColor */
402
+ @media ios {
403
+ :root {
404
+ --sf-blue: platformColor(systemBlue);
405
+ --sf-green: platformColor(systemGreen);
406
+ --sf-red: platformColor(systemRed);
407
+ --sf-gray: platformColor(systemGray);
408
+ --sf-text: platformColor(label);
409
+ --sf-text-2: platformColor(secondaryLabel);
410
+ --sf-bg: platformColor(systemBackground);
411
+ --sf-bg-2: platformColor(secondarySystemBackground);
412
+ }
413
+ }
414
+
415
+ /* Register as Tailwind theme colors */
416
+ @layer theme {
417
+ @theme {
418
+ --color-sf-blue: var(--sf-blue);
419
+ --color-sf-green: var(--sf-green);
420
+ --color-sf-red: var(--sf-red);
421
+ --color-sf-gray: var(--sf-gray);
422
+ --color-sf-text: var(--sf-text);
423
+ --color-sf-text-2: var(--sf-text-2);
424
+ --color-sf-bg: var(--sf-bg);
425
+ --color-sf-bg-2: var(--sf-bg-2);
426
+ }
427
+ }
428
+ ```
429
+
430
+ Then use in components:
431
+
432
+ ```tsx
433
+ <Text className="text-sf-text">Primary text</Text>
434
+ <Text className="text-sf-text-2">Secondary text</Text>
435
+ <View className="bg-sf-bg">...</View>
436
+ ```
437
+
438
+ ## Using CSS Variables in JavaScript
439
+
440
+ Use the `useCSSVariable` hook:
441
+
442
+ ```tsx
443
+ import { useCSSVariable } from "@/tw";
444
+
445
+ function MyComponent() {
446
+ const blue = useCSSVariable("--sf-blue");
447
+
448
+ return <View style={{ borderColor: blue }} />;
449
+ }
450
+ ```
451
+
452
+ ## Key Differences from NativeWind v4 / Tailwind v3
453
+
454
+ 1. **No babel.config.js** - Configuration is now CSS-first
455
+ 2. **PostCSS plugin** - Uses `@tailwindcss/postcss` instead of `tailwindcss`
456
+ 3. **CSS imports** - Use `@import "tailwindcss/..."` instead of `@tailwind` directives
457
+ 4. **Theme config** - Use `@theme` in CSS instead of `tailwind.config.js`
458
+ 5. **Component wrappers** - Must wrap components with `useCssElement` for className support
459
+ 6. **Metro config** - Use `withNativewind` with different options (`inlineVariables: false`)
460
+
461
+ ## Troubleshooting
462
+
463
+ ### Styles not applying
464
+
465
+ 1. Ensure you have the CSS file imported in your app entry
466
+ 2. Check that components are wrapped with `useCssElement`
467
+ 3. Verify Metro config has `withNativewind` applied
468
+
469
+ ### Platform colors not working
470
+
471
+ 1. Use `platformColor()` in `@media ios` blocks
472
+ 2. Fall back to `light-dark()` for web/Android
473
+
474
+ ### TypeScript errors
475
+
476
+ Add className to component props:
477
+
478
+ ```tsx
479
+ type Props = React.ComponentProps<typeof RNView> & { className?: string };
480
+ ```
@@ -0,0 +1,40 @@
1
+ ---
2
+ name: Expo UI Jetpack Compose
3
+ description: "`@expo/ui/jetpack-compose` package lets you use Jetpack Compose Views and modifiers in your app."
4
+ ---
5
+
6
+ > The instructions in this skill apply to SDK 55 only. For other SDK versions, refer to the Expo UI Jetpack Compose docs for that version for the most accurate information.
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ npx expo install @expo/ui
12
+ ```
13
+
14
+ A native rebuild is required after installation (`npx expo run:android`).
15
+
16
+ ## Instructions
17
+
18
+ - Expo UI's API mirrors Jetpack Compose's API. Use Jetpack Compose and Material Design 3 knowledge to decide which components or modifiers to use. If you need deeper Jetpack Compose or Material 3 guidance (e.g. which component to pick, layout patterns, theming), spawn a subagent to research [Jetpack Compose](https://developer.android.com/develop/ui/compose/components) and [Material Design 3](https://m3.material.io/) best practices.
19
+ - Components are imported from `@expo/ui/jetpack-compose`, modifiers from `@expo/ui/jetpack-compose/modifiers`.
20
+ - **Always read the `.d.ts` type files** to confirm the exact API before using a component or modifier. Run `node -e "console.log(path.dirname(require.resolve('@expo/ui/jetpack-compose')))"` to locate the package, then read the relevant `{ComponentName}/index.d.ts` files. This is the most reliable source of truth.
21
+ - When about to use a component, fetch its docs to confirm the API - https://docs.expo.dev/versions/v55.0.0/sdk/ui/jetpack-compose/{component-name}/index.md
22
+ - When unsure about a modifier's API, refer to the docs - https://docs.expo.dev/versions/v55.0.0/sdk/ui/jetpack-compose/modifiers/index.md
23
+ - Every Jetpack Compose tree must be wrapped in `Host`. Use `<Host matchContents>` for intrinsic sizing, or `<Host style={{ flex: 1 }}>` when you need explicit size (e.g. as a parent of `LazyColumn`). Example:
24
+
25
+ ```jsx
26
+ import { Host, Column, Button, Text } from "@expo/ui/jetpack-compose";
27
+ import { fillMaxWidth, paddingAll } from "@expo/ui/jetpack-compose/modifiers";
28
+
29
+ <Host matchContents>
30
+ <Column verticalArrangement={{ spacedBy: 8 }} modifiers={[fillMaxWidth(), paddingAll(16)]}>
31
+ <Text style={{ typography: "titleLarge" }}>Hello</Text>
32
+ <Button onPress={() => alert("Pressed!")}>Press me</Button>
33
+ </Column>
34
+ </Host>;
35
+ ```
36
+
37
+ ## Key Components
38
+
39
+ - **LazyColumn** — Use instead of react-native `ScrollView`/`FlatList` for scrollable lists. Wrap in `<Host style={{ flex: 1 }}>`.
40
+ - **Icon** — Use `<Icon source={require('./icon.xml')} size={24} />` with Android XML vector drawables. To get icons: go to [Material Symbols](https://fonts.google.com/icons), select an icon, choose the Android platform, and download the XML vector drawable. Save these as `.xml` files in your project's `assets/` directory (e.g. `assets/icons/wifi.xml`). Metro bundles `.xml` assets automatically — no metro config changes needed.