import React, { useRef, useState, useMemo, useCallback, useEffect, } from "react"; import classNames from "classnames"; import { TableProps } from "./TableProps"; import { TableHead } from "./TableHead"; import { TableBody } from "./TableBody"; import { useMiddleware } from "./util/use-middleware"; import { createRocket } from "../_util/create-rocket"; import { useConfig } from "../_util/config-context"; import { TableContextValue, TableContext } from "./TableContext"; import { forwardRefWithStatics } from "../_util/forward-ref-with-statics"; import * as addons from "./addons"; import { mergeEventProps } from "../_util/merge-event-props"; export const Table = forwardRefWithStatics( function Table(props: TableProps, ref: React.Ref) { const { classPrefix } = useConfig(); const [scrollStatus, setScrollStatus] = useState< TableContextValue["scrollStatus"] >("left"); const [columnsWidths, setColumnsWidths] = useState([]); const { addons = [], bordered, compact, verticalTop } = props; const headRef = useRef(null); const bodyRef = useRef(null); // 执行 addon props middleware // eslint-disable-next-line no-param-reassign props = useMiddleware(addons, "onInjectProps")(props); const hasFixedColumn = useMemo( () => props.columns.find(column => !!column.fixed), [props.columns] ); // 同步 body 和 header 滚动位置 const handleScroll = useCallback(() => { // 设置水平滚动状态(固定列样式) if (bodyRef.current && hasFixedColumn) { const { scrollWidth, clientWidth, scrollLeft } = bodyRef.current; const atLeft = scrollLeft === 0; const atRight = scrollWidth <= Math.ceil(clientWidth + scrollLeft); if (atLeft && atRight) { setScrollStatus("no-scroll"); } else if (atLeft) { setScrollStatus("left"); } else if (atRight) { setScrollStatus("right"); } else { setScrollStatus("scrolling"); } } if (headRef.current && bodyRef.current) { headRef.current.scrollLeft = bodyRef.current.scrollLeft; } }, [hasFixedColumn]); useEffect(() => { handleScroll(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [columnsWidths]); const renderTable = useMiddleware( addons, "onInjectTable" )(({ className, style, ...props }) => (
)); return renderTable(props); }, { addons, ActionPanel: createRocket( "ActionPanel", "div.@{prefix}-table__action-panel" ), } as any ) as (( props: TableProps & { ref?: React.Ref } ) => React.ReactElement) & { addons: typeof addons; ActionPanel: ReturnType; displayName: string; }; Table.displayName = "Table";