diff --git a/src/components/OptionsListSkeletonView.js b/src/components/OptionsListSkeletonView.js deleted file mode 100644 index 2c46ac5d4d7a..000000000000 --- a/src/components/OptionsListSkeletonView.js +++ /dev/null @@ -1,114 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import {View} from 'react-native'; -import {Circle, Rect} from 'react-native-svg'; -import compose from '@libs/compose'; -import CONST from '@src/CONST'; -import SkeletonViewContentLoader from './SkeletonViewContentLoader'; -import withTheme, {withThemePropTypes} from './withTheme'; -import withThemeStyles, {withThemeStylesPropTypes} from './withThemeStyles'; - -const propTypes = { - /** Whether to animate the skeleton view */ - shouldAnimate: PropTypes.bool, - ...withThemeStylesPropTypes, - ...withThemePropTypes, -}; - -const defaultTypes = { - shouldAnimate: true, -}; - -class OptionsListSkeletonView extends React.Component { - constructor(props) { - super(props); - this.state = { - skeletonViewItems: [], - }; - } - - /** - * Generate the skeleton view items. - * - * @param {Number} numItems - */ - generateSkeletonViewItems(numItems) { - if (this.state.skeletonViewItems.length === numItems) { - return; - } - - if (this.state.skeletonViewItems.length > numItems) { - this.setState((prevState) => ({ - skeletonViewItems: prevState.skeletonViewItems.slice(0, numItems), - })); - return; - } - - const skeletonViewItems = []; - for (let i = this.state.skeletonViewItems.length; i < numItems; i++) { - const step = i % 3; - let lineWidth; - switch (step) { - case 0: - lineWidth = '100%'; - break; - case 1: - lineWidth = '50%'; - break; - default: - lineWidth = '25%'; - } - skeletonViewItems.push( - - - - - , - ); - } - - this.setState((prevState) => ({ - skeletonViewItems: [...prevState.skeletonViewItems, ...skeletonViewItems], - })); - } - - render() { - return ( - { - const numItems = Math.ceil(event.nativeEvent.layout.height / CONST.LHN_SKELETON_VIEW_ITEM_HEIGHT); - this.generateSkeletonViewItems(numItems); - }} - > - {this.state.skeletonViewItems} - - ); - } -} - -OptionsListSkeletonView.propTypes = propTypes; -OptionsListSkeletonView.defaultProps = defaultTypes; - -export default compose(withThemeStyles, withTheme)(OptionsListSkeletonView); diff --git a/src/components/OptionsListSkeletonView.tsx b/src/components/OptionsListSkeletonView.tsx new file mode 100644 index 000000000000..9f60f1e5fc40 --- /dev/null +++ b/src/components/OptionsListSkeletonView.tsx @@ -0,0 +1,83 @@ +import React, {useMemo, useState} from 'react'; +import {View} from 'react-native'; +import {Circle, Rect} from 'react-native-svg'; +import useTheme from '@hooks/useTheme'; +import useThemeStyles from '@hooks/useThemeStyles'; +import CONST from '@src/CONST'; +import SkeletonViewContentLoader from './SkeletonViewContentLoader'; + +type OptionsListSkeletonViewProps = { + shouldAnimate?: boolean; +}; + +function OptionsListSkeletonView({shouldAnimate = true}: OptionsListSkeletonViewProps) { + const theme = useTheme(); + const themeStyles = useThemeStyles(); + + const [numItems, setNumItems] = useState(0); + const skeletonViewItems = useMemo(() => { + const items = []; + for (let i = 0; i < numItems; i++) { + const step = i % 3; + let lineWidth; + switch (step) { + case 0: + lineWidth = '100%'; + break; + case 1: + lineWidth = '50%'; + break; + default: + lineWidth = '25%'; + } + items.push( + + + + + , + ); + } + return items; + }, [numItems, shouldAnimate, theme, themeStyles]); + + return ( + { + const newNumItems = Math.ceil(event.nativeEvent.layout.height / CONST.LHN_SKELETON_VIEW_ITEM_HEIGHT); + if (newNumItems === numItems) { + return; + } + setNumItems(newNumItems); + }} + > + {skeletonViewItems} + + ); +} + +OptionsListSkeletonView.displayName = 'OptionsListSkeletonView'; + +export default OptionsListSkeletonView;