Chore: Migrate containers: List to Typescript (#3921)

* Chore: Migrate containers: List to Typescript

* minor tweak

* fix storyshot List - item flatlist

* fix IListContainer

* fix type of childrens

* minor tweak
This commit is contained in:
Reinaldo Neto 2022-03-25 15:09:02 -03:00 committed by GitHub
parent 744712b8d5
commit 70cb252d1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 80 additions and 72 deletions

View File

@ -11,7 +11,7 @@ const styles = StyleSheet.create({
}); });
interface IListContainer { interface IListContainer {
children: React.ReactNode; children: (React.ReactElement | null)[] | React.ReactElement | null;
testID?: string; testID?: string;
} }
const ListContainer = React.memo(({ children, ...props }: IListContainer) => ( const ListContainer = React.memo(({ children, ...props }: IListContainer) => (

View File

@ -25,6 +25,7 @@ interface IListHeader {
const ListHeader = React.memo(({ title, translateTitle = true }: IListHeader) => { const ListHeader = React.memo(({ title, translateTitle = true }: IListHeader) => {
const { theme } = useTheme(); const { theme } = useTheme();
return ( return (
<View style={styles.container}> <View style={styles.container}>
<Text style={[styles.title, { color: themes[theme].infoText }]} numberOfLines={1}> <Text style={[styles.title, { color: themes[theme].infoText }]} numberOfLines={1}>

View File

@ -3,11 +3,10 @@ import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
import { themes } from '../../constants/colors'; import { themes } from '../../constants/colors';
import { CustomIcon } from '../../lib/Icons'; import { CustomIcon } from '../../lib/Icons';
import { withTheme } from '../../theme'; import { useTheme } from '../../theme';
import { ICON_SIZE } from './constants'; import { ICON_SIZE } from './constants';
interface IListIcon { interface IListIcon {
theme?: string;
name: string; name: string;
color?: string; color?: string;
style?: StyleProp<ViewStyle>; style?: StyleProp<ViewStyle>;
@ -21,12 +20,16 @@ const styles = StyleSheet.create({
} }
}); });
const ListIcon = React.memo(({ theme, name, color, style, testID }: IListIcon) => ( const ListIcon = React.memo(({ name, color, style, testID }: IListIcon) => {
const { theme } = useTheme();
return (
<View style={[styles.icon, style]}> <View style={[styles.icon, style]}>
<CustomIcon name={name} color={color ?? themes[theme!].auxiliaryText} size={ICON_SIZE} testID={testID} /> <CustomIcon name={name} color={color ?? themes[theme].auxiliaryText} size={ICON_SIZE} testID={testID} />
</View> </View>
)); );
});
ListIcon.displayName = 'List.Icon'; ListIcon.displayName = 'List.Icon';
export default withTheme(ListIcon); export default ListIcon;

View File

@ -4,11 +4,11 @@ import { I18nManager, StyleSheet, Text, View } from 'react-native';
import Touch from '../../utils/touch'; import Touch from '../../utils/touch';
import { themes } from '../../constants/colors'; import { themes } from '../../constants/colors';
import sharedStyles from '../../views/Styles'; import sharedStyles from '../../views/Styles';
import { withTheme } from '../../theme'; import { useTheme } from '../../theme';
import I18n from '../../i18n'; import I18n from '../../i18n';
import { Icon } from '.'; import { Icon } from '.';
import { BASE_HEIGHT, ICON_SIZE, PADDING_HORIZONTAL } from './constants'; import { BASE_HEIGHT, ICON_SIZE, PADDING_HORIZONTAL } from './constants';
import { withDimensions } from '../../dimensions'; import { useDimensions } from '../../dimensions';
import { CustomIcon } from '../../lib/Icons'; import { CustomIcon } from '../../lib/Icons';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
@ -59,13 +59,12 @@ interface IListItemContent {
left?: () => JSX.Element | null; left?: () => JSX.Element | null;
right?: () => JSX.Element | null; right?: () => JSX.Element | null;
disabled?: boolean; disabled?: boolean;
theme: string;
testID?: string; testID?: string;
theme?: string;
color?: string; color?: string;
translateTitle?: boolean; translateTitle?: boolean;
translateSubtitle?: boolean; translateSubtitle?: boolean;
showActionIndicator?: boolean; showActionIndicator?: boolean;
fontScale?: number;
alert?: boolean; alert?: boolean;
} }
@ -78,26 +77,28 @@ const Content = React.memo(
left, left,
right, right,
color, color,
theme,
fontScale,
alert, alert,
translateTitle = true, translateTitle = true,
translateSubtitle = true, translateSubtitle = true,
showActionIndicator = false showActionIndicator = false,
}: IListItemContent) => ( theme
<View style={[styles.container, disabled && styles.disabled, { height: BASE_HEIGHT * fontScale! }]} testID={testID}> }: IListItemContent) => {
const { fontScale } = useDimensions();
return (
<View style={[styles.container, disabled && styles.disabled, { height: BASE_HEIGHT * fontScale }]} testID={testID}>
{left ? <View style={styles.leftContainer}>{left()}</View> : null} {left ? <View style={styles.leftContainer}>{left()}</View> : null}
<View style={styles.textContainer}> <View style={styles.textContainer}>
<View style={styles.textAlertContainer}> <View style={styles.textAlertContainer}>
<Text style={[styles.title, { color: color || themes[theme!].titleText }]} numberOfLines={1}> <Text style={[styles.title, { color: color || themes[theme].titleText }]} numberOfLines={1}>
{translateTitle ? I18n.t(title) : title} {translateTitle ? I18n.t(title) : title}
</Text> </Text>
{alert ? ( {alert ? (
<CustomIcon style={[styles.alertIcon, { color: themes[theme!].dangerColor }]} size={ICON_SIZE} name='info' /> <CustomIcon style={[styles.alertIcon, { color: themes[theme].dangerColor }]} size={ICON_SIZE} name='info' />
) : null} ) : null}
</View> </View>
{subtitle ? ( {subtitle ? (
<Text style={[styles.subtitle, { color: themes[theme!].auxiliaryText }]} numberOfLines={1}> <Text style={[styles.subtitle, { color: themes[theme].auxiliaryText }]} numberOfLines={1}>
{translateSubtitle ? I18n.t(subtitle) : subtitle} {translateSubtitle ? I18n.t(subtitle) : subtitle}
</Text> </Text>
) : null} ) : null}
@ -109,47 +110,52 @@ const Content = React.memo(
</View> </View>
) : null} ) : null}
</View> </View>
) );
}
); );
interface IListButtonPress { interface IListButtonPress extends IListItemButton {
onPress?: Function; onPress: Function;
} }
interface IListItemButton extends IListButtonPress { interface IListItemButton {
title?: string; title?: string;
disabled?: boolean; disabled?: boolean;
theme?: string; theme: string;
backgroundColor?: string; backgroundColor?: string;
underlayColor?: string; underlayColor?: string;
} }
const Button = React.memo<IListItemButton>(({ onPress, backgroundColor, underlayColor, ...props }: IListItemButton) => ( const Button = React.memo(({ onPress, backgroundColor, underlayColor, ...props }: IListButtonPress) => (
<Touch <Touch
onPress={() => onPress!(props.title)} onPress={() => onPress(props.title)}
style={{ backgroundColor: backgroundColor || themes[props.theme!].backgroundColor }} style={{ backgroundColor: backgroundColor || themes[props.theme].backgroundColor }}
underlayColor={underlayColor} underlayColor={underlayColor}
enabled={!props.disabled} enabled={!props.disabled}
theme={props.theme!}> theme={props.theme}>
<Content {...props} /> <Content {...props} />
</Touch> </Touch>
)); ));
interface IListItem extends IListItemContent, IListItemButton { interface IListItem extends Omit<IListItemContent, 'theme'>, Omit<IListItemButton, 'theme'> {
backgroundColor?: string; backgroundColor?: string;
onPress?: Function;
} }
const ListItem = React.memo<IListItem>(({ ...props }: IListItem) => { const ListItem = React.memo(({ ...props }: IListItem) => {
const { theme } = useTheme();
if (props.onPress) { if (props.onPress) {
return <Button {...props} />; const { onPress } = props;
return <Button {...props} theme={theme} onPress={onPress} />;
} }
return ( return (
<View style={{ backgroundColor: props.backgroundColor || themes[props.theme!].backgroundColor }}> <View style={{ backgroundColor: props.backgroundColor || themes[theme].backgroundColor }}>
<Content {...props} /> <Content {...props} theme={theme} />
</View> </View>
); );
}); });
ListItem.displayName = 'List.Item'; ListItem.displayName = 'List.Item';
export default withTheme(withDimensions(ListItem)); export default ListItem;

View File

@ -1,7 +1,6 @@
import React from 'react'; import React from 'react';
import { StyleSheet, View } from 'react-native'; import { StyleSheet, View } from 'react-native';
import { withTheme } from '../../theme';
import { Header } from '.'; import { Header } from '.';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
@ -11,7 +10,7 @@ const styles = StyleSheet.create({
}); });
interface IListSection { interface IListSection {
children: React.ReactNode; children: (React.ReactElement | null)[] | React.ReactElement | null;
title?: string; title?: string;
translateTitle?: boolean; translateTitle?: boolean;
} }
@ -25,4 +24,4 @@ const ListSection = React.memo(({ children, title, translateTitle }: IListSectio
ListSection.displayName = 'List.Section'; ListSection.displayName = 'List.Section';
export default withTheme(ListSection); export default ListSection;

View File

@ -2,7 +2,7 @@ import React from 'react';
import { StyleSheet, View, ViewStyle } from 'react-native'; import { StyleSheet, View, ViewStyle } from 'react-native';
import { themes } from '../../constants/colors'; import { themes } from '../../constants/colors';
import { withTheme } from '../../theme'; import { useTheme } from '../../theme';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
separator: { separator: {
@ -12,13 +12,14 @@ const styles = StyleSheet.create({
interface IListSeparator { interface IListSeparator {
style?: ViewStyle; style?: ViewStyle;
theme?: string;
} }
const ListSeparator = React.memo(({ style, theme }: IListSeparator) => ( const ListSeparator = React.memo(({ style }: IListSeparator) => {
<View style={[styles.separator, style, { backgroundColor: themes[theme!].separatorColor }]} /> const { theme } = useTheme();
));
return <View style={[styles.separator, style, { backgroundColor: themes[theme].separatorColor }]} />;
});
ListSeparator.displayName = 'List.Separator'; ListSeparator.displayName = 'List.Separator';
export default withTheme(ListSeparator); export default ListSeparator;

View File

@ -8,7 +8,7 @@ export interface IDimensionsContextProps {
width: number; width: number;
height: number; height: number;
scale?: number; scale?: number;
fontScale?: number; fontScale: number;
setDimensions?: ({ setDimensions?: ({
width, width,
height, height,
@ -22,7 +22,9 @@ export interface IDimensionsContextProps {
}) => void; }) => void;
} }
export const DimensionsContext = React.createContext<IDimensionsContextProps>(Dimensions.get('window')); export const DimensionsContext = React.createContext<IDimensionsContextProps>(
Dimensions.get('window') as IDimensionsContextProps
);
export function withDimensions<T extends object>(Component: React.ComponentType<T> & TNavigationOptions): typeof Component { export function withDimensions<T extends object>(Component: React.ComponentType<T> & TNavigationOptions): typeof Component {
const DimensionsComponent = (props: T) => ( const DimensionsComponent = (props: T) => (

View File

@ -6,7 +6,6 @@ import { CompositeNavigationProp } from '@react-navigation/core';
import * as List from '../containers/List'; import * as List from '../containers/List';
import StatusBar from '../containers/StatusBar'; import StatusBar from '../containers/StatusBar';
import { useTheme } from '../theme';
import * as HeaderButton from '../containers/HeaderButton'; import * as HeaderButton from '../containers/HeaderButton';
import SafeAreaView from '../containers/SafeAreaView'; import SafeAreaView from '../containers/SafeAreaView';
import I18n from '../i18n'; import I18n from '../i18n';
@ -41,7 +40,6 @@ const setHeader = ({
const AddChannelTeamView = ({ navigation, route, isMasterDetail }: IAddChannelTeamView) => { const AddChannelTeamView = ({ navigation, route, isMasterDetail }: IAddChannelTeamView) => {
const { teamId, teamChannels } = route.params; const { teamId, teamChannels } = route.params;
const { theme } = useTheme();
useEffect(() => { useEffect(() => {
setHeader({ navigation, isMasterDetail }); setHeader({ navigation, isMasterDetail });
@ -67,7 +65,6 @@ const AddChannelTeamView = ({ navigation, route, isMasterDetail }: IAddChannelTe
testID='add-channel-team-view-create-channel' testID='add-channel-team-view-create-channel'
left={() => <List.Icon name='team' />} left={() => <List.Icon name='team' />}
right={() => <List.Icon name='chevron-right' />} right={() => <List.Icon name='chevron-right' />}
theme={theme}
/> />
<List.Separator /> <List.Separator />
<List.Item <List.Item
@ -76,7 +73,6 @@ const AddChannelTeamView = ({ navigation, route, isMasterDetail }: IAddChannelTe
testID='add-channel-team-view-add-existing' testID='add-channel-team-view-add-existing'
left={() => <List.Icon name='channel-public' />} left={() => <List.Icon name='channel-public' />}
right={() => <List.Icon name='chevron-right' />} right={() => <List.Icon name='chevron-right' />}
theme={theme}
/> />
<List.Separator /> <List.Separator />
</List.Container> </List.Container>

View File

@ -223,7 +223,7 @@ class ScreenLockConfigView extends React.Component<IScreenLockConfigViewProps, I
return ( return (
<List.Section> <List.Section>
<List.Separator /> <List.Separator />
{items.map(item => this.renderItem({ item }))} <>{items.map(item => this.renderItem({ item }))}</>
</List.Section> </List.Section>
); );
}; };

View File

@ -131,11 +131,11 @@ class ThemeView extends React.Component<IThemeViewProps> {
<List.Container> <List.Container>
<List.Section title='Theme'> <List.Section title='Theme'>
<List.Separator /> <List.Separator />
{themeGroup.map(item => this.renderItem({ item }))} <>{themeGroup.map(item => this.renderItem({ item }))}</>
</List.Section> </List.Section>
<List.Section title='Dark_level'> <List.Section title='Dark_level'>
<List.Separator /> <List.Separator />
{darkGroup.map(item => this.renderItem({ item }))} <>{darkGroup.map(item => this.renderItem({ item }))}</>
</List.Section> </List.Section>
</List.Container> </List.Container>
</SafeAreaView> </SafeAreaView>

File diff suppressed because one or more lines are too long