Phecda

refactor: navigation theme & DesignList

... ... @@ -13,6 +13,13 @@ import { DarkModeProvider } from 'react-native-dark-mode';
import { enableScreens } from 'react-native-screens';
import AppNavigationContainer from './src/screen/AppNavigationContainer';
if (__DEV__) {
const whyDidYouRender = require('@welldone-software/why-did-you-render');
whyDidYouRender(React, {
trackAllPureComponents: false,
});
}
enableScreens();
const App = () => {
... ...
... ... @@ -11,6 +11,7 @@
"commit": "git-cz"
},
"dependencies": {
"@huse/previous-value": "^1.0.1",
"@react-native-community/masked-view": "^0.1.7",
"@react-navigation/bottom-tabs": "^5.2.5",
"@react-navigation/drawer": "^5.4.0",
... ... @@ -40,6 +41,7 @@
"@types/react-test-renderer": "16.9.2",
"@typescript-eslint/eslint-plugin": "^2.27.0",
"@typescript-eslint/parser": "^2.27.0",
"@welldone-software/why-did-you-render": "^4.0.7",
"babel-jest": "^24.9.0",
"commitizen": "^4.0.3",
"cz-conventional-changelog": "^3.1.0",
... ...
... ... @@ -9,12 +9,15 @@ import {
SectionListProps,
ScrollViewProps,
ScrollView,
StyleSheet,
} from 'react-native';
import { useOriginalCopy } from '@huse/previous-value';
import { colorPreset } from '../../design';
import {
DynamicStyleSheet,
useDynamicStyleSheet,
} from 'react-native-dark-mode';
import { useSafeArea } from 'react-native-safe-area-context';
const dynamicStyles = new DynamicStyleSheet({
background: {
... ... @@ -31,6 +34,18 @@ type BackgroundProps<Props> = PropsWithChildren<Props> & {
white?: boolean;
};
function useSafeContentContainerStyle(
contentContainerStyle: ScrollViewProps['contentContainerStyle']
) {
const { left, right } = useSafeArea();
const calculated = StyleSheet.compose(contentContainerStyle, {
paddingLeft: left,
paddingRight: right,
});
const originValue = useOriginalCopy(calculated);
return originValue;
}
export const BGView = ({
style,
white,
... ... @@ -62,13 +77,16 @@ export const BGSafe = ({
export const BGScroll = ({
style,
white,
contentContainerStyle,
...props
}: BackgroundProps<ScrollViewProps>) => {
const styles = useDynamicStyleSheet(dynamicStyles);
const safeContentStyle = useSafeContentContainerStyle(contentContainerStyle);
return (
<ScrollView
style={[white ? styles.whiteBackground : styles.background, style]}
contentInsetAdjustmentBehavior="automatic"
contentContainerStyle={safeContentStyle}
{...props}
/>
);
... ... @@ -77,13 +95,16 @@ export const BGScroll = ({
export const BGList = <T extends any>({
style,
white,
contentContainerStyle,
...props
}: BackgroundProps<FlatListProps<T>>) => {
const styles = useDynamicStyleSheet(dynamicStyles);
const safeContentStyle = useSafeContentContainerStyle(contentContainerStyle);
return (
<FlatList
style={[white ? styles.whiteBackground : styles.background, style]}
contentInsetAdjustmentBehavior="automatic"
contentContainerStyle={safeContentStyle}
keyExtractor={(_, i) => i.toString()}
{...props}
/>
... ...
... ... @@ -34,3 +34,15 @@ export const groupedBackgroundColor = {
secondary: new DynamicValue('#FFFFFF', '#1C1C1E'),
tertiary: new DynamicValue('#F2F2F7', '#2C2C2E'),
};
export const rainbow = {
blue: new DynamicValue('rgb(0,122,255)', 'rgb(10,132,255)'),
green: new DynamicValue('rgb(52,199,89)', 'rgb(48,209,88)'),
indigo: new DynamicValue('rgb(88,86,214)', 'rgb(94,92,230)'),
orange: new DynamicValue('rgb(255,149,0)', 'rgb(255,159,10)'),
pink: new DynamicValue('rgb(255,45,85)', 'rgb(255,55,95)'),
purple: new DynamicValue('rgb(175,82,222)', 'rgb(191,90,242)'),
red: new DynamicValue('rgb(255,59,48)', 'rgb(255,69,58)'),
teal: new DynamicValue('rgb(90,200,250)', 'rgb(100,210,255)'),
yellow: new DynamicValue('rgb(255,204,0)', 'rgb(255,214,10)'),
};
... ...
import * as colorPreset from './color';
export { colorPreset };
import * as themeForNav from './themeForReactNavigation';
export { colorPreset, themeForNav };
... ...
import { DefaultTheme } from '@react-navigation/native';
import { rainbow } from './color';
type Theme = typeof DefaultTheme;
export const light: Theme = {
dark: false,
colors: {
primary: rainbow.teal.light,
background: 'rgb(242, 242, 242)',
card: 'rgb(255, 255, 255)',
text: 'rgb(28, 28, 30)',
border: 'rgb(224, 224, 224)',
},
};
export const dark: Theme = {
dark: true,
colors: {
primary: rainbow.teal.dark,
background: 'rgb(1, 1, 1)',
card: 'rgb(18, 18, 18)',
text: 'rgb(229, 229, 231)',
border: 'rgb(39, 39, 41)',
},
};
... ...
... ... @@ -13,10 +13,9 @@ import Ionicons from 'react-native-vector-icons/Ionicons';
import { MainTabParamList, MainStackParamList } from '../type/Navigation';
import SystemInfo from './SystemInfo';
import DesignList from './DesignList';
import { useDynamicValue } from 'react-native-dark-mode';
import { colorPreset } from '../design';
import { useDarkMode } from 'react-native-dark-mode';
import { themeForNav } from '../design';
import RNDeviceInfoList from './RNDeviceInfo';
import { StyleSheet } from 'react-native';
const MainTab = createBottomTabNavigator<MainTabParamList>();
... ... @@ -33,9 +32,6 @@ function getTabHeader(
}
const Home = () => {
const backgroundColor = useDynamicValue(colorPreset.backgroundColor.primary);
const tintColor = useDynamicValue(colorPreset.linkColor);
const opaqueSeparator = useDynamicValue(colorPreset.separator.opaque);
return (
<MainTab.Navigator
screenOptions={({ route }) => {
... ... @@ -69,13 +65,6 @@ const Home = () => {
},
};
}}
tabBarOptions={{
activeTintColor: tintColor,
style: {
backgroundColor: backgroundColor,
borderTopColor: opaqueSeparator,
},
}}
>
<MainTab.Screen name="SystemInfo" component={SystemInfo} />
<MainTab.Screen name="DesignList" component={DesignList} />
... ... @@ -86,20 +75,13 @@ const Home = () => {
const MainStack = createStackNavigator<MainStackParamList>();
export default () => {
const backgroundColor = useDynamicValue(colorPreset.backgroundColor.primary);
const primaryLabelColor = useDynamicValue(colorPreset.labelColor.primary);
const opaqueSeparator = useDynamicValue(colorPreset.separator.opaque);
const inDarkMode = useDarkMode();
return (
<NavigationContainer>
<NavigationContainer
theme={inDarkMode ? themeForNav.dark : themeForNav.light}
>
<MainStack.Navigator
screenOptions={{
headerStyle: {
backgroundColor,
shadowOffset: { width: 0, height: 0 },
borderBottomColor: opaqueSeparator,
borderBottomWidth: StyleSheet.hairlineWidth,
},
headerTintColor: primaryLabelColor,
headerStyleInterpolator: HeaderStyleInterpolators.forUIKit,
}}
>
... ...
import React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { BGScroll } from '../component/View/background';
import { BGScroll, BGSection } from '../component/View/background';
import { colorPreset } from '../design';
import {
useDynamicStyleSheet,
useDynamicValue,
DynamicStyleSheet,
useDarkMode,
useDarkModeContext,
} from 'react-native-dark-mode';
import { ListItem, Divider, Card } from '../component/View';
const dynamicStyles = new DynamicStyleSheet({
primaryLabel: { color: colorPreset.labelColor.primary },
secondaryLabel: { color: colorPreset.labelColor.secondary },
tertiaryLabel: { color: colorPreset.labelColor.tertiary },
quaternaryLabel: { color: colorPreset.labelColor.quaternary },
central: { justifyContent: 'center', alignItems: 'center' },
primaryBG: {
backgroundColor: colorPreset.backgroundColor.primary,
borderWidth: StyleSheet.hairlineWidth,
borderColor: colorPreset.separator.opaque,
width: 240,
height: 100,
},
secondaryBG: {
backgroundColor: colorPreset.backgroundColor.secondary,
width: 200,
height: 80,
},
tertiaryBG: {
backgroundColor: colorPreset.backgroundColor.tertiary,
width: 160,
height: 60,
},
primaryGroupedBG: {
backgroundColor: colorPreset.groupedBackgroundColor.primary,
borderWidth: StyleSheet.hairlineWidth,
borderColor: colorPreset.separator.opaque,
width: 240,
height: 100,
},
secondaryGroupedBG: {
backgroundColor: colorPreset.groupedBackgroundColor.secondary,
width: 200,
height: 80,
},
tertiaryGroupedBG: {
backgroundColor: colorPreset.groupedBackgroundColor.tertiary,
width: 160,
height: 60,
},
rightSquare: { width: 40, height: 40 },
});
const { labelColor, rainbow } = colorPreset;
export default () => {
const DesignList = () => {
const styles = useDynamicStyleSheet(dynamicStyles);
const inDarkMode = useDarkMode();
const currentMode = useDarkModeContext();
return (
<BGScroll>
<Text style={styles.primaryLabel}>Primary Label</Text>
<Text style={styles.secondaryLabel}>Secondary Label</Text>
<Text style={styles.tertiaryLabel}>Tertiary Label</Text>
<Text style={styles.quaternaryLabel}>Quaternary Label</Text>
<View style={[styles.primaryBG, styles.central]}>
<View style={[styles.secondaryBG, styles.central]}>
<View style={[styles.tertiaryBG, styles.central]}>
<Text style={styles.primaryLabel}>Background</Text>
</View>
</View>
</View>
<View style={[styles.primaryGroupedBG, styles.central]}>
<View style={[styles.secondaryGroupedBG, styles.central]}>
<View style={[styles.tertiaryGroupedBG, styles.central]}>
<Text style={styles.primaryLabel}>
{'Grouped Background' +
(inDarkMode ? ', same as background in dark mode' : '')}
</Text>
</View>
</View>
</View>
<Card round>
{Object.keys(labelColor).map((name) => {
return (
<ListItem
title={name}
key={name}
titleStyle={{
color: labelColor[name as keyof typeof labelColor][currentMode],
}}
/>
);
})}
</Card>
<Card round>
{Object.keys(rainbow).map((name) => {
const color = rainbow[name as keyof typeof rainbow];
return (
<ListItem
title={name}
key={name}
titleStyle={{
color: color[currentMode],
}}
rightElement={
<>
<View
style={[
styles.rightSquare,
{ backgroundColor: color.light },
]}
/>
<View
style={[
styles.rightSquare,
{ backgroundColor: color.dark },
]}
/>
</>
}
/>
);
})}
</Card>
</BGScroll>
);
};
DesignList.whyDidYouRender = true;
export default DesignList;
... ...
... ... @@ -6,7 +6,10 @@ import { MainTabScreenProps } from '../type/Navigation';
declare var global: { HermesInternal: null | {} };
export default ({ navigation, route }: MainTabScreenProps<'SystemInfo'>) => {
const SystemInfo = ({
navigation,
route,
}: MainTabScreenProps<'SystemInfo'>) => {
const { width, height, fontScale, scale } = useWindowDimensions();
return (
<BGScroll white>
... ... @@ -49,3 +52,5 @@ export default ({ navigation, route }: MainTabScreenProps<'SystemInfo'>) => {
</BGScroll>
);
};
export default SystemInfo;
... ...
... ... @@ -841,6 +841,14 @@
dependencies:
"@hapi/hoek" "^8.3.0"
"@huse/previous-value@^1.0.1":
version "1.0.1"
resolved "https://registry.npm.taobao.org/@huse/previous-value/download/@huse/previous-value-1.0.1.tgz#77807e59b26e2cd86ebb6aac295163a71bbf1099"
integrity sha1-d4B+WbJuLNhuu2qsKVFjpxu/EJk=
dependencies:
fast-deep-equal "^3.1.1"
shallowequal "^1.1.0"
"@jest/console@^24.7.1", "@jest/console@^24.9.0":
version "24.9.0"
resolved "https://registry.npm.taobao.org/@jest/console/download/@jest/console-24.9.0.tgz?cache=0&sync_timestamp=1585823724080&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40jest%2Fconsole%2Fdownload%2F%40jest%2Fconsole-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0"
... ... @@ -1388,6 +1396,13 @@
semver "^6.3.0"
tsutils "^3.17.1"
"@welldone-software/why-did-you-render@^4.0.7":
version "4.0.7"
resolved "https://registry.npm.taobao.org/@welldone-software/why-did-you-render/download/@welldone-software/why-did-you-render-4.0.7.tgz#13c81eef665a34911c029dff821b23cd2495567b"
integrity sha1-E8ge72ZaNJEcAp3/ghsjzSSVVns=
dependencies:
lodash "^4"
JSONStream@^1.0.4:
version "1.3.5"
resolved "https://registry.npm.taobao.org/JSONStream/download/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0"
... ... @@ -5271,7 +5286,7 @@ lodash.throttle@^4.1.1:
resolved "https://registry.npm.taobao.org/lodash.throttle/download/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=
lodash@4.17.15, lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.2.1, lodash@^4.3.0:
lodash@4.17.15, lodash@^4, lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.2.1, lodash@^4.3.0:
version "4.17.15"
resolved "https://registry.npm.taobao.org/lodash/download/lodash-4.17.15.tgz?cache=0&sync_timestamp=1571657272199&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha1-tEf2ZwoEVbv+7dETku/zMOoJdUg=
... ... @@ -7261,6 +7276,11 @@ setprototypeof@1.1.1:
resolved "https://registry.npm.taobao.org/setprototypeof/download/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683"
integrity sha1-fpWsskqpL1iF4KvvW6ExMw1K5oM=
shallowequal@^1.1.0:
version "1.1.0"
resolved "https://registry.npm.taobao.org/shallowequal/download/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
integrity sha1-GI1SHelbkIdAT9TctosT3wrk5/g=
shebang-command@^1.2.0:
version "1.2.0"
resolved "https://registry.npm.taobao.org/shebang-command/download/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
... ...