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