create-expo-stack 2.7.0-next.54eb637 → 2.7.0-next.753769c

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +9 -9
  2. package/build/templates/base/app.json.ejs +5 -1
  3. package/build/templates/base/package.json.ejs +30 -2
  4. package/build/templates/base/tsconfig.json.ejs +1 -1
  5. package/build/templates/packages/nativewindui/app/+not-found.tsx.ejs +1 -1
  6. package/build/templates/packages/nativewindui/app/_layout.tsx.ejs +25 -19
  7. package/build/templates/packages/nativewindui/app/index.tsx.ejs +658 -46
  8. package/build/templates/packages/nativewindui/app/modal.tsx.ejs +20 -19
  9. package/build/templates/packages/nativewindui/components/nativewind-ui/ActivityIndicator.tsx.ejs +10 -0
  10. package/build/templates/packages/nativewindui/components/nativewind-ui/Avatar.tsx.ejs +139 -0
  11. package/build/templates/packages/nativewindui/components/nativewind-ui/DatePicker.android.tsx.ejs +66 -0
  12. package/build/templates/packages/nativewindui/components/nativewind-ui/DatePicker.tsx.ejs +10 -0
  13. package/build/templates/packages/nativewindui/components/nativewind-ui/Picker.tsx.ejs +39 -0
  14. package/build/templates/packages/nativewindui/components/nativewind-ui/ProgressIndicator.tsx.ejs +95 -0
  15. package/build/templates/packages/nativewindui/components/nativewind-ui/SegmentedControl.tsx.ejs +22 -0
  16. package/build/templates/packages/nativewindui/components/nativewind-ui/Sheet.tsx.ejs +59 -0
  17. package/build/templates/packages/nativewindui/components/nativewind-ui/Slider.tsx.ejs +28 -0
  18. package/build/templates/packages/nativewindui/components/nativewind-ui/Text.tsx.ejs +26 -2
  19. package/build/templates/packages/nativewindui/components/{ThemeToggle.tsx.ejs → nativewind-ui/ThemeToggle.tsx.ejs} +6 -8
  20. package/build/templates/packages/nativewindui/components/nativewind-ui/Toggle.tsx.ejs +17 -0
  21. package/build/templates/packages/nativewindui/global.css.ejs +2 -2
  22. package/build/templates/packages/nativewindui/lib/useColorScheme.tsx.ejs +1 -1
  23. package/build/templates/packages/nativewindui/lib/useHeaderSearchBar.tsx.ejs +2 -2
  24. package/build/templates/packages/nativewindui/theme/colors.ts.ejs +8 -8
  25. package/build/templates/packages/nativewindui/theme/index.ts.ejs +4 -4
  26. package/build/types/types.d.ts +2 -0
  27. package/build/utilities/configureProjectFiles.js +41 -12
  28. package/build/utilities/runCLI.js +80 -26
  29. package/package.json +1 -1
  30. package/build/templates/packages/nativewindui/app/bottom-tabs/_layout.tsx.ejs +0 -34
  31. package/build/templates/packages/nativewindui/app/bottom-tabs/index.tsx.ejs +0 -11
  32. package/build/templates/packages/nativewindui/app/bottom-tabs/profile.tsx.ejs +0 -11
  33. package/build/templates/packages/nativewindui/app/drawer/_layout.tsx.ejs +0 -29
  34. package/build/templates/packages/nativewindui/app/drawer/index.tsx.ejs +0 -11
  35. package/build/templates/packages/nativewindui/app/top-tabs/_layout.tsx.ejs +0 -71
  36. package/build/templates/packages/nativewindui/app/top-tabs/following.tsx.ejs +0 -13
  37. package/build/templates/packages/nativewindui/app/top-tabs/index.tsx.ejs +0 -13
  38. package/build/templates/packages/nativewindui/app/top-tabs/my-group.tsx.ejs +0 -13
@@ -1,63 +1,171 @@
1
+ import { useHeaderHeight } from '@react-navigation/elements';
2
+ import { FlashList } from '@shopify/flash-list';
3
+ import { cssInterop } from 'nativewind';
1
4
  import * as React from 'react';
2
- import { Button as RNButton, ButtonProps, FlatList, Linking, View } from 'react-native';
5
+ import {
6
+ <% if (props.stylingPackage?.options.selectedComponents.includes('alert')) { %>
7
+ Alert,
8
+ <% } %>
9
+ <% if (
10
+ props.stylingPackage?.options.selectedComponents.includes('alert') ||
11
+ props.stylingPackage?.options.selectedComponents.includes('action-sheet') ||
12
+ props.stylingPackage?.options.selectedComponents.includes('activity-view') ||
13
+ props.stylingPackage?.options.selectedComponents.includes('bottom-sheet')
14
+ ) { %>
15
+ Button as RNButton,
16
+ ButtonProps,
17
+ <% } %>
18
+ Linking,
19
+ <% if (props.stylingPackage?.options.selectedComponents.includes('alert') || props.stylingPackage?.options.selectedComponents.includes('bottom-sheet')) { %>
20
+ Platform,
21
+ <% } %>
22
+ <% if (props.stylingPackage?.options.selectedComponents.includes('dropdown-menu')) { %>
23
+ Pressable,
24
+ <% } %>
25
+ <% if (props.stylingPackage?.options.selectedComponents.includes('activity-view')) { %>
26
+ Share,
27
+ <% } %>
28
+ useWindowDimensions,
29
+ View,
30
+ } from 'react-native';
31
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
32
+ <% if (props.stylingPackage?.options.selectedComponents.includes('action-sheet')) { %>
33
+ import { useActionSheet } from '@expo/react-native-action-sheet';
34
+ <% } %>
35
+ import { Icon } from '@roninoss/icons';
36
+ <% if (props.stylingPackage?.options.selectedComponents.includes('ratings-indicator')) { %>
37
+ import * as StoreReview from 'expo-store-review';
38
+ <% } %>
39
+ <% if (props.stylingPackage?.options.selectedComponents.includes('context-menu')) { %>
40
+ import * as ContextMenu from 'zeego/context-menu';
41
+ <% } %>
42
+ <% if (props.stylingPackage?.options.selectedComponents.includes('dropdown-menu')) { %>
43
+ import * as DropdownMenu from 'zeego/dropdown-menu';
44
+ <% } %>
3
45
 
4
- import { Text } from '@/components/nativewind-ui/Text';
5
- import { useColorScheme } from '@/lib/useColorScheme';
6
- import { useHeaderSearchBar } from '@/lib/useHeaderSearchBar';
46
+ <% if (props.stylingPackage?.options.selectedComponents.includes('activity-indicator')) { %>
47
+ import { ActivityIndicator } from '~/components/nativewind-ui/ActivityIndicator';
48
+ <% } %>
49
+ <% if (props.stylingPackage?.options.selectedComponents.includes('avatar')) { %>
50
+ import { Avatar, AvatarFallback, AvatarImage } from '~/components/nativewind-ui/Avatar';
51
+ <% } %>
52
+ <% if (props.stylingPackage?.options.selectedComponents.includes('date-picker')) { %>
53
+ import { DatePicker } from '~/components/nativewind-ui/DatePicker';
54
+ <% } %>
55
+ <% if (props.stylingPackage?.options.selectedComponents.includes('picker')) { %>
56
+ import { Picker, PickerItem } from '~/components/nativewind-ui/Picker';
57
+ <% } %>
58
+ <% if (props.stylingPackage?.options.selectedComponents.includes('progress-indicator')) { %>
59
+ import { ProgressIndicator } from '~/components/nativewind-ui/ProgressIndicator';
60
+ <% } %>
61
+ <% if (props.stylingPackage?.options.selectedComponents.includes('segmented-control')) { %>
62
+ import { SegmentedControl } from '~/components/nativewind-ui/SegmentedControl';
63
+ <% } %>
64
+ <% if (props.stylingPackage?.options.selectedComponents.includes('bottom-sheet')) { %>
65
+ import { Sheet, useSheetRef } from '~/components/nativewind-ui/Sheet';
66
+ <% } %>
67
+ <% if (props.stylingPackage?.options.selectedComponents.includes('slider')) { %>
68
+ import { Slider } from '~/components/nativewind-ui/Slider';
69
+ <% } %>
70
+ import { Text } from '~/components/nativewind-ui/Text';
71
+ <% if (props.stylingPackage?.options.selectedComponents.includes('toggle')) { %>
72
+ import { Toggle } from '~/components/nativewind-ui/Toggle';
73
+ <% } %>
74
+ import { useColorScheme } from '~/lib/useColorScheme';
75
+ import { useHeaderSearchBar } from '~/lib/useHeaderSearchBar';
7
76
 
77
+
78
+ cssInterop(FlashList, {
79
+ className: 'style',
80
+ contentContainerClassName: 'contentContainerStyle',
81
+ });
82
+ <% if (
83
+ props.stylingPackage?.options.selectedComponents.includes('alert') ||
84
+ props.stylingPackage?.options.selectedComponents.includes('action-sheet') ||
85
+ props.stylingPackage?.options.selectedComponents.includes('activity-view') ||
86
+ props.stylingPackage?.options.selectedComponents.includes('bottom-sheet')
87
+ ) { %>
8
88
  function DefaultButton({ color, ...props }: ButtonProps) {
9
89
  const { colors } = useColorScheme();
10
- return <RNButton color={color ?? colors.blue} {...props} />;
90
+ return <RNButton color={color ?? colors.primary} {...props} />;
11
91
  }
12
-
92
+ <% } %>
13
93
  export default function Screen() {
14
- const searchValue = useHeaderSearchBar();
94
+ const searchValue = useHeaderSearchBar({ hideWhenScrolling: COMPONENTS.length === 0 });
15
95
 
16
96
  const data = searchValue
17
97
  ? COMPONENTS.filter((c) => c.name.toLowerCase().includes(searchValue.toLowerCase()))
18
98
  : COMPONENTS;
19
99
 
20
- const screens = searchValue
21
- ? FULL_SCREEN_COMPONENTS.filter((c) => c.name.toLowerCase().includes(searchValue.toLowerCase()))
22
- : FULL_SCREEN_COMPONENTS;
23
-
24
100
  return (
25
- <FlatList
101
+ <FlashList
26
102
  contentInsetAdjustmentBehavior="automatic"
103
+ keyboardShouldPersistTaps="handled"
27
104
  data={data}
28
- contentContainerClassName="flex flex-1 py-4 items-center justify-center"
105
+ estimatedItemSize={200}
106
+ contentContainerClassName="py-4"
29
107
  extraData={searchValue}
108
+ <% if (props.stylingPackage?.options.selectedComponents.includes('selectable-text')) { %>
30
109
  removeClippedSubviews={false} // used for selecting text on android
31
- keyExtractor={(item) => item.name}
32
- ItemSeparatorComponent={() => <View className="p-2" />}
33
- renderItem={({ item }) => {
34
- return (
35
- <Card title={item.name}>
36
- <item.component />
37
- </Card>
38
- );
39
- }}
40
- ListEmptyComponent={() => {
41
- return (
42
- <View className='px-4'>
43
- <Text variant="title3" className="text-center font-bold">
44
- No Components Installed
45
- </Text>
46
- <Text color="tertiary" variant="body" className="text-center pb-4">
47
- You can install any of the free components from the NativeWindUI website.
48
- </Text>
49
- <DefaultButton title="Open NativeWindUI" onPress={() => Linking.openURL('https://nativewindui.com')} />
50
- </View>
51
- )
52
- }}
110
+ <% } %>
111
+ keyExtractor={keyExtractor}
112
+ ItemSeparatorComponent={renderItemSeparator}
113
+ renderItem={renderItem}
114
+ ListEmptyComponent={COMPONENTS.length === 0 ? ListEmptyComponent : undefined}
53
115
  />
54
116
  );
55
117
  }
56
118
 
119
+ function ListEmptyComponent() {
120
+ const insets = useSafeAreaInsets();
121
+ const dimensions = useWindowDimensions();
122
+ const headerHeight = useHeaderHeight();
123
+ const { colors } = useColorScheme();
124
+ const height = dimensions.height - headerHeight - insets.bottom - insets.top;
125
+
126
+ return (
127
+ <View style={{ height }} className="flex-1 items-center justify-center gap-1 px-12">
128
+ <Icon name="file-plus-outline" size={42} color={colors.grey} />
129
+ <Text variant='title3' className='pb-1 text-center font-semibold'>
130
+ No Components Installed
131
+ </Text>
132
+ <Text color='tertiary' variant='subhead' className='pb-4 text-center'>
133
+ You can install any of the free components from the{' '}
134
+ <Text
135
+ onPress={() => Linking.openURL('https://nativewindui.com')}
136
+ variant='subhead'
137
+ className='text-primary'
138
+ >
139
+ NativeWindUI
140
+ </Text>
141
+ {' website.'}
142
+ </Text>
143
+ </View>
144
+ );
145
+ }
146
+
147
+ type ComponentItem = { name: string; component: React.FC };
148
+
149
+ function keyExtractor(item: ComponentItem) {
150
+ return item.name;
151
+ }
152
+
153
+ function renderItemSeparator() {
154
+ return <View className="p-2" />;
155
+ }
156
+
157
+ function renderItem({ item }: { item: ComponentItem }) {
158
+ return (
159
+ <Card title={item.name}>
160
+ <item.component />
161
+ </Card>
162
+ );
163
+ }
164
+
57
165
  function Card({ children, title }: { children: React.ReactNode; title: string }) {
58
166
  return (
59
167
  <View className="px-4">
60
- <View className="bg-card border-border gap-4 rounded-xl border p-4 pb-6 shadow-sm shadow-black/10 dark:shadow-none">
168
+ <View className="gap-4 rounded-xl border border-border bg-card p-4 pb-6 shadow-sm shadow-black/10 dark:shadow-none">
61
169
  <Text className="text-center text-sm font-medium tracking-wider opacity-60">{title}</Text>
62
170
  {children}
63
171
  </View>
@@ -65,20 +173,524 @@ function Card({ children, title }: { children: React.ReactNode; title: string })
65
173
  );
66
174
  }
67
175
 
68
- const COMPONENTS = [
69
- ] as const;
176
+ const COMPONENTS: ComponentItem[] = [
177
+ <% if (props.stylingPackage?.options.selectedComponents.includes('picker')) { %>
178
+ {
179
+ name: 'Picker',
180
+ component: function PickerExample() {
181
+ const { colors } = useColorScheme();
182
+ const [picker, setPicker] = React.useState('blue');
183
+ return (
184
+ <Picker
185
+ selectedValue={picker}
186
+ onValueChange={(itemValue) => setPicker(itemValue)}
187
+ >
188
+ <PickerItem
189
+ label='Red'
190
+ value='red'
191
+ color={colors.foreground}
192
+ style={{
193
+ backgroundColor: colors.root,
194
+ }}
195
+ />
196
+ <PickerItem
197
+ label='Blue'
198
+ value='blue'
199
+ color={colors.foreground}
200
+ style={{
201
+ backgroundColor: colors.root,
202
+ }}
203
+ />
204
+ <PickerItem
205
+ label='Green'
206
+ value='green'
207
+ color={colors.foreground}
208
+ style={{
209
+ backgroundColor: colors.root,
210
+ }}
211
+ />
212
+ </Picker>
213
+ );
214
+ },
215
+ },
216
+ <% } %>
217
+ <% if (props.stylingPackage?.options.selectedComponents.includes('date-picker')) { %>
218
+ {
219
+ name: 'Date Picker',
220
+ component: function DatePickerExample() {
221
+ const [date, setDate] = React.useState(new Date());
222
+ return (
223
+ <View className='items-center'>
224
+ <DatePicker
225
+ value={date}
226
+ mode='datetime'
227
+ onChange={(ev) => {
228
+ setDate(new Date(ev.nativeEvent.timestamp));
229
+ }}
230
+ />
231
+ </View>
232
+ );
233
+ },
234
+ },
235
+ <% } %>
236
+ <% if (props.stylingPackage?.options.selectedComponents.includes('segmented-control')) { %>
237
+ {
238
+ name: 'Segmented Controls',
239
+ component: function SegmentedControlsExample() {
240
+ const [segment, setSegment] = React.useState(0);
241
+ return (
242
+ <SegmentedControl
243
+ values={['red', 'green', 'blue']}
244
+ selectedIndex={segment}
245
+ onChange={(event) => {
246
+ setSegment(event.nativeEvent.selectedSegmentIndex);
247
+ }}
248
+ />
249
+ );
250
+ },
251
+ },
252
+ <% } %>
253
+ <% if (props.stylingPackage?.options.selectedComponents.includes('slider')) { %>
254
+ {
255
+ name: 'Slider',
256
+ component: function SliderExample() {
257
+ const [sliderValue, setSliderValue] = React.useState(0.5);
258
+ return <Slider value={sliderValue} onValueChange={setSliderValue} />;
259
+ },
260
+ },
261
+ <% } %>
262
+ <% if (props.stylingPackage?.options.selectedComponents.includes('toggle')) { %>
263
+ {
264
+ name: 'Toggle',
265
+ component: function ToggleExample() {
266
+ const [switchValue, setSwitchValue] = React.useState(true);
267
+ return (
268
+ <View className='items-center'>
269
+ <Toggle value={switchValue} onValueChange={setSwitchValue} />
270
+ </View>
271
+ );
272
+ }
273
+ },
274
+ <% } %>
275
+ <% if (props.stylingPackage?.options.selectedComponents.includes('context-menu')) { %>
276
+ {
277
+ name: 'Context Menu',
278
+ component: function ContextMenuExample() {
279
+ const [isChecked, setIsChecked] = React.useState(true);
280
+ return (
281
+ <View>
282
+ <ContextMenu.Root style={{ borderRadius: 12 }}>
283
+ <ContextMenu.Trigger>
284
+ <View className='w-full h-36 rounded-xl border border-foreground border-dashed justify-center items-center'>
285
+ <Text>Press and hold me</Text>
286
+ </View>
287
+ </ContextMenu.Trigger>
288
+ <ContextMenu.Content>
289
+ <ContextMenu.Label children='Label 1' />
290
+ <ContextMenu.Item key='item-1'>
291
+ <ContextMenu.ItemTitle>Item 1</ContextMenu.ItemTitle>
292
+ </ContextMenu.Item>
293
+ <ContextMenu.Group>
294
+ <ContextMenu.Item key='item-2'>
295
+ <ContextMenu.ItemTitle>Item 2</ContextMenu.ItemTitle>
296
+ </ContextMenu.Item>
297
+ <ContextMenu.CheckboxItem
298
+ key='checkbox-example'
299
+ value={isChecked}
300
+ onValueChange={(val) => {
301
+ setIsChecked(val === 'on');
302
+ }}
303
+ >
304
+ <ContextMenu.ItemTitle>Item 3</ContextMenu.ItemTitle>
305
+ <ContextMenu.ItemIndicator />
306
+ </ContextMenu.CheckboxItem>
307
+ </ContextMenu.Group>
308
+ <ContextMenu.Separator />
309
+ </ContextMenu.Content>
310
+ </ContextMenu.Root>
311
+ </View>
312
+ );
313
+ },
314
+ },
315
+ <% } %>
316
+ <% if (props.stylingPackage?.options.selectedComponents.includes('dropdown-menu')) { %>
317
+ {
318
+ name: 'Dropdown Menu',
319
+ component: function DropdownMenuExample() {
320
+ const { colors } = useColorScheme();
321
+ const [menu, setMenu] = React.useState<'primary' | 'destructive'>('primary');
322
+
323
+ return (
324
+ <View className='items-center'>
325
+ <DropdownMenu.Root>
326
+ <DropdownMenu.Trigger>
327
+ <Pressable className='flex-row items-center gap-1.5 android:gap-3'>
328
+ <Text>
329
+ Selected: <Text style={{ color: colors[menu] }}>{menu}</Text>
330
+ </Text>
331
+ <View className='pl-0.5 opacity-70'>
332
+ <Icon
333
+ name='chevron-down'
334
+ color={colors.foreground}
335
+ size={21}
336
+ />
337
+ </View>
338
+ </Pressable>
339
+ </DropdownMenu.Trigger>
340
+ <DropdownMenu.Content>
341
+ <DropdownMenu.CheckboxItem
342
+ key='destructive'
343
+ value={menu === 'destructive'}
344
+ onValueChange={() => {
345
+ setMenu('destructive');
346
+ }}
347
+ >
348
+ <DropdownMenu.ItemIndicator />
349
+ <DropdownMenu.ItemTitle children='destructive' />
350
+ </DropdownMenu.CheckboxItem>
351
+ <DropdownMenu.CheckboxItem
352
+ key='primary'
353
+ value={menu === 'primary'}
354
+ onValueChange={() => {
355
+ setMenu('primary');
356
+ }}
357
+ >
358
+ <DropdownMenu.ItemIndicator />
359
+ <DropdownMenu.ItemTitle children='primary' />
360
+ </DropdownMenu.CheckboxItem>
361
+ </DropdownMenu.Content>
362
+ </DropdownMenu.Root>
363
+ </View>
364
+ );
365
+ },
366
+ },
367
+ <% } %>
368
+ <% if (props.stylingPackage?.options.selectedComponents.includes('progress-indicator')) { %>
369
+ {
370
+ name: 'Progress Indicator',
371
+ component: function ProgressIndicatorExample() {
372
+ const [progress, setProgress] = React.useState(13);
373
+ let id: ReturnType<typeof setInterval> | null = null;
374
+ React.useEffect(() => {
375
+ if (!id) {
376
+ id = setInterval(() => {
377
+ setProgress((prev) => (prev >= 99 ? 0 : prev + 5));
378
+ }, Math.random() * 3000);
379
+ }
380
+ return () => {
381
+ if (id) clearInterval(id);
382
+ };
383
+ }, []);
384
+ return (
385
+ <View className='p-4'>
386
+ <ProgressIndicator value={progress} />
387
+ </View>
388
+ );
389
+ },
390
+ },
391
+ <% } %>
392
+ <% if (props.stylingPackage?.options.selectedComponents.includes('activity-indicator')) { %>
393
+ {
394
+ name: 'Activity Indicator',
395
+ component: function ActivityIndicatorExample() {
396
+ return (
397
+ <View className='p-4 items-center'>
398
+ <ActivityIndicator />
399
+ </View>
400
+ );
401
+ },
402
+ },
403
+ <% } %>
404
+ <% if (props.stylingPackage?.options.selectedComponents.includes('alert')) { %>
405
+ {
406
+ name: 'Alert',
407
+ component: function AlertExample() {
408
+ const { colors } = useColorScheme();
409
+ return (
410
+ <View className='items-center'>
411
+ <DefaultButton
412
+ color={colors.destructive}
413
+ onPress={() => {
414
+ if (Platform.OS === 'ios') {
415
+ Alert.prompt(
416
+ 'Delete account?',
417
+ 'Enter your password to delete your account.',
418
+ [
419
+ {
420
+ text: 'Cancel',
421
+ onPress: () => console.log('Cancel Pressed'),
422
+ style: 'cancel',
423
+ },
424
+ {
425
+ text: 'Delete',
426
+ style: 'destructive',
427
+ onPress: () => console.log('Delete Pressed'),
428
+ },
429
+ ],
430
+ 'secure-text',
431
+ '',
432
+ 'default'
433
+ );
434
+ } else {
435
+ Alert.alert(
436
+ 'Delete account?',
437
+ 'Enter your password to delete your account.',
438
+ [
439
+ {
440
+ text: 'Cancel',
441
+ onPress: () => console.log('Cancel Pressed'),
442
+ style: 'cancel',
443
+ },
444
+ {
445
+ text: 'Delete',
446
+ style: 'destructive',
447
+ onPress: () => console.log('Delete Pressed'),
448
+ },
449
+ ]
450
+ );
451
+ }
452
+ }}
453
+ title='Delete account'
454
+ />
455
+ </View>
456
+ );
457
+ },
458
+ },
459
+ <% } %>
460
+ <% if (props.stylingPackage?.options.selectedComponents.includes('action-sheet')) { %>
461
+ {
462
+ name: 'Action Sheet',
463
+ component: function ActionSheetExample() {
464
+ const { colorScheme, colors } = useColorScheme();
465
+ const { showActionSheetWithOptions } = useActionSheet();
466
+ return (
467
+ <View className='items-center'>
468
+ <DefaultButton
469
+ color={'grey'}
470
+ onPress={async () => {
471
+ const options = ['Delete', 'Save', 'Cancel'];
472
+ const destructiveButtonIndex = 0;
473
+ const cancelButtonIndex = 2;
474
+
475
+ showActionSheetWithOptions(
476
+ {
477
+ options,
478
+ cancelButtonIndex,
479
+ destructiveButtonIndex,
480
+ containerStyle: {
481
+ backgroundColor: colorScheme === 'dark' ? 'black' : 'white',
482
+ },
483
+ textStyle: {
484
+ color: colors.foreground,
485
+ },
486
+ },
487
+ (selectedIndex) => {
488
+ switch (selectedIndex) {
489
+ case 1:
490
+ // Save
491
+ break;
492
+
493
+ case destructiveButtonIndex:
494
+ // Delete
495
+ break;
70
496
 
71
- const FULL_SCREEN_COMPONENTS = [
497
+ case cancelButtonIndex:
498
+ // Canceled
499
+ }
500
+ }
501
+ );
502
+ }}
503
+ title='Open action sheet'
504
+ />
505
+ </View>
506
+ );
507
+ },
508
+ },
509
+ <% } %>
510
+ <% if (props.stylingPackage?.options.selectedComponents.includes('text')) { %>
511
+ {
512
+ name: 'Text',
513
+ component: function TextExample() {
514
+ return (
515
+ <View className='gap-2'>
516
+ <Text variant='largeTitle' className='text-center'>
517
+ Large Title
518
+ </Text>
519
+ <Text variant='title1' className='text-center'>
520
+ Title 1
521
+ </Text>
522
+ <Text variant='title2' className='text-center'>
523
+ Title 2
524
+ </Text>
525
+ <Text variant='title3' className='text-center'>
526
+ Title 3
527
+ </Text>
528
+ <Text variant='heading' className='text-center'>
529
+ Heading
530
+ </Text>
531
+ <Text variant='body' className='text-center'>
532
+ Body
533
+ </Text>
534
+ <Text variant='callout' className='text-center'>
535
+ Callout
536
+ </Text>
537
+ <Text variant='subhead' className='text-center'>
538
+ Subhead
539
+ </Text>
540
+ <Text variant='footnote' className='text-center'>
541
+ Footnote
542
+ </Text>
543
+ <Text variant='caption1' className='text-center'>
544
+ Caption 1
545
+ </Text>
546
+ <Text variant='caption2' className='text-center'>
547
+ Caption 2
548
+ </Text>
549
+ </View>
550
+ );
551
+ },
552
+ },
553
+ <% } %>
554
+ <% if (props.stylingPackage?.options.selectedComponents.includes('selectable-text')) { %>
555
+ {
556
+ name: 'Selectable Text',
557
+ component: function SelectableTextExample() {
558
+ return (
559
+ <Text uiTextView selectable>
560
+ Long press or double press this text
561
+ </Text>
562
+ );
563
+ },
564
+ },
565
+ <% } %>
566
+ <% if (props.stylingPackage?.options.selectedComponents.includes('ratings-indicator')) { %>
567
+ {
568
+ name: 'Ratings Indicator',
569
+ component: function RatingsIndicatorExample() {
570
+ React.useEffect(() => {
571
+ async function showRequestReview() {
572
+ if (await StoreReview.hasAction()) {
573
+ // For android, make sure you meet all conditions to be able to test and use it: https://developer.android.com/guide/playcore/in-app-review/test#troubleshooting
574
+ StoreReview.requestReview();
575
+ }
576
+ }
577
+ const timeout = setTimeout(() => {
578
+ showRequestReview();
579
+ }, 1000);
580
+
581
+ return () => clearTimeout(timeout);
582
+ }, []);
583
+
584
+ return (
585
+ <View className="gap-3">
586
+ <Text className="pb-2 text-center font-semibold">Please follow the guidelines.</Text>
587
+ <View className="flex-row">
588
+ <Text className="w-6 text-center text-muted-foreground">·</Text>
589
+ <View className="flex-1">
590
+ <Text variant="caption1" className="text-muted-foreground">
591
+ Don't call StoreReview.requestReview() from a button
592
+ </Text>
593
+ </View>
594
+ </View>
595
+ <View className="flex-row">
596
+ <Text className="w-6 text-center text-muted-foreground">·</Text>
597
+ <View className="flex-1">
598
+ <Text variant="caption1" className="text-muted-foreground">
599
+ Don't request a review when the user is doing something time sensitive.
600
+ </Text>
601
+ </View>
602
+ </View>
603
+ <View className="flex-row">
604
+ <Text className="w-6 text-center text-muted-foreground">·</Text>
605
+ <View className="flex-1">
606
+ <Text variant="caption1" className="text-muted-foreground">
607
+ Don't ask the user any questions before or while presenting the rating button or
608
+ card.
609
+ </Text>
610
+ </View>
611
+ </View>
612
+ </View>
613
+ );
614
+ },
615
+ },
616
+ <% } %>
617
+ <% if (props.stylingPackage?.options.selectedComponents.includes('activity-view')) { %>
72
618
  {
73
- name: 'Drawer Navigation',
74
- href: '/drawer/',
619
+ name: 'Activity View',
620
+ component: function ActivityViewExample() {
621
+ return (
622
+ <View className='items-center'>
623
+ <DefaultButton
624
+ onPress={async () => {
625
+ try {
626
+ const result = await Share.share({
627
+ message: 'NativeWindUI | Familiar interface, native feel.',
628
+ });
629
+ if (result.action === Share.sharedAction) {
630
+ if (result.activityType) {
631
+ // shared with activity type of result.activityType
632
+ } else {
633
+ // shared
634
+ }
635
+ } else if (result.action === Share.dismissedAction) {
636
+ // dismissed
637
+ }
638
+ } catch (error: any) {
639
+ Alert.alert(error.message);
640
+ }
641
+ }}
642
+ title='Share a message'
643
+ />
644
+ </View>
645
+ );
646
+ },
75
647
  },
648
+ <% } %>
649
+ <% if (props.stylingPackage?.options.selectedComponents.includes('bottom-sheet')) { %>
76
650
  {
77
- name: 'Bottom Tabs Navigation',
78
- href: '/bottom-tabs/',
651
+ name: 'Bottom Sheet',
652
+ component: function BottomSheetExample() {
653
+ const { colorScheme } = useColorScheme();
654
+ const bottomSheetModalRef = useSheetRef();
655
+
656
+ return (
657
+ <View className='items-center'>
658
+ <DefaultButton
659
+ color={
660
+ colorScheme === 'dark' && Platform.OS === 'ios'
661
+ ? 'white'
662
+ : 'black'
663
+ }
664
+ title='Open Bottom Sheet'
665
+ onPress={() => bottomSheetModalRef.current?.present()}
666
+ />
667
+ <Sheet ref={bottomSheetModalRef} snapPoints={[200]}>
668
+ <View className='flex-1 justify-center items-center pb-8'>
669
+ <Text>@gorhom/bottom-sheet 🎉</Text>
670
+ </View>
671
+ </Sheet>
672
+ </View>
673
+ );
674
+ },
79
675
  },
676
+ <% } %>
677
+ <% if (props.stylingPackage?.options.selectedComponents.includes('avatar')) { %>
80
678
  {
81
- name: 'Top Tabs Navigation',
82
- href: '/top-tabs/',
679
+ name: 'Avatar',
680
+ component: function AvatarExample() {
681
+ const GITHUB_AVATAR_URI = 'https://github.com/mrzachnugent.png';
682
+ return (
683
+ <View className='items-center'>
684
+ <Avatar alt="Zach Nugent's Avatar">
685
+ <AvatarImage source={{ uri: GITHUB_AVATAR_URI }} />
686
+ <AvatarFallback>
687
+ <Text>ZN</Text>
688
+ </AvatarFallback>
689
+ </Avatar>
690
+ </View>
691
+ );
692
+ },
83
693
  },
84
- ] as const;
694
+ <% } %>
695
+ ];
696
+