Skip to content

Commit 18c2ac4

Browse files
committed
feat: change themes dynamically on the example project
1 parent 4aba135 commit 18c2ac4

File tree

9 files changed

+275
-145
lines changed

9 files changed

+275
-145
lines changed

.eslintrc.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module.exports = {
44
'plugin:prettier/recommended',
55
'prettier/react',
66
'plugin:jest/recommended',
7+
'plugin:@typescript-eslint/recommended',
78
],
89
parser: '@typescript-eslint/parser',
910
plugins: ['react', 'prettier'],
@@ -37,5 +38,6 @@ module.exports = {
3738
'react/require-default-props': 'off',
3839
'react/jsx-props-no-spreading': 'off',
3940
'react/prop-types': 'off',
41+
'@typescript-eslint/explicit-module-boundary-types': 'off',
4042
},
4143
};

example/src/App.tsx

Lines changed: 5 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,17 @@
11
import React from 'react';
2-
import { createStackNavigator } from '@react-navigation/stack';
32

43
import { NavigationContainer } from '@react-navigation/native';
5-
import { AppBar, ThemeProvider, original } from 'react95-native';
64

7-
import ExamplesScreen from './ExamplesScreen';
8-
import examples from './examples';
9-
10-
const flattenedExamples = examples
11-
.map(group => group.sections.map(section => section.items))
12-
.flat(2);
13-
14-
type RootStackParamList = {
15-
Home: undefined;
16-
ButtonExample: undefined;
17-
TextInputExample: undefined;
18-
};
19-
20-
const Stack = createStackNavigator<RootStackParamList>();
5+
import { LocalThemeProvider } from './util/LocalThemeContext';
6+
import MainNavigation from './MainNavigation';
217

228
const App = () => {
239
return (
24-
<ThemeProvider theme={original}>
10+
<LocalThemeProvider>
2511
<NavigationContainer>
26-
<Stack.Navigator
27-
headerMode='screen'
28-
screenOptions={{
29-
header: ({ navigation, scene, previous }) => (
30-
<AppBar>
31-
{previous && (
32-
<AppBar.BackAction onPress={() => navigation.goBack()} />
33-
)}
34-
<AppBar.Content title={scene.descriptor.options.title} />
35-
</AppBar>
36-
),
37-
}}
38-
>
39-
<Stack.Screen
40-
name='Home'
41-
component={ExamplesScreen}
42-
options={{ title: 'Examples' }}
43-
/>
44-
{flattenedExamples.map(({ name, title, component }) => (
45-
<Stack.Screen
46-
key={name}
47-
/* @ts-ignore */
48-
name={name}
49-
component={component}
50-
options={{ title }}
51-
/>
52-
))}
53-
</Stack.Navigator>
12+
<MainNavigation />
5413
</NavigationContainer>
55-
</ThemeProvider>
14+
</LocalThemeProvider>
5615
);
5716
};
5817

example/src/ExamplesScreen.tsx

Lines changed: 50 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,63 @@
1-
import React from 'react';
2-
import { StyleSheet, SafeAreaView, View } from 'react-native';
1+
import React, { useContext } from 'react';
2+
import { StyleSheet, SafeAreaView } from 'react-native';
33
import { useNavigation } from '@react-navigation/native';
4-
import { Panel, Cutout, List, ScrollView } from 'react95-native';
4+
import { Panel, Cutout, List, ScrollView, original } from 'react95-native';
55

66
import examples from './examples';
7+
import themes from './examples/themes';
8+
import { LocalThemeContext } from './util/LocalThemeContext';
79

810
const ExamplesScreen = () => {
911
const navigation = useNavigation();
1012

13+
const { setTheme } = useContext(LocalThemeContext);
14+
15+
const onThemePress = (themeId: string) => {
16+
const { theme = original } = themes.find(({ id }) => id === themeId) || {};
17+
18+
setTheme(theme);
19+
};
20+
1121
return (
1222
<SafeAreaView style={styles.container}>
13-
<Panel variant='outside' style={[styles.panel]}>
14-
<Cutout style={[styles.cutout]}>
15-
<ScrollView style={[styles.scrollView]} alwaysShowScrollbars>
16-
<View style={[styles.content]}>
17-
{examples.map(group => (
18-
<List.Accordion
19-
title={group.title}
20-
key={group.title}
21-
style={[styles.section]}
22-
defaultExpanded
23-
>
24-
{group.sections.map((section, i) => (
25-
<React.Fragment key={section.title}>
26-
{i > 0 && <List.Divider />}
27-
<List.Section title={section.title}>
28-
{section.items.map(item => (
29-
<List.Item
30-
title={item.title}
31-
key={item.title}
32-
onPress={() => navigation.navigate(item.name)}
33-
/>
34-
))}
35-
</List.Section>
36-
</React.Fragment>
37-
))}
38-
</List.Accordion>
23+
<Panel variant='outside' style={styles.panel}>
24+
<Cutout style={styles.cutout}>
25+
<ScrollView
26+
style={styles.scrollView}
27+
contentContainerStyle={styles.content}
28+
alwaysShowScrollbars
29+
>
30+
<List.Accordion title='Themes' defaultExpanded>
31+
<List.Section>
32+
{themes.map(theme => (
33+
<List.Item
34+
key={theme.id}
35+
title={theme.id}
36+
onPress={() => onThemePress(theme.id)}
37+
/>
38+
))}
39+
</List.Section>
40+
</List.Accordion>
41+
<List.Accordion
42+
title='Components'
43+
style={styles.section}
44+
defaultExpanded
45+
>
46+
{examples.map((section, i) => (
47+
<React.Fragment key={section.title}>
48+
{i > 0 && <List.Divider />}
49+
<List.Section title={section.title}>
50+
{section.items.map(item => (
51+
<List.Item
52+
title={item.title}
53+
key={item.title}
54+
onPress={() => navigation.navigate(item.name)}
55+
/>
56+
))}
57+
</List.Section>
58+
</React.Fragment>
3959
))}
40-
</View>
60+
</List.Accordion>
4161
</ScrollView>
4262
</Cutout>
4363
</Panel>

example/src/MainNavigation.tsx

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import React, { useContext } from 'react';
2+
import { createStackNavigator } from '@react-navigation/stack';
3+
import { AppBar, ThemeProvider as React95Provider } from 'react95-native';
4+
5+
import { LocalThemeContext } from './util/LocalThemeContext';
6+
import ExamplesScreen from './ExamplesScreen';
7+
import examples from './examples';
8+
9+
const flattenedExamples = examples.map(section => section.items).flat();
10+
11+
type RootStackParamList = {
12+
Home: undefined;
13+
ButtonExample: undefined;
14+
TextInputExample: undefined;
15+
};
16+
17+
const Stack = createStackNavigator<RootStackParamList>();
18+
19+
const MainNavigation = () => {
20+
const { theme } = useContext(LocalThemeContext);
21+
22+
return (
23+
<React95Provider theme={theme}>
24+
<Stack.Navigator
25+
headerMode='screen'
26+
screenOptions={{
27+
header: ({ navigation, scene, previous }) => (
28+
<AppBar>
29+
{previous && (
30+
<AppBar.BackAction onPress={() => navigation.goBack()} />
31+
)}
32+
<AppBar.Content title={scene.descriptor.options.title} />
33+
</AppBar>
34+
),
35+
}}
36+
>
37+
<Stack.Screen
38+
name='Home'
39+
component={ExamplesScreen}
40+
options={{ title: 'Examples' }}
41+
/>
42+
{flattenedExamples.map(({ name, title, component }) => (
43+
<Stack.Screen
44+
key={name}
45+
name={name}
46+
component={component}
47+
options={{ title }}
48+
/>
49+
))}
50+
</Stack.Navigator>
51+
</React95Provider>
52+
);
53+
};
54+
55+
export default MainNavigation;

example/src/examples/index.tsx

Lines changed: 59 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -20,86 +20,77 @@ import WindowExample from './WindowExample';
2020

2121
export default [
2222
{
23-
title: 'Components',
24-
sections: [
23+
title: 'Inputs',
24+
items: [
25+
{ name: 'ButtonExample', component: ButtonExample, title: 'Button' },
2526
{
26-
title: 'Inputs',
27-
items: [
28-
{ name: 'ButtonExample', component: ButtonExample, title: 'Button' },
29-
{
30-
name: 'CheckboxExample',
31-
component: CheckboxExample,
32-
title: 'Checkbox',
33-
},
34-
{
35-
name: 'FieldsetExample',
36-
component: FieldsetExample,
37-
title: 'Fieldset',
38-
},
39-
{ name: 'RadioExample', component: RadioExample, title: 'Radio' },
40-
{ name: 'SelectExample', component: SelectExample, title: 'Select' },
41-
{
42-
name: 'SelectBoxExample',
43-
component: SelectBoxExample,
44-
title: 'SelectBox',
45-
},
46-
{
47-
name: 'TextInputExample',
48-
component: TextInputExample,
49-
title: 'TextInput',
50-
},
51-
],
27+
name: 'CheckboxExample',
28+
component: CheckboxExample,
29+
title: 'Checkbox',
5230
},
5331
{
54-
title: 'Layout',
55-
items: [
56-
{ name: 'AppBarExample', component: AppBarExample, title: 'AppBar' },
57-
{ name: 'CutoutExample', component: CutoutExample, title: 'Cutout' },
58-
{
59-
name: 'DividerExample',
60-
component: DividerExample,
61-
title: 'Divider',
62-
},
63-
{ name: 'PanelExample', component: PanelExample, title: 'Panel' },
64-
{ name: 'WindowExample', component: WindowExample, title: 'Window' },
65-
],
32+
name: 'FieldsetExample',
33+
component: FieldsetExample,
34+
title: 'Fieldset',
6635
},
36+
{ name: 'RadioExample', component: RadioExample, title: 'Radio' },
37+
{ name: 'SelectExample', component: SelectExample, title: 'Select' },
6738
{
68-
title: 'Navigation',
69-
items: [
70-
{ name: 'ListExample', component: ListExample, title: 'List' },
71-
{ name: 'MenuExample', component: MenuExample, title: 'Menu' },
72-
{ name: 'TabsExample', component: TabsExample, title: 'Tabs' },
73-
],
39+
name: 'SelectBoxExample',
40+
component: SelectBoxExample,
41+
title: 'SelectBox',
7442
},
7543
{
76-
title: 'Other',
77-
items: [
78-
{
79-
name: 'DesktopExample',
80-
component: DesktopExample,
81-
title: 'Desktop',
82-
},
83-
{
84-
name: 'HourglassExample',
85-
component: HourglassExample,
86-
title: 'Hourglass',
87-
},
88-
{
89-
name: 'ProgressExample',
90-
component: ProgressExample,
91-
title: 'Progress',
92-
},
93-
],
44+
name: 'TextInputExample',
45+
component: TextInputExample,
46+
title: 'TextInput',
47+
},
48+
],
49+
},
50+
{
51+
title: 'Layout',
52+
items: [
53+
{ name: 'AppBarExample', component: AppBarExample, title: 'AppBar' },
54+
{ name: 'CutoutExample', component: CutoutExample, title: 'Cutout' },
55+
{
56+
name: 'DividerExample',
57+
component: DividerExample,
58+
title: 'Divider',
59+
},
60+
{ name: 'PanelExample', component: PanelExample, title: 'Panel' },
61+
{ name: 'WindowExample', component: WindowExample, title: 'Window' },
62+
],
63+
},
64+
{
65+
title: 'Navigation',
66+
items: [
67+
{ name: 'ListExample', component: ListExample, title: 'List' },
68+
{ name: 'MenuExample', component: MenuExample, title: 'Menu' },
69+
{ name: 'TabsExample', component: TabsExample, title: 'Tabs' },
70+
],
71+
},
72+
{
73+
title: 'Other',
74+
items: [
75+
{
76+
name: 'DesktopExample',
77+
component: DesktopExample,
78+
title: 'Desktop',
79+
},
80+
{
81+
name: 'HourglassExample',
82+
component: HourglassExample,
83+
title: 'Hourglass',
9484
},
9585
{
96-
title: 'Typography',
97-
items: [{ name: 'TextExample', component: TextExample, title: 'Text' }],
86+
name: 'ProgressExample',
87+
component: ProgressExample,
88+
title: 'Progress',
9889
},
9990
],
10091
},
10192
{
102-
title: 'Themes',
103-
sections: [],
93+
title: 'Typography',
94+
items: [{ name: 'TextExample', component: TextExample, title: 'Text' }],
10495
},
10596
];

example/src/examples/themes.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { original, counterStrike, vaporTeal } from 'react95-native';
2+
3+
export default [
4+
{ id: original.name, theme: original },
5+
{ id: counterStrike.name, theme: counterStrike },
6+
{ id: vaporTeal.name, theme: vaporTeal },
7+
];

0 commit comments

Comments
 (0)