create-expo-stack 2.7.0-next.a59a8d8 → 2.7.0-next.b1717c9

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