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 {
|
||||
children: React.ReactNode;
|
||||
children: (React.ReactElement | null)[] | React.ReactElement | null;
|
||||
testID?: string;
|
||||
}
|
||||
const ListContainer = React.memo(({ children, ...props }: IListContainer) => (
|
||||
|
|
|
@ -25,6 +25,7 @@ interface IListHeader {
|
|||
|
||||
const ListHeader = React.memo(({ title, translateTitle = true }: IListHeader) => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<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 { CustomIcon } from '../../lib/Icons';
|
||||
import { withTheme } from '../../theme';
|
||||
import { useTheme } from '../../theme';
|
||||
import { ICON_SIZE } from './constants';
|
||||
|
||||
interface IListIcon {
|
||||
theme?: string;
|
||||
name: string;
|
||||
color?: string;
|
||||
style?: StyleProp<ViewStyle>;
|
||||
|
@ -21,12 +20,16 @@ const styles = StyleSheet.create({
|
|||
}
|
||||
});
|
||||
|
||||
const ListIcon = React.memo(({ theme, name, color, style, testID }: IListIcon) => (
|
||||
<View style={[styles.icon, style]}>
|
||||
<CustomIcon name={name} color={color ?? themes[theme!].auxiliaryText} size={ICON_SIZE} testID={testID} />
|
||||
</View>
|
||||
));
|
||||
const ListIcon = React.memo(({ name, color, style, testID }: IListIcon) => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
return (
|
||||
<View style={[styles.icon, style]}>
|
||||
<CustomIcon name={name} color={color ?? themes[theme].auxiliaryText} size={ICON_SIZE} testID={testID} />
|
||||
</View>
|
||||
);
|
||||
});
|
||||
|
||||
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 { themes } from '../../constants/colors';
|
||||
import sharedStyles from '../../views/Styles';
|
||||
import { withTheme } from '../../theme';
|
||||
import { useTheme } from '../../theme';
|
||||
import I18n from '../../i18n';
|
||||
import { Icon } from '.';
|
||||
import { BASE_HEIGHT, ICON_SIZE, PADDING_HORIZONTAL } from './constants';
|
||||
import { withDimensions } from '../../dimensions';
|
||||
import { useDimensions } from '../../dimensions';
|
||||
import { CustomIcon } from '../../lib/Icons';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
|
@ -59,13 +59,12 @@ interface IListItemContent {
|
|||
left?: () => JSX.Element | null;
|
||||
right?: () => JSX.Element | null;
|
||||
disabled?: boolean;
|
||||
theme: string;
|
||||
testID?: string;
|
||||
theme?: string;
|
||||
color?: string;
|
||||
translateTitle?: boolean;
|
||||
translateSubtitle?: boolean;
|
||||
showActionIndicator?: boolean;
|
||||
fontScale?: number;
|
||||
alert?: boolean;
|
||||
}
|
||||
|
||||
|
@ -78,78 +77,85 @@ const Content = React.memo(
|
|||
left,
|
||||
right,
|
||||
color,
|
||||
theme,
|
||||
fontScale,
|
||||
alert,
|
||||
translateTitle = true,
|
||||
translateSubtitle = true,
|
||||
showActionIndicator = false
|
||||
}: IListItemContent) => (
|
||||
<View style={[styles.container, disabled && styles.disabled, { height: BASE_HEIGHT * fontScale! }]} testID={testID}>
|
||||
{left ? <View style={styles.leftContainer}>{left()}</View> : null}
|
||||
<View style={styles.textContainer}>
|
||||
<View style={styles.textAlertContainer}>
|
||||
<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' />
|
||||
showActionIndicator = false,
|
||||
theme
|
||||
}: 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}
|
||||
<View style={styles.textContainer}>
|
||||
<View style={styles.textAlertContainer}>
|
||||
<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}
|
||||
</View>
|
||||
{subtitle ? (
|
||||
<Text style={[styles.subtitle, { color: themes[theme!].auxiliaryText }]} numberOfLines={1}>
|
||||
{translateSubtitle ? I18n.t(subtitle) : subtitle}
|
||||
</Text>
|
||||
{right || showActionIndicator ? (
|
||||
<View style={styles.rightContainer}>
|
||||
{right ? right() : null}
|
||||
{showActionIndicator ? <Icon name='chevron-right' style={styles.actionIndicator} /> : null}
|
||||
</View>
|
||||
) : null}
|
||||
</View>
|
||||
{right || showActionIndicator ? (
|
||||
<View style={styles.rightContainer}>
|
||||
{right ? right() : null}
|
||||
{showActionIndicator ? <Icon name='chevron-right' style={styles.actionIndicator} /> : null}
|
||||
</View>
|
||||
) : null}
|
||||
</View>
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
interface IListButtonPress {
|
||||
onPress?: Function;
|
||||
interface IListButtonPress extends IListItemButton {
|
||||
onPress: Function;
|
||||
}
|
||||
|
||||
interface IListItemButton extends IListButtonPress {
|
||||
interface IListItemButton {
|
||||
title?: string;
|
||||
disabled?: boolean;
|
||||
theme?: string;
|
||||
theme: string;
|
||||
backgroundColor?: string;
|
||||
underlayColor?: string;
|
||||
}
|
||||
|
||||
const Button = React.memo<IListItemButton>(({ onPress, backgroundColor, underlayColor, ...props }: IListItemButton) => (
|
||||
const Button = React.memo(({ onPress, backgroundColor, underlayColor, ...props }: IListButtonPress) => (
|
||||
<Touch
|
||||
onPress={() => onPress!(props.title)}
|
||||
style={{ backgroundColor: backgroundColor || themes[props.theme!].backgroundColor }}
|
||||
onPress={() => onPress(props.title)}
|
||||
style={{ backgroundColor: backgroundColor || themes[props.theme].backgroundColor }}
|
||||
underlayColor={underlayColor}
|
||||
enabled={!props.disabled}
|
||||
theme={props.theme!}>
|
||||
theme={props.theme}>
|
||||
<Content {...props} />
|
||||
</Touch>
|
||||
));
|
||||
|
||||
interface IListItem extends IListItemContent, IListItemButton {
|
||||
interface IListItem extends Omit<IListItemContent, 'theme'>, Omit<IListItemButton, 'theme'> {
|
||||
backgroundColor?: string;
|
||||
onPress?: Function;
|
||||
}
|
||||
|
||||
const ListItem = React.memo<IListItem>(({ ...props }: IListItem) => {
|
||||
const ListItem = React.memo(({ ...props }: IListItem) => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
if (props.onPress) {
|
||||
return <Button {...props} />;
|
||||
const { onPress } = props;
|
||||
return <Button {...props} theme={theme} onPress={onPress} />;
|
||||
}
|
||||
return (
|
||||
<View style={{ backgroundColor: props.backgroundColor || themes[props.theme!].backgroundColor }}>
|
||||
<Content {...props} />
|
||||
<View style={{ backgroundColor: props.backgroundColor || themes[theme].backgroundColor }}>
|
||||
<Content {...props} theme={theme} />
|
||||
</View>
|
||||
);
|
||||
});
|
||||
|
||||
ListItem.displayName = 'List.Item';
|
||||
|
||||
export default withTheme(withDimensions(ListItem));
|
||||
export default ListItem;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
|
||||
import { withTheme } from '../../theme';
|
||||
import { Header } from '.';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
|
@ -11,7 +10,7 @@ const styles = StyleSheet.create({
|
|||
});
|
||||
|
||||
interface IListSection {
|
||||
children: React.ReactNode;
|
||||
children: (React.ReactElement | null)[] | React.ReactElement | null;
|
||||
title?: string;
|
||||
translateTitle?: boolean;
|
||||
}
|
||||
|
@ -25,4 +24,4 @@ const ListSection = React.memo(({ children, title, translateTitle }: IListSectio
|
|||
|
||||
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 { themes } from '../../constants/colors';
|
||||
import { withTheme } from '../../theme';
|
||||
import { useTheme } from '../../theme';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
separator: {
|
||||
|
@ -12,13 +12,14 @@ const styles = StyleSheet.create({
|
|||
|
||||
interface IListSeparator {
|
||||
style?: ViewStyle;
|
||||
theme?: string;
|
||||
}
|
||||
|
||||
const ListSeparator = React.memo(({ style, theme }: IListSeparator) => (
|
||||
<View style={[styles.separator, style, { backgroundColor: themes[theme!].separatorColor }]} />
|
||||
));
|
||||
const ListSeparator = React.memo(({ style }: IListSeparator) => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
return <View style={[styles.separator, style, { backgroundColor: themes[theme].separatorColor }]} />;
|
||||
});
|
||||
|
||||
ListSeparator.displayName = 'List.Separator';
|
||||
|
||||
export default withTheme(ListSeparator);
|
||||
export default ListSeparator;
|
||||
|
|
|
@ -8,7 +8,7 @@ export interface IDimensionsContextProps {
|
|||
width: number;
|
||||
height: number;
|
||||
scale?: number;
|
||||
fontScale?: number;
|
||||
fontScale: number;
|
||||
setDimensions?: ({
|
||||
width,
|
||||
height,
|
||||
|
@ -22,7 +22,9 @@ export interface IDimensionsContextProps {
|
|||
}) => 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 {
|
||||
const DimensionsComponent = (props: T) => (
|
||||
|
|
|
@ -900,4 +900,4 @@ export const e2eFetchMyKeys = async () => {
|
|||
};
|
||||
}
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -6,7 +6,6 @@ import { CompositeNavigationProp } from '@react-navigation/core';
|
|||
|
||||
import * as List from '../containers/List';
|
||||
import StatusBar from '../containers/StatusBar';
|
||||
import { useTheme } from '../theme';
|
||||
import * as HeaderButton from '../containers/HeaderButton';
|
||||
import SafeAreaView from '../containers/SafeAreaView';
|
||||
import I18n from '../i18n';
|
||||
|
@ -41,7 +40,6 @@ const setHeader = ({
|
|||
|
||||
const AddChannelTeamView = ({ navigation, route, isMasterDetail }: IAddChannelTeamView) => {
|
||||
const { teamId, teamChannels } = route.params;
|
||||
const { theme } = useTheme();
|
||||
|
||||
useEffect(() => {
|
||||
setHeader({ navigation, isMasterDetail });
|
||||
|
@ -67,7 +65,6 @@ const AddChannelTeamView = ({ navigation, route, isMasterDetail }: IAddChannelTe
|
|||
testID='add-channel-team-view-create-channel'
|
||||
left={() => <List.Icon name='team' />}
|
||||
right={() => <List.Icon name='chevron-right' />}
|
||||
theme={theme}
|
||||
/>
|
||||
<List.Separator />
|
||||
<List.Item
|
||||
|
@ -76,7 +73,6 @@ const AddChannelTeamView = ({ navigation, route, isMasterDetail }: IAddChannelTe
|
|||
testID='add-channel-team-view-add-existing'
|
||||
left={() => <List.Icon name='channel-public' />}
|
||||
right={() => <List.Icon name='chevron-right' />}
|
||||
theme={theme}
|
||||
/>
|
||||
<List.Separator />
|
||||
</List.Container>
|
||||
|
|
|
@ -223,7 +223,7 @@ class ScreenLockConfigView extends React.Component<IScreenLockConfigViewProps, I
|
|||
return (
|
||||
<List.Section>
|
||||
<List.Separator />
|
||||
{items.map(item => this.renderItem({ item }))}
|
||||
<>{items.map(item => this.renderItem({ item }))}</>
|
||||
</List.Section>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -131,11 +131,11 @@ class ThemeView extends React.Component<IThemeViewProps> {
|
|||
<List.Container>
|
||||
<List.Section title='Theme'>
|
||||
<List.Separator />
|
||||
{themeGroup.map(item => this.renderItem({ item }))}
|
||||
<>{themeGroup.map(item => this.renderItem({ item }))}</>
|
||||
</List.Section>
|
||||
<List.Section title='Dark_level'>
|
||||
<List.Separator />
|
||||
{darkGroup.map(item => this.renderItem({ item }))}
|
||||
<>{darkGroup.map(item => this.renderItem({ item }))}</>
|
||||
</List.Section>
|
||||
</List.Container>
|
||||
</SafeAreaView>
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue