@codyswann/lisa 2.111.0 → 2.113.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.
- package/cdk/package-lisa/package.lisa.json +1 -0
- package/dist/core/lisa.d.ts +42 -0
- package/dist/core/lisa.d.ts.map +1 -1
- package/dist/core/lisa.js +67 -0
- package/dist/core/lisa.js.map +1 -1
- package/expo/package-lisa/package.lisa.json +1 -0
- package/nestjs/package-lisa/package.lisa.json +1 -0
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.mcp.json +3 -3
- package/plugins/lisa-expo/THIRD-PARTY-NOTICES.md +57 -0
- package/plugins/lisa-expo/skills/add-app-clip/SKILL.md +280 -0
- package/plugins/lisa-expo/skills/add-app-clip/agents/openai.yaml +4 -0
- package/plugins/lisa-expo/skills/add-app-clip/references/native-module.md +96 -0
- package/plugins/lisa-expo/skills/building-native-ui/SKILL.md +321 -0
- package/plugins/lisa-expo/skills/building-native-ui/agents/openai.yaml +4 -0
- package/plugins/lisa-expo/skills/building-native-ui/references/animations.md +220 -0
- package/plugins/lisa-expo/skills/building-native-ui/references/controls.md +272 -0
- package/plugins/lisa-expo/skills/building-native-ui/references/form-sheet.md +253 -0
- package/plugins/lisa-expo/skills/building-native-ui/references/gradients.md +106 -0
- package/plugins/lisa-expo/skills/building-native-ui/references/icons.md +213 -0
- package/plugins/lisa-expo/skills/building-native-ui/references/media.md +198 -0
- package/plugins/lisa-expo/skills/building-native-ui/references/route-structure.md +229 -0
- package/plugins/lisa-expo/skills/building-native-ui/references/search.md +248 -0
- package/plugins/lisa-expo/skills/building-native-ui/references/storage.md +121 -0
- package/plugins/lisa-expo/skills/building-native-ui/references/tabs.md +433 -0
- package/plugins/lisa-expo/skills/building-native-ui/references/toolbar-and-headers.md +284 -0
- package/plugins/lisa-expo/skills/building-native-ui/references/visual-effects.md +197 -0
- package/plugins/lisa-expo/skills/building-native-ui/references/webgpu-three.md +605 -0
- package/plugins/lisa-expo/skills/building-native-ui/references/zoom-transitions.md +158 -0
- package/plugins/lisa-expo/skills/eas-update-insights/SKILL.md +228 -0
- package/plugins/lisa-expo/skills/eas-update-insights/agents/openai.yaml +4 -0
- package/plugins/lisa-expo/skills/eas-update-insights/references/channel-insights-schema.md +47 -0
- package/plugins/lisa-expo/skills/eas-update-insights/references/update-insights-schema.md +69 -0
- package/plugins/lisa-expo/skills/expo-api-routes/SKILL.md +369 -0
- package/plugins/lisa-expo/skills/expo-api-routes/agents/openai.yaml +4 -0
- package/plugins/lisa-expo/skills/expo-brownfield/SKILL.md +54 -0
- package/plugins/lisa-expo/skills/expo-brownfield/agents/openai.yaml +4 -0
- package/plugins/lisa-expo/skills/expo-brownfield/references/brownfield-integrated.md +526 -0
- package/plugins/lisa-expo/skills/expo-brownfield/references/brownfield-isolated.md +402 -0
- package/plugins/lisa-expo/skills/expo-brownfield/references/comparison.md +63 -0
- package/plugins/lisa-expo/skills/expo-brownfield/references/troubleshooting.md +88 -0
- package/plugins/lisa-expo/skills/expo-cicd-workflows/SKILL.md +92 -0
- package/plugins/lisa-expo/skills/expo-cicd-workflows/agents/openai.yaml +4 -0
- package/plugins/lisa-expo/skills/expo-cicd-workflows/scripts/fetch.js +113 -0
- package/plugins/lisa-expo/skills/expo-cicd-workflows/scripts/package.json +11 -0
- package/plugins/lisa-expo/skills/expo-cicd-workflows/scripts/validate.js +85 -0
- package/plugins/lisa-expo/skills/expo-deployment/SKILL.md +190 -0
- package/plugins/lisa-expo/skills/expo-deployment/agents/openai.yaml +4 -0
- package/plugins/lisa-expo/skills/expo-deployment/references/app-store-metadata.md +479 -0
- package/plugins/lisa-expo/skills/expo-deployment/references/ios-app-store.md +355 -0
- package/plugins/lisa-expo/skills/expo-deployment/references/play-store.md +246 -0
- package/plugins/lisa-expo/skills/expo-deployment/references/testflight.md +58 -0
- package/plugins/lisa-expo/skills/expo-deployment/references/workflows.md +200 -0
- package/plugins/lisa-expo/skills/expo-dev-client/SKILL.md +164 -0
- package/plugins/lisa-expo/skills/expo-dev-client/agents/openai.yaml +4 -0
- package/plugins/lisa-expo/skills/expo-module/SKILL.md +141 -0
- package/plugins/lisa-expo/skills/expo-module/agents/openai.yaml +4 -0
- package/plugins/lisa-expo/skills/expo-module/references/config-plugin.md +90 -0
- package/plugins/lisa-expo/skills/expo-module/references/create-expo-module.md +206 -0
- package/plugins/lisa-expo/skills/expo-module/references/lifecycle.md +127 -0
- package/plugins/lisa-expo/skills/expo-module/references/module-config.md +48 -0
- package/plugins/lisa-expo/skills/expo-module/references/native-module.md +286 -0
- package/plugins/lisa-expo/skills/expo-module/references/native-view.md +171 -0
- package/plugins/lisa-expo/skills/expo-tailwind-setup/SKILL.md +480 -0
- package/plugins/lisa-expo/skills/expo-tailwind-setup/agents/openai.yaml +4 -0
- package/plugins/lisa-expo/skills/expo-ui-jetpack-compose/SKILL.md +40 -0
- package/plugins/lisa-expo/skills/expo-ui-jetpack-compose/agents/openai.yaml +4 -0
- package/plugins/lisa-expo/skills/expo-ui-swift-ui/SKILL.md +39 -0
- package/plugins/lisa-expo/skills/expo-ui-swift-ui/agents/openai.yaml +4 -0
- package/plugins/lisa-expo/skills/native-data-fetching/SKILL.md +507 -0
- package/plugins/lisa-expo/skills/native-data-fetching/agents/openai.yaml +4 -0
- package/plugins/lisa-expo/skills/native-data-fetching/references/expo-router-loaders.md +344 -0
- package/plugins/lisa-expo/skills/upgrading-expo/SKILL.md +134 -0
- package/plugins/lisa-expo/skills/upgrading-expo/agents/openai.yaml +4 -0
- package/plugins/lisa-expo/skills/upgrading-expo/references/expo-av-to-audio.md +132 -0
- package/plugins/lisa-expo/skills/upgrading-expo/references/expo-av-to-video.md +160 -0
- package/plugins/lisa-expo/skills/upgrading-expo/references/native-tabs.md +124 -0
- package/plugins/lisa-expo/skills/upgrading-expo/references/new-architecture.md +79 -0
- package/plugins/lisa-expo/skills/upgrading-expo/references/react-19.md +79 -0
- package/plugins/lisa-expo/skills/upgrading-expo/references/react-compiler.md +59 -0
- package/plugins/lisa-expo/skills/upgrading-expo/references/react-navigation-to-expo-router.md +61 -0
- package/plugins/lisa-expo/skills/use-dom/SKILL.md +417 -0
- package/plugins/lisa-expo/skills/use-dom/agents/openai.yaml +4 -0
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/src/expo/.mcp.json +3 -3
- package/plugins/src/expo/THIRD-PARTY-NOTICES.md +57 -0
- package/plugins/src/expo/skills/add-app-clip/SKILL.md +280 -0
- package/plugins/src/expo/skills/add-app-clip/references/native-module.md +96 -0
- package/plugins/src/expo/skills/building-native-ui/SKILL.md +321 -0
- package/plugins/src/expo/skills/building-native-ui/references/animations.md +220 -0
- package/plugins/src/expo/skills/building-native-ui/references/controls.md +272 -0
- package/plugins/src/expo/skills/building-native-ui/references/form-sheet.md +253 -0
- package/plugins/src/expo/skills/building-native-ui/references/gradients.md +106 -0
- package/plugins/src/expo/skills/building-native-ui/references/icons.md +213 -0
- package/plugins/src/expo/skills/building-native-ui/references/media.md +198 -0
- package/plugins/src/expo/skills/building-native-ui/references/route-structure.md +229 -0
- package/plugins/src/expo/skills/building-native-ui/references/search.md +248 -0
- package/plugins/src/expo/skills/building-native-ui/references/storage.md +121 -0
- package/plugins/src/expo/skills/building-native-ui/references/tabs.md +433 -0
- package/plugins/src/expo/skills/building-native-ui/references/toolbar-and-headers.md +284 -0
- package/plugins/src/expo/skills/building-native-ui/references/visual-effects.md +197 -0
- package/plugins/src/expo/skills/building-native-ui/references/webgpu-three.md +605 -0
- package/plugins/src/expo/skills/building-native-ui/references/zoom-transitions.md +158 -0
- package/plugins/src/expo/skills/eas-update-insights/SKILL.md +228 -0
- package/plugins/src/expo/skills/eas-update-insights/references/channel-insights-schema.md +47 -0
- package/plugins/src/expo/skills/eas-update-insights/references/update-insights-schema.md +69 -0
- package/plugins/src/expo/skills/expo-api-routes/SKILL.md +369 -0
- package/plugins/src/expo/skills/expo-brownfield/SKILL.md +54 -0
- package/plugins/src/expo/skills/expo-brownfield/references/brownfield-integrated.md +526 -0
- package/plugins/src/expo/skills/expo-brownfield/references/brownfield-isolated.md +402 -0
- package/plugins/src/expo/skills/expo-brownfield/references/comparison.md +63 -0
- package/plugins/src/expo/skills/expo-brownfield/references/troubleshooting.md +88 -0
- package/plugins/src/expo/skills/expo-cicd-workflows/SKILL.md +92 -0
- package/plugins/src/expo/skills/expo-cicd-workflows/scripts/fetch.js +113 -0
- package/plugins/src/expo/skills/expo-cicd-workflows/scripts/package.json +11 -0
- package/plugins/src/expo/skills/expo-cicd-workflows/scripts/validate.js +85 -0
- package/plugins/src/expo/skills/expo-deployment/SKILL.md +190 -0
- package/plugins/src/expo/skills/expo-deployment/references/app-store-metadata.md +479 -0
- package/plugins/src/expo/skills/expo-deployment/references/ios-app-store.md +355 -0
- package/plugins/src/expo/skills/expo-deployment/references/play-store.md +246 -0
- package/plugins/src/expo/skills/expo-deployment/references/testflight.md +58 -0
- package/plugins/src/expo/skills/expo-deployment/references/workflows.md +200 -0
- package/plugins/src/expo/skills/expo-dev-client/SKILL.md +164 -0
- package/plugins/src/expo/skills/expo-module/SKILL.md +141 -0
- package/plugins/src/expo/skills/expo-module/references/config-plugin.md +90 -0
- package/plugins/src/expo/skills/expo-module/references/create-expo-module.md +206 -0
- package/plugins/src/expo/skills/expo-module/references/lifecycle.md +127 -0
- package/plugins/src/expo/skills/expo-module/references/module-config.md +48 -0
- package/plugins/src/expo/skills/expo-module/references/native-module.md +286 -0
- package/plugins/src/expo/skills/expo-module/references/native-view.md +171 -0
- package/plugins/src/expo/skills/expo-tailwind-setup/SKILL.md +480 -0
- package/plugins/src/expo/skills/expo-ui-jetpack-compose/SKILL.md +40 -0
- package/plugins/src/expo/skills/expo-ui-swift-ui/SKILL.md +39 -0
- package/plugins/src/expo/skills/native-data-fetching/SKILL.md +507 -0
- package/plugins/src/expo/skills/native-data-fetching/references/expo-router-loaders.md +344 -0
- package/plugins/src/expo/skills/upgrading-expo/SKILL.md +134 -0
- package/plugins/src/expo/skills/upgrading-expo/references/expo-av-to-audio.md +132 -0
- package/plugins/src/expo/skills/upgrading-expo/references/expo-av-to-video.md +160 -0
- package/plugins/src/expo/skills/upgrading-expo/references/native-tabs.md +124 -0
- package/plugins/src/expo/skills/upgrading-expo/references/new-architecture.md +79 -0
- package/plugins/src/expo/skills/upgrading-expo/references/react-19.md +79 -0
- package/plugins/src/expo/skills/upgrading-expo/references/react-compiler.md +59 -0
- package/plugins/src/expo/skills/upgrading-expo/references/react-navigation-to-expo-router.md +61 -0
- package/plugins/src/expo/skills/use-dom/SKILL.md +417 -0
- package/scripts/generate-codex-plugin-artifacts.mjs +7 -2
- package/scripts/install-claude-plugins.sh +23 -7
- package/typescript/package-lisa/package.lisa.json +2 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# Form Sheets in Expo Router
|
|
2
|
+
|
|
3
|
+
This skill covers implementing form sheets with footers using Expo Router's Stack navigator and react-native-screens.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Form sheets are modal presentations that appear as a card sliding up from the bottom of the screen. They're ideal for:
|
|
8
|
+
|
|
9
|
+
- Quick actions and confirmations
|
|
10
|
+
- Settings panels
|
|
11
|
+
- Login/signup flows
|
|
12
|
+
- Action sheets with custom content
|
|
13
|
+
|
|
14
|
+
**Requirements:**
|
|
15
|
+
|
|
16
|
+
- Expo Router Stack navigator
|
|
17
|
+
|
|
18
|
+
## Basic Usage
|
|
19
|
+
|
|
20
|
+
### Form Sheet with Footer
|
|
21
|
+
|
|
22
|
+
Configure the Stack.Screen with transparent backgrounds and sheet presentation:
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
// app/_layout.tsx
|
|
26
|
+
import { Stack } from "expo-router";
|
|
27
|
+
|
|
28
|
+
export default function Layout() {
|
|
29
|
+
return (
|
|
30
|
+
<Stack>
|
|
31
|
+
<Stack.Screen name="index" />
|
|
32
|
+
<Stack.Screen
|
|
33
|
+
name="about"
|
|
34
|
+
options={{
|
|
35
|
+
presentation: "formSheet",
|
|
36
|
+
sheetAllowedDetents: [0.25],
|
|
37
|
+
headerTransparent: true,
|
|
38
|
+
contentStyle: { backgroundColor: "transparent" },
|
|
39
|
+
sheetGrabberVisible: true,
|
|
40
|
+
}}
|
|
41
|
+
>
|
|
42
|
+
<Stack.Header style={{ backgroundColor: "transparent" }}></Stack.Header>
|
|
43
|
+
</Stack.Screen>
|
|
44
|
+
</Stack>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Form Sheet Screen Content
|
|
50
|
+
|
|
51
|
+
> Requires Expo SDK 55 or later.
|
|
52
|
+
|
|
53
|
+
Use `flex: 1` to allow the content to fill available space, enabling footer positioning:
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
// app/about.tsx
|
|
57
|
+
import { View, Text, StyleSheet } from "react-native";
|
|
58
|
+
|
|
59
|
+
export default function AboutSheet() {
|
|
60
|
+
return (
|
|
61
|
+
<View style={styles.container}>
|
|
62
|
+
{/* Main content */}
|
|
63
|
+
<View style={styles.content}>
|
|
64
|
+
<Text>Sheet Content</Text>
|
|
65
|
+
</View>
|
|
66
|
+
|
|
67
|
+
{/* Footer - stays at bottom */}
|
|
68
|
+
<View style={styles.footer}>
|
|
69
|
+
<Text>Footer Content</Text>
|
|
70
|
+
</View>
|
|
71
|
+
</View>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const styles = StyleSheet.create({
|
|
76
|
+
container: {
|
|
77
|
+
flex: 1,
|
|
78
|
+
},
|
|
79
|
+
content: {
|
|
80
|
+
flex: 1,
|
|
81
|
+
padding: 16,
|
|
82
|
+
},
|
|
83
|
+
footer: {
|
|
84
|
+
padding: 16,
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Formsheet with interactive content below
|
|
90
|
+
|
|
91
|
+
Use `sheetLargestUndimmedDetentIndex` (zero-indexed) to keep content behind the form sheet interactive — e.g. letting users pan a map beneath it. Setting it to `1` allows interaction at the first two detents but dims on the third.
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
// app/_layout.tsx
|
|
95
|
+
import { Stack } from 'expo-router';
|
|
96
|
+
|
|
97
|
+
export default function Layout() {
|
|
98
|
+
return (
|
|
99
|
+
<Stack screenOptions={{ headerShown: false }}>
|
|
100
|
+
<Stack.Screen name="index" />
|
|
101
|
+
<Stack.Screen
|
|
102
|
+
name="info-sheet"
|
|
103
|
+
options={{
|
|
104
|
+
presentation: "formSheet",
|
|
105
|
+
sheetAllowedDetents: [0.2, 0.5, 1.0],
|
|
106
|
+
sheetLargestUndimmedDetentIndex: 1,
|
|
107
|
+
/* other options */
|
|
108
|
+
}}
|
|
109
|
+
/>
|
|
110
|
+
</Stack>
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Key Options
|
|
116
|
+
|
|
117
|
+
| Option | Type | Description |
|
|
118
|
+
| --------------------- | ---------- | ----------------------------------------------------------- |
|
|
119
|
+
| `presentation` | `string` | Set to `'formSheet'` for sheet presentation |
|
|
120
|
+
| `sheetGrabberVisible` | `boolean` | Shows the drag handle at the top of the sheet |
|
|
121
|
+
| `sheetAllowedDetents` | `number[]` | Array of detent heights (0-1 range, e.g., `[0.25]` for 25%) |
|
|
122
|
+
| `headerTransparent` | `boolean` | Makes header background transparent |
|
|
123
|
+
| `contentStyle` | `object` | Style object for the screen content container |
|
|
124
|
+
| `title` | `string` | Screen title (set to `''` for no title) |
|
|
125
|
+
|
|
126
|
+
## Common Detent Values
|
|
127
|
+
|
|
128
|
+
- `[0.25]` - Quarter sheet (compact actions)
|
|
129
|
+
- `[0.5]` - Half sheet (medium content)
|
|
130
|
+
- `[0.75]` - Three-quarter sheet (detailed forms)
|
|
131
|
+
- `[0.25, 0.5, 1]` - Multiple stops (expandable sheet)
|
|
132
|
+
|
|
133
|
+
## Complete Example
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
// _layout.tsx
|
|
137
|
+
import { Stack } from "expo-router";
|
|
138
|
+
|
|
139
|
+
export default function Layout() {
|
|
140
|
+
return (
|
|
141
|
+
<Stack>
|
|
142
|
+
<Stack.Screen name="index" options={{ title: "Home" }} />
|
|
143
|
+
<Stack.Screen
|
|
144
|
+
name="confirm"
|
|
145
|
+
options={{
|
|
146
|
+
contentStyle: { backgroundColor: "transparent" },
|
|
147
|
+
presentation: "formSheet",
|
|
148
|
+
title: "",
|
|
149
|
+
sheetGrabberVisible: true,
|
|
150
|
+
sheetAllowedDetents: [0.25],
|
|
151
|
+
headerTransparent: true,
|
|
152
|
+
}}
|
|
153
|
+
>
|
|
154
|
+
<Stack.Header style={{ backgroundColor: "transparent" }}>
|
|
155
|
+
<Stack.Header.Right />
|
|
156
|
+
</Stack.Header>
|
|
157
|
+
</Stack.Screen>
|
|
158
|
+
</Stack>
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
```tsx
|
|
164
|
+
// app/confirm.tsx
|
|
165
|
+
import { View, Text, Pressable, StyleSheet } from "react-native";
|
|
166
|
+
import { router } from "expo-router";
|
|
167
|
+
|
|
168
|
+
export default function ConfirmSheet() {
|
|
169
|
+
return (
|
|
170
|
+
<View style={styles.container}>
|
|
171
|
+
<View style={styles.content}>
|
|
172
|
+
<Text style={styles.title}>Confirm Action</Text>
|
|
173
|
+
<Text style={styles.description}>
|
|
174
|
+
Are you sure you want to proceed?
|
|
175
|
+
</Text>
|
|
176
|
+
</View>
|
|
177
|
+
|
|
178
|
+
<View style={styles.footer}>
|
|
179
|
+
<Pressable style={styles.cancelButton} onPress={() => router.back()}>
|
|
180
|
+
<Text style={styles.cancelText}>Cancel</Text>
|
|
181
|
+
</Pressable>
|
|
182
|
+
<Pressable style={styles.confirmButton} onPress={() => router.back()}>
|
|
183
|
+
<Text style={styles.confirmText}>Confirm</Text>
|
|
184
|
+
</Pressable>
|
|
185
|
+
</View>
|
|
186
|
+
</View>
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const styles = StyleSheet.create({
|
|
191
|
+
container: {
|
|
192
|
+
flex: 1,
|
|
193
|
+
},
|
|
194
|
+
content: {
|
|
195
|
+
flex: 1,
|
|
196
|
+
padding: 20,
|
|
197
|
+
alignItems: "center",
|
|
198
|
+
justifyContent: "center",
|
|
199
|
+
},
|
|
200
|
+
title: {
|
|
201
|
+
fontSize: 18,
|
|
202
|
+
fontWeight: "600",
|
|
203
|
+
marginBottom: 8,
|
|
204
|
+
},
|
|
205
|
+
description: {
|
|
206
|
+
fontSize: 14,
|
|
207
|
+
color: "#666",
|
|
208
|
+
textAlign: "center",
|
|
209
|
+
},
|
|
210
|
+
footer: {
|
|
211
|
+
flexDirection: "row",
|
|
212
|
+
padding: 16,
|
|
213
|
+
gap: 12,
|
|
214
|
+
},
|
|
215
|
+
cancelButton: {
|
|
216
|
+
flex: 1,
|
|
217
|
+
padding: 14,
|
|
218
|
+
borderRadius: 10,
|
|
219
|
+
backgroundColor: "#f0f0f0",
|
|
220
|
+
alignItems: "center",
|
|
221
|
+
},
|
|
222
|
+
cancelText: {
|
|
223
|
+
fontSize: 16,
|
|
224
|
+
fontWeight: "500",
|
|
225
|
+
},
|
|
226
|
+
confirmButton: {
|
|
227
|
+
flex: 1,
|
|
228
|
+
padding: 14,
|
|
229
|
+
borderRadius: 10,
|
|
230
|
+
backgroundColor: "#007AFF",
|
|
231
|
+
alignItems: "center",
|
|
232
|
+
},
|
|
233
|
+
confirmText: {
|
|
234
|
+
fontSize: 16,
|
|
235
|
+
fontWeight: "500",
|
|
236
|
+
color: "white",
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Troubleshooting
|
|
242
|
+
|
|
243
|
+
### Content not filling sheet
|
|
244
|
+
|
|
245
|
+
Make sure the root View uses `flex: 1`:
|
|
246
|
+
|
|
247
|
+
```tsx
|
|
248
|
+
<View style={{ flex: 1 }}>{/* content */}</View>
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Sheet background showing through
|
|
252
|
+
|
|
253
|
+
Set `contentStyle: { backgroundColor: 'transparent' }` in options and style your content container with the desired background color instead.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# CSS Gradients
|
|
2
|
+
|
|
3
|
+
> **New Architecture Only**: CSS gradients require React Native's New Architecture (Fabric). They are not available in the old architecture or Expo Go.
|
|
4
|
+
|
|
5
|
+
Use CSS gradients with the `experimental_backgroundImage` style property.
|
|
6
|
+
|
|
7
|
+
## Linear Gradients
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
// Top to bottom
|
|
11
|
+
<View style={{
|
|
12
|
+
experimental_backgroundImage: 'linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 100%)'
|
|
13
|
+
}} />
|
|
14
|
+
|
|
15
|
+
// Left to right
|
|
16
|
+
<View style={{
|
|
17
|
+
experimental_backgroundImage: 'linear-gradient(to right, #ff0000 0%, #0000ff 100%)'
|
|
18
|
+
}} />
|
|
19
|
+
|
|
20
|
+
// Diagonal
|
|
21
|
+
<View style={{
|
|
22
|
+
experimental_backgroundImage: 'linear-gradient(45deg, #ff0000 0%, #00ff00 50%, #0000ff 100%)'
|
|
23
|
+
}} />
|
|
24
|
+
|
|
25
|
+
// Using degrees
|
|
26
|
+
<View style={{
|
|
27
|
+
experimental_backgroundImage: 'linear-gradient(135deg, transparent 0%, black 100%)'
|
|
28
|
+
}} />
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Radial Gradients
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
// Circle at center
|
|
35
|
+
<View style={{
|
|
36
|
+
experimental_backgroundImage: 'radial-gradient(circle at center, rgba(255, 0, 0, 1) 0%, rgba(0, 0, 255, 1) 100%)'
|
|
37
|
+
}} />
|
|
38
|
+
|
|
39
|
+
// Ellipse
|
|
40
|
+
<View style={{
|
|
41
|
+
experimental_backgroundImage: 'radial-gradient(ellipse at center, #fff 0%, #000 100%)'
|
|
42
|
+
}} />
|
|
43
|
+
|
|
44
|
+
// Positioned
|
|
45
|
+
<View style={{
|
|
46
|
+
experimental_backgroundImage: 'radial-gradient(circle at top left, #ff0000 0%, transparent 70%)'
|
|
47
|
+
}} />
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Multiple Gradients
|
|
51
|
+
|
|
52
|
+
Stack multiple gradients by comma-separating them:
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
<View style={{
|
|
56
|
+
experimental_backgroundImage: `
|
|
57
|
+
linear-gradient(to bottom, transparent 0%, black 100%),
|
|
58
|
+
radial-gradient(circle at top right, rgba(255, 0, 0, 0.5) 0%, transparent 50%)
|
|
59
|
+
`
|
|
60
|
+
}} />
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Common Patterns
|
|
64
|
+
|
|
65
|
+
### Overlay on Image
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
<View style={{ position: 'relative' }}>
|
|
69
|
+
<Image source={{ uri: '...' }} style={{ width: '100%', height: 200 }} />
|
|
70
|
+
<View style={{
|
|
71
|
+
position: 'absolute',
|
|
72
|
+
inset: 0,
|
|
73
|
+
experimental_backgroundImage: 'linear-gradient(to top, rgba(0, 0, 0, 0.8) 0%, transparent 50%)'
|
|
74
|
+
}} />
|
|
75
|
+
</View>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Frosted Glass Effect
|
|
79
|
+
|
|
80
|
+
```tsx
|
|
81
|
+
<View style={{
|
|
82
|
+
experimental_backgroundImage: 'linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 100%)',
|
|
83
|
+
backdropFilter: 'blur(10px)',
|
|
84
|
+
}} />
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Button Gradient
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
<Pressable style={{
|
|
91
|
+
experimental_backgroundImage: 'linear-gradient(to bottom, #4CAF50 0%, #388E3C 100%)',
|
|
92
|
+
padding: 16,
|
|
93
|
+
borderRadius: 8,
|
|
94
|
+
}}>
|
|
95
|
+
<Text style={{ color: 'white', textAlign: 'center' }}>Submit</Text>
|
|
96
|
+
</Pressable>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Important Notes
|
|
100
|
+
|
|
101
|
+
- Do NOT use `expo-linear-gradient` — use CSS gradients instead
|
|
102
|
+
- Gradients are strings, not objects
|
|
103
|
+
- Use `rgba()` for transparency, or `transparent` keyword
|
|
104
|
+
- Color stops use percentages (0%, 50%, 100%)
|
|
105
|
+
- Direction keywords: `to top`, `to bottom`, `to left`, `to right`, `to top left`, etc.
|
|
106
|
+
- Degree values: `45deg`, `90deg`, `135deg`, etc.
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# Icons (SF Symbols)
|
|
2
|
+
|
|
3
|
+
Use SF Symbols for native feel. Never use FontAwesome or Ionicons.
|
|
4
|
+
|
|
5
|
+
## Basic Usage
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { SymbolView } from "expo-symbols";
|
|
9
|
+
import { PlatformColor } from "react-native";
|
|
10
|
+
|
|
11
|
+
<SymbolView
|
|
12
|
+
tintColor={PlatformColor("label")}
|
|
13
|
+
resizeMode="scaleAspectFit"
|
|
14
|
+
name="square.and.arrow.down"
|
|
15
|
+
style={{ width: 16, height: 16 }}
|
|
16
|
+
/>;
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Props
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
<SymbolView
|
|
23
|
+
name="star.fill" // SF Symbol name (required)
|
|
24
|
+
tintColor={PlatformColor("label")} // Icon color
|
|
25
|
+
size={24} // Shorthand for width/height
|
|
26
|
+
resizeMode="scaleAspectFit" // How to scale
|
|
27
|
+
weight="regular" // thin | ultraLight | light | regular | medium | semibold | bold | heavy | black
|
|
28
|
+
scale="medium" // small | medium | large
|
|
29
|
+
style={{ width: 16, height: 16 }} // Standard style props
|
|
30
|
+
/>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Common Icons
|
|
34
|
+
|
|
35
|
+
### Navigation & Actions
|
|
36
|
+
- `house.fill` - home
|
|
37
|
+
- `gear` - settings
|
|
38
|
+
- `magnifyingglass` - search
|
|
39
|
+
- `plus` - add
|
|
40
|
+
- `xmark` - close
|
|
41
|
+
- `chevron.left` - back
|
|
42
|
+
- `chevron.right` - forward
|
|
43
|
+
- `arrow.left` - back arrow
|
|
44
|
+
- `arrow.right` - forward arrow
|
|
45
|
+
|
|
46
|
+
### Media
|
|
47
|
+
- `play.fill` - play
|
|
48
|
+
- `pause.fill` - pause
|
|
49
|
+
- `stop.fill` - stop
|
|
50
|
+
- `backward.fill` - rewind
|
|
51
|
+
- `forward.fill` - fast forward
|
|
52
|
+
- `speaker.wave.2.fill` - volume
|
|
53
|
+
- `speaker.slash.fill` - mute
|
|
54
|
+
|
|
55
|
+
### Camera
|
|
56
|
+
- `camera` - camera
|
|
57
|
+
- `camera.fill` - camera filled
|
|
58
|
+
- `arrow.triangle.2.circlepath` - flip camera
|
|
59
|
+
- `photo` - gallery/photos
|
|
60
|
+
- `bolt` - flash
|
|
61
|
+
- `bolt.slash` - flash off
|
|
62
|
+
|
|
63
|
+
### Communication
|
|
64
|
+
- `message` - message
|
|
65
|
+
- `message.fill` - message filled
|
|
66
|
+
- `envelope` - email
|
|
67
|
+
- `envelope.fill` - email filled
|
|
68
|
+
- `phone` - phone
|
|
69
|
+
- `phone.fill` - phone filled
|
|
70
|
+
- `video` - video call
|
|
71
|
+
- `video.fill` - video call filled
|
|
72
|
+
|
|
73
|
+
### Social
|
|
74
|
+
- `heart` - like
|
|
75
|
+
- `heart.fill` - liked
|
|
76
|
+
- `star` - favorite
|
|
77
|
+
- `star.fill` - favorited
|
|
78
|
+
- `hand.thumbsup` - thumbs up
|
|
79
|
+
- `hand.thumbsdown` - thumbs down
|
|
80
|
+
- `person` - profile
|
|
81
|
+
- `person.fill` - profile filled
|
|
82
|
+
- `person.2` - people
|
|
83
|
+
- `person.2.fill` - people filled
|
|
84
|
+
|
|
85
|
+
### Content Actions
|
|
86
|
+
- `square.and.arrow.up` - share
|
|
87
|
+
- `square.and.arrow.down` - download
|
|
88
|
+
- `doc.on.doc` - copy
|
|
89
|
+
- `trash` - delete
|
|
90
|
+
- `pencil` - edit
|
|
91
|
+
- `folder` - folder
|
|
92
|
+
- `folder.fill` - folder filled
|
|
93
|
+
- `bookmark` - bookmark
|
|
94
|
+
- `bookmark.fill` - bookmarked
|
|
95
|
+
|
|
96
|
+
### Status & Feedback
|
|
97
|
+
- `checkmark` - success/done
|
|
98
|
+
- `checkmark.circle.fill` - completed
|
|
99
|
+
- `xmark.circle.fill` - error/failed
|
|
100
|
+
- `exclamationmark.triangle` - warning
|
|
101
|
+
- `info.circle` - info
|
|
102
|
+
- `questionmark.circle` - help
|
|
103
|
+
- `bell` - notification
|
|
104
|
+
- `bell.fill` - notification filled
|
|
105
|
+
|
|
106
|
+
### Misc
|
|
107
|
+
- `ellipsis` - more options
|
|
108
|
+
- `ellipsis.circle` - more in circle
|
|
109
|
+
- `line.3.horizontal` - menu/hamburger
|
|
110
|
+
- `slider.horizontal.3` - filters
|
|
111
|
+
- `arrow.clockwise` - refresh
|
|
112
|
+
- `location` - location
|
|
113
|
+
- `location.fill` - location filled
|
|
114
|
+
- `map` - map
|
|
115
|
+
- `mappin` - pin
|
|
116
|
+
- `clock` - time
|
|
117
|
+
- `calendar` - calendar
|
|
118
|
+
- `link` - link
|
|
119
|
+
- `nosign` - block/prohibited
|
|
120
|
+
|
|
121
|
+
## Animated Symbols
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
<SymbolView
|
|
125
|
+
name="checkmark.circle"
|
|
126
|
+
animationSpec={{
|
|
127
|
+
effect: {
|
|
128
|
+
type: "bounce",
|
|
129
|
+
direction: "up",
|
|
130
|
+
},
|
|
131
|
+
}}
|
|
132
|
+
/>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Animation Effects
|
|
136
|
+
|
|
137
|
+
- `bounce` - Bouncy animation
|
|
138
|
+
- `pulse` - Pulsing effect
|
|
139
|
+
- `variableColor` - Color cycling
|
|
140
|
+
- `scale` - Scale animation
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
// Bounce with direction
|
|
144
|
+
animationSpec={{
|
|
145
|
+
effect: { type: "bounce", direction: "up" } // up | down
|
|
146
|
+
}}
|
|
147
|
+
|
|
148
|
+
// Pulse
|
|
149
|
+
animationSpec={{
|
|
150
|
+
effect: { type: "pulse" }
|
|
151
|
+
}}
|
|
152
|
+
|
|
153
|
+
// Variable color (multicolor symbols)
|
|
154
|
+
animationSpec={{
|
|
155
|
+
effect: {
|
|
156
|
+
type: "variableColor",
|
|
157
|
+
cumulative: true,
|
|
158
|
+
reversing: true
|
|
159
|
+
}
|
|
160
|
+
}}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Symbol Weights
|
|
164
|
+
|
|
165
|
+
```tsx
|
|
166
|
+
// Lighter weights
|
|
167
|
+
<SymbolView name="star" weight="ultraLight" />
|
|
168
|
+
<SymbolView name="star" weight="thin" />
|
|
169
|
+
<SymbolView name="star" weight="light" />
|
|
170
|
+
|
|
171
|
+
// Default
|
|
172
|
+
<SymbolView name="star" weight="regular" />
|
|
173
|
+
|
|
174
|
+
// Heavier weights
|
|
175
|
+
<SymbolView name="star" weight="medium" />
|
|
176
|
+
<SymbolView name="star" weight="semibold" />
|
|
177
|
+
<SymbolView name="star" weight="bold" />
|
|
178
|
+
<SymbolView name="star" weight="heavy" />
|
|
179
|
+
<SymbolView name="star" weight="black" />
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Symbol Scales
|
|
183
|
+
|
|
184
|
+
```tsx
|
|
185
|
+
<SymbolView name="star" scale="small" />
|
|
186
|
+
<SymbolView name="star" scale="medium" /> // default
|
|
187
|
+
<SymbolView name="star" scale="large" />
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Multicolor Symbols
|
|
191
|
+
|
|
192
|
+
Some symbols support multiple colors:
|
|
193
|
+
|
|
194
|
+
```tsx
|
|
195
|
+
<SymbolView
|
|
196
|
+
name="cloud.sun.rain.fill"
|
|
197
|
+
type="multicolor"
|
|
198
|
+
/>
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Finding Symbol Names
|
|
202
|
+
|
|
203
|
+
1. Use the SF Symbols app on macOS (free from Apple)
|
|
204
|
+
2. Search at https://developer.apple.com/sf-symbols/
|
|
205
|
+
3. Symbol names use dot notation: `square.and.arrow.up`
|
|
206
|
+
|
|
207
|
+
## Best Practices
|
|
208
|
+
|
|
209
|
+
- Always use SF Symbols over vector icon libraries
|
|
210
|
+
- Match symbol weight to nearby text weight
|
|
211
|
+
- Use `.fill` variants for selected/active states
|
|
212
|
+
- Use PlatformColor for tint to support dark mode
|
|
213
|
+
- Keep icons at consistent sizes (16, 20, 24, 32)
|