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