[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6XGFQ0SWJX4K7539J2P7ZBA":3,"skill-same:01M6XGFQ0SWJX4K7539J2P7ZBA":67},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":41,"linkOnly":42,"markdownContent":43,"markdownBody":44,"frontMatter":45,"refName":47,"commitSha":48,"skillDirectory":49,"forksCount":14,"repositoryHtmlUrl":50,"repositoryHomepageUrl":6,"ownerHtmlUrl":51,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":52,"install":53,"resources":66},"01M6XGFQ0SWJX4K7539J2P7ZBA","expo-tailwind-setup",null,"Set up Tailwind CSS v4 in Expo with react-native-css and NativeWind v5 for universal styling","sapsapshen\u002Fai-memory-router","sapsapshen","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F20347959?v=4","01M6XDQEF1DP50DKF37H81J3J5","shenmian","01M6XDQEJPE41Y3DT2763X8ZJN",0,"MIT","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fcopilot\u002Fexpo-tailwind-setup\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40],"setup","expo tailwind setup","Tailwind","expo","react-native","unknown","for","with","nativewind","native","Tailwind CSS","community","css","styling","up","SET","react","2026-11-10 10:12:30",false,"---\nname: expo-tailwind-setup\ndescription: Set up Tailwind CSS v4 in Expo with react-native-css and NativeWind v5 for universal styling\nrisk: unknown\nsource: community\nversion: 1.0.0\nlicense: MIT\n---\n\n# Tailwind CSS Setup for Expo with react-native-css\n\nThis guide covers setting up Tailwind CSS v4 in Expo using react-native-css and NativeWind v5 for universal styling across iOS, Android, and Web.\n\n## Overview\n\nThis setup uses:\n\n- **Tailwind CSS v4** - Modern CSS-first configuration\n- **react-native-css** - CSS runtime for React Native\n- **NativeWind v5** - Metro transformer for Tailwind in React Native\n- **@tailwindcss\u002Fpostcss** - PostCSS plugin for Tailwind v4\n\n## Installation\n\n```bash\n# Install dependencies\nnpx expo install tailwindcss@^4 nativewind@5.0.0-preview.2 react-native-css@0.0.0-nightly.5ce6396 @tailwindcss\u002Fpostcss tailwind-merge clsx\n```\n\nAdd resolutions for lightningcss compatibility:\n\n```json\n\u002F\u002F package.json\n{\n  \"resolutions\": {\n    \"lightningcss\": \"1.30.1\"\n  }\n}\n```\n\n- autoprefixer is not needed in Expo because of lightningcss\n- postcss is included in expo by default\n\n## Configuration Files\n\n### Metro Config\n\nCreate or update `metro.config.js`:\n\n```js\n\u002F\u002F metro.config.js\nconst { getDefaultConfig } = require(\"expo\u002Fmetro-config\");\nconst { withNativewind } = require(\"nativewind\u002Fmetro\");\n\n\u002F** @type {import('expo\u002Fmetro-config').MetroConfig} *\u002F\nconst config = getDefaultConfig(__dirname);\n\nmodule.exports = withNativewind(config, {\n  \u002F\u002F inline variables break PlatformColor in CSS variables\n  inlineVariables: false,\n  \u002F\u002F We add className support manually\n  globalClassNamePolyfill: false,\n});\n```\n\n### PostCSS Config\n\nCreate `postcss.config.mjs`:\n\n```js\n\u002F\u002F postcss.config.mjs\nexport default {\n  plugins: {\n    \"@tailwindcss\u002Fpostcss\": {},\n  },\n};\n```\n\n### Global CSS\n\nCreate `src\u002Fglobal.css`:\n\n```css\n@import \"tailwindcss\u002Ftheme.css\" layer(theme);\n@import \"tailwindcss\u002Fpreflight.css\" layer(base);\n@import \"tailwindcss\u002Futilities.css\";\n\n\u002F* Platform-specific font families *\u002F\n@media android {\n  :root {\n    --font-mono: monospace;\n    --font-rounded: normal;\n    --font-serif: serif;\n    --font-sans: normal;\n  }\n}\n\n@media ios {\n  :root {\n    --font-mono: ui-monospace;\n    --font-serif: ui-serif;\n    --font-sans: system-ui;\n    --font-rounded: ui-rounded;\n  }\n}\n```\n\n## IMPORTANT: No Babel Config Needed\n\nWith Tailwind v4 and NativeWind v5, you do NOT need a babel.config.js for Tailwind. Remove any NativeWind babel presets if present:\n\n```js\n\u002F\u002F DELETE babel.config.js if it only contains NativeWind config\n\u002F\u002F The following is NO LONGER needed:\n\u002F\u002F module.exports = function (api) {\n\u002F\u002F   api.cache(true);\n\u002F\u002F   return {\n\u002F\u002F     presets: [\n\u002F\u002F       [\"babel-preset-expo\", { jsxImportSource: \"nativewind\" }],\n\u002F\u002F       \"nativewind\u002Fbabel\",\n\u002F\u002F     ],\n\u002F\u002F   };\n\u002F\u002F };\n```\n\n## CSS Component Wrappers\n\nSince react-native-css requires explicit CSS element wrapping, create reusable components:\n\n### Main Components (`src\u002Ftw\u002Findex.tsx`)\n\n```tsx\nimport {\n  useCssElement,\n  useNativeVariable as useFunctionalVariable,\n} from \"react-native-css\";\n\nimport { Link as RouterLink } from \"expo-router\";\nimport Animated from \"react-native-reanimated\";\nimport React from \"react\";\nimport {\n  View as RNView,\n  Text as RNText,\n  Pressable as RNPressable,\n  ScrollView as RNScrollView,\n  TouchableHighlight as RNTouchableHighlight,\n  TextInput as RNTextInput,\n  StyleSheet,\n} from \"react-native\";\n\n\u002F\u002F CSS-enabled Link\nexport const Link = (\n  props: React.ComponentProps\u003Ctypeof RouterLink> & { className?: string }\n) => {\n  return useCssElement(RouterLink, props, { className: \"style\" });\n};\n\nLink.Trigger = RouterLink.Trigger;\nLink.Menu = RouterLink.Menu;\nLink.MenuAction = RouterLink.MenuAction;\nLink.Preview = RouterLink.Preview;\n\n\u002F\u002F CSS Variable hook\nexport const useCSSVariable =\n  process.env.EXPO_OS !== \"web\"\n    ? useFunctionalVariable\n    : (variable: string) => `var(${variable})`;\n\n\u002F\u002F View\nexport type ViewProps = React.ComponentProps\u003Ctypeof RNView> & {\n  className?: string;\n};\n\nexport const View = (props: ViewProps) => {\n  return useCssElement(RNView, props, { className: \"style\" });\n};\nView.displayName = \"CSS(View)\";\n\n\u002F\u002F Text\nexport const Text = (\n  props: React.ComponentProps\u003Ctypeof RNText> & { className?: string }\n) => {\n  return useCssElement(RNText, props, { className: \"style\" });\n};\nText.displayName = \"CSS(Text)\";\n\n\u002F\u002F ScrollView\nexport const ScrollView = (\n  props: React.ComponentProps\u003Ctypeof RNScrollView> & {\n    className?: string;\n    contentContainerClassName?: string;\n  }\n) => {\n  return useCssElement(RNScrollView, props, {\n    className: \"style\",\n    contentContainerClassName: \"contentContainerStyle\",\n  });\n};\nScrollView.displayName = \"CSS(ScrollView)\";\n\n\u002F\u002F Pressable\nexport const Pressable = (\n  props: React.ComponentProps\u003Ctypeof RNPressable> & { className?: string }\n) => {\n  return useCssElement(RNPressable, props, { className: \"style\" });\n};\nPressable.displayName = \"CSS(Pressable)\";\n\n\u002F\u002F TextInput\nexport const TextInput = (\n  props: React.ComponentProps\u003Ctypeof RNTextInput> & { className?: string }\n) => {\n  return useCssElement(RNTextInput, props, { className: \"style\" });\n};\nTextInput.displayName = \"CSS(TextInput)\";\n\n\u002F\u002F AnimatedScrollView\nexport const AnimatedScrollView = (\n  props: React.ComponentProps\u003Ctypeof Animated.ScrollView> & {\n    className?: string;\n    contentClassName?: string;\n    contentContainerClassName?: string;\n  }\n) => {\n  return useCssElement(Animated.ScrollView, props, {\n    className: \"style\",\n    contentClassName: \"contentContainerStyle\",\n    contentContainerClassName: \"contentContainerStyle\",\n  });\n};\n\n\u002F\u002F TouchableHighlight with underlayColor extraction\nfunction XXTouchableHighlight(\n  props: React.ComponentProps\u003Ctypeof RNTouchableHighlight>\n) {\n  const { underlayColor, ...style } = StyleSheet.flatten(props.style) || {};\n  return (\n    \u003CRNTouchableHighlight\n      underlayColor={underlayColor}\n      {...props}\n      style={style}\n    \u002F>\n  );\n}\n\nexport const TouchableHighlight = (\n  props: React.ComponentProps\u003Ctypeof RNTouchableHighlight>\n) => {\n  return useCssElement(XXTouchableHighlight, props, { className: \"style\" });\n};\nTouchableHighlight.displayName = \"CSS(TouchableHighlight)\";\n```\n\n### Image Component (`src\u002Ftw\u002Fimage.tsx`)\n\n```tsx\nimport { useCssElement } from \"react-native-css\";\nimport React from \"react\";\nimport { StyleSheet } from \"react-native\";\nimport Animated from \"react-native-reanimated\";\nimport { Image as RNImage } from \"expo-image\";\n\nconst AnimatedExpoImage = Animated.createAnimatedComponent(RNImage);\n\nexport type ImageProps = React.ComponentProps\u003Ctypeof Image>;\n\nfunction CSSImage(props: React.ComponentProps\u003Ctypeof AnimatedExpoImage>) {\n  \u002F\u002F @ts-expect-error: Remap objectFit style to contentFit property\n  const { objectFit, objectPosition, ...style } =\n    StyleSheet.flatten(props.style) || {};\n\n  return (\n    \u003CAnimatedExpoImage\n      contentFit={objectFit}\n      contentPosition={objectPosition}\n      {...props}\n      source={\n        typeof props.source === \"string\" ? { uri: props.source } : props.source\n      }\n      \u002F\u002F @ts-expect-error: Style is remapped above\n      style={style}\n    \u002F>\n  );\n}\n\nexport const Image = (\n  props: React.ComponentProps\u003Ctypeof CSSImage> & { className?: string }\n) => {\n  return useCssElement(CSSImage, props, { className: \"style\" });\n};\n\nImage.displayName = \"CSS(Image)\";\n```\n\n### Animated Components (`src\u002Ftw\u002Fanimated.tsx`)\n\n```tsx\nimport * as TW from \".\u002Findex\";\nimport RNAnimated from \"react-native-reanimated\";\n\nexport const Animated = {\n  ...RNAnimated,\n  View: RNAnimated.createAnimatedComponent(TW.View),\n};\n```\n\n## Usage\n\nImport CSS-wrapped components from your tw directory:\n\n```tsx\nimport { View, Text, ScrollView, Image } from \"@\u002Ftw\";\n\nexport default function MyScreen() {\n  return (\n    \u003CScrollView className=\"flex-1 bg-white\">\n      \u003CView className=\"p-4 gap-4\">\n        \u003CText className=\"text-xl font-bold text-gray-900\">Hello Tailwind!\u003C\u002FText>\n        \u003CImage\n          className=\"w-full h-48 rounded-lg object-cover\"\n          source={{ uri: \"https:\u002F\u002Fexample.com\u002Fimage.jpg\" }}\n        \u002F>\n      \u003C\u002FView>\n    \u003C\u002FScrollView>\n  );\n}\n```\n\n## Custom Theme Variables\n\nAdd custom theme variables in your global.css using `@theme`:\n\n```css\n@layer theme {\n  @theme {\n    \u002F* Custom fonts *\u002F\n    --font-rounded: \"SF Pro Rounded\", sans-serif;\n\n    \u002F* Custom line heights *\u002F\n    --text-xs--line-height: calc(1em \u002F 0.75);\n    --text-sm--line-height: calc(1.25em \u002F 0.875);\n    --text-base--line-height: calc(1.5em \u002F 1);\n\n    \u002F* Custom leading scales *\u002F\n    --leading-tight: 1.25em;\n    --leading-snug: 1.375em;\n    --leading-normal: 1.5em;\n  }\n}\n```\n\n## Platform-Specific Styles\n\nUse platform media queries for platform-specific styling:\n\n```css\n@media ios {\n  :root {\n    --font-sans: system-ui;\n    --font-rounded: ui-rounded;\n  }\n}\n\n@media android {\n  :root {\n    --font-sans: normal;\n    --font-rounded: normal;\n  }\n}\n```\n\n## Apple System Colors with CSS Variables\n\nCreate a CSS file for Apple semantic colors:\n\n```css\n\u002F* src\u002Fcss\u002Fsf.css *\u002F\n@layer base {\n  html {\n    color-scheme: light;\n  }\n}\n\n:root {\n  \u002F* Accent colors with light\u002Fdark mode *\u002F\n  --sf-blue: light-dark(rgb(0 122 255), rgb(10 132 255));\n  --sf-green: light-dark(rgb(52 199 89), rgb(48 209 89));\n  --sf-red: light-dark(rgb(255 59 48), rgb(255 69 58));\n\n  \u002F* Gray scales *\u002F\n  --sf-gray: light-dark(rgb(142 142 147), rgb(142 142 147));\n  --sf-gray-2: light-dark(rgb(174 174 178), rgb(99 99 102));\n\n  \u002F* Text colors *\u002F\n  --sf-text: light-dark(rgb(0 0 0), rgb(255 255 255));\n  --sf-text-2: light-dark(rgb(60 60 67 \u002F 0.6), rgb(235 235 245 \u002F 0.6));\n\n  \u002F* Background colors *\u002F\n  --sf-bg: light-dark(rgb(255 255 255), rgb(0 0 0));\n  --sf-bg-2: light-dark(rgb(242 242 247), rgb(28 28 30));\n}\n\n\u002F* iOS native colors via platformColor *\u002F\n@media ios {\n  :root {\n    --sf-blue: platformColor(systemBlue);\n    --sf-green: platformColor(systemGreen);\n    --sf-red: platformColor(systemRed);\n    --sf-gray: platformColor(systemGray);\n    --sf-text: platformColor(label);\n    --sf-text-2: platformColor(secondaryLabel);\n    --sf-bg: platformColor(systemBackground);\n    --sf-bg-2: platformColor(secondarySystemBackground);\n  }\n}\n\n\u002F* Register as Tailwind theme colors *\u002F\n@layer theme {\n  @theme {\n    --color-sf-blue: var(--sf-blue);\n    --color-sf-green: var(--sf-green);\n    --color-sf-red: var(--sf-red);\n    --color-sf-gray: var(--sf-gray);\n    --color-sf-text: var(--sf-text);\n    --color-sf-text-2: var(--sf-text-2);\n    --color-sf-bg: var(--sf-bg);\n    --color-sf-bg-2: var(--sf-bg-2);\n  }\n}\n```\n\nThen use in components:\n\n```tsx\n\u003CText className=\"text-sf-text\">Primary text\u003C\u002FText>\n\u003CText className=\"text-sf-text-2\">Secondary text\u003C\u002FText>\n\u003CView className=\"bg-sf-bg\">...\u003C\u002FView>\n```\n\n## Using CSS Variables in JavaScript\n\nUse the `useCSSVariable` hook:\n\n```tsx\nimport { useCSSVariable } from \"@\u002Ftw\";\n\nfunction MyComponent() {\n  const blue = useCSSVariable(\"--sf-blue\");\n\n  return \u003CView style={{ borderColor: blue }} \u002F>;\n}\n```\n\n## Key Differences from NativeWind v4 \u002F Tailwind v3\n\n1. **No babel.config.js** - Configuration is now CSS-first\n2. **PostCSS plugin** - Uses `@tailwindcss\u002Fpostcss` instead of `tailwindcss`\n3. **CSS imports** - Use `@import \"tailwindcss\u002F...\"` instead of `@tailwind` directives\n4. **Theme config** - Use `@theme` in CSS instead of `tailwind.config.js`\n5. **Component wrappers** - Must wrap components with `useCssElement` for className support\n6. **Metro config** - Use `withNativewind` with different options (`inlineVariables: false`)\n\n## Troubleshooting\n\n### Styles not applying\n\n1. Ensure you have the CSS file imported in your app entry\n2. Check that components are wrapped with `useCssElement`\n3. Verify Metro config has `withNativewind` applied\n\n### Platform colors not working\n\n1. Use `platformColor()` in `@media ios` blocks\n2. Fall back to `light-dark()` for web\u002FAndroid\n\n### TypeScript errors\n\nAdd className to component props:\n\n```tsx\ntype Props = React.ComponentProps\u003Ctypeof RNView> & { className?: string };\n```\n","# Tailwind CSS Setup for Expo with react-native-css\n\nThis guide covers setting up Tailwind CSS v4 in Expo using react-native-css and NativeWind v5 for universal styling across iOS, Android, and Web.\n\n## Overview\n\nThis setup uses:\n\n- **Tailwind CSS v4** - Modern CSS-first configuration\n- **react-native-css** - CSS runtime for React Native\n- **NativeWind v5** - Metro transformer for Tailwind in React Native\n- **@tailwindcss\u002Fpostcss** - PostCSS plugin for Tailwind v4\n\n## Installation\n\n```bash\n# Install dependencies\nnpx expo install tailwindcss@^4 nativewind@5.0.0-preview.2 react-native-css@0.0.0-nightly.5ce6396 @tailwindcss\u002Fpostcss tailwind-merge clsx\n```\n\nAdd resolutions for lightningcss compatibility:\n\n```json\n\u002F\u002F package.json\n{\n  \"resolutions\": {\n    \"lightningcss\": \"1.30.1\"\n  }\n}\n```\n\n- autoprefixer is not needed in Expo because of lightningcss\n- postcss is included in expo by default\n\n## Configuration Files\n\n### Metro Config\n\nCreate or update `metro.config.js`:\n\n```js\n\u002F\u002F metro.config.js\nconst { getDefaultConfig } = require(\"expo\u002Fmetro-config\");\nconst { withNativewind } = require(\"nativewind\u002Fmetro\");\n\n\u002F** @type {import('expo\u002Fmetro-config').MetroConfig} *\u002F\nconst config = getDefaultConfig(__dirname);\n\nmodule.exports = withNativewind(config, {\n  \u002F\u002F inline variables break PlatformColor in CSS variables\n  inlineVariables: false,\n  \u002F\u002F We add className support manually\n  globalClassNamePolyfill: false,\n});\n```\n\n### PostCSS Config\n\nCreate `postcss.config.mjs`:\n\n```js\n\u002F\u002F postcss.config.mjs\nexport default {\n  plugins: {\n    \"@tailwindcss\u002Fpostcss\": {},\n  },\n};\n```\n\n### Global CSS\n\nCreate `src\u002Fglobal.css`:\n\n```css\n@import \"tailwindcss\u002Ftheme.css\" layer(theme);\n@import \"tailwindcss\u002Fpreflight.css\" layer(base);\n@import \"tailwindcss\u002Futilities.css\";\n\n\u002F* Platform-specific font families *\u002F\n@media android {\n  :root {\n    --font-mono: monospace;\n    --font-rounded: normal;\n    --font-serif: serif;\n    --font-sans: normal;\n  }\n}\n\n@media ios {\n  :root {\n    --font-mono: ui-monospace;\n    --font-serif: ui-serif;\n    --font-sans: system-ui;\n    --font-rounded: ui-rounded;\n  }\n}\n```\n\n## IMPORTANT: No Babel Config Needed\n\nWith Tailwind v4 and NativeWind v5, you do NOT need a babel.config.js for Tailwind. Remove any NativeWind babel presets if present:\n\n```js\n\u002F\u002F DELETE babel.config.js if it only contains NativeWind config\n\u002F\u002F The following is NO LONGER needed:\n\u002F\u002F module.exports = function (api) {\n\u002F\u002F   api.cache(true);\n\u002F\u002F   return {\n\u002F\u002F     presets: [\n\u002F\u002F       [\"babel-preset-expo\", { jsxImportSource: \"nativewind\" }],\n\u002F\u002F       \"nativewind\u002Fbabel\",\n\u002F\u002F     ],\n\u002F\u002F   };\n\u002F\u002F };\n```\n\n## CSS Component Wrappers\n\nSince react-native-css requires explicit CSS element wrapping, create reusable components:\n\n### Main Components (`src\u002Ftw\u002Findex.tsx`)\n\n```tsx\nimport {\n  useCssElement,\n  useNativeVariable as useFunctionalVariable,\n} from \"react-native-css\";\n\nimport { Link as RouterLink } from \"expo-router\";\nimport Animated from \"react-native-reanimated\";\nimport React from \"react\";\nimport {\n  View as RNView,\n  Text as RNText,\n  Pressable as RNPressable,\n  ScrollView as RNScrollView,\n  TouchableHighlight as RNTouchableHighlight,\n  TextInput as RNTextInput,\n  StyleSheet,\n} from \"react-native\";\n\n\u002F\u002F CSS-enabled Link\nexport const Link = (\n  props: React.ComponentProps\u003Ctypeof RouterLink> & { className?: string }\n) => {\n  return useCssElement(RouterLink, props, { className: \"style\" });\n};\n\nLink.Trigger = RouterLink.Trigger;\nLink.Menu = RouterLink.Menu;\nLink.MenuAction = RouterLink.MenuAction;\nLink.Preview = RouterLink.Preview;\n\n\u002F\u002F CSS Variable hook\nexport const useCSSVariable =\n  process.env.EXPO_OS !== \"web\"\n    ? useFunctionalVariable\n    : (variable: string) => `var(${variable})`;\n\n\u002F\u002F View\nexport type ViewProps = React.ComponentProps\u003Ctypeof RNView> & {\n  className?: string;\n};\n\nexport const View = (props: ViewProps) => {\n  return useCssElement(RNView, props, { className: \"style\" });\n};\nView.displayName = \"CSS(View)\";\n\n\u002F\u002F Text\nexport const Text = (\n  props: React.ComponentProps\u003Ctypeof RNText> & { className?: string }\n) => {\n  return useCssElement(RNText, props, { className: \"style\" });\n};\nText.displayName = \"CSS(Text)\";\n\n\u002F\u002F ScrollView\nexport const ScrollView = (\n  props: React.ComponentProps\u003Ctypeof RNScrollView> & {\n    className?: string;\n    contentContainerClassName?: string;\n  }\n) => {\n  return useCssElement(RNScrollView, props, {\n    className: \"style\",\n    contentContainerClassName: \"contentContainerStyle\",\n  });\n};\nScrollView.displayName = \"CSS(ScrollView)\";\n\n\u002F\u002F Pressable\nexport const Pressable = (\n  props: React.ComponentProps\u003Ctypeof RNPressable> & { className?: string }\n) => {\n  return useCssElement(RNPressable, props, { className: \"style\" });\n};\nPressable.displayName = \"CSS(Pressable)\";\n\n\u002F\u002F TextInput\nexport const TextInput = (\n  props: React.ComponentProps\u003Ctypeof RNTextInput> & { className?: string }\n) => {\n  return useCssElement(RNTextInput, props, { className: \"style\" });\n};\nTextInput.displayName = \"CSS(TextInput)\";\n\n\u002F\u002F AnimatedScrollView\nexport const AnimatedScrollView = (\n  props: React.ComponentProps\u003Ctypeof Animated.ScrollView> & {\n    className?: string;\n    contentClassName?: string;\n    contentContainerClassName?: string;\n  }\n) => {\n  return useCssElement(Animated.ScrollView, props, {\n    className: \"style\",\n    contentClassName: \"contentContainerStyle\",\n    contentContainerClassName: \"contentContainerStyle\",\n  });\n};\n\n\u002F\u002F TouchableHighlight with underlayColor extraction\nfunction XXTouchableHighlight(\n  props: React.ComponentProps\u003Ctypeof RNTouchableHighlight>\n) {\n  const { underlayColor, ...style } = StyleSheet.flatten(props.style) || {};\n  return (\n    \u003CRNTouchableHighlight\n      underlayColor={underlayColor}\n      {...props}\n      style={style}\n    \u002F>\n  );\n}\n\nexport const TouchableHighlight = (\n  props: React.ComponentProps\u003Ctypeof RNTouchableHighlight>\n) => {\n  return useCssElement(XXTouchableHighlight, props, { className: \"style\" });\n};\nTouchableHighlight.displayName = \"CSS(TouchableHighlight)\";\n```\n\n### Image Component (`src\u002Ftw\u002Fimage.tsx`)\n\n```tsx\nimport { useCssElement } from \"react-native-css\";\nimport React from \"react\";\nimport { StyleSheet } from \"react-native\";\nimport Animated from \"react-native-reanimated\";\nimport { Image as RNImage } from \"expo-image\";\n\nconst AnimatedExpoImage = Animated.createAnimatedComponent(RNImage);\n\nexport type ImageProps = React.ComponentProps\u003Ctypeof Image>;\n\nfunction CSSImage(props: React.ComponentProps\u003Ctypeof AnimatedExpoImage>) {\n  \u002F\u002F @ts-expect-error: Remap objectFit style to contentFit property\n  const { objectFit, objectPosition, ...style } =\n    StyleSheet.flatten(props.style) || {};\n\n  return (\n    \u003CAnimatedExpoImage\n      contentFit={objectFit}\n      contentPosition={objectPosition}\n      {...props}\n      source={\n        typeof props.source === \"string\" ? { uri: props.source } : props.source\n      }\n      \u002F\u002F @ts-expect-error: Style is remapped above\n      style={style}\n    \u002F>\n  );\n}\n\nexport const Image = (\n  props: React.ComponentProps\u003Ctypeof CSSImage> & { className?: string }\n) => {\n  return useCssElement(CSSImage, props, { className: \"style\" });\n};\n\nImage.displayName = \"CSS(Image)\";\n```\n\n### Animated Components (`src\u002Ftw\u002Fanimated.tsx`)\n\n```tsx\nimport * as TW from \".\u002Findex\";\nimport RNAnimated from \"react-native-reanimated\";\n\nexport const Animated = {\n  ...RNAnimated,\n  View: RNAnimated.createAnimatedComponent(TW.View),\n};\n```\n\n## Usage\n\nImport CSS-wrapped components from your tw directory:\n\n```tsx\nimport { View, Text, ScrollView, Image } from \"@\u002Ftw\";\n\nexport default function MyScreen() {\n  return (\n    \u003CScrollView className=\"flex-1 bg-white\">\n      \u003CView className=\"p-4 gap-4\">\n        \u003CText className=\"text-xl font-bold text-gray-900\">Hello Tailwind!\u003C\u002FText>\n        \u003CImage\n          className=\"w-full h-48 rounded-lg object-cover\"\n          source={{ uri: \"https:\u002F\u002Fexample.com\u002Fimage.jpg\" }}\n        \u002F>\n      \u003C\u002FView>\n    \u003C\u002FScrollView>\n  );\n}\n```\n\n## Custom Theme Variables\n\nAdd custom theme variables in your global.css using `@theme`:\n\n```css\n@layer theme {\n  @theme {\n    \u002F* Custom fonts *\u002F\n    --font-rounded: \"SF Pro Rounded\", sans-serif;\n\n    \u002F* Custom line heights *\u002F\n    --text-xs--line-height: calc(1em \u002F 0.75);\n    --text-sm--line-height: calc(1.25em \u002F 0.875);\n    --text-base--line-height: calc(1.5em \u002F 1);\n\n    \u002F* Custom leading scales *\u002F\n    --leading-tight: 1.25em;\n    --leading-snug: 1.375em;\n    --leading-normal: 1.5em;\n  }\n}\n```\n\n## Platform-Specific Styles\n\nUse platform media queries for platform-specific styling:\n\n```css\n@media ios {\n  :root {\n    --font-sans: system-ui;\n    --font-rounded: ui-rounded;\n  }\n}\n\n@media android {\n  :root {\n    --font-sans: normal;\n    --font-rounded: normal;\n  }\n}\n```\n\n## Apple System Colors with CSS Variables\n\nCreate a CSS file for Apple semantic colors:\n\n```css\n\u002F* src\u002Fcss\u002Fsf.css *\u002F\n@layer base {\n  html {\n    color-scheme: light;\n  }\n}\n\n:root {\n  \u002F* Accent colors with light\u002Fdark mode *\u002F\n  --sf-blue: light-dark(rgb(0 122 255), rgb(10 132 255));\n  --sf-green: light-dark(rgb(52 199 89), rgb(48 209 89));\n  --sf-red: light-dark(rgb(255 59 48), rgb(255 69 58));\n\n  \u002F* Gray scales *\u002F\n  --sf-gray: light-dark(rgb(142 142 147), rgb(142 142 147));\n  --sf-gray-2: light-dark(rgb(174 174 178), rgb(99 99 102));\n\n  \u002F* Text colors *\u002F\n  --sf-text: light-dark(rgb(0 0 0), rgb(255 255 255));\n  --sf-text-2: light-dark(rgb(60 60 67 \u002F 0.6), rgb(235 235 245 \u002F 0.6));\n\n  \u002F* Background colors *\u002F\n  --sf-bg: light-dark(rgb(255 255 255), rgb(0 0 0));\n  --sf-bg-2: light-dark(rgb(242 242 247), rgb(28 28 30));\n}\n\n\u002F* iOS native colors via platformColor *\u002F\n@media ios {\n  :root {\n    --sf-blue: platformColor(systemBlue);\n    --sf-green: platformColor(systemGreen);\n    --sf-red: platformColor(systemRed);\n    --sf-gray: platformColor(systemGray);\n    --sf-text: platformColor(label);\n    --sf-text-2: platformColor(secondaryLabel);\n    --sf-bg: platformColor(systemBackground);\n    --sf-bg-2: platformColor(secondarySystemBackground);\n  }\n}\n\n\u002F* Register as Tailwind theme colors *\u002F\n@layer theme {\n  @theme {\n    --color-sf-blue: var(--sf-blue);\n    --color-sf-green: var(--sf-green);\n    --color-sf-red: var(--sf-red);\n    --color-sf-gray: var(--sf-gray);\n    --color-sf-text: var(--sf-text);\n    --color-sf-text-2: var(--sf-text-2);\n    --color-sf-bg: var(--sf-bg);\n    --color-sf-bg-2: var(--sf-bg-2);\n  }\n}\n```\n\nThen use in components:\n\n```tsx\n\u003CText className=\"text-sf-text\">Primary text\u003C\u002FText>\n\u003CText className=\"text-sf-text-2\">Secondary text\u003C\u002FText>\n\u003CView className=\"bg-sf-bg\">...\u003C\u002FView>\n```\n\n## Using CSS Variables in JavaScript\n\nUse the `useCSSVariable` hook:\n\n```tsx\nimport { useCSSVariable } from \"@\u002Ftw\";\n\nfunction MyComponent() {\n  const blue = useCSSVariable(\"--sf-blue\");\n\n  return \u003CView style={{ borderColor: blue }} \u002F>;\n}\n```\n\n## Key Differences from NativeWind v4 \u002F Tailwind v3\n\n1. **No babel.config.js** - Configuration is now CSS-first\n2. **PostCSS plugin** - Uses `@tailwindcss\u002Fpostcss` instead of `tailwindcss`\n3. **CSS imports** - Use `@import \"tailwindcss\u002F...\"` instead of `@tailwind` directives\n4. **Theme config** - Use `@theme` in CSS instead of `tailwind.config.js`\n5. **Component wrappers** - Must wrap components with `useCssElement` for className support\n6. **Metro config** - Use `withNativewind` with different options (`inlineVariables: false`)\n\n## Troubleshooting\n\n### Styles not applying\n\n1. Ensure you have the CSS file imported in your app entry\n2. Check that components are wrapped with `useCssElement`\n3. Verify Metro config has `withNativewind` applied\n\n### Platform colors not working\n\n1. Use `platformColor()` in `@media ios` blocks\n2. Fall back to `light-dark()` for web\u002FAndroid\n\n### TypeScript errors\n\nAdd className to component props:\n\n```tsx\ntype Props = React.ComponentProps\u003Ctypeof RNView> & { className?: string };\n```\n",{"name":5,"risk":29,"source":35,"license":15,"version":46,"description":7},"1.0.0","main","7a38d8e7073e61c16eda85681cb32fb68a8657a5","skills-store\u002Fcopilot\u002Fexpo-tailwind-setup","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router","https:\u002F\u002Fgithub.com\u002Fsapsapshen","2026-04-14 21:12:12",{"source":8,"skillName":5,"commands":54,"prompt":64,"zipAvailable":65},[55,58,61],{"tool":56,"command":57},"npx","npx skills add sapsapshen\u002Fai-memory-router --skill expo-tailwind-setup",{"tool":59,"command":60},"bunx","bunx skills add sapsapshen\u002Fai-memory-router --skill expo-tailwind-setup",{"tool":62,"command":63},"pnpm","pnpm dlx skills add sapsapshen\u002Fai-memory-router --skill expo-tailwind-setup","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fcopilot\u002Fexpo-tailwind-setup\u002FSKILL.md",true,[],[68,91,117,127,140,157],{"skillNo":69,"name":70,"nameZh":6,"description":71,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":72,"categories":73,"keywords":79,"publishedAt":41},"01M71ATQRKG48SH06FQ697T5G9","wechat-search","Search WeChat Official Account articles using OpenClaw's web search and fetch capabilities with compliance-focused design.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fwechat-search-release\u002FSKILL.md",[74],{"categoryNo":75,"categoryName":76,"taxonomyType":77,"taxonomyTypeDesc":78},"01JBSEEDCAT000000000000037","律师与法务","PROFESSION","适用职业",[80,81,82,83,84,85,86,87,88,89,90,31],"wechat search","wechat","search","capabilities","openclaw","design","web search","compliance","web","official","fetch",{"skillNo":92,"name":93,"nameZh":6,"description":94,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":95,"categories":96,"keywords":97,"publishedAt":41},"01M71ATNAVGZB35PFYM2GC5N00","trend-tap","Real-time trending topics aggregator across 7 platforms (X\u002FTwitter, Reddit, Google Trends, Hacker News, Zhihu, Bilibili, Weibo). Trigger: when user says 'trend', 'trends', 'trend tap', '热点', '热搜', or asks what is trending\u002Fhot. Do NOT use web_search — this skill already fetches live data from all platforms with zero API keys.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftrend-tap\u002FSKILL.md",[],[98,99,100,101,102,103,82,104,105,106,107,108,109,110,111,112,113,114,115,116],"trend","trend tap","tap","api keys","Bash","time","trending","hacker","aggregator","do","when","brew","live","data","google","install","read","across","api",{"skillNo":118,"name":119,"nameZh":6,"description":120,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":121,"categories":122,"keywords":123,"publishedAt":41},"01M71ATJ9AM5KM15AA8PS302EB","trend-radar","Real-time trending topics aggregator across 7 platforms (X\u002FTwitter, Reddit, Google Trends, Hacker News, Zhihu, Bilibili, Weibo). Trigger: when user says 'trend', 'trends', 'trend pulse', '热点', '热搜', or asks what is trending\u002Fhot. Do NOT use web_search — this skill already fetches live data from all platforms with zero API keys.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftrend-radar\u002FSKILL.md",[],[124,125,98,109,110,111,112,102,82,114,126,115,116,108,106,105,104,113,103,101],"trend radar","radar","pulse",{"skillNo":128,"name":129,"nameZh":6,"description":130,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":131,"categories":132,"keywords":133,"publishedAt":41},"01M71ATGF095N3EJM9G8SD0BB5","tech-news-daily","每日科技新闻汇——从全球多个 RSS 源抓取最新科技新闻，翻译（英→中）、去重、排版成每日简报。当用户询问科技新闻、科技新鲜事、每日科技、技术动态、Daily Tech News 或类似表达时触发此技能。","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftech-news-daily\u002FSKILL.md",[],[134,135,136,137,138,139],"news","tech","tech news daily","daily","rss","翻译",{"skillNo":141,"name":142,"nameZh":6,"description":143,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":144,"categories":145,"keywords":149,"publishedAt":41},"01M71ATFAEAMQ17M70NQNY7SR8","summarize","Summarize URLs or files with the summarize CLI (web, PDFs, images, audio, YouTube).","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fsummarize\u002FSKILL.md",[146],{"categoryNo":147,"categoryName":148,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000021","资料检索与研究",[142,88,150,151,152,31,109,153,154,155,100,156,113],"Audio","cli","youtube","images","https","files","pdfs",{"skillNo":158,"name":159,"nameZh":6,"description":160,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":161,"categories":162,"keywords":163,"publishedAt":41},"01M71ATDNS3R0M4H936PACQAWZ","sonoscli","Control Sonos speakers (discover\u002Fstatus\u002Fplay\u002Fvolume\u002Fgroup).","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fsonoscli\u002FSKILL.md",[],[159,164,165,166,113,167,154,168,169,170,171,172],"status","play","go","latest","github","discover","control","cmd","volume"]