diff --git a/packages/components/src/array-table/index.tsx b/packages/components/src/array-table/index.tsx index bd0bbf2..ad39de5 100644 --- a/packages/components/src/array-table/index.tsx +++ b/packages/components/src/array-table/index.tsx @@ -22,6 +22,7 @@ import { ColumnProps, ColumnsType } from 'antd/es/table' import cls from 'classnames' import React, { createContext, + forwardRef, Fragment, useCallback, useContext, @@ -31,6 +32,7 @@ import React, { } from 'react' import { ArrayBase, ArrayBaseMixins } from '../array-base' import { + ISortableContainerProps, SortableContainer, SortableElement, usePrefixCls, @@ -62,12 +64,21 @@ interface IStatusSelectProps extends SelectProps { interface PaginationAction { totalPage?: number pageSize?: number + startIndex?: number changePage?: (page: number) => void } const SortableRow = SortableElement((props) => ) -const SortableBody = SortableContainer((props) => ) +const SortableBodyRaw = SortableContainer< + React.HTMLAttributes & { + tbodyRef: React.LegacyRef + } +>(({ tbodyRef, ...props }) => ) +const SortableBody = forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes & ISortableContainerProps +>((props, ref) => ) const isColumnComponent = (schema: Schema) => { return schema['x-component']?.indexOf('Column') > -1 @@ -309,7 +320,7 @@ const ArrayTablePagination: ReactFC = (props) => { return wrapSSR( {props.children?.( dataSource?.slice(startIndex, endIndex + 1), @@ -323,6 +334,48 @@ const ArrayTablePagination: ReactFC = (props) => { ) } +const WrapperComp = (props: React.HTMLAttributes) => { + const ref = useRef(null) + const field = useField() + const prefixCls = usePrefixCls('formily-array-table') + const { startIndex } = useContext(PaginationContext) + const dataSource = Array.isArray(field.value) ? field.value.slice() : [] + + const addTdStyles = (id: number) => { + const node = ref.current?.querySelector(`.${prefixCls}-row-${id}`) + const helper = document.body.querySelector(`.${prefixCls}-sort-helper`) + if (!helper) return + const tds = node?.querySelectorAll('td') + if (!tds) return + requestAnimationFrame(() => { + helper.querySelectorAll('td').forEach((td, index) => { + if (tds[index]) { + td.style.width = getComputedStyle(tds[index]).width + } + }) + }) + } + + return ( + { + addTdStyles(event.active.id as number) + }} + onSortEnd={({ oldIndex, newIndex }) => { + field.move(oldIndex, newIndex) + }} + className={cls(`${prefixCls}-sort-helper`, props.className)} + /> + ) +} + const RowComp: ReactFC> = (props) => { const prefixCls = usePrefixCls('formily-array-table') const index = props['data-row-key'] || 0 @@ -353,50 +406,6 @@ const InternalArrayTable: ReactFC> = observer( const defaultRowKey = (record: any) => { return record[indexKey] } - const addTdStyles = (id: number) => { - const node = ref.current?.querySelector(`.${prefixCls}-row-${id}`) - const helper = ref.current?.querySelector(`.${prefixCls}-sort-helper`) - if (helper) { - const tds = node?.querySelectorAll('td') - if (tds) { - requestAnimationFrame(() => { - helper.querySelectorAll('td').forEach((td, index) => { - if (tds[index]) { - td.style.width = getComputedStyle(tds[index]).width - } - }) - }) - } - } - } - const genWrapperComp = useCallback( - (list: any[], start: number) => - (props: React.HTMLAttributes) => { - return ( - { - addTdStyles(event.active.id as number) - }} - onSortEnd={(event) => { - const { oldIndex, newIndex } = event - window.requestAnimationFrame(() => { - field.move(oldIndex, newIndex) - }) - }} - className={cls(`${prefixCls}-sort-helper`, props.className)} - > - {props.children} - - ) - }, - [field] - ) return wrapSSR( @@ -415,7 +424,7 @@ const InternalArrayTable: ReactFC> = observer( dataSource={dataSource} components={{ body: { - wrapper: genWrapperComp(dataSource, startIndex), + wrapper: WrapperComp, row: RowComp, }, }}