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:
parent
744712b8d5
commit
70cb252d1b
|
@ -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) => (
|
||||||
|
|
|
@ -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}>
|
||||||
|
|
|
@ -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) => {
|
||||||
<View style={[styles.icon, style]}>
|
const { theme } = useTheme();
|
||||||
<CustomIcon name={name} color={color ?? themes[theme!].auxiliaryText} size={ICON_SIZE} testID={testID} />
|
|
||||||
</View>
|
return (
|
||||||
));
|
<View style={[styles.icon, style]}>
|
||||||
|
<CustomIcon name={name} color={color ?? themes[theme].auxiliaryText} size={ICON_SIZE} testID={testID} />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
ListIcon.displayName = 'List.Icon';
|
ListIcon.displayName = 'List.Icon';
|
||||||
|
|
||||||
export default withTheme(ListIcon);
|
export default ListIcon;
|
||||||
|
|
|
@ -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,78 +77,85 @@ 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) => {
|
||||||
{left ? <View style={styles.leftContainer}>{left()}</View> : null}
|
const { fontScale } = useDimensions();
|
||||||
<View style={styles.textContainer}>
|
|
||||||
<View style={styles.textAlertContainer}>
|
return (
|
||||||
<Text style={[styles.title, { color: color || themes[theme!].titleText }]} numberOfLines={1}>
|
<View style={[styles.container, disabled && styles.disabled, { height: BASE_HEIGHT * fontScale }]} testID={testID}>
|
||||||
{translateTitle ? I18n.t(title) : title}
|
{left ? <View style={styles.leftContainer}>{left()}</View> : null}
|
||||||
</Text>
|
<View style={styles.textContainer}>
|
||||||
{alert ? (
|
<View style={styles.textAlertContainer}>
|
||||||
<CustomIcon style={[styles.alertIcon, { color: themes[theme!].dangerColor }]} size={ICON_SIZE} name='info' />
|
<Text style={[styles.title, { color: color || themes[theme].titleText }]} numberOfLines={1}>
|
||||||
|
{translateTitle ? I18n.t(title) : title}
|
||||||
|
</Text>
|
||||||
|
{alert ? (
|
||||||
|
<CustomIcon style={[styles.alertIcon, { color: themes[theme].dangerColor }]} size={ICON_SIZE} name='info' />
|
||||||
|
) : null}
|
||||||
|
</View>
|
||||||
|
{subtitle ? (
|
||||||
|
<Text style={[styles.subtitle, { color: themes[theme].auxiliaryText }]} numberOfLines={1}>
|
||||||
|
{translateSubtitle ? I18n.t(subtitle) : subtitle}
|
||||||
|
</Text>
|
||||||
) : null}
|
) : null}
|
||||||
</View>
|
</View>
|
||||||
{subtitle ? (
|
{right || showActionIndicator ? (
|
||||||
<Text style={[styles.subtitle, { color: themes[theme!].auxiliaryText }]} numberOfLines={1}>
|
<View style={styles.rightContainer}>
|
||||||
{translateSubtitle ? I18n.t(subtitle) : subtitle}
|
{right ? right() : null}
|
||||||
</Text>
|
{showActionIndicator ? <Icon name='chevron-right' style={styles.actionIndicator} /> : null}
|
||||||
|
</View>
|
||||||
) : null}
|
) : null}
|
||||||
</View>
|
</View>
|
||||||
{right || showActionIndicator ? (
|
);
|
||||||
<View style={styles.rightContainer}>
|
}
|
||||||
{right ? right() : null}
|
|
||||||
{showActionIndicator ? <Icon name='chevron-right' style={styles.actionIndicator} /> : null}
|
|
||||||
</View>
|
|
||||||
) : null}
|
|
||||||
</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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) => (
|
||||||
|
|
|
@ -900,4 +900,4 @@ export const e2eFetchMyKeys = async () => {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
Loading…
Reference in New Issue