@mr.dj2u/cli 0.1.5 → 0.1.8
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/bundles/claude-code/.claude-plugin/plugin.json +20 -12
- package/bundles/claude-code/.mcp.json +11 -8
- package/bundles/claude-code/README.md +31 -11
- package/bundles/claude-code/commands/continue-development.md +3 -3
- package/bundles/claude-code/commands/create-expo-super-stack.md +1 -1
- package/bundles/claude-code/commands/fix-seo.md +1 -1
- package/bundles/claude-code/commands/prepare-deploy.md +2 -4
- package/bundles/claude-code/commands/project-research-plan.md +1 -1
- package/bundles/claude-code/commands/push-merge-loop.md +25 -0
- package/bundles/claude-code/commands/review-expo-project.md +3 -6
- package/bundles/claude-code/commands/run-doctor.md +4 -6
- package/bundles/claude-code/commands/wrap-up.md +67 -0
- package/bundles/claude-code/skills/continue-development/SKILL.md +3 -3
- package/bundles/claude-code/skills/create-expo-super-stack/SKILL.md +1 -1
- package/bundles/claude-code/skills/dev-server-management/SKILL.md +1 -1
- package/bundles/claude-code/skills/fix-seo/SKILL.md +1 -1
- package/bundles/claude-code/skills/prepare-deploy/SKILL.md +2 -4
- package/bundles/claude-code/skills/project-research-plan/SKILL.md +1 -1
- package/bundles/claude-code/skills/push-merge-loop/SKILL.md +30 -0
- package/bundles/claude-code/skills/review-expo-project/SKILL.md +3 -6
- package/bundles/claude-code/skills/run-doctor/SKILL.md +4 -6
- package/bundles/claude-code/skills/wrap-up/SKILL.md +72 -0
- package/bundles/codex/.codex-plugin/plugin.json +4 -4
- package/bundles/codex/commands/continue-development.md +3 -3
- package/bundles/codex/commands/create-expo-super-stack.md +1 -1
- package/bundles/codex/commands/fix-seo.md +1 -1
- package/bundles/codex/commands/prepare-deploy.md +2 -4
- package/bundles/codex/commands/project-research-plan.md +1 -1
- package/bundles/codex/commands/push-merge-loop.md +24 -0
- package/bundles/codex/commands/review-expo-project.md +3 -6
- package/bundles/codex/commands/run-doctor.md +4 -6
- package/bundles/codex/commands/wrap-up.md +67 -0
- package/bundles/codex/skills/workflow-continue-development/SKILL.md +3 -3
- package/bundles/codex/skills/workflow-create-expo-super-stack/SKILL.md +1 -1
- package/bundles/codex/skills/workflow-fix-seo/SKILL.md +1 -1
- package/bundles/codex/skills/workflow-prepare-deploy/SKILL.md +2 -4
- package/bundles/codex/skills/workflow-project-research-plan/SKILL.md +1 -1
- package/bundles/codex/skills/workflow-push-merge-loop/SKILL.md +36 -0
- package/bundles/codex/skills/workflow-review-expo-project/SKILL.md +3 -6
- package/bundles/codex/skills/workflow-run-doctor/SKILL.md +4 -6
- package/bundles/codex/skills/workflow-wrap-up/SKILL.md +79 -0
- package/bundles/vscode-copilot/.github/prompts/continue-development.prompt.md +3 -3
- package/bundles/vscode-copilot/.github/prompts/create-expo-super-stack.prompt.md +1 -1
- package/bundles/vscode-copilot/.github/prompts/fix-seo.prompt.md +1 -1
- package/bundles/vscode-copilot/.github/prompts/prepare-deploy.prompt.md +2 -4
- package/bundles/vscode-copilot/.github/prompts/project-research-plan.prompt.md +1 -1
- package/bundles/vscode-copilot/.github/prompts/push-merge-loop.prompt.md +30 -0
- package/bundles/vscode-copilot/.github/prompts/review-expo-project.prompt.md +3 -6
- package/bundles/vscode-copilot/.github/prompts/run-doctor.prompt.md +4 -6
- package/bundles/vscode-copilot/.github/prompts/wrap-up.prompt.md +72 -0
- package/bundles/vscode-copilot/user/.copilot/skills/workflow-continue-development/SKILL.md +3 -3
- package/bundles/vscode-copilot/user/.copilot/skills/workflow-create-expo-super-stack/SKILL.md +1 -1
- package/bundles/vscode-copilot/user/.copilot/skills/workflow-fix-seo/SKILL.md +1 -1
- package/bundles/vscode-copilot/user/.copilot/skills/workflow-prepare-deploy/SKILL.md +2 -4
- package/bundles/vscode-copilot/user/.copilot/skills/workflow-project-research-plan/SKILL.md +1 -1
- package/bundles/vscode-copilot/user/.copilot/skills/workflow-push-merge-loop/SKILL.md +30 -0
- package/bundles/vscode-copilot/user/.copilot/skills/workflow-review-expo-project/SKILL.md +3 -6
- package/bundles/vscode-copilot/user/.copilot/skills/workflow-run-doctor/SKILL.md +4 -6
- package/bundles/vscode-copilot/user/.copilot/skills/workflow-wrap-up/SKILL.md +72 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +135 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/continue.d.ts +1 -1
- package/dist/commands/continue.d.ts.map +1 -1
- package/dist/commands/continue.js +21 -0
- package/dist/commands/continue.js.map +1 -1
- package/dist/commands/dev-tools.d.ts.map +1 -1
- package/dist/commands/dev-tools.js +22 -4
- package/dist/commands/dev-tools.js.map +1 -1
- package/dist/commands/eject.d.ts +12 -0
- package/dist/commands/eject.d.ts.map +1 -0
- package/dist/commands/eject.js +328 -0
- package/dist/commands/eject.js.map +1 -0
- package/dist/commands/onboard.d.ts +29 -1
- package/dist/commands/onboard.d.ts.map +1 -1
- package/dist/commands/onboard.js +223 -23
- package/dist/commands/onboard.js.map +1 -1
- package/dist/commands/stylist.d.ts +25 -0
- package/dist/commands/stylist.d.ts.map +1 -0
- package/dist/commands/stylist.js +392 -0
- package/dist/commands/stylist.js.map +1 -0
- package/dist/project-memory.d.ts +2 -0
- package/dist/project-memory.d.ts.map +1 -1
- package/dist/project-memory.js +3043 -399
- package/dist/project-memory.js.map +1 -1
- package/dist/stylist-theme.d.ts +104 -0
- package/dist/stylist-theme.d.ts.map +1 -0
- package/dist/stylist-theme.js +1374 -0
- package/dist/stylist-theme.js.map +1 -0
- package/package.json +1 -1
- package/templates/embedded-fonts.template.ts +72 -0
- package/templates/expo-sdk-56-screen-universal.template.tsx +709 -0
- package/templates/project/guidelines.md +4 -3
- package/templates/stylist-screen.template.tsx +3446 -0
|
@@ -0,0 +1,709 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Linking,
|
|
4
|
+
Platform,
|
|
5
|
+
ScrollView as RNScrollView,
|
|
6
|
+
StyleSheet,
|
|
7
|
+
Text,
|
|
8
|
+
View,
|
|
9
|
+
} from 'react-native';
|
|
10
|
+
import Svg, { Path } from 'react-native-svg';
|
|
11
|
+
import {
|
|
12
|
+
BottomSheet,
|
|
13
|
+
Button as ExpoUIButton,
|
|
14
|
+
Checkbox as ExpoUICheckbox,
|
|
15
|
+
Collapsible,
|
|
16
|
+
Column,
|
|
17
|
+
Host,
|
|
18
|
+
Icon as ExpoUIIcon,
|
|
19
|
+
Picker as ExpoUIPicker,
|
|
20
|
+
Row,
|
|
21
|
+
Slider as ExpoUISlider,
|
|
22
|
+
Spacer,
|
|
23
|
+
Switch as ExpoUISwitch,
|
|
24
|
+
Text as ExpoUIText,
|
|
25
|
+
TextInput as ExpoUITextInput,
|
|
26
|
+
useNativeState,
|
|
27
|
+
} from '@expo/ui';
|
|
28
|
+
|
|
29
|
+
import { ExpositionNotice, PackageCard } from '../../components/exposition';
|
|
30
|
+
import { useAppTheme } from '../../theme/provider';
|
|
31
|
+
|
|
32
|
+
type TopicKind =
|
|
33
|
+
| 'expo-ui'
|
|
34
|
+
| 'universal'
|
|
35
|
+
| 'native-state'
|
|
36
|
+
| 'drop-in'
|
|
37
|
+
| 'inline-modules'
|
|
38
|
+
| 'native-tabs'
|
|
39
|
+
| 'runtime'
|
|
40
|
+
| 'widgets'
|
|
41
|
+
| 'audio';
|
|
42
|
+
|
|
43
|
+
const highlights: Array<{
|
|
44
|
+
kind: TopicKind;
|
|
45
|
+
title: string;
|
|
46
|
+
packageName: string;
|
|
47
|
+
body: string;
|
|
48
|
+
links: Array<{ label: string; href: string }>;
|
|
49
|
+
}> = [
|
|
50
|
+
{
|
|
51
|
+
kind: 'expo-ui',
|
|
52
|
+
title: 'Expo UI is production-ready',
|
|
53
|
+
packageName: '@expo/ui',
|
|
54
|
+
body: 'This page uses Expo UI Universal components directly instead of describing them from the sidelines.',
|
|
55
|
+
links: [
|
|
56
|
+
{
|
|
57
|
+
label: 'Expo UI docs',
|
|
58
|
+
href: 'https://docs.expo.dev/versions/latest/sdk/ui/',
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
kind: 'universal',
|
|
64
|
+
title: 'Universal components',
|
|
65
|
+
packageName: '@expo/ui',
|
|
66
|
+
body: 'One component tree targets Android, iOS, and web. The lab below uses layout, display, controls, disclosure, lists, and forms.',
|
|
67
|
+
links: [
|
|
68
|
+
{
|
|
69
|
+
label: 'Universal components docs',
|
|
70
|
+
href: 'https://docs.expo.dev/versions/latest/sdk/ui/universal/',
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
kind: 'native-state',
|
|
76
|
+
title: 'useNativeState',
|
|
77
|
+
packageName: '@expo/ui',
|
|
78
|
+
body: 'The note field below stores text in an observable native state object, so native text controls can own their editing state.',
|
|
79
|
+
links: [
|
|
80
|
+
{
|
|
81
|
+
label: 'useNativeState docs',
|
|
82
|
+
href: 'https://docs.expo.dev/versions/latest/sdk/ui/swift-ui/usenativestate/',
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
kind: 'drop-in',
|
|
88
|
+
title: 'Drop-in replacements',
|
|
89
|
+
packageName: '@expo/ui',
|
|
90
|
+
body: 'The slider, picker, switch, checkbox, button, and text input are wired as drop-in starter controls for generated apps.',
|
|
91
|
+
links: [
|
|
92
|
+
{
|
|
93
|
+
label: 'Drop-in replacements docs',
|
|
94
|
+
href: 'https://docs.expo.dev/versions/latest/sdk/ui/drop-in-replacements/',
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
kind: 'inline-modules',
|
|
100
|
+
title: 'Inline modules',
|
|
101
|
+
packageName: 'expo-modules-core',
|
|
102
|
+
body: 'Use inline Swift/Kotlin modules for app-local native features that are too specific to publish as a package.',
|
|
103
|
+
links: [
|
|
104
|
+
{
|
|
105
|
+
label: 'Inline modules tutorial',
|
|
106
|
+
href: 'https://docs.expo.dev/modules/inline-modules-tutorial/',
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
kind: 'native-tabs',
|
|
112
|
+
title: 'Router and native tabs',
|
|
113
|
+
packageName: 'expo-router',
|
|
114
|
+
body: 'When Expo Native Tabs are enabled, the generated tabs shell uses NativeTabs instead of the JavaScript Tabs navigator.',
|
|
115
|
+
links: [
|
|
116
|
+
{
|
|
117
|
+
label: 'Native tabs docs',
|
|
118
|
+
href: 'https://docs.expo.dev/versions/latest/sdk/router/native-tabs/',
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
kind: 'runtime',
|
|
124
|
+
title: 'Runtime baseline',
|
|
125
|
+
packageName: 'react-native + react',
|
|
126
|
+
body: 'SDK 56 aligns generated apps to React Native 0.85, React 19.2, Hermes V1, and faster precompiled native builds.',
|
|
127
|
+
links: [],
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
kind: 'widgets',
|
|
131
|
+
title: 'Widgets',
|
|
132
|
+
packageName: 'expo-widgets',
|
|
133
|
+
body: 'Widgets are called out as a production candidate for lock-screen, home-screen, and glanceable companion surfaces.',
|
|
134
|
+
links: [
|
|
135
|
+
{
|
|
136
|
+
label: 'Widgets docs',
|
|
137
|
+
href: 'https://docs.expo.dev/versions/latest/sdk/widgets/',
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
kind: 'audio',
|
|
143
|
+
title: 'Audio and haptics updates',
|
|
144
|
+
packageName: 'expo-audio + expo-haptics',
|
|
145
|
+
body: 'Expo Audio is the forward-looking audio API, while haptics remain a good fit for tactile control feedback.',
|
|
146
|
+
links: [
|
|
147
|
+
{
|
|
148
|
+
label: 'Expo Audio docs',
|
|
149
|
+
href: 'https://docs.expo.dev/versions/latest/sdk/audio/',
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
},
|
|
153
|
+
];
|
|
154
|
+
|
|
155
|
+
function ExpoLogoSvg({ size }: { size: number }) {
|
|
156
|
+
return (
|
|
157
|
+
<Svg
|
|
158
|
+
width={size}
|
|
159
|
+
height={size}
|
|
160
|
+
viewBox="0 0 20 20"
|
|
161
|
+
accessibilityRole="image"
|
|
162
|
+
accessibilityLabel="Expo logo"
|
|
163
|
+
>
|
|
164
|
+
<Path
|
|
165
|
+
d="M9.477 7.638c.164-.24.343-.27.488-.27.145 0 .387.03.551.27 2.13 2.901 6.55 10.56 6.959 10.976.605.618 1.436.233 1.918-.468.475-.69.607-1.174.607-1.69 0-.352-6.883-13.05-7.576-14.106-.667-1.017-.884-1.274-2.025-1.274h-.854c-1.138 0-1.302.257-1.969 1.274C6.883 3.406 0 16.104 0 16.456c0 .517.132 1 .607 1.69.482.7 1.313 1.086 1.918.468.41-.417 4.822-8.075 6.952-10.977z"
|
|
166
|
+
fill="#111827"
|
|
167
|
+
/>
|
|
168
|
+
</Svg>
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function ExpoIconMark({ visible, size }: { visible: boolean; size: number }) {
|
|
173
|
+
if (!visible) return null;
|
|
174
|
+
if (Platform.OS === 'web') {
|
|
175
|
+
return (
|
|
176
|
+
<View style={styles.logoFrame}>
|
|
177
|
+
<ExpoLogoSvg size={size} />
|
|
178
|
+
</View>
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return (
|
|
183
|
+
<ExpoUIIcon
|
|
184
|
+
name={'app.fill' as any}
|
|
185
|
+
size={size}
|
|
186
|
+
color="#111827"
|
|
187
|
+
accessibilityLabel="Expo app icon"
|
|
188
|
+
/>
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function UniversalComponentLab() {
|
|
193
|
+
const [count, setCount] = useState(0);
|
|
194
|
+
const [showIcon, setShowIcon] = useState(true);
|
|
195
|
+
const [likesSuperStack, setLikesSuperStack] = useState(true);
|
|
196
|
+
const [logoSize, setLogoSize] = useState(40);
|
|
197
|
+
const [density, setDensity] = useState<'compact' | 'balanced' | 'spacious'>('balanced');
|
|
198
|
+
const [isSheetOpen, setSheetOpen] = useState(false);
|
|
199
|
+
const [isOpen, setOpen] = useState(true);
|
|
200
|
+
const name = useNativeState('Ada Lovelace');
|
|
201
|
+
|
|
202
|
+
return (
|
|
203
|
+
<View style={styles.universalExampleBox}>
|
|
204
|
+
<Host matchContents={{ vertical: true }} style={styles.universalHost}>
|
|
205
|
+
<Column spacing={14}>
|
|
206
|
+
<Row spacing={10} alignment="center">
|
|
207
|
+
<ExpoIconMark visible={showIcon} size={logoSize} />
|
|
208
|
+
<Column spacing={3}>
|
|
209
|
+
<ExpoUIText textStyle={styles.universalHeading}>Universal component lab</ExpoUIText>
|
|
210
|
+
<ExpoUIText
|
|
211
|
+
textStyle={styles.universalBody}
|
|
212
|
+
>{`Count: ${count} | Density: ${density}`}</ExpoUIText>
|
|
213
|
+
</Column>
|
|
214
|
+
<Spacer flexible />
|
|
215
|
+
<ExpoUIText textStyle={styles.statusPill}>
|
|
216
|
+
{likesSuperStack ? 'Approved' : 'Reviewing'}
|
|
217
|
+
</ExpoUIText>
|
|
218
|
+
</Row>
|
|
219
|
+
|
|
220
|
+
<Collapsible
|
|
221
|
+
label={isOpen ? 'Hide details' : 'Show details'}
|
|
222
|
+
isOpen={isOpen}
|
|
223
|
+
onOpenChange={setOpen}
|
|
224
|
+
>
|
|
225
|
+
<ExpoUIText textStyle={styles.universalBody}>
|
|
226
|
+
Host, Column, Row, Collapsible, Button, Switch, Checkbox, Slider, Picker, TextInput,
|
|
227
|
+
and BottomSheet are all live here in one universal tree.
|
|
228
|
+
</ExpoUIText>
|
|
229
|
+
</Collapsible>
|
|
230
|
+
|
|
231
|
+
<Row spacing={10} alignment="center">
|
|
232
|
+
<ExpoUIButton
|
|
233
|
+
label={`Increment (${count})`}
|
|
234
|
+
onPress={() => setCount((value) => value + 1)}
|
|
235
|
+
/>
|
|
236
|
+
<ExpoUIButton
|
|
237
|
+
variant="outlined"
|
|
238
|
+
label="Open sheet"
|
|
239
|
+
onPress={() => setSheetOpen(true)}
|
|
240
|
+
/>
|
|
241
|
+
</Row>
|
|
242
|
+
<ExpoUISwitch label="Show Expo icon/logo" value={showIcon} onValueChange={setShowIcon} />
|
|
243
|
+
<ExpoUICheckbox
|
|
244
|
+
label="I think Super Stack is great"
|
|
245
|
+
value={likesSuperStack}
|
|
246
|
+
onValueChange={setLikesSuperStack}
|
|
247
|
+
/>
|
|
248
|
+
|
|
249
|
+
<Column spacing={6}>
|
|
250
|
+
<ExpoUIText textStyle={styles.universalBody}>{`Logo size: ${logoSize}`}</ExpoUIText>
|
|
251
|
+
<ExpoUISlider min={28} max={72} step={4} value={logoSize} onValueChange={setLogoSize} />
|
|
252
|
+
</Column>
|
|
253
|
+
<ExpoUIPicker selectedValue={density} onValueChange={setDensity}>
|
|
254
|
+
<ExpoUIPicker.Item label="Compact" value="compact" />
|
|
255
|
+
<ExpoUIPicker.Item label="Balanced" value="balanced" />
|
|
256
|
+
<ExpoUIPicker.Item label="Spacious" value="spacious" />
|
|
257
|
+
</ExpoUIPicker>
|
|
258
|
+
<ExpoUITextInput
|
|
259
|
+
value={name}
|
|
260
|
+
placeholder="Display name"
|
|
261
|
+
placeholderTextColor="#64748b"
|
|
262
|
+
style={styles.textInput}
|
|
263
|
+
textStyle={styles.textInputText}
|
|
264
|
+
/>
|
|
265
|
+
<ExpoUIText textStyle={styles.universalBody}>{`Input value: ${name.value}`}</ExpoUIText>
|
|
266
|
+
|
|
267
|
+
<BottomSheet
|
|
268
|
+
isPresented={isSheetOpen}
|
|
269
|
+
onDismiss={() => setSheetOpen(false)}
|
|
270
|
+
snapPoints={[{ height: 320 }, 'half']}
|
|
271
|
+
>
|
|
272
|
+
<Column spacing={10}>
|
|
273
|
+
<ExpoUIText textStyle={styles.universalHeading}>BottomSheet example</ExpoUIText>
|
|
274
|
+
<ExpoUIText textStyle={styles.universalBody}>
|
|
275
|
+
This sheet is rendered by Expo UI BottomSheet and opened by the universal Button.
|
|
276
|
+
</ExpoUIText>
|
|
277
|
+
<ExpoUIButton label="Close sheet" onPress={() => setSheetOpen(false)} />
|
|
278
|
+
</Column>
|
|
279
|
+
</BottomSheet>
|
|
280
|
+
</Column>
|
|
281
|
+
</Host>
|
|
282
|
+
</View>
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function NativeStateExample() {
|
|
287
|
+
const text = useNativeState('Ada Lovelace');
|
|
288
|
+
return (
|
|
289
|
+
<View style={styles.exampleBox}>
|
|
290
|
+
<Host matchContents={{ vertical: true }} style={styles.universalHost}>
|
|
291
|
+
<Column spacing={8}>
|
|
292
|
+
<ExpoUIText textStyle={styles.universalHeading}>Native-owned text field</ExpoUIText>
|
|
293
|
+
<ExpoUITextInput
|
|
294
|
+
value={text}
|
|
295
|
+
placeholder="Display name"
|
|
296
|
+
placeholderTextColor="#64748b"
|
|
297
|
+
style={styles.textInput}
|
|
298
|
+
textStyle={styles.textInputText}
|
|
299
|
+
/>
|
|
300
|
+
<ExpoUIText
|
|
301
|
+
textStyle={styles.universalBody}
|
|
302
|
+
>{`Current native state: ${text.value}`}</ExpoUIText>
|
|
303
|
+
</Column>
|
|
304
|
+
</Host>
|
|
305
|
+
</View>
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function DropInExample() {
|
|
310
|
+
const [enabled, setEnabled] = useState(true);
|
|
311
|
+
const [level, setLevel] = useState(3);
|
|
312
|
+
return (
|
|
313
|
+
<View style={styles.exampleBox}>
|
|
314
|
+
<Host matchContents={{ vertical: true }} style={styles.universalHost}>
|
|
315
|
+
<Column spacing={12}>
|
|
316
|
+
<ExpoUIText textStyle={styles.exampleTitle}>Drop-in controls wired together</ExpoUIText>
|
|
317
|
+
<ExpoUISwitch label="Enabled" value={enabled} onValueChange={setEnabled} />
|
|
318
|
+
<Column spacing={6}>
|
|
319
|
+
<ExpoUIText textStyle={styles.exampleBody}>{`Selected intensity: ${level}`}</ExpoUIText>
|
|
320
|
+
<ExpoUISlider
|
|
321
|
+
min={1}
|
|
322
|
+
max={5}
|
|
323
|
+
step={1}
|
|
324
|
+
value={level}
|
|
325
|
+
onValueChange={setLevel}
|
|
326
|
+
disabled={!enabled}
|
|
327
|
+
/>
|
|
328
|
+
</Column>
|
|
329
|
+
</Column>
|
|
330
|
+
</Host>
|
|
331
|
+
</View>
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function InlineModuleExample() {
|
|
336
|
+
return (
|
|
337
|
+
<View style={styles.exampleBox}>
|
|
338
|
+
<Text style={styles.exampleTitle}>Inline module shape</Text>
|
|
339
|
+
<Text style={styles.codeLine}>modules/LocalGreeting/index.ts</Text>
|
|
340
|
+
<Text style={styles.codeLine}>modules/LocalGreeting/ios/LocalGreeting.swift</Text>
|
|
341
|
+
<Text style={styles.codeLine}>modules/LocalGreeting/android/LocalGreeting.kt</Text>
|
|
342
|
+
</View>
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function NativeTabsExample() {
|
|
347
|
+
return (
|
|
348
|
+
<View style={styles.exampleBox}>
|
|
349
|
+
<Text style={styles.exampleTitle}>No fake tab preview here</Text>
|
|
350
|
+
<Text style={styles.exampleBody}>
|
|
351
|
+
In generated tabs apps, the actual tab bar uses expo-router NativeTabs when Expo Native Tabs
|
|
352
|
+
are enabled. Keep mobile tab counts tight because Android native tabs are best with five or
|
|
353
|
+
fewer destinations.
|
|
354
|
+
</Text>
|
|
355
|
+
</View>
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
function RuntimeExample() {
|
|
360
|
+
return (
|
|
361
|
+
<View style={styles.exampleBox}>
|
|
362
|
+
<View style={styles.componentLabelGrid}>
|
|
363
|
+
<Text style={styles.componentLabel}>React Native 0.85</Text>
|
|
364
|
+
<Text style={styles.componentLabel}>React 19.2</Text>
|
|
365
|
+
<Text style={styles.componentLabel}>Hermes V1</Text>
|
|
366
|
+
<Text style={styles.componentLabel}>Precompiled modules</Text>
|
|
367
|
+
</View>
|
|
368
|
+
</View>
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
function WidgetsExample() {
|
|
373
|
+
return (
|
|
374
|
+
<View style={styles.exampleBox}>
|
|
375
|
+
<View style={styles.widgetTile}>
|
|
376
|
+
<Text style={styles.widgetTitle}>Today</Text>
|
|
377
|
+
<Text style={styles.widgetBody}>3 generated-app checks ready</Text>
|
|
378
|
+
</View>
|
|
379
|
+
</View>
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
function AudioExample() {
|
|
384
|
+
return (
|
|
385
|
+
<View style={styles.exampleBox}>
|
|
386
|
+
<View style={styles.transportRow}>
|
|
387
|
+
<Text style={styles.transportButton}>expo-audio player</Text>
|
|
388
|
+
<Text style={styles.transportButton}>haptic confirmation</Text>
|
|
389
|
+
</View>
|
|
390
|
+
<Text style={styles.exampleBody}>
|
|
391
|
+
Add expo-audio when the product needs real playback; keep haptics for important control
|
|
392
|
+
transitions.
|
|
393
|
+
</Text>
|
|
394
|
+
</View>
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
function TopicExample({ kind }: { kind: TopicKind }) {
|
|
399
|
+
if (kind === 'universal') return <UniversalComponentLab />;
|
|
400
|
+
if (kind === 'expo-ui') return null;
|
|
401
|
+
if (kind === 'native-state') return <NativeStateExample />;
|
|
402
|
+
if (kind === 'drop-in') return <DropInExample />;
|
|
403
|
+
if (kind === 'inline-modules') return <InlineModuleExample />;
|
|
404
|
+
if (kind === 'native-tabs') return <NativeTabsExample />;
|
|
405
|
+
if (kind === 'runtime') return <RuntimeExample />;
|
|
406
|
+
if (kind === 'widgets') return <WidgetsExample />;
|
|
407
|
+
return <AudioExample />;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
export default function ExpoSdk56Screen() {
|
|
411
|
+
const theme = useAppTheme();
|
|
412
|
+
const colors = theme.activeColors;
|
|
413
|
+
|
|
414
|
+
return (
|
|
415
|
+
<RNScrollView
|
|
416
|
+
contentInsetAdjustmentBehavior="automatic"
|
|
417
|
+
contentContainerStyle={styles.content}
|
|
418
|
+
style={[styles.screen, { backgroundColor: colors.background }]}
|
|
419
|
+
>
|
|
420
|
+
<Text style={{ ...styles.title, color: colors.text }}>Expo SDK 56 Exposition</Text>
|
|
421
|
+
<Text style={{ ...styles.intro, color: colors.text }}>
|
|
422
|
+
Examples first: this page uses Expo UI Universal components where the SDK topic supports it,
|
|
423
|
+
then explains exactly what each component is doing.
|
|
424
|
+
</Text>
|
|
425
|
+
<ExpositionNotice />
|
|
426
|
+
{highlights.map((item) => (
|
|
427
|
+
<PackageCard
|
|
428
|
+
key={item.title}
|
|
429
|
+
packageName={item.packageName}
|
|
430
|
+
title={item.title}
|
|
431
|
+
body={item.body}
|
|
432
|
+
>
|
|
433
|
+
<View style={styles.cardChildren}>
|
|
434
|
+
<TopicExample kind={item.kind} />
|
|
435
|
+
{item.links.length ? (
|
|
436
|
+
<View style={styles.linkList}>
|
|
437
|
+
{item.links.map((link) => (
|
|
438
|
+
<Text
|
|
439
|
+
key={link.href}
|
|
440
|
+
onPress={() => Linking.openURL(link.href)}
|
|
441
|
+
style={styles.link}
|
|
442
|
+
>
|
|
443
|
+
{link.label}
|
|
444
|
+
</Text>
|
|
445
|
+
))}
|
|
446
|
+
</View>
|
|
447
|
+
) : null}
|
|
448
|
+
</View>
|
|
449
|
+
</PackageCard>
|
|
450
|
+
))}
|
|
451
|
+
<View style={styles.linksCard}>
|
|
452
|
+
<Text style={styles.linksTitle}>Video sources</Text>
|
|
453
|
+
<Text
|
|
454
|
+
onPress={() => Linking.openURL('https://www.youtube.com/watch?v=MKqGbv-Tssg&t')}
|
|
455
|
+
style={styles.link}
|
|
456
|
+
>
|
|
457
|
+
{
|
|
458
|
+
"What's New in Expo SDK 56: Expo UI, Inline Swift/Kotlin Modules, and Faster Builds by Expo"
|
|
459
|
+
}
|
|
460
|
+
</Text>
|
|
461
|
+
<Text
|
|
462
|
+
onPress={() => Linking.openURL('https://www.youtube.com/watch?v=ywvywq0AGPM')}
|
|
463
|
+
style={styles.link}
|
|
464
|
+
>
|
|
465
|
+
Everything new in Expo SDK 56 by Code with Beto
|
|
466
|
+
</Text>
|
|
467
|
+
</View>
|
|
468
|
+
</RNScrollView>
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
const styles = StyleSheet.create({
|
|
473
|
+
screen: {
|
|
474
|
+
backgroundColor: '#f9fafb',
|
|
475
|
+
flex: 1,
|
|
476
|
+
},
|
|
477
|
+
content: {
|
|
478
|
+
gap: 16,
|
|
479
|
+
padding: 20,
|
|
480
|
+
paddingTop: Platform.OS === 'web' ? 84 : 20,
|
|
481
|
+
},
|
|
482
|
+
title: {
|
|
483
|
+
color: '#111827',
|
|
484
|
+
fontSize: 30,
|
|
485
|
+
fontWeight: '900',
|
|
486
|
+
textAlign: 'center',
|
|
487
|
+
},
|
|
488
|
+
intro: {
|
|
489
|
+
color: '#4b5563',
|
|
490
|
+
fontSize: 16,
|
|
491
|
+
lineHeight: 24,
|
|
492
|
+
},
|
|
493
|
+
cardChildren: {
|
|
494
|
+
gap: 14,
|
|
495
|
+
paddingTop: 8,
|
|
496
|
+
},
|
|
497
|
+
exampleBox: {
|
|
498
|
+
backgroundColor: '#eff6ff',
|
|
499
|
+
borderColor: '#bfdbfe',
|
|
500
|
+
borderRadius: 12,
|
|
501
|
+
borderWidth: 1,
|
|
502
|
+
gap: 12,
|
|
503
|
+
padding: 12,
|
|
504
|
+
alignSelf: 'stretch',
|
|
505
|
+
},
|
|
506
|
+
universalExampleBox: {
|
|
507
|
+
backgroundColor: '#eff6ff',
|
|
508
|
+
borderColor: '#bfdbfe',
|
|
509
|
+
borderRadius: 12,
|
|
510
|
+
borderWidth: 1,
|
|
511
|
+
gap: 12,
|
|
512
|
+
padding: 12,
|
|
513
|
+
alignSelf: 'stretch',
|
|
514
|
+
},
|
|
515
|
+
universalHost: {
|
|
516
|
+
alignSelf: 'stretch',
|
|
517
|
+
width: '100%',
|
|
518
|
+
},
|
|
519
|
+
universalHeading: {
|
|
520
|
+
color: '#111827',
|
|
521
|
+
fontSize: 17,
|
|
522
|
+
fontWeight: '900',
|
|
523
|
+
},
|
|
524
|
+
universalBody: {
|
|
525
|
+
color: '#334155',
|
|
526
|
+
fontSize: 13,
|
|
527
|
+
fontWeight: '600',
|
|
528
|
+
lineHeight: 19,
|
|
529
|
+
},
|
|
530
|
+
collapsibleHeaderScope: {
|
|
531
|
+
alignSelf: 'stretch',
|
|
532
|
+
},
|
|
533
|
+
collapsibleTitle: {
|
|
534
|
+
color: '#0f2a5f',
|
|
535
|
+
fontSize: 14,
|
|
536
|
+
fontWeight: '900',
|
|
537
|
+
marginBottom: 2,
|
|
538
|
+
},
|
|
539
|
+
collapsibleBody: {
|
|
540
|
+
color: '#111827',
|
|
541
|
+
fontSize: 13,
|
|
542
|
+
fontWeight: '600',
|
|
543
|
+
lineHeight: 19,
|
|
544
|
+
},
|
|
545
|
+
exampleTitle: {
|
|
546
|
+
color: '#1e3a8a',
|
|
547
|
+
fontSize: 13,
|
|
548
|
+
fontWeight: '900',
|
|
549
|
+
},
|
|
550
|
+
exampleBody: {
|
|
551
|
+
color: '#1e3a8a',
|
|
552
|
+
fontSize: 13,
|
|
553
|
+
fontWeight: '600',
|
|
554
|
+
lineHeight: 19,
|
|
555
|
+
},
|
|
556
|
+
logoFrame: {
|
|
557
|
+
alignItems: 'center',
|
|
558
|
+
backgroundColor: '#ffffff',
|
|
559
|
+
borderColor: '#dbeafe',
|
|
560
|
+
borderRadius: 14,
|
|
561
|
+
borderWidth: 1,
|
|
562
|
+
height: 76,
|
|
563
|
+
justifyContent: 'center',
|
|
564
|
+
width: 76,
|
|
565
|
+
},
|
|
566
|
+
statusPill: {
|
|
567
|
+
backgroundColor: '#dcfce7',
|
|
568
|
+
borderRadius: 999,
|
|
569
|
+
color: '#166534',
|
|
570
|
+
fontSize: 12,
|
|
571
|
+
fontWeight: '900',
|
|
572
|
+
includeFontPadding: false,
|
|
573
|
+
lineHeight: 16,
|
|
574
|
+
minHeight: 24,
|
|
575
|
+
paddingHorizontal: 10,
|
|
576
|
+
paddingVertical: 4,
|
|
577
|
+
textAlignVertical: 'center',
|
|
578
|
+
},
|
|
579
|
+
textInput: {
|
|
580
|
+
backgroundColor: '#ffffff',
|
|
581
|
+
borderColor: '#bfdbfe',
|
|
582
|
+
borderRadius: 10,
|
|
583
|
+
borderWidth: 1,
|
|
584
|
+
paddingHorizontal: 10,
|
|
585
|
+
paddingVertical: 8,
|
|
586
|
+
},
|
|
587
|
+
textInputText: {
|
|
588
|
+
color: '#0f172a',
|
|
589
|
+
fontSize: 15,
|
|
590
|
+
fontWeight: '700',
|
|
591
|
+
},
|
|
592
|
+
listItemTitle: {
|
|
593
|
+
color: '#0f2a5f',
|
|
594
|
+
fontSize: 15,
|
|
595
|
+
fontWeight: '900',
|
|
596
|
+
},
|
|
597
|
+
listItemBody: {
|
|
598
|
+
color: '#111827',
|
|
599
|
+
fontSize: 13,
|
|
600
|
+
fontWeight: '700',
|
|
601
|
+
lineHeight: 19,
|
|
602
|
+
},
|
|
603
|
+
listBadge: {
|
|
604
|
+
backgroundColor: '#e0f2fe',
|
|
605
|
+
borderRadius: 999,
|
|
606
|
+
color: '#075985',
|
|
607
|
+
fontSize: 11,
|
|
608
|
+
fontWeight: '900',
|
|
609
|
+
overflow: 'hidden',
|
|
610
|
+
paddingHorizontal: 8,
|
|
611
|
+
paddingVertical: 3,
|
|
612
|
+
},
|
|
613
|
+
listBadgeMuted: {
|
|
614
|
+
backgroundColor: '#e5e7eb',
|
|
615
|
+
borderRadius: 999,
|
|
616
|
+
color: '#334155',
|
|
617
|
+
fontSize: 11,
|
|
618
|
+
fontWeight: '900',
|
|
619
|
+
overflow: 'hidden',
|
|
620
|
+
paddingHorizontal: 8,
|
|
621
|
+
paddingVertical: 3,
|
|
622
|
+
},
|
|
623
|
+
codeLine: {
|
|
624
|
+
backgroundColor: '#0f172a',
|
|
625
|
+
borderRadius: 6,
|
|
626
|
+
color: '#e5e7eb',
|
|
627
|
+
fontSize: 12,
|
|
628
|
+
fontWeight: '700',
|
|
629
|
+
paddingHorizontal: 10,
|
|
630
|
+
paddingVertical: 7,
|
|
631
|
+
},
|
|
632
|
+
componentLabelGrid: {
|
|
633
|
+
flexDirection: 'row',
|
|
634
|
+
flexWrap: 'wrap',
|
|
635
|
+
gap: 8,
|
|
636
|
+
},
|
|
637
|
+
componentLabel: {
|
|
638
|
+
alignSelf: 'flex-start',
|
|
639
|
+
backgroundColor: '#dbeafe',
|
|
640
|
+
borderRadius: 999,
|
|
641
|
+
color: '#1e3a8a',
|
|
642
|
+
fontSize: 12,
|
|
643
|
+
fontWeight: '800',
|
|
644
|
+
includeFontPadding: false,
|
|
645
|
+
lineHeight: 18,
|
|
646
|
+
minHeight: 28,
|
|
647
|
+
paddingHorizontal: 9,
|
|
648
|
+
paddingVertical: 4,
|
|
649
|
+
textAlignVertical: 'center',
|
|
650
|
+
},
|
|
651
|
+
widgetTile: {
|
|
652
|
+
backgroundColor: '#ffffff',
|
|
653
|
+
borderColor: '#bfdbfe',
|
|
654
|
+
borderRadius: 14,
|
|
655
|
+
borderWidth: 1,
|
|
656
|
+
padding: 16,
|
|
657
|
+
},
|
|
658
|
+
widgetTitle: {
|
|
659
|
+
color: '#111827',
|
|
660
|
+
fontSize: 22,
|
|
661
|
+
fontWeight: '900',
|
|
662
|
+
},
|
|
663
|
+
widgetBody: {
|
|
664
|
+
color: '#475569',
|
|
665
|
+
fontSize: 13,
|
|
666
|
+
fontWeight: '700',
|
|
667
|
+
marginTop: 4,
|
|
668
|
+
},
|
|
669
|
+
transportRow: {
|
|
670
|
+
flexDirection: 'row',
|
|
671
|
+
flexWrap: 'wrap',
|
|
672
|
+
gap: 8,
|
|
673
|
+
},
|
|
674
|
+
transportButton: {
|
|
675
|
+
backgroundColor: '#ffffff',
|
|
676
|
+
borderColor: '#bfdbfe',
|
|
677
|
+
borderRadius: 8,
|
|
678
|
+
borderWidth: 1,
|
|
679
|
+
color: '#1e3a8a',
|
|
680
|
+
fontSize: 13,
|
|
681
|
+
fontWeight: '800',
|
|
682
|
+
overflow: 'hidden',
|
|
683
|
+
paddingHorizontal: 10,
|
|
684
|
+
paddingVertical: 8,
|
|
685
|
+
},
|
|
686
|
+
linkList: {
|
|
687
|
+
gap: 8,
|
|
688
|
+
paddingTop: 2,
|
|
689
|
+
},
|
|
690
|
+
linksCard: {
|
|
691
|
+
backgroundColor: '#eef2ff',
|
|
692
|
+
borderColor: '#c7d2fe',
|
|
693
|
+
borderRadius: 12,
|
|
694
|
+
borderWidth: 1,
|
|
695
|
+
gap: 8,
|
|
696
|
+
padding: 14,
|
|
697
|
+
},
|
|
698
|
+
linksTitle: {
|
|
699
|
+
color: '#312e81',
|
|
700
|
+
fontSize: 16,
|
|
701
|
+
fontWeight: '900',
|
|
702
|
+
},
|
|
703
|
+
link: {
|
|
704
|
+
color: '#1d4ed8',
|
|
705
|
+
fontSize: 14,
|
|
706
|
+
fontWeight: '800',
|
|
707
|
+
lineHeight: 20,
|
|
708
|
+
},
|
|
709
|
+
});
|