import { Table, TableProps } from "antd"; import React, { useLayoutEffect, useRef, useState } from "react"; import { ReactComponent as Loading } from "./loader.svg"; import "./Table.scss"; import useObserverWithRefCallback from "./../../hooks/useObserverWithRefCallback"; import { DEFAULT_TABLE_HEADER_HEIGHT } from "../../utils/constants"; import { useDebouncedWindowSize } from "../../hooks/useDebouncedWindowSize"; import { ReactComponent as Lefticon } from "./left.svg"; import { ReactComponent as RightIcon } from "./right.svg"; import { debounce } from "../../utils/utils"; type Props = { loading?: boolean; infiniteScrollConfig?: { callback: () => void; numberOfObserverSkippedFromLast?: number; hasMore?: boolean; }; flexHeight?: boolean; horizontalScrollConfig?: { enable: boolean; threshold: number; }; }; const StarshipTable = ( props: TableProps & Props ) => { const { className, loading = false, dataSource, infiniteScrollConfig, onRow, flexHeight = false, scroll = {}, horizontalScrollConfig = { enable: false, threshold: 10 }, ...restProps } = props; const { callback, numberOfObserverSkippedFromLast = 0, hasMore = true, } = infiniteScrollConfig || {}; const { enable: horizontalScrollEnabled, threshold } = horizontalScrollConfig; const [tableHeight, setTableHeight] = useState(0); const wrapperRef = useRef(null); const setRef = useObserverWithRefCallback(callback, hasMore); const dimensions = useDebouncedWindowSize({ activateListner: flexHeight }); const antdTable = useRef(null); const [horizontalScrollLeft, setHorizontalScrollLeft] = useState(0); const [maxHorizontalScroll, setMaxHorizontalScroll] = useState(0); const onScrollArrow = (threshold: number = 0) => { if (antdTable.current) { //setting state of lefr scroll setHorizontalScrollLeft(antdTable.current.scrollLeft + threshold); //scrolling element antdTable.current.scroll({ left: antdTable.current.scrollLeft + threshold, }); } }; const scrollCb = debounce(() => { if (antdTable.current) setHorizontalScrollLeft(antdTable.current.scrollLeft); }, 200); useLayoutEffect(() => { if (wrapperRef.current && flexHeight) { //handling table height const wrapperHeight = wrapperRef.current?.clientHeight; const tableHeaderHeight = wrapperRef.current.querySelector(".ant-table-header")?.clientHeight; const tableContentHeight = tableHeaderHeight ? wrapperHeight - tableHeaderHeight : wrapperHeight - DEFAULT_TABLE_HEADER_HEIGHT; setTableHeight(tableContentHeight); //handling horizontal scroll if (horizontalScrollEnabled) { antdTable.current = wrapperRef.current.querySelector(".ant-table-body"); const antdScrollWidth = antdTable.current?.scrollWidth; const antdWidth = antdTable.current?.clientWidth; let antMaxHorizontalScroll = 0; if (antdScrollWidth && antdWidth) { antMaxHorizontalScroll = antdScrollWidth - antdWidth; setMaxHorizontalScroll(antMaxHorizontalScroll); } antdTable.current?.addEventListener("scroll", scrollCb); } } return () => { antdTable.current?.removeEventListener("scroll", scrollCb); }; }, [wrapperRef.current, flexHeight, dimensions]); return (
{horizontalScrollEnabled && maxHorizontalScroll > 0 && (
{horizontalScrollLeft > 0 && maxHorizontalScroll > 0 && (
onScrollArrow(-threshold)} >
)} {horizontalScrollLeft < maxHorizontalScroll && (
onScrollArrow(threshold)} >
)}
)} }} onRow={ onRow ? onRow : (_, index) => { //attaching ref to the last element to observe it if ( !loading && infiniteScrollConfig && dataSource && dataSource.length > 0 ) { if ( index === dataSource.length - 1 - numberOfObserverSkippedFromLast ) { return { ref: setRef, }; } } return { className: "", //need to return set or props else showing TS warning }; } } scroll={ flexHeight && tableHeight !== 0 ? { y: tableHeight, ...scroll } : scroll } /> ); }; export default StarshipTable;