create-expo-stack 2.20.0-next.7f9c8bc → 2.20.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.
Files changed (87) hide show
  1. package/README.md +1 -3
  2. package/build/cli.js +3 -2
  3. package/build/commands/create-expo-stack.js +9 -30
  4. package/build/constants.js +4 -4
  5. package/build/templates/base/App.tsx.ejs +12 -51
  6. package/build/templates/base/app.json.ejs +1 -0
  7. package/build/templates/base/babel.config.js.ejs +13 -16
  8. package/build/templates/base/components/Button.tsx.ejs +1 -0
  9. package/build/templates/base/components/Container.tsx.ejs +1 -0
  10. package/build/templates/base/package.json.ejs +34 -67
  11. package/build/templates/base/tsconfig.json.ejs +12 -7
  12. package/build/templates/packages/expo-router/drawer/app/+not-found.tsx.ejs +19 -60
  13. package/build/templates/packages/expo-router/drawer/app/_layout.tsx.ejs +2 -41
  14. package/build/templates/packages/expo-router/stack/app/+not-found.tsx.ejs +34 -66
  15. package/build/templates/packages/expo-router/stack/app/_layout.tsx.ejs +15 -51
  16. package/build/templates/packages/expo-router/stack/app/details.tsx.ejs +37 -5
  17. package/build/templates/packages/expo-router/stack/app/index.tsx.ejs +34 -11
  18. package/build/templates/packages/expo-router/tabs/app/+not-found.tsx.ejs +21 -60
  19. package/build/templates/packages/expo-router/tabs/app/_layout.tsx.ejs +8 -48
  20. package/build/templates/packages/nativewind/global.css +3 -2
  21. package/build/templates/packages/nativewind/metro.config.js +3 -4
  22. package/build/templates/packages/nativewind/nativewind-env.d.ts +1 -3
  23. package/build/templates/packages/nativewind/tailwind.config.js.ejs +15 -0
  24. package/build/templates/packages/nativewindui/components/Container.tsx.ejs +1 -0
  25. package/build/templates/packages/nativewindui/components/EditScreenInfo.tsx.ejs +1 -1
  26. package/build/templates/packages/nativewindui/components/ScreenContent.tsx.ejs +1 -1
  27. package/build/templates/packages/nativewindui/components/nativewindui/Icon/Icon.ios.tsx.ejs +52 -0
  28. package/build/templates/packages/nativewindui/components/nativewindui/Icon/Icon.tsx.ejs +58 -0
  29. package/build/templates/packages/nativewindui/components/nativewindui/Icon/index.ts.ejs +16 -0
  30. package/build/templates/packages/nativewindui/components/nativewindui/Icon/types.ts.ejs +18 -0
  31. package/build/templates/packages/nativewindui/components/{ThemeToggle.tsx.ejs → nativewindui/ThemeToggle.tsx.ejs} +8 -10
  32. package/build/templates/packages/nativewindui/drawer/app/(drawer)/index.tsx.ejs +17 -19
  33. package/build/templates/packages/nativewindui/drawer/app/+not-found.tsx.ejs +4 -44
  34. package/build/templates/packages/nativewindui/drawer/app/_layout.tsx.ejs +2 -2
  35. package/build/templates/packages/nativewindui/drawer/app/modal.tsx.ejs +4 -4
  36. package/build/templates/packages/nativewindui/lib/useColorScheme.tsx.ejs +3 -37
  37. package/build/templates/packages/nativewindui/stack/app/+not-found.tsx.ejs +1 -1
  38. package/build/templates/packages/nativewindui/stack/app/_layout.tsx.ejs +17 -34
  39. package/build/templates/packages/nativewindui/stack/app/index.tsx.ejs +230 -275
  40. package/build/templates/packages/nativewindui/stack/app/modal.tsx.ejs +7 -7
  41. package/build/templates/packages/nativewindui/tabs/app/(tabs)/index.tsx.ejs +6 -7
  42. package/build/templates/packages/nativewindui/tabs/app/+not-found.tsx.ejs +0 -40
  43. package/build/templates/packages/nativewindui/theme/colors.ts.ejs +52 -0
  44. package/build/templates/packages/nativewindui/theme/index.ts.ejs +2 -2
  45. package/build/templates/packages/nativewindui/theme/with-opacity.ts.ejs +155 -0
  46. package/build/templates/packages/react-navigation/App.tsx.ejs +2 -42
  47. package/build/types/constants.d.ts +1 -1
  48. package/build/types/types.d.ts +3 -3
  49. package/build/types/utilities/configAnalytics.d.ts +2 -2
  50. package/build/types.js +1 -3
  51. package/build/utilities/clearNavigationPackages.js +2 -2
  52. package/build/utilities/clearStylingPackages.js +2 -2
  53. package/build/utilities/configAnalytics.js +5 -4
  54. package/build/utilities/configureProjectFiles.js +31 -68
  55. package/build/utilities/copyBaseAssets.js +3 -2
  56. package/build/utilities/generateNWUI.js +8 -7
  57. package/build/utilities/generateProjectFiles.js +4 -9
  58. package/build/utilities/getPackageManager.js +6 -5
  59. package/build/utilities/printOutput.js +5 -16
  60. package/build/utilities/renderTitle.js +3 -2
  61. package/build/utilities/runCLI.js +15 -17
  62. package/build/utilities/runEasConfigure.js +3 -2
  63. package/build/utilities/runIgnite.js +3 -2
  64. package/build/utilities/showHelp.js +3 -4
  65. package/build/utilities/systemCommand.js +3 -3
  66. package/build/utilities/usePackage.js +3 -2
  67. package/build/utilities/validateProjectName.js +3 -2
  68. package/package.json +73 -71
  69. package/build/templates/packages/nativewind/postcss.config.mjs +0 -5
  70. package/build/templates/packages/nativewindui/components/BackButton.tsx.ejs +0 -23
  71. package/build/templates/packages/nativewindui/components/Button.tsx.ejs +0 -41
  72. package/build/templates/packages/nativewindui/lib/useHeaderSearchBar.tsx.ejs +0 -31
  73. package/build/templates/packages/restyle/components/BackButton.tsx.ejs +0 -15
  74. package/build/templates/packages/restyle/components/Button.tsx.ejs +0 -40
  75. package/build/templates/packages/restyle/components/Container.tsx.ejs +0 -6
  76. package/build/templates/packages/restyle/components/EditScreenInfo.tsx.ejs +0 -29
  77. package/build/templates/packages/restyle/components/ScreenContent.tsx.ejs +0 -21
  78. package/build/templates/packages/restyle/theme/Box.tsx.ejs +0 -6
  79. package/build/templates/packages/restyle/theme/Text.tsx.ejs +0 -6
  80. package/build/templates/packages/restyle/theme/index.ts.ejs +0 -6
  81. package/build/templates/packages/restyle/theme/theme.ts.ejs +0 -67
  82. package/build/templates/packages/tamagui/components/BackButton.tsx.ejs +0 -19
  83. package/build/templates/packages/tamagui/components/Button.tsx.ejs +0 -18
  84. package/build/templates/packages/tamagui/components/Container.tsx.ejs +0 -6
  85. package/build/templates/packages/tamagui/components/EditScreenInfo.tsx.ejs +0 -29
  86. package/build/templates/packages/tamagui/components/ScreenContent.tsx.ejs +0 -23
  87. package/build/templates/packages/tamagui/tamagui.config.ts.ejs +0 -130
@@ -1,79 +1,77 @@
1
1
  import { useHeaderHeight } from '@react-navigation/elements';
2
- import { LegendList } from '@legendapp/list';
2
+ import { FlashList } from '@shopify/flash-list';
3
3
  import { cssInterop } from 'nativewind';
4
4
  import * as React from 'react';
5
5
  import {
6
+ <% if (props.stylingPackage?.options.selectedComponents.includes('activity-view')) { %>
7
+ Alert,
8
+ <% } %>
6
9
  <% if (
7
10
  props.stylingPackage?.options.selectedComponents.includes('action-sheet') ||
8
- props.stylingPackage?.options.selectedComponents.includes('activity-view') ||
9
- props.stylingPackage?.options.selectedComponents.includes('bottom-sheet')
11
+ props.stylingPackage?.options.selectedComponents.includes('activity-view')
10
12
  ) { %>
11
13
  Button as RNButton,
12
14
  ButtonProps,
13
15
  <% } %>
14
16
  Linking,
15
- <% if (props.stylingPackage?.options.selectedComponents.includes('bottom-sheet')) { %>
16
- Platform,
17
- <% } %>
18
17
  <% if (props.stylingPackage?.options.selectedComponents.includes('activity-view')) { %>
19
18
  Share,
20
19
  <% } %>
21
20
  useWindowDimensions,
22
21
  View,
23
- Alert,
24
22
  } from 'react-native';
25
23
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
24
+ import { SearchBarProps } from 'react-native-screens';
26
25
  <% if (props.stylingPackage?.options.selectedComponents.includes('action-sheet')) { %>
27
26
  import { useActionSheet } from '@expo/react-native-action-sheet';
28
27
  <% } %>
29
- import { Icon } from '@roninoss/icons';
30
- <% if (props.stylingPackage?.options.selectedComponents.includes('ratings-indicator')) { %>
31
- import * as StoreReview from 'expo-store-review';
28
+ import { useNavigation } from '@react-navigation/native';
29
+ <% if (props.stylingPackage?.options.selectedComponents.includes('button')) { %>
30
+ import * as Haptics from 'expo-haptics';
31
+ <% } else { %>
32
+ // import * as Haptics from 'expo-haptics';
32
33
  <% } %>
33
34
 
34
35
  <% if (props.stylingPackage?.options.selectedComponents.includes('activity-indicator')) { %>
35
- import { ActivityIndicator } from '~/components/nativewindui/ActivityIndicator';
36
+ import { ActivityIndicator } from '@/components/nativewindui/ActivityIndicator';
36
37
  <% } %>
37
38
  <% if (props.stylingPackage?.options.selectedComponents.includes('avatar')) { %>
38
- import { Avatar, AvatarFallback, AvatarImage } from '~/components/nativewindui/Avatar';
39
+ import { Avatar, AvatarFallback, AvatarImage } from '@/components/nativewindui/Avatar';
40
+ <% } %>
41
+ <% if (props.stylingPackage?.options.selectedComponents.includes('button')) { %>
42
+ import { Button } from '@/components/nativewindui/Button';
43
+ <% } else { %>
44
+ // import { Button } from '@/components/nativewindui/Button';
39
45
  <% } %>
40
46
  <% if (props.stylingPackage?.options.selectedComponents.includes('date-picker')) { %>
41
- import { DatePicker } from '~/components/nativewindui/DatePicker';
47
+ import { DatePicker } from '@/components/nativewindui/DatePicker';
42
48
  <% } %>
49
+ import { Icon } from '@/components/nativewindui/Icon';
43
50
  <% if (props.stylingPackage?.options.selectedComponents.includes('picker')) { %>
44
- import { Picker, PickerItem } from '~/components/nativewindui/Picker';
51
+ import { Picker, PickerItem } from '@/components/nativewindui/Picker';
45
52
  <% } %>
46
53
  <% if (props.stylingPackage?.options.selectedComponents.includes('progress-indicator')) { %>
47
- import { ProgressIndicator } from '~/components/nativewindui/ProgressIndicator';
48
- <% } %>
49
- <% if (props.stylingPackage?.options.selectedComponents.includes('bottom-sheet')) { %>
50
- import { Sheet, useSheetRef } from '~/components/nativewindui/Sheet';
54
+ import { ProgressIndicator } from '@/components/nativewindui/ProgressIndicator';
51
55
  <% } %>
52
56
  <% if (props.stylingPackage?.options.selectedComponents.includes('slider')) { %>
53
- import { Slider } from '~/components/nativewindui/Slider';
57
+ import { Slider } from '@/components/nativewindui/Slider';
58
+ <% } %>
59
+ <% if (props.stylingPackage?.options.selectedComponents.includes('text')) { %>
60
+ import { Text } from '@/components/nativewindui/Text';
61
+ <% } else { %>
62
+ // import { Text } from '@/components/nativewindui/Text';
54
63
  <% } %>
55
- import { Text } from '~/components/nativewindui/Text';
56
64
  <% if (props.stylingPackage?.options.selectedComponents.includes('toggle')) { %>
57
- import { Toggle } from '~/components/nativewindui/Toggle';
65
+ import { Toggle } from '@/components/nativewindui/Toggle';
58
66
  <% } %>
59
- import { useColorScheme } from '~/lib/useColorScheme';
60
- import { useHeaderSearchBar } from '~/lib/useHeaderSearchBar';
61
-
67
+ import { useColorScheme } from '@/lib/useColorScheme';
68
+ import { COLORS } from '@/theme/colors';
62
69
 
63
- cssInterop(LegendList, {
70
+ cssInterop(FlashList, {
64
71
  className: 'style',
65
72
  contentContainerClassName: 'contentContainerStyle',
66
73
  });
67
- <% if (
68
- props.stylingPackage?.options.selectedComponents.includes('action-sheet') ||
69
- props.stylingPackage?.options.selectedComponents.includes('activity-view') ||
70
- props.stylingPackage?.options.selectedComponents.includes('bottom-sheet')
71
- ) { %>
72
- function DefaultButton({ color, ...props }: ButtonProps) {
73
- const { colors } = useColorScheme();
74
- return <RNButton color={color ?? colors.primary} {...props} />;
75
- }
76
- <% } %>
74
+
77
75
  export default function Screen() {
78
76
  const searchValue = useHeaderSearchBar({ hideWhenScrolling: COMPONENTS.length === 0 });
79
77
 
@@ -82,22 +80,47 @@ export default function Screen() {
82
80
  : COMPONENTS;
83
81
 
84
82
  return (
85
- <LegendList
83
+ <FlashList
86
84
  contentInsetAdjustmentBehavior="automatic"
87
85
  keyboardShouldPersistTaps="handled"
88
86
  data={data}
89
- estimatedItemSize={200}
90
87
  contentContainerClassName="py-4 android:pb-12"
91
88
  extraData={searchValue}
89
+ removeClippedSubviews={false} // used for slecting text on android
92
90
  keyExtractor={keyExtractor}
93
91
  ItemSeparatorComponent={renderItemSeparator}
94
92
  renderItem={renderItem}
95
93
  ListEmptyComponent={COMPONENTS.length === 0 ? ListEmptyComponent : undefined}
96
- recycleItems
97
94
  />
98
95
  );
99
96
  }
100
97
 
98
+ function useHeaderSearchBar(props: SearchBarProps = {}) {
99
+ const { colorScheme, colors } = useColorScheme();
100
+ const navigation = useNavigation();
101
+ const [search, setSearch] = React.useState('');
102
+
103
+ React.useLayoutEffect(() => {
104
+ navigation.setOptions({
105
+ headerSearchBarOptions: {
106
+ placeholder: 'Search...',
107
+ textColor: colors.foreground,
108
+ tintColor: colors.primary,
109
+ headerIconColor: colors.foreground,
110
+ hintTextColor: colors.grey,
111
+ hideWhenScrolling: false,
112
+ onChangeText(ev) {
113
+ setSearch(ev.nativeEvent.text);
114
+ },
115
+ ...props,
116
+ } satisfies SearchBarProps,
117
+ });
118
+ // eslint-disable-next-line react-hooks/exhaustive-deps
119
+ }, [navigation, colorScheme]);
120
+
121
+ return search;
122
+ }
123
+
101
124
  function ListEmptyComponent() {
102
125
  const insets = useSafeAreaInsets();
103
126
  const dimensions = useWindowDimensions();
@@ -107,7 +130,7 @@ function ListEmptyComponent() {
107
130
 
108
131
  return (
109
132
  <View style={{ height }} className="flex-1 items-center justify-center gap-1 px-12">
110
- <Icon name="file-plus-outline" size={42} color={colors.grey} />
133
+ <Icon name="doc.badge.plus" size={42} color={colors.grey} />
111
134
  <Text variant='title3' className='pb-1 text-center font-semibold'>
112
135
  No Components Installed
113
136
  </Text>
@@ -118,7 +141,7 @@ function ListEmptyComponent() {
118
141
  variant='subhead'
119
142
  className='text-primary'
120
143
  >
121
- NativeWindUI
144
+ NativewindUI
122
145
  </Text>
123
146
  {' website.'}
124
147
  </Text>
@@ -154,9 +177,7 @@ function Card({ children, title }: { children: React.ReactNode; title: string })
154
177
  </View>
155
178
  );
156
179
  }
157
- <% if (props.stylingPackage?.options.selectedComponents.includes('ratings-indicator')) { %>
158
- let hasRequestedReview = false;
159
- <% } %>
180
+
160
181
  const COMPONENTS: ComponentItem[] = [
161
182
  <% if (!props.stylingPackage?.options.selectedComponents.length) { %>
162
183
  // ADD ANY ADDITIONAL COMPONENTS HERE
@@ -171,108 +192,58 @@ const COMPONENTS: ComponentItem[] = [
171
192
  // },
172
193
  // },
173
194
  <% } %>
174
- <% if (props.stylingPackage?.options.selectedComponents.includes('picker')) { %>
175
- {
176
- name: 'Picker',
177
- component: function PickerExample() {
178
- const { colors } = useColorScheme();
179
- const [picker, setPicker] = React.useState('blue');
180
- return (
181
- <Picker
182
- selectedValue={picker}
183
- onValueChange={(itemValue) => setPicker(itemValue)}
184
- >
185
- <PickerItem
186
- label='Red'
187
- value='red'
188
- color={colors.foreground}
189
- style={{
190
- backgroundColor: colors.root,
191
- }}
192
- />
193
- <PickerItem
194
- label='Blue'
195
- value='blue'
196
- color={colors.foreground}
197
- style={{
198
- backgroundColor: colors.root,
199
- }}
200
- />
201
- <PickerItem
202
- label='Green'
203
- value='green'
204
- color={colors.foreground}
205
- style={{
206
- backgroundColor: colors.root,
207
- }}
208
- />
209
- </Picker>
210
- );
211
- },
212
- },
213
- <% } %>
214
- <% if (props.stylingPackage?.options.selectedComponents.includes('date-picker')) { %>
195
+ <% if (props.stylingPackage?.options.selectedComponents.includes('avatar')) { %>
215
196
  {
216
- name: 'Date Picker',
217
- component: function DatePickerExample() {
218
- const [date, setDate] = React.useState(new Date());
197
+ name: 'Avatar',
198
+ component: function AvatarExample() {
199
+ const TWITTER_AVATAR_URI = 'https://pbs.twimg.com/profile_images/1782428433898708992/1voyv4_A_400x400.jpg';
219
200
  return (
220
201
  <View className='items-center'>
221
- <DatePicker
222
- value={date}
223
- mode='datetime'
224
- onChange={(ev) => {
225
- setDate(new Date(ev.nativeEvent.timestamp));
226
- }}
227
- />
202
+ <Avatar alt="NativewindUI Avatar">
203
+ <AvatarImage source={{ uri: TWITTER_AVATAR_URI }} />
204
+ <AvatarFallback>
205
+ <Text>NWUI</Text>
206
+ </AvatarFallback>
207
+ </Avatar>
228
208
  </View>
229
209
  );
230
210
  },
231
211
  },
232
212
  <% } %>
213
+ // {
214
+ // name: 'Button',
215
+ // component: function ButtonExample() {
216
+ // function onPress() {
217
+ // Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
218
+ // }
219
+ // return (
220
+ // <View className="items-center justify-center gap-4 p-4">
221
+ // <Button onPress={onPress}>
222
+ // <Icon name="play.fill" className="ios:size-4 text-white" />
223
+ // <Text>Primary</Text>
224
+ // </Button>
225
+ // <Button onPress={onPress} variant="secondary">
226
+ // <Text>Secondary</Text>
227
+ // </Button>
228
+ // <Button onPress={onPress} variant="tonal">
229
+ // <Text>Tonal</Text>
230
+ // </Button>
231
+ // <Button onPress={onPress} variant="plain">
232
+ // <Text>Plain</Text>
233
+ // </Button>
234
+ // <Button onPress={onPress} variant="tonal" size="icon">
235
+ // <Icon name="heart.fill" className="ios:text-primary size-5 text-foreground" />
236
+ // </Button>
237
+ // </View>
238
+ // );
239
+ // },
240
+ // },
233
241
  <% if (props.stylingPackage?.options.selectedComponents.includes('slider')) { %>
234
242
  {
235
243
  name: 'Slider',
236
244
  component: function SliderExample() {
237
245
  const [sliderValue, setSliderValue] = React.useState(0.5);
238
- return <Slider value={sliderValue} onValueChange={setSliderValue} />;
239
- },
240
- },
241
- <% } %>
242
- <% if (props.stylingPackage?.options.selectedComponents.includes('toggle')) { %>
243
- {
244
- name: 'Toggle',
245
- component: function ToggleExample() {
246
- const [switchValue, setSwitchValue] = React.useState(true);
247
- return (
248
- <View className='items-center'>
249
- <Toggle value={switchValue} onValueChange={setSwitchValue} />
250
- </View>
251
- );
252
- }
253
- },
254
- <% } %>
255
- <% if (props.stylingPackage?.options.selectedComponents.includes('progress-indicator')) { %>
256
- {
257
- name: 'Progress Indicator',
258
- component: function ProgressIndicatorExample() {
259
- const [progress, setProgress] = React.useState(13);
260
- const id = React.useRef<ReturnType<typeof setInterval> | null>(null);
261
- React.useEffect(() => {
262
- if (!id.current) {
263
- id.current = setInterval(() => {
264
- setProgress((prev) => (prev >= 99 ? 0 : prev + 5));
265
- }, 1000);
266
- }
267
- return () => {
268
- if (id.current) clearInterval(id.current);
269
- };
270
- }, []);
271
- return (
272
- <View className='p-4'>
273
- <ProgressIndicator value={progress} />
274
- </View>
275
- );
246
+ return <Slider value={sliderValue} onValueChange={setSliderValue} minimumValue={0} maximumValue={1} />;
276
247
  },
277
248
  },
278
249
  <% } %>
@@ -281,7 +252,7 @@ const COMPONENTS: ComponentItem[] = [
281
252
  name: 'Activity Indicator',
282
253
  component: function ActivityIndicatorExample() {
283
254
  return (
284
- <View className='p-4 items-center'>
255
+ <View className='items-center p-4'>
285
256
  <ActivityIndicator />
286
257
  </View>
287
258
  );
@@ -294,10 +265,11 @@ const COMPONENTS: ComponentItem[] = [
294
265
  component: function ActionSheetExample() {
295
266
  const { colorScheme, colors } = useColorScheme();
296
267
  const { showActionSheetWithOptions } = useActionSheet();
268
+
297
269
  return (
298
270
  <View className='items-center'>
299
- <DefaultButton
300
- color={'grey'}
271
+ <Button
272
+ variant='secondary'
301
273
  onPress={async () => {
302
274
  const options = ['Delete', 'Save', 'Cancel'];
303
275
  const destructiveButtonIndex = 0;
@@ -330,121 +302,34 @@ const COMPONENTS: ComponentItem[] = [
330
302
  }
331
303
  }
332
304
  );
333
- }}
334
- title='Open action sheet'
335
- />
305
+ }}>
306
+ <Text>Open action sheet</Text>
307
+ </Button>
336
308
  </View>
337
309
  );
338
310
  },
339
311
  },
340
312
  <% } %>
313
+ <% if (props.stylingPackage?.options.selectedComponents.includes('progress-indicator')) { %>
341
314
  {
342
- name: 'Text',
343
- component: function TextExample() {
344
- return (
345
- <View className='gap-2'>
346
- <Text variant='largeTitle' className='text-center'>
347
- Large Title
348
- </Text>
349
- <Text variant='title1' className='text-center'>
350
- Title 1
351
- </Text>
352
- <Text variant='title2' className='text-center'>
353
- Title 2
354
- </Text>
355
- <Text variant='title3' className='text-center'>
356
- Title 3
357
- </Text>
358
- <Text variant='heading' className='text-center'>
359
- Heading
360
- </Text>
361
- <Text variant='body' className='text-center'>
362
- Body
363
- </Text>
364
- <Text variant='callout' className='text-center'>
365
- Callout
366
- </Text>
367
- <Text variant='subhead' className='text-center'>
368
- Subhead
369
- </Text>
370
- <Text variant='footnote' className='text-center'>
371
- Footnote
372
- </Text>
373
- <Text variant='caption1' className='text-center'>
374
- Caption 1
375
- </Text>
376
- <Text variant='caption2' className='text-center'>
377
- Caption 2
378
- </Text>
379
- </View>
380
- );
381
- },
382
- },
383
- {
384
- name: 'Selectable Text',
385
- component: function SelectableTextExample() {
386
- return (
387
- <Text uiTextView selectable>
388
- Long press or double press this text
389
- </Text>
390
- );
391
- },
392
- },
393
- <% if (props.stylingPackage?.options.selectedComponents.includes('ratings-indicator')) { %>
394
- {
395
- name: 'Ratings Indicator',
396
- component: function RatingsIndicatorExample() {
397
- React.useEffect(() => {
398
- async function showRequestReview() {
399
- if (hasRequestedReview) return;
400
- try {
401
- if (await StoreReview.hasAction()) {
402
- await StoreReview.requestReview();
403
- }
404
- } catch (error) {
405
- console.log(
406
- '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',
407
- error
408
- );
409
- } finally {
410
- hasRequestedReview = true;
411
- }
412
- }
413
- const timeout = setTimeout(() => {
414
- showRequestReview();
415
- }, 1000);
315
+ name: 'Progress Indicator',
316
+ component: function ProgressIndicatorExample() {
317
+ const [progress, setProgress] = React.useState(13);
416
318
 
417
- return () => clearTimeout(timeout);
319
+ React.useEffect(() => {
320
+ let id: ReturnType<typeof setInterval> | null = null;
321
+ if (!id) {
322
+ id = setInterval(() => {
323
+ setProgress((prev) => (prev >= 99 ? 0 : prev + 5));
324
+ }, 1000);
325
+ }
326
+ return () => {
327
+ if (id) clearInterval(id);
328
+ };
418
329
  }, []);
419
-
420
330
  return (
421
- <View className="gap-3">
422
- <Text className="pb-2 text-center font-semibold">Please follow the guidelines.</Text>
423
- <View className="flex-row">
424
- <Text className="w-6 text-center text-muted-foreground">·</Text>
425
- <View className="flex-1">
426
- <Text variant="caption1" className="text-muted-foreground">
427
- Do not call StoreReview.requestReview() from a button
428
- </Text>
429
- </View>
430
- </View>
431
- <View className="flex-row">
432
- <Text className="w-6 text-center text-muted-foreground">·</Text>
433
- <View className="flex-1">
434
- <Text variant="caption1" className="text-muted-foreground">
435
- Do not request a review when the user is doing something time sensitive.
436
- </Text>
437
- </View>
438
- </View>
439
- <View className="flex-row">
440
- <Text className="w-6 text-center text-muted-foreground">·</Text>
441
- <View className="flex-1">
442
- <Text variant="caption1" className="text-muted-foreground">
443
- Do not ask the user any questions before or while presenting the rating button or
444
- card.
445
- </Text>
446
- </View>
447
- </View>
331
+ <View className='p-4'>
332
+ <ProgressIndicator value={progress} />
448
333
  </View>
449
334
  );
450
335
  },
@@ -456,11 +341,12 @@ const COMPONENTS: ComponentItem[] = [
456
341
  component: function ActivityViewExample() {
457
342
  return (
458
343
  <View className='items-center'>
459
- <DefaultButton
344
+ <Button
345
+ variant='tonal'
460
346
  onPress={async () => {
461
347
  try {
462
348
  const result = await Share.share({
463
- message: 'NativeWindUI | Familiar interface, native feel.',
349
+ message: 'NativewindUI | Native feeling UI with TailwindCSS.',
464
350
  });
465
351
  if (result.action === Share.sharedAction) {
466
352
  if (result.activityType) {
@@ -474,58 +360,127 @@ const COMPONENTS: ComponentItem[] = [
474
360
  } catch (error: any) {
475
361
  Alert.alert(error.message);
476
362
  }
363
+ }}>
364
+ <Text>Share a message</Text>
365
+ </Button>
366
+ </View>
367
+ );
368
+ },
369
+ },
370
+ <% } %>
371
+ <% if (props.stylingPackage?.options.selectedComponents.includes('date-picker')) { %>
372
+ {
373
+ name: 'Date Picker',
374
+ component: function DatePickerExample() {
375
+ const [date, setDate] = React.useState(new Date());
376
+ return (
377
+ <View className='items-center'>
378
+ <DatePicker
379
+ value={date}
380
+ mode='datetime'
381
+ onChange={(ev) => {
382
+ setDate(new Date(ev.nativeEvent.timestamp));
477
383
  }}
478
- title='Share a message'
479
384
  />
480
385
  </View>
481
386
  );
482
387
  },
483
388
  },
484
389
  <% } %>
485
- <% if (props.stylingPackage?.options.selectedComponents.includes('bottom-sheet')) { %>
390
+ <% if (props.stylingPackage?.options.selectedComponents.includes('picker')) { %>
486
391
  {
487
- name: 'Bottom Sheet',
488
- component: function BottomSheetExample() {
489
- const { colorScheme } = useColorScheme();
490
- const bottomSheetModalRef = useSheetRef();
392
+ name: 'Picker',
393
+ component: function PickerExample() {
394
+ const { colors } = useColorScheme();
395
+ const [picker, setPicker] = React.useState('blue');
491
396
 
492
397
  return (
493
- <View className='items-center'>
494
- <DefaultButton
495
- color={
496
- colorScheme === 'dark' && Platform.OS === 'ios'
497
- ? 'white'
498
- : 'black'
499
- }
500
- title='Open Bottom Sheet'
501
- onPress={() => bottomSheetModalRef.current?.present()}
398
+ <Picker
399
+ selectedValue={picker}
400
+ onValueChange={(itemValue) => setPicker(itemValue)}
401
+ >
402
+ <PickerItem
403
+ label='Red'
404
+ value='red'
405
+ color={colors.foreground}
406
+ style={{
407
+ backgroundColor: colors.root,
408
+ }}
502
409
  />
503
- <Sheet ref={bottomSheetModalRef} snapPoints={[200]}>
504
- <View className='flex-1 justify-center items-center pb-8'>
505
- <Text>@gorhom/bottom-sheet 🎉</Text>
506
- </View>
507
- </Sheet>
508
- </View>
410
+ <PickerItem
411
+ label='Blue'
412
+ value='blue'
413
+ color={colors.foreground}
414
+ style={{
415
+ backgroundColor: colors.root,
416
+ }}
417
+ />
418
+ <PickerItem
419
+ label='Green'
420
+ value='green'
421
+ color={colors.foreground}
422
+ style={{
423
+ backgroundColor: colors.root,
424
+ }}
425
+ />
426
+ </Picker>
509
427
  );
510
428
  },
511
429
  },
512
430
  <% } %>
513
- <% if (props.stylingPackage?.options.selectedComponents.includes('avatar')) { %>
431
+ // {
432
+ // name: 'Text',
433
+ // component: function TextExample() {
434
+ // return (
435
+ // <View className="gap-2">
436
+ // <Text variant="largeTitle" className="text-center">
437
+ // Large Title
438
+ // </Text>
439
+ // <Text variant="title1" className="text-center">
440
+ // Title 1
441
+ // </Text>
442
+ // <Text variant="title2" className="text-center">
443
+ // Title 2
444
+ // </Text>
445
+ // <Text variant="title3" className="text-center">
446
+ // Title 3
447
+ // </Text>
448
+ // <Text variant="heading" className="text-center">
449
+ // Heading
450
+ // </Text>
451
+ // <Text variant="body" className="text-center">
452
+ // Body
453
+ // </Text>
454
+ // <Text variant="callout" className="text-center">
455
+ // Callout
456
+ // </Text>
457
+ // <Text variant="subhead" className="text-center">
458
+ // Subhead
459
+ // </Text>
460
+ // <Text variant="footnote" className="text-center">
461
+ // Footnote
462
+ // </Text>
463
+ // <Text variant="caption1" className="text-center">
464
+ // Caption 1
465
+ // </Text>
466
+ // <Text variant="caption2" className="text-center">
467
+ // Caption 2
468
+ // </Text>
469
+ // </View>
470
+ // );
471
+ // },
472
+ // },
473
+ <% if (props.stylingPackage?.options.selectedComponents.includes('toggle')) { %>
514
474
  {
515
- name: 'Avatar',
516
- component: function AvatarExample() {
517
- const TWITTER_AVATAR_URI = 'https://pbs.twimg.com/profile_images/1782428433898708992/1voyv4_A_400x400.jpg';
475
+ name: 'Toggle',
476
+ component: function ToggleExample() {
477
+ const [switchValue, setSwitchValue] = React.useState(true);
518
478
  return (
519
479
  <View className='items-center'>
520
- <Avatar alt="NativeWindUI Avatar">
521
- <AvatarImage source={{ uri: TWITTER_AVATAR_URI }} />
522
- <AvatarFallback>
523
- <Text>NUI</Text>
524
- </AvatarFallback>
525
- </Avatar>
480
+ <Toggle value={switchValue} onValueChange={setSwitchValue} className='mx-auto' />
526
481
  </View>
527
482
  );
528
- },
483
+ }
529
484
  },
530
485
  <% } %>
531
486
  ];