@codyswann/lisa 2.111.0 → 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.
- 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
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
# Toolbars and headers
|
|
2
|
+
|
|
3
|
+
Add native iOS toolbar items to Stack screens. Items can be placed in the header (left/right) or in a bottom toolbar area.
|
|
4
|
+
|
|
5
|
+
**Important:** iOS only. Available in Expo SDK 55+.
|
|
6
|
+
|
|
7
|
+
## Notes app example
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Stack } from "expo-router";
|
|
11
|
+
import { ScrollView } from "react-native";
|
|
12
|
+
|
|
13
|
+
export default function FoldersScreen() {
|
|
14
|
+
return (
|
|
15
|
+
<>
|
|
16
|
+
{/* ScrollView must be the first child of the screen */}
|
|
17
|
+
<ScrollView
|
|
18
|
+
style={{ flex: 1 }}
|
|
19
|
+
contentInsetAdjustmentBehavior="automatic"
|
|
20
|
+
>
|
|
21
|
+
{/* Screen content */}
|
|
22
|
+
</ScrollView>
|
|
23
|
+
<Stack.Screen.Title large>Folders</Stack.Screen.Title>
|
|
24
|
+
<Stack.SearchBar placeholder="Search" onChangeText={() => {}} />
|
|
25
|
+
{/* Header toolbar - right side */}
|
|
26
|
+
<Stack.Toolbar placement="right">
|
|
27
|
+
<Stack.Toolbar.Button icon="folder.badge.plus" onPress={() => {}} />
|
|
28
|
+
<Stack.Toolbar.Button onPress={() => {}}>Edit</Stack.Toolbar.Button>
|
|
29
|
+
</Stack.Toolbar>
|
|
30
|
+
|
|
31
|
+
{/* Bottom toolbar */}
|
|
32
|
+
<Stack.Toolbar placement="bottom">
|
|
33
|
+
<Stack.Toolbar.SearchBarSlot />
|
|
34
|
+
<Stack.Toolbar.Button
|
|
35
|
+
icon="square.and.pencil"
|
|
36
|
+
onPress={() => {}}
|
|
37
|
+
separateBackground
|
|
38
|
+
/>
|
|
39
|
+
</Stack.Toolbar>
|
|
40
|
+
</>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Mail inbox example
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
import { Color, Stack } from "expo-router";
|
|
49
|
+
import { useState } from "react";
|
|
50
|
+
import { ScrollView, Text, View } from "react-native";
|
|
51
|
+
|
|
52
|
+
export default function InboxScreen() {
|
|
53
|
+
const [isFilterOpen, setIsFilterOpen] = useState(false);
|
|
54
|
+
return (
|
|
55
|
+
<>
|
|
56
|
+
<ScrollView
|
|
57
|
+
style={{ flex: 1 }}
|
|
58
|
+
contentInsetAdjustmentBehavior="automatic"
|
|
59
|
+
contentContainerStyle={{ paddingHorizontal: 16 }}
|
|
60
|
+
>
|
|
61
|
+
{/* Screen content */}
|
|
62
|
+
</ScrollView>
|
|
63
|
+
<Stack.Screen options={{ headerTransparent: true }} />
|
|
64
|
+
<Stack.Screen.Title>Inbox</Stack.Screen.Title>
|
|
65
|
+
<Stack.SearchBar placeholder="Search" onChangeText={() => {}} />
|
|
66
|
+
{/* Header toolbar - right side */}
|
|
67
|
+
<Stack.Toolbar placement="right">
|
|
68
|
+
<Stack.Toolbar.Button onPress={() => {}}>Select</Stack.Toolbar.Button>
|
|
69
|
+
<Stack.Toolbar.Menu icon="ellipsis">
|
|
70
|
+
<Stack.Toolbar.Menu inline>
|
|
71
|
+
<Stack.Toolbar.Menu inline title="Sort By">
|
|
72
|
+
<Stack.Toolbar.MenuAction isOn>
|
|
73
|
+
Categories
|
|
74
|
+
</Stack.Toolbar.MenuAction>
|
|
75
|
+
<Stack.Toolbar.MenuAction>List</Stack.Toolbar.MenuAction>
|
|
76
|
+
</Stack.Toolbar.Menu>
|
|
77
|
+
<Stack.Toolbar.MenuAction icon="info.circle">
|
|
78
|
+
About categories
|
|
79
|
+
</Stack.Toolbar.MenuAction>
|
|
80
|
+
</Stack.Toolbar.Menu>
|
|
81
|
+
<Stack.Toolbar.MenuAction icon="person.circle">
|
|
82
|
+
Show Contact Photos
|
|
83
|
+
</Stack.Toolbar.MenuAction>
|
|
84
|
+
</Stack.Toolbar.Menu>
|
|
85
|
+
</Stack.Toolbar>
|
|
86
|
+
|
|
87
|
+
{/* Bottom toolbar */}
|
|
88
|
+
<Stack.Toolbar placement="bottom">
|
|
89
|
+
<Stack.Toolbar.Button
|
|
90
|
+
icon="line.3.horizontal.decrease"
|
|
91
|
+
selected={isFilterOpen}
|
|
92
|
+
onPress={() => setIsFilterOpen((prev) => !prev)}
|
|
93
|
+
/>
|
|
94
|
+
<Stack.Toolbar.View hidden={!isFilterOpen}>
|
|
95
|
+
<View style={{ width: 70, height: 32, justifyContent: "center" }}>
|
|
96
|
+
<Text style={{ fontSize: 12, fontWeight: "700" }}>Filter by</Text>
|
|
97
|
+
<Text
|
|
98
|
+
style={{
|
|
99
|
+
fontSize: 12,
|
|
100
|
+
fontWeight: "700",
|
|
101
|
+
color: Color.ios.systemBlue,
|
|
102
|
+
}}
|
|
103
|
+
>
|
|
104
|
+
Unread
|
|
105
|
+
</Text>
|
|
106
|
+
</View>
|
|
107
|
+
</Stack.Toolbar.View>
|
|
108
|
+
<Stack.Toolbar.Spacer />
|
|
109
|
+
<Stack.Toolbar.SearchBarSlot />
|
|
110
|
+
<Stack.Toolbar.Button
|
|
111
|
+
icon="square.and.pencil"
|
|
112
|
+
onPress={() => {}}
|
|
113
|
+
separateBackground
|
|
114
|
+
/>
|
|
115
|
+
</Stack.Toolbar>
|
|
116
|
+
</>
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Placement
|
|
122
|
+
|
|
123
|
+
- `"left"` - Header left
|
|
124
|
+
- `"right"` - Header right
|
|
125
|
+
- `"bottom"` (default) - Bottom toolbar
|
|
126
|
+
|
|
127
|
+
## Components
|
|
128
|
+
|
|
129
|
+
### Button
|
|
130
|
+
|
|
131
|
+
- Icon button: `<Stack.Toolbar.Button icon="star.fill" onPress={() => {}} />`
|
|
132
|
+
- Text button: `<Stack.Toolbar.Button onPress={() => {}}>Done</Stack.Toolbar.Button>`
|
|
133
|
+
|
|
134
|
+
**Props:** `icon`, `image`, `onPress`, `disabled`, `hidden`, `variant` (`"plain"` | `"done"` | `"prominent"`), `tintColor`
|
|
135
|
+
|
|
136
|
+
### Menu
|
|
137
|
+
|
|
138
|
+
Dropdown menu for grouping actions.
|
|
139
|
+
|
|
140
|
+
```tsx
|
|
141
|
+
<Stack.Toolbar.Menu icon="ellipsis">
|
|
142
|
+
<Stack.Toolbar.Menu inline>
|
|
143
|
+
<Stack.Toolbar.MenuAction>Sort by Recently Added</Stack.Toolbar.MenuAction>
|
|
144
|
+
<Stack.Toolbar.MenuAction isOn>
|
|
145
|
+
Sort by Date Captured
|
|
146
|
+
</Stack.Toolbar.MenuAction>
|
|
147
|
+
</Stack.Toolbar.Menu>
|
|
148
|
+
<Stack.Toolbar.Menu title="Filter">
|
|
149
|
+
<Stack.Toolbar.Menu inline>
|
|
150
|
+
<Stack.Toolbar.MenuAction isOn icon="square.grid.2x2">
|
|
151
|
+
All Items
|
|
152
|
+
</Stack.Toolbar.MenuAction>
|
|
153
|
+
</Stack.Toolbar.Menu>
|
|
154
|
+
<Stack.Toolbar.MenuAction icon="heart">Favorites</Stack.Toolbar.MenuAction>
|
|
155
|
+
<Stack.Toolbar.MenuAction icon="photo">Photos</Stack.Toolbar.MenuAction>
|
|
156
|
+
<Stack.Toolbar.MenuAction icon="video">Videos</Stack.Toolbar.MenuAction>
|
|
157
|
+
</Stack.Toolbar.Menu>
|
|
158
|
+
</Stack.Toolbar.Menu>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**Menu Props:** All Button props plus `title`, `inline`, `palette`, `elementSize` (`"small"` | `"medium"` | `"large"`)
|
|
162
|
+
|
|
163
|
+
**MenuAction Props:** `icon`, `onPress`, `isOn`, `destructive`, `disabled`, `subtitle`
|
|
164
|
+
|
|
165
|
+
When creating a palette with dividers, use `inline` combined with `elementSize="small"`. `palette` will not apply dividers on iOS 26.
|
|
166
|
+
|
|
167
|
+
### Spacer
|
|
168
|
+
|
|
169
|
+
```tsx
|
|
170
|
+
<Stack.Toolbar.Spacer /> // Bottom toolbar - flexible
|
|
171
|
+
<Stack.Toolbar.Spacer width={16} /> // Header - requires explicit width
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### View
|
|
175
|
+
|
|
176
|
+
Embed custom React Native components. When adding a custom view make sure that there is only a single child with **explicit width and height**.
|
|
177
|
+
|
|
178
|
+
```tsx
|
|
179
|
+
<Stack.Toolbar.View>
|
|
180
|
+
<View style={{ width: 70, height: 32, justifyContent: "center" }}>
|
|
181
|
+
<Text style={{ fontSize: 12, fontWeight: "700" }}>Filter by</Text>
|
|
182
|
+
</View>
|
|
183
|
+
</Stack.Toolbar.View>
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
You can pass custom components to views as well:
|
|
187
|
+
|
|
188
|
+
```tsx
|
|
189
|
+
function CustomFilterView() {
|
|
190
|
+
return (
|
|
191
|
+
<View style={{ width: 70, height: 32, justifyContent: "center" }}>
|
|
192
|
+
<Text style={{ fontSize: 12, fontWeight: "700" }}>Filter by</Text>
|
|
193
|
+
</View>
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
...
|
|
197
|
+
<Stack.Toolbar.View>
|
|
198
|
+
<CustomFilterView />
|
|
199
|
+
</Stack.Toolbar.View>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Recommendations
|
|
203
|
+
|
|
204
|
+
- When creating more complex headers, extract them to a single component
|
|
205
|
+
|
|
206
|
+
```tsx
|
|
207
|
+
export default function Page() {
|
|
208
|
+
return (
|
|
209
|
+
<>
|
|
210
|
+
<ScrollView>{/* Screen content */}</ScrollView>
|
|
211
|
+
<InboxHeader />
|
|
212
|
+
</>
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function InboxHeader() {
|
|
217
|
+
return (
|
|
218
|
+
<>
|
|
219
|
+
<Stack.Screen.Title>Inbox</Stack.Screen.Title>
|
|
220
|
+
<Stack.SearchBar placeholder="Search" onChangeText={() => {}} />
|
|
221
|
+
<Stack.Toolbar placement="right">{/* Toolbar buttons */}</Stack.Toolbar>
|
|
222
|
+
</>
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
- When using `Stack.Toolbar`, make sure that all `Stack.Toolbar.*` components are wrapped inside `Stack.Toolbar` component.
|
|
228
|
+
|
|
229
|
+
This will **not work**:
|
|
230
|
+
|
|
231
|
+
```tsx
|
|
232
|
+
function Buttons() {
|
|
233
|
+
return (
|
|
234
|
+
<>
|
|
235
|
+
<Stack.Toolbar.Button icon="star.fill" onPress={() => {}} />
|
|
236
|
+
<Stack.Toolbar.Button onPress={() => {}}>Done</Stack.Toolbar.Button>
|
|
237
|
+
</>
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function Page() {
|
|
242
|
+
return (
|
|
243
|
+
<>
|
|
244
|
+
<ScrollView>{/* Screen content */}</ScrollView>
|
|
245
|
+
<Stack.Toolbar placement="right">
|
|
246
|
+
<Buttons /> {/* ❌ This will NOT work */}
|
|
247
|
+
</Stack.Toolbar>
|
|
248
|
+
</>
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
This will work:
|
|
254
|
+
|
|
255
|
+
```tsx
|
|
256
|
+
function ToolbarWithButtons() {
|
|
257
|
+
return (
|
|
258
|
+
<Stack.Toolbar>
|
|
259
|
+
<Stack.Toolbar.Button icon="star.fill" onPress={() => {}} />
|
|
260
|
+
<Stack.Toolbar.Button onPress={() => {}}>Done</Stack.Toolbar.Button>
|
|
261
|
+
</Stack.Toolbar>
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function Page() {
|
|
266
|
+
return (
|
|
267
|
+
<>
|
|
268
|
+
<ScrollView>{/* Screen content */}</ScrollView>
|
|
269
|
+
<ToolbarWithButtons /> {/* ✅ This will work */}
|
|
270
|
+
</>
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## Limitations
|
|
276
|
+
|
|
277
|
+
- iOS only
|
|
278
|
+
- `placement="bottom"` can only be used inside screen components (not in layout files)
|
|
279
|
+
- `Stack.Toolbar.Badge` only works with `placement="left"` or `"right"`
|
|
280
|
+
- Header Spacers require explicit `width`
|
|
281
|
+
|
|
282
|
+
## Reference
|
|
283
|
+
|
|
284
|
+
Docs https://docs.expo.dev/versions/unversioned/sdk/router - read to see the full API.
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# Visual Effects
|
|
2
|
+
|
|
3
|
+
## Backdrop Blur
|
|
4
|
+
|
|
5
|
+
Use `expo-blur` for blur effects. Prefer systemMaterial tints as they adapt to dark mode.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { BlurView } from "expo-blur";
|
|
9
|
+
|
|
10
|
+
<BlurView tint="systemMaterial" intensity={100} />;
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Tint Options
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
// System materials (adapt to dark mode)
|
|
17
|
+
<BlurView tint="systemMaterial" />
|
|
18
|
+
<BlurView tint="systemThinMaterial" />
|
|
19
|
+
<BlurView tint="systemUltraThinMaterial" />
|
|
20
|
+
<BlurView tint="systemThickMaterial" />
|
|
21
|
+
<BlurView tint="systemChromeMaterial" />
|
|
22
|
+
|
|
23
|
+
// Basic tints
|
|
24
|
+
<BlurView tint="light" />
|
|
25
|
+
<BlurView tint="dark" />
|
|
26
|
+
<BlurView tint="default" />
|
|
27
|
+
|
|
28
|
+
// Prominent (more visible)
|
|
29
|
+
<BlurView tint="prominent" />
|
|
30
|
+
|
|
31
|
+
// Extra light/dark
|
|
32
|
+
<BlurView tint="extraLight" />
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Intensity
|
|
36
|
+
|
|
37
|
+
Control blur strength with `intensity` (0-100):
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
<BlurView tint="systemMaterial" intensity={50} /> // Subtle
|
|
41
|
+
<BlurView tint="systemMaterial" intensity={100} /> // Full
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Rounded Corners
|
|
45
|
+
|
|
46
|
+
BlurView requires `overflow: 'hidden'` to clip rounded corners:
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
<BlurView
|
|
50
|
+
tint="systemMaterial"
|
|
51
|
+
intensity={100}
|
|
52
|
+
style={{
|
|
53
|
+
borderRadius: 16,
|
|
54
|
+
overflow: 'hidden',
|
|
55
|
+
}}
|
|
56
|
+
/>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Overlay Pattern
|
|
60
|
+
|
|
61
|
+
Common pattern for overlaying blur on content:
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
<View style={{ position: 'relative' }}>
|
|
65
|
+
<Image source={{ uri: '...' }} style={{ width: '100%', height: 200 }} />
|
|
66
|
+
<BlurView
|
|
67
|
+
tint="systemUltraThinMaterial"
|
|
68
|
+
intensity={80}
|
|
69
|
+
style={{
|
|
70
|
+
position: 'absolute',
|
|
71
|
+
bottom: 0,
|
|
72
|
+
left: 0,
|
|
73
|
+
right: 0,
|
|
74
|
+
padding: 16,
|
|
75
|
+
}}
|
|
76
|
+
>
|
|
77
|
+
<Text style={{ color: 'white' }}>Caption</Text>
|
|
78
|
+
</BlurView>
|
|
79
|
+
</View>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Glass Effects (iOS 26+)
|
|
83
|
+
|
|
84
|
+
Use `expo-glass-effect` for liquid glass backdrops on iOS 26+.
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
import { GlassView } from "expo-glass-effect";
|
|
88
|
+
|
|
89
|
+
<GlassView style={{ borderRadius: 16, padding: 16 }}>
|
|
90
|
+
<Text>Content inside glass</Text>
|
|
91
|
+
</GlassView>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Interactive Glass
|
|
95
|
+
|
|
96
|
+
Add `isInteractive` for buttons and pressable glass:
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
import { GlassView } from "expo-glass-effect";
|
|
100
|
+
import { SymbolView } from "expo-symbols";
|
|
101
|
+
import { PlatformColor } from "react-native";
|
|
102
|
+
|
|
103
|
+
<GlassView isInteractive style={{ borderRadius: 50 }}>
|
|
104
|
+
<Pressable style={{ padding: 12 }} onPress={handlePress}>
|
|
105
|
+
<SymbolView name="plus" tintColor={PlatformColor("label")} size={36} />
|
|
106
|
+
</Pressable>
|
|
107
|
+
</GlassView>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Glass Buttons
|
|
111
|
+
|
|
112
|
+
Create liquid glass buttons:
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
function GlassButton({ icon, onPress }) {
|
|
116
|
+
return (
|
|
117
|
+
<GlassView isInteractive style={{ borderRadius: 50 }}>
|
|
118
|
+
<Pressable style={{ padding: 12 }} onPress={onPress}>
|
|
119
|
+
<SymbolView name={icon} tintColor={PlatformColor("label")} size={24} />
|
|
120
|
+
</Pressable>
|
|
121
|
+
</GlassView>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Usage
|
|
126
|
+
<GlassButton icon="plus" onPress={handleAdd} />
|
|
127
|
+
<GlassButton icon="gear" onPress={handleSettings} />
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Glass Card
|
|
131
|
+
|
|
132
|
+
```tsx
|
|
133
|
+
<GlassView style={{ borderRadius: 20, padding: 20 }}>
|
|
134
|
+
<Text style={{ fontSize: 18, fontWeight: '600', color: PlatformColor("label") }}>
|
|
135
|
+
Card Title
|
|
136
|
+
</Text>
|
|
137
|
+
<Text style={{ color: PlatformColor("secondaryLabel"), marginTop: 8 }}>
|
|
138
|
+
Card content goes here
|
|
139
|
+
</Text>
|
|
140
|
+
</GlassView>
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Checking Availability
|
|
144
|
+
|
|
145
|
+
```tsx
|
|
146
|
+
import { isLiquidGlassAvailable } from "expo-glass-effect";
|
|
147
|
+
|
|
148
|
+
if (isLiquidGlassAvailable()) {
|
|
149
|
+
// Use GlassView
|
|
150
|
+
} else {
|
|
151
|
+
// Fallback to BlurView or solid background
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Fallback Pattern
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
import { GlassView, isLiquidGlassAvailable } from "expo-glass-effect";
|
|
159
|
+
import { BlurView } from "expo-blur";
|
|
160
|
+
|
|
161
|
+
function AdaptiveGlass({ children, style }) {
|
|
162
|
+
if (isLiquidGlassAvailable()) {
|
|
163
|
+
return <GlassView style={style}>{children}</GlassView>;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return (
|
|
167
|
+
<BlurView tint="systemMaterial" intensity={80} style={style}>
|
|
168
|
+
{children}
|
|
169
|
+
</BlurView>
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Sheet with Glass Background
|
|
175
|
+
|
|
176
|
+
Make sheet backgrounds liquid glass on iOS 26+:
|
|
177
|
+
|
|
178
|
+
```tsx
|
|
179
|
+
<Stack.Screen
|
|
180
|
+
name="sheet"
|
|
181
|
+
options={{
|
|
182
|
+
presentation: "formSheet",
|
|
183
|
+
sheetGrabberVisible: true,
|
|
184
|
+
sheetAllowedDetents: [0.5, 1.0],
|
|
185
|
+
contentStyle: { backgroundColor: "transparent" },
|
|
186
|
+
}}
|
|
187
|
+
/>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Best Practices
|
|
191
|
+
|
|
192
|
+
- Use `systemMaterial` tints for automatic dark mode support
|
|
193
|
+
- Always set `overflow: 'hidden'` on BlurView for rounded corners
|
|
194
|
+
- Use `isInteractive` on GlassView for buttons and pressables
|
|
195
|
+
- Check `isLiquidGlassAvailable()` and provide fallbacks
|
|
196
|
+
- Avoid nesting blur views (performance impact)
|
|
197
|
+
- Keep blur intensity reasonable (50-100) for readability
|