1import { BottomTabNavigationProp } from '@react-navigation/bottom-tabs';
2import { createStackNavigator } from '@react-navigation/stack';
3import * as React from 'react';
4
5import TabIcon from '../components/TabIcon';
6import { Layout } from '../constants';
7import ExpoComponents from '../screens/ExpoComponentsScreen';
8import { ImageScreens } from '../screens/Image/ImageScreen';
9import getStackConfig from './StackConfig';
10import { optionalRequire } from './routeBuilder';
11
12const Stack = createStackNavigator();
13
14export const Screens = [
15  {
16    getComponent() {
17      return optionalRequire(() => require('../screens/DrawerLayoutAndroidScreen'));
18    },
19    name: 'DrawerLayoutAndroid',
20  },
21  {
22    getComponent() {
23      return optionalRequire(() => require('../screens/BarCodeScannerScreen'));
24    },
25    name: 'BarCodeScanner',
26  },
27  {
28    getComponent() {
29      return optionalRequire(() => require('../screens/ModalScreen'));
30    },
31    name: 'Modal',
32  },
33  {
34    getComponent() {
35      return optionalRequire(() => require('../screens/ScrollViewScreen'));
36    },
37    name: 'ScrollView',
38  },
39  {
40    getComponent() {
41      return optionalRequire(() => require('../screens/MaskedViewScreen'));
42    },
43    name: 'MaskedView',
44    options: { title: 'Basic Mask Example' },
45  },
46  {
47    getComponent() {
48      return optionalRequire(() => require('../screens/BlurView/BlurViewScreen'));
49    },
50    name: 'BlurView',
51  },
52  {
53    getComponent() {
54      return optionalRequire(() => require('../screens/Camera/CameraScreen'));
55    },
56    name: 'Camera',
57  },
58  {
59    getComponent() {
60      return optionalRequire(() => require('../screens/TextScreen'));
61    },
62    name: 'Text',
63  },
64  {
65    getComponent() {
66      return optionalRequire(() => require('../screens/TextInputScreen'));
67    },
68    name: 'TextInput',
69  },
70  {
71    getComponent() {
72      return optionalRequire(() => require('../screens/TouchablesScreen'));
73    },
74    name: 'Touchables',
75  },
76  {
77    getComponent() {
78      return optionalRequire(() => require('../screens/ProgressViewIOSScreen'));
79    },
80    name: 'ProgressViewIOS',
81  },
82  {
83    getComponent() {
84      return optionalRequire(() => require('../screens/ProgressBarAndroidScreen'));
85    },
86    name: 'ProgressBarAndroid',
87  },
88  {
89    getComponent() {
90      return optionalRequire(() => require('../screens/TouchableBounceScreen'));
91    },
92    name: 'TouchableBounce',
93  },
94  {
95    getComponent() {
96      return optionalRequire(() => require('../screens/SwitchScreen'));
97    },
98    name: 'Switch',
99  },
100  {
101    getComponent() {
102      return optionalRequire(() => require('../screens/SliderScreen'));
103    },
104    name: 'Slider',
105  },
106  {
107    getComponent() {
108      return optionalRequire(() => require('../screens/PressableScreen'));
109    },
110    name: 'Pressable',
111  },
112  {
113    getComponent() {
114      return optionalRequire(() => require('../screens/PickerScreen'));
115    },
116    name: 'Picker',
117  },
118  {
119    getComponent() {
120      return optionalRequire(() => require('../screens/CheckboxScreen'));
121    },
122    name: 'Checkbox',
123  },
124  {
125    getComponent() {
126      return optionalRequire(() => require('../screens/ButtonScreen'));
127    },
128    name: 'Button',
129  },
130  {
131    getComponent() {
132      return optionalRequire(() => require('../screens/ActivityIndicatorScreen'));
133    },
134    name: 'ActivityIndicator',
135  },
136  {
137    getComponent() {
138      return optionalRequire(() => require('../screens/QRCodeScreen'));
139    },
140    name: 'QRCode',
141    options: { title: 'QR Code' },
142  },
143  {
144    getComponent() {
145      return optionalRequire(() => require('../screens/DateTimePickerScreen'));
146    },
147    name: 'DateTimePicker',
148  },
149  {
150    getComponent() {
151      return optionalRequire(() => require('../screens/GL/GLScreen'));
152    },
153    name: 'GL',
154    options: { title: 'Examples of GL use' },
155  },
156  {
157    getComponent() {
158      return optionalRequire(() => require('../screens/GL/ClearToBlueScreen'));
159    },
160    name: 'ClearToBlue',
161    options: { title: 'Clear to blue' },
162    route: 'gl/cleartoblue',
163  },
164  {
165    getComponent() {
166      return optionalRequire(() => require('../screens/GL/BasicTextureScreen'));
167    },
168    name: 'BasicTexture',
169    options: { title: 'Basic texture use' },
170    route: 'gl/basictexture',
171  },
172  {
173    getComponent() {
174      return optionalRequire(() => require('../screens/GL/GLViewScreen'));
175    },
176    name: 'GLViewScreen',
177    options: { title: 'GLView example' },
178    route: 'gl/glviewscreen',
179  },
180  {
181    getComponent() {
182      return optionalRequire(() => require('../screens/GL/GLMaskScreen'));
183    },
184    name: 'Mask',
185    options: { title: 'MaskedView integration' },
186    route: 'gl/mask',
187  },
188  {
189    getComponent() {
190      return optionalRequire(() => require('../screens/GL/GLSnapshotsScreen'));
191    },
192    name: 'Snapshots',
193    options: { title: 'Taking snapshots' },
194    route: 'gl/snapshots',
195  },
196  {
197    getComponent() {
198      return optionalRequire(() => require('../screens/GL/GLThreeComposerScreen'));
199    },
200    name: 'THREEComposer',
201    options: { title: 'three.js glitch and film effects' },
202    route: 'gl/threecomposer',
203  },
204  {
205    getComponent() {
206      return optionalRequire(() => require('../screens/GL/GLThreeDepthStencilBufferScreen'));
207    },
208    name: 'THREEDepthStencilBuffer',
209    options: { title: 'three.js depth and stencil buffer' },
210    route: 'gl/threedepthstencilbuffer',
211  },
212  {
213    getComponent() {
214      return optionalRequire(() => require('../screens/GL/GLThreeSpriteScreen'));
215    },
216    name: 'THREESprite',
217    options: { title: 'three.js sprite rendering' },
218    route: 'gl/threesprite',
219  },
220  {
221    getComponent() {
222      return optionalRequire(() => require('../screens/GL/ProcessingInAndOutScreen'));
223    },
224    name: 'ProcessingInAndOut',
225    options: { title: "'In and out' from openprocessing.org" },
226    route: 'gl/processinginandout',
227  },
228  {
229    getComponent() {
230      return optionalRequire(() => require('../screens/GL/ProcessingNoClearScreen'));
231    },
232    name: 'ProcessingNoClear',
233    options: { title: 'Draw without clearing screen with processing.js' },
234    route: 'gl/processingnoclear',
235  },
236  {
237    getComponent() {
238      return optionalRequire(() => require('../screens/GL/PIXIBasicScreen'));
239    },
240    name: 'PIXIBasic',
241    options: { title: 'Basic pixi.js use' },
242    route: 'gl/pixibasic',
243  },
244  {
245    getComponent() {
246      return optionalRequire(() => require('../screens/GL/PIXISpriteScreen'));
247    },
248    name: 'PIXISprite',
249    options: { title: 'pixi.js sprite rendering' },
250    route: 'gl/pixisprite',
251  },
252  {
253    getComponent() {
254      return optionalRequire(() => require('../screens/GL/GLCameraScreen'));
255    },
256    name: 'GLCamera',
257    options: { title: 'Expo.Camera integration' },
258    route: 'gl/glcamera',
259  },
260  {
261    getComponent() {
262      return optionalRequire(() => require('../screens/GL/WebGL2TransformFeedbackScreen'));
263    },
264    name: 'WebGL2TransformFeedback',
265    options: { title: 'WebGL2 - Transform feedback' },
266    route: 'gl/webgl2transformfeedback',
267  },
268  {
269    getComponent() {
270      return optionalRequire(() => require('../screens/GL/CanvasScreen'));
271    },
272    name: 'Canvas',
273    options: { title: 'Canvas example - expo-2d-context' },
274    route: 'gl/canvas',
275  },
276  {
277    getComponent() {
278      return optionalRequire(() => require('../screens/GL/GLHeadlessRenderingScreen'));
279    },
280    name: 'HeadlessRendering',
281    options: { title: 'Headless rendering' },
282    route: 'gl/headlessrendering',
283  },
284  {
285    getComponent() {
286      return optionalRequire(() => require('../screens/GL/GLReanimatedExample'));
287    },
288    name: 'ReanimatedWorklets',
289    options: { title: 'Reanimated worklets + gesture handler' },
290    route: 'gl/reanimated',
291  },
292  {
293    getComponent() {
294      return optionalRequire(() => require('../screens/GL/GLViewOnBusyThread'));
295    },
296    name: 'GLViewOnBusyThread',
297    options: { title: 'Creating GLView when a thread is busy' },
298    route: 'gl/busythread',
299  },
300  {
301    getComponent() {
302      return optionalRequire(() => require('../screens/GestureHandlerPinchScreen'));
303    },
304    name: 'GestureHandlerPinch',
305    options: { title: 'Pinch and Rotate' },
306  },
307  {
308    getComponent() {
309      return optionalRequire(() => require('../screens/GestureHandlerListScreen'));
310    },
311    name: 'GestureHandlerList',
312    options: { title: 'Gesture Handler List' },
313  },
314  {
315    getComponent() {
316      return optionalRequire(() => require('../screens/GestureHandlerSwipeableScreen'));
317    },
318    name: 'GestureHandlerSwipeable',
319    options: { title: 'Swipeable Rows' },
320  },
321  {
322    getComponent() {
323      return optionalRequire(() => require('../screens/HTMLElementsScreen'));
324    },
325    name: 'HTML',
326  },
327  {
328    getComponent() {
329      return optionalRequire(() => require('../screens/Image/ImageScreen'));
330    },
331    name: 'Image',
332  },
333  {
334    getComponent() {
335      return optionalRequire(() => require('../screens/Reanimated/ReanimatedScreen'));
336    },
337    name: 'Reanimated',
338  },
339  {
340    getComponent() {
341      return optionalRequire(() => require('../screens/GifScreen'));
342    },
343    name: 'Gif',
344  },
345  {
346    getComponent() {
347      return optionalRequire(() => require('../screens/SegmentedControlScreen'));
348    },
349    name: 'SegmentedControl',
350  },
351  {
352    getComponent() {
353      return optionalRequire(() => require('../screens/Skia/SkiaScreen'));
354    },
355    name: 'Skia',
356  },
357  {
358    getComponent() {
359      return optionalRequire(() => require('../screens/SVG/SVGScreen'));
360    },
361    name: 'SVG',
362  },
363  {
364    getComponent() {
365      return optionalRequire(() => require('../screens/SVG/SVGExampleScreen'));
366    },
367    name: 'SVGExample',
368  },
369  {
370    getComponent() {
371      return optionalRequire(() => require('../screens/LinearGradientScreen'));
372    },
373    name: 'LinearGradient',
374  },
375  {
376    getComponent() {
377      return optionalRequire(() => require('../screens/LottieScreen'));
378    },
379    name: 'Lottie',
380  },
381  {
382    getComponent() {
383      return optionalRequire(() => require('../screens/MapsScreen'));
384    },
385    name: 'Maps',
386  },
387  {
388    getComponent() {
389      return optionalRequire(() => require('../screens/ExpoMaps/ExpoMapsScreen'));
390    },
391    name: 'ExpoMaps',
392  },
393  {
394    getComponent() {
395      return optionalRequire(() => require('../screens/AV/VideoScreen'));
396    },
397    name: 'Video',
398  },
399  {
400    getComponent() {
401      return optionalRequire(() => require('../screens/Screens'));
402    },
403    name: 'Screens',
404  },
405  {
406    getComponent() {
407      return optionalRequire(() => require('../screens/WebViewScreen'));
408    },
409    name: 'WebView',
410  },
411  {
412    getComponent() {
413      return optionalRequire(() => require('../screens/PagerViewScreen'));
414    },
415    name: 'PagerView',
416    options: { gesturesEnabled: false, title: 'PagerView Example' },
417  },
418  {
419    getComponent() {
420      return optionalRequire(() => require('../screens/SharedElementScreen'));
421    },
422    name: 'SharedElement',
423  },
424  {
425    getComponent() {
426      return optionalRequire(() => require('../screens/FlashListScreen'));
427    },
428    name: 'FlashList',
429  },
430  ...ImageScreens,
431];
432
433function ExpoComponentsStackNavigator(props: { navigation: BottomTabNavigationProp<any> }) {
434  return (
435    <Stack.Navigator {...props} {...getStackConfig(props)}>
436      <Stack.Screen
437        name="ExpoComponents"
438        options={{ title: Layout.isSmallDevice ? 'Expo SDK Components' : 'Components in Expo SDK' }}
439        component={ExpoComponents}
440      />
441      {Screens.map(({ name, getComponent, options }) => (
442        <Stack.Screen name={name} key={name} getComponent={getComponent} options={options ?? {}} />
443      ))}
444    </Stack.Navigator>
445  );
446}
447
448const icon = ({ focused }: { focused: boolean }) => {
449  return <TabIcon name="react" focused={focused} />;
450};
451ExpoComponentsStackNavigator.navigationOptions = {
452  title: 'Components',
453  tabBarLabel: 'Components',
454  tabBarIcon: icon,
455  drawerIcon: icon,
456};
457export default ExpoComponentsStackNavigator;
458