import React, { useEffect, useRef, useState } from 'react' import { type useVirtualizer } from '@tanstack/react-virtual' import Button from '../../Button/Button' import EmptyState from '../../EmptyState/EmptyState' import Icon from '../../Icons/Icon' import isClient from '../../../services/isClient' import Popover from '../../Popover/Popover' import SearchBar from '../../SearchBar/SearchBar' import { useIsMobileView } from '../../../hooks/useIsMobileView/useIsMobileView' import styles from './_pagination-ellipsis.module.scss' import { SelectDisplayRow } from '../../Selects/SelectDisplay/SelectDisplay' import { Virtual } from '../../Virtual/Virtual' import ScrollingContainer from '../../ScrollingContainer/ScrollingContainer' import { c } from '../../../translations/LibraryTranslationService' type PaginationEllipsisProps = { activePage: number position: 'start' | 'end' lastPage: number updatePage: (page: number) => void pageOptions: { name: string; label: string }[] } const PaginationEllipsis = ({ activePage, position, lastPage, updatePage, pageOptions, }: PaginationEllipsisProps): React.JSX.Element => { const [showPopover, setShowPopover] = useState(false) const [searchValue, setSearchValue] = useState('') const [options, setOptions] = useState(pageOptions) const [filteredOptions, setFilteredOptions] = useState< { name: string label: string }[] >([]) const searchBarRef = useRef(null) const searchBarTimeout = useRef>(undefined) const optionTimeout = useRef>(undefined) const scrollTimeout = useRef>(undefined) const isMobileView = useIsMobileView() useEffect(() => { if (showPopover && searchBarRef.current) { searchBarTimeout.current = setTimeout(() => { searchBarRef.current?.focus() }, 250) } return () => { clearTimeout(searchBarTimeout.current) } }, [showPopover]) useEffect(() => { return () => { clearTimeout(optionTimeout.current) clearTimeout(scrollTimeout.current) } }, []) const updateSearch = (searchValue: string) => { setSearchValue(searchValue) const filteredOptions = searchValue ? options.filter((option) => option.name .toLowerCase() .includes(searchValue.replace(/,/g, '').toLowerCase()), ) : options setFilteredOptions(filteredOptions) } useEffect(() => { const createPagesArray = (): { name: string; label: string }[] => { let startPage: number let endPage: number if (isMobileView) { // For mobile, use the full range startPage = 1 endPage = lastPage + 1 } else { if (position === 'start') { startPage = 2 endPage = activePage + 4 > lastPage ? lastPage - 4 : activePage - 1 } else { startPage = activePage > 3 ? activePage + 3 : 6 endPage = lastPage } } return Array.from({ length: endPage - startPage + 1 }, (_, i) => ({ name: (i + startPage).toString(), label: (i + startPage).toLocaleString(), })) } const newOptions = createPagesArray() setOptions(newOptions) setFilteredOptions(newOptions) }, [activePage, lastPage, position, isMobileView]) const renderContent = ( virtualizer: ReturnType, virtualizedParentRef: React.RefObject, setVisible?: (visible: boolean) => void, ) => (
{filteredOptions.length === 0 ? ( ) : ( {({ index }) => ( { setSearchValue('') setShowPopover(false) setVisible && setVisible(false) optionTimeout.current = setTimeout(() => { updatePage(Number(option.name) - 1) virtualizer.scrollToIndex(0) }, 200) }} option={filteredOptions[index]} /> )} )}
) return ( {({ virtualizer, virtualizedParentRef }) => ( { setShowPopover(false) scrollTimeout.current = setTimeout(() => { virtualizer.scrollToIndex(0) }, 200) }} noPadding popoverContent={({ setVisible }) => renderContent( virtualizer, virtualizedParentRef as unknown as React.RefObject, setVisible, ) } > {({ setVisible }) => (
{isMobileView ? ( ) : ( )}
)}
)}
) } export default PaginationEllipsis