Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TS migration] Migrate 'FeatureList.js' component to TypeScript #25039 #35492

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 33 additions & 33 deletions src/components/FeatureList.js → src/components/FeatureList.tsx
Original file line number Diff line number Diff line change
@@ -1,60 +1,61 @@
import PropTypes from 'prop-types';
import React from 'react';
import {View} from 'react-native';
import _ from 'underscore';
import type {StyleProp, ViewStyle} from 'react-native';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import stylePropTypes from '@styles/stylePropTypes';
import variables from '@styles/variables';
import type {TranslationPaths} from '@src/languages/types';
import type IconAsset from '@src/types/utils/IconAsset';
import Button from './Button';
import type DotLottieAnimation from './LottieAnimations/types';
import MenuItem from './MenuItem';
import menuItemPropTypes from './menuItemPropTypes';
import Section from './Section';

const propTypes = {
type FeatureListItem = {
icon: IconAsset;
translationKey: TranslationPaths;
};

type FeatureListProps = {
/** The text to display in the title of the section */
title: PropTypes.string.isRequired,
title: string;

/** The text to display in the subtitle of the section */
subtitle: PropTypes.string,
subtitle?: string;

/** Text of the call to action button */
ctaText: PropTypes.string,
ctaText?: string;

/** Accessibility label for the call to action button */
ctaAccessibilityLabel: PropTypes.string,
ctaAccessibilityLabel?: string;

/** Action to call on cta button press */
onCtaPress: PropTypes.func,
onCtaPress?: () => void;

/** A list of menuItems representing the feature list. */
menuItems: PropTypes.arrayOf(PropTypes.shape({...menuItemPropTypes, translationKey: PropTypes.string})).isRequired,
menuItems: FeatureListItem[];

/** The illustration to display in the header. Can be a JSON object representing a Lottie animation. */
illustration: PropTypes.shape({
file: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
w: PropTypes.number.isRequired,
h: PropTypes.number.isRequired,
}),
illustration: DotLottieAnimation;

/** The style passed to the illustration */
illustrationStyle: stylePropTypes,
illustrationStyle?: StyleProp<ViewStyle>;

/** The background color to apply in the upper half of the screen. */
illustrationBackgroundColor: PropTypes.string,
};

const defaultProps = {
ctaText: '',
ctaAccessibilityLabel: '',
subtitle: '',
onCtaPress: () => {},
illustration: null,
illustrationBackgroundColor: '',
illustrationStyle: [],
illustrationBackgroundColor?: string;
};

function FeatureList({title, subtitle, ctaText, ctaAccessibilityLabel, onCtaPress, menuItems, illustration, illustrationStyle, illustrationBackgroundColor}) {
function FeatureList({
title,
subtitle = '',
ctaText = '',
ctaAccessibilityLabel = '',
onCtaPress,
menuItems,
illustration,
illustrationStyle,
illustrationBackgroundColor = '',
}: FeatureListProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();

Expand All @@ -70,7 +71,7 @@ function FeatureList({title, subtitle, ctaText, ctaAccessibilityLabel, onCtaPres
>
<View style={styles.flex1}>
<View style={[styles.flex1, styles.flexRow, styles.flexWrap, styles.rowGap4, styles.pv4, styles.pl1]}>
{_.map(menuItems, ({translationKey, icon}) => (
{menuItems.map(({translationKey, icon}) => (
<View
key={translationKey}
style={styles.w100}
Expand All @@ -93,16 +94,15 @@ function FeatureList({title, subtitle, ctaText, ctaAccessibilityLabel, onCtaPres
text={ctaText}
onPress={onCtaPress}
accessibilityLabel={ctaAccessibilityLabel}
style={[styles.w100]}
style={styles.w100}
success
/>
</View>
</Section>
);
}

FeatureList.propTypes = propTypes;
FeatureList.defaultProps = defaultProps;
FeatureList.displayName = 'FeatureList';

export default FeatureList;
export type {FeatureListItem};
4 changes: 2 additions & 2 deletions src/pages/workspace/WorkspacesListPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {ValueOf} from 'type-fest';
import Button from '@components/Button';
import ConfirmModal from '@components/ConfirmModal';
import FeatureList from '@components/FeatureList';
import type {FeatureListItem} from '@components/FeatureList';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import * as Expensicons from '@components/Icon/Expensicons';
import * as Illustrations from '@components/Icon/Illustrations';
Expand Down Expand Up @@ -78,7 +79,7 @@ type WorkspaceListPageOnyxProps = {

type WorkspaceListPageProps = WithPolicyAndFullscreenLoadingProps & WorkspaceListPageOnyxProps;

const workspaceFeatures = [
const workspaceFeatures: FeatureListItem[] = [
{
icon: Illustrations.MoneyReceipts,
translationKey: 'workspace.emptyWorkspace.features.trackAndCollect',
Expand Down Expand Up @@ -341,7 +342,6 @@ function WorkspacesListPage({policies, allPolicyMembers, reimbursementAccount, r
ctaText={translate('workspace.new.newWorkspace')}
ctaAccessibilityLabel={translate('workspace.new.newWorkspace')}
onCtaPress={() => App.createWorkspaceWithPolicyDraftAndNavigateToIt()}
// @ts-expect-error TODO: Remove once FeatureList (https://github.com/Expensify/App/issues/25039) is migrated to TS
illustration={LottieAnimations.WorkspacePlanet}
illustrationBackgroundColor={theme.PAGE_THEMES[SCREENS.SETTINGS.WORKSPACES].backgroundColor}
// We use this style to vertically center the illustration, as the original illustration is not centered
Expand Down
Loading