Skip to content

Commit 3033f99

Browse files
authored
Merge pull request #34008 from software-mansion-labs/@szymczak/SelectionList
[TS migration] Migrate 'SelectionList' component to TypeScript
2 parents fe9c2e8 + 7d65ede commit 3033f99

15 files changed

+505
-222
lines changed

src/components/SectionList/index.android.tsx

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
import React, {forwardRef} from 'react';
2+
import type {ForwardedRef} from 'react';
23
import {SectionList as RNSectionList} from 'react-native';
3-
import type ForwardedSectionList from './types';
4+
import type {SectionListProps} from 'react-native';
45

56
// eslint-disable-next-line react/function-component-definition
6-
const SectionListWithRef: ForwardedSectionList = (props, ref) => (
7-
<RNSectionList
8-
// eslint-disable-next-line react/jsx-props-no-spreading
9-
{...props}
10-
ref={ref}
11-
// For Android we want to use removeClippedSubviews since it helps manage memory consumption. When we
12-
// run out memory images stop loading and appear as grey circles
13-
// eslint-disable-next-line react/jsx-props-no-multi-spaces
14-
removeClippedSubviews
15-
/>
16-
);
7+
function SectionListWithRef<ItemT, SectionT>(props: SectionListProps<ItemT, SectionT>, ref: ForwardedRef<RNSectionList<ItemT, SectionT>>) {
8+
return (
9+
<RNSectionList
10+
// eslint-disable-next-line react/jsx-props-no-spreading
11+
{...props}
12+
ref={ref}
13+
// For Android we want to use removeClippedSubviews since it helps manage memory consumption. When we
14+
// run out memory images stop loading and appear as grey circles
15+
// eslint-disable-next-line react/jsx-props-no-multi-spaces
16+
removeClippedSubviews
17+
/>
18+
);
19+
}
1720

1821
SectionListWithRef.displayName = 'SectionListWithRef';
1922

src/components/SectionList/index.tsx

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
import React, {forwardRef} from 'react';
2+
import type {ForwardedRef} from 'react';
23
import {SectionList as RNSectionList} from 'react-native';
3-
import type ForwardedSectionList from './types';
4+
import type {SectionListProps} from 'react-native';
45

56
// eslint-disable-next-line react/function-component-definition
6-
const SectionList: ForwardedSectionList = (props, ref) => (
7-
<RNSectionList
8-
// eslint-disable-next-line react/jsx-props-no-spreading
9-
{...props}
10-
ref={ref}
11-
/>
12-
);
13-
14-
SectionList.displayName = 'SectionList';
7+
function SectionList<ItemT, SectionT>(props: SectionListProps<ItemT, SectionT>, ref: ForwardedRef<RNSectionList<ItemT, SectionT>>) {
8+
return (
9+
<RNSectionList
10+
// eslint-disable-next-line react/jsx-props-no-spreading
11+
{...props}
12+
ref={ref}
13+
/>
14+
);
15+
}
1516

1617
export default forwardRef(SectionList);

src/components/SectionList/types.ts

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/components/SelectionList/BaseListItem.js renamed to src/components/SelectionList/BaseListItem.tsx

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import lodashGet from 'lodash/get';
21
import React from 'react';
32
import {View} from 'react-native';
43
import Icon from '@components/Icon';
@@ -12,10 +11,10 @@ import useTheme from '@hooks/useTheme';
1211
import useThemeStyles from '@hooks/useThemeStyles';
1312
import CONST from '@src/CONST';
1413
import RadioListItem from './RadioListItem';
15-
import {baseListItemPropTypes} from './selectionListPropTypes';
14+
import type {BaseListItemProps, RadioItem, User} from './types';
1615
import UserListItem from './UserListItem';
1716

18-
function BaseListItem({
17+
function BaseListItem<TItem extends User | RadioItem>({
1918
item,
2019
isFocused = false,
2120
isDisabled = false,
@@ -26,13 +25,12 @@ function BaseListItem({
2625
onDismissError = () => {},
2726
rightHandSideComponent,
2827
keyForList,
29-
}) {
28+
}: BaseListItemProps<TItem>) {
3029
const theme = useTheme();
3130
const styles = useThemeStyles();
3231
const StyleUtils = useStyleUtils();
3332
const {translate} = useLocalize();
34-
const isUserItem = lodashGet(item, 'icons.length', 0) > 0;
35-
const ListItem = isUserItem ? UserListItem : RadioListItem;
33+
const isRadioItem = item.rightElement === undefined;
3634

3735
const rightHandSideComponentRender = () => {
3836
if (canSelectMultiple || !rightHandSideComponent) {
@@ -70,7 +68,7 @@ function BaseListItem({
7068
styles.justifyContentBetween,
7169
styles.sidebarLinkInner,
7270
styles.userSelectNone,
73-
isUserItem ? styles.peopleRow : styles.optionRow,
71+
isRadioItem ? styles.optionRow : styles.peopleRow,
7472
isFocused && styles.sidebarLinkActive,
7573
]}
7674
>
@@ -100,20 +98,32 @@ function BaseListItem({
10098
</View>
10199
</View>
102100
)}
103-
<ListItem
104-
item={item}
105-
textStyles={[
106-
styles.optionDisplayName,
107-
isFocused ? styles.sidebarLinkActiveText : styles.sidebarLinkText,
108-
styles.sidebarLinkTextBold,
109-
styles.pre,
110-
item.alternateText ? styles.mb1 : null,
111-
]}
112-
alternateTextStyles={[styles.textLabelSupporting, styles.lh16, styles.pre]}
113-
isDisabled={isDisabled}
114-
onSelectRow={onSelectRow}
115-
showTooltip={showTooltip}
116-
/>
101+
102+
{isRadioItem ? (
103+
<RadioListItem
104+
item={item}
105+
textStyles={[styles.optionDisplayName, isFocused ? styles.sidebarLinkActiveText : styles.sidebarLinkText, styles.pre, item.alternateText ? styles.mb1 : null]}
106+
alternateTextStyles={[styles.textLabelSupporting, styles.lh16, styles.pre]}
107+
isDisabled={isDisabled}
108+
onSelectRow={() => onSelectRow(item)}
109+
showTooltip={showTooltip}
110+
/>
111+
) : (
112+
<UserListItem
113+
item={item}
114+
textStyles={[
115+
styles.optionDisplayName,
116+
isFocused ? styles.sidebarLinkActiveText : styles.sidebarLinkText,
117+
styles.sidebarLinkTextBold,
118+
styles.pre,
119+
item.alternateText ? styles.mb1 : null,
120+
]}
121+
alternateTextStyles={[styles.textLabelSupporting, styles.lh16, styles.pre]}
122+
isDisabled={isDisabled}
123+
onSelectRow={() => onSelectRow(item)}
124+
showTooltip={showTooltip}
125+
/>
126+
)}
117127
{!canSelectMultiple && item.isSelected && !rightHandSideComponent && (
118128
<View
119129
style={[styles.flexRow, styles.alignItemsCenter, styles.ml3]}
@@ -129,7 +139,7 @@ function BaseListItem({
129139
)}
130140
{rightHandSideComponentRender()}
131141
</View>
132-
{Boolean(item.invitedSecondaryLogin) && (
142+
{!!item.invitedSecondaryLogin && (
133143
<Text style={[styles.ml9, styles.ph5, styles.pb3, styles.textLabelSupporting]}>
134144
{translate('workspace.people.invitedBySecondaryLogin', {secondaryLogin: item.invitedSecondaryLogin})}
135145
</Text>
@@ -140,6 +150,5 @@ function BaseListItem({
140150
}
141151

142152
BaseListItem.displayName = 'BaseListItem';
143-
BaseListItem.propTypes = baseListItemPropTypes;
144153

145154
export default BaseListItem;

0 commit comments

Comments
 (0)