diff --git a/src/components/OptionsListSkeletonView.tsx b/src/components/OptionsListSkeletonView.tsx index 9f60f1e5fc40..1f09876b18d3 100644 --- a/src/components/OptionsListSkeletonView.tsx +++ b/src/components/OptionsListSkeletonView.tsx @@ -1,80 +1,54 @@ -import React, {useMemo, useState} from 'react'; -import {View} from 'react-native'; +import React from 'react'; 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'; +import ItemListSkeletonView from './Skeletons/ItemListSkeletonView'; + +function getLinedWidth(index: number): string { + const step = index % 3; + if (step === 0) { + return '100%'; + } + + if (step === 1) { + return '50%'; + } + + return '25%'; +} 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); + { + const lineWidth = getLinedWidth(itemIndex); + + return ( + <> + + + + + ); }} - > - {skeletonViewItems} - + /> ); } diff --git a/src/components/Skeletons/ItemListSkeletonView.tsx b/src/components/Skeletons/ItemListSkeletonView.tsx new file mode 100644 index 000000000000..00854471f2e3 --- /dev/null +++ b/src/components/Skeletons/ItemListSkeletonView.tsx @@ -0,0 +1,55 @@ +import React, {useMemo, useState} from 'react'; +import {View} from 'react-native'; +import SkeletonViewContentLoader from '@components/SkeletonViewContentLoader'; +import useTheme from '@hooks/useTheme'; +import useThemeStyles from '@hooks/useThemeStyles'; +import CONST from '@src/CONST'; + +type ListItemSkeletonProps = { + shouldAnimate?: boolean; + renderSkeletonItem: (args: {itemIndex: number}) => React.ReactNode; +}; + +function ItemListSkeletonView({shouldAnimate = true, renderSkeletonItem}: ListItemSkeletonProps) { + const theme = useTheme(); + const themeStyles = useThemeStyles(); + + const [numItems, setNumItems] = useState(0); + const skeletonViewItems = useMemo(() => { + const items = []; + for (let i = 0; i < numItems; i++) { + items.push( + + {renderSkeletonItem({itemIndex: i})} + , + ); + } + return items; + }, [numItems, shouldAnimate, theme, themeStyles, renderSkeletonItem]); + + return ( + { + const newNumItems = Math.ceil(event.nativeEvent.layout.height / CONST.LHN_SKELETON_VIEW_ITEM_HEIGHT); + if (newNumItems === numItems) { + return; + } + setNumItems(newNumItems); + }} + > + {skeletonViewItems} + + ); +} + +ItemListSkeletonView.displayName = 'ListItemSkeleton'; + +export default ItemListSkeletonView; diff --git a/src/components/Skeletons/TableListItemSkeleton.tsx b/src/components/Skeletons/TableListItemSkeleton.tsx new file mode 100644 index 000000000000..d24268521100 --- /dev/null +++ b/src/components/Skeletons/TableListItemSkeleton.tsx @@ -0,0 +1,65 @@ +import React from 'react'; +import {Rect} from 'react-native-svg'; +import ItemListSkeletonView from './ItemListSkeletonView'; + +type TableListItemSkeletonProps = { + shouldAnimate?: boolean; +}; + +const barHeight = '10'; +const shortBarWidth = '40'; +const longBarWidth = '120'; + +function TableListItemSkeleton({shouldAnimate = true}: TableListItemSkeletonProps) { + return ( + ( + <> + + + + + + + + )} + /> + ); +} + +TableListItemSkeleton.displayName = 'TableListItemSkeleton'; + +export default TableListItemSkeleton; diff --git a/src/pages/Search/EmptySearchView.tsx b/src/pages/Search/EmptySearchView.tsx new file mode 100644 index 000000000000..7109b1faa1d4 --- /dev/null +++ b/src/pages/Search/EmptySearchView.tsx @@ -0,0 +1,10 @@ +import React from 'react'; +import TableListItemSkeleton from '@components/Skeletons/TableListItemSkeleton'; + +function EmptySearchView() { + return ; +} + +EmptySearchView.displayName = 'EmptySearchView'; + +export default EmptySearchView; diff --git a/src/pages/Search/SearchPage.tsx b/src/pages/Search/SearchPage.tsx index 3f69371841ce..634dbe0572ec 100644 --- a/src/pages/Search/SearchPage.tsx +++ b/src/pages/Search/SearchPage.tsx @@ -3,6 +3,7 @@ import React from 'react'; import ScreenWrapper from '@components/ScreenWrapper'; import type {CentralPaneNavigatorParamList} from '@libs/Navigation/types'; import type SCREENS from '@src/SCREENS'; +// import EmptySearchView from './EmptySearchView'; import SearchResults from './SearchResults'; import useCustomBackHandler from './useCustomBackHandler'; @@ -14,6 +15,7 @@ function SearchPage({route}: SearchPageProps) { return ( + {/* */} ); } diff --git a/src/pages/Search/SearchPageBottomTab.tsx b/src/pages/Search/SearchPageBottomTab.tsx index 62413d743d76..f90f066d72a7 100644 --- a/src/pages/Search/SearchPageBottomTab.tsx +++ b/src/pages/Search/SearchPageBottomTab.tsx @@ -11,6 +11,8 @@ import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import type IconAsset from '@src/types/utils/IconAsset'; +// import EmptySearchView from './EmptySearchView'; + type SearchMenuItem = { title: string; icon: IconAsset; @@ -59,6 +61,7 @@ function SearchPageBottomTab() { /> ))} + {/* */} ); }