diff --git a/packages/amis/src/renderers/Table/Cell.tsx b/packages/amis/src/renderers/Table/Cell.tsx new file mode 100644 index 000000000..1a4bb7f88 --- /dev/null +++ b/packages/amis/src/renderers/Table/Cell.tsx @@ -0,0 +1,221 @@ +import { + IColumn, + IRow, + ITableStore, + PlainObject, + SchemaNode, + ThemeProps, + resolveVariable +} from 'amis-core'; +import {BadgeObject, Checkbox, Icon} from 'amis-ui'; +import React from 'react'; + +export interface CellProps extends ThemeProps { + region: string; + column: IColumn; + item: IRow; + props: PlainObject; + ignoreDrag?: boolean; + render: ( + region: string, + node: SchemaNode, + props?: PlainObject + ) => JSX.Element; + store: ITableStore; + multiple: boolean; + canAccessSuperData?: boolean; + itemBadge?: BadgeObject; + onCheck?: (item: IRow) => void; + onDragStart?: (e: React.DragEvent) => void; + popOverContainer?: any; + quickEditFormRef: any; + onImageEnlarge?: any; +} + +export default function Cell({ + region, + column, + item, + props, + ignoreDrag, + render, + store, + multiple, + itemBadge, + classnames: cx, + classPrefix: ns, + canAccessSuperData, + onCheck, + onDragStart, + popOverContainer, + quickEditFormRef, + onImageEnlarge +}: CellProps) { + if (column.name && item.rowSpans[column.name] === 0) { + return null; + } + + const [style, stickyClassName]: any = React.useMemo(() => { + const style = {...column.pristine.style}; + const [stickyStyle, stickyClassName] = store.getStickyStyles( + column, + store.filteredColumns + ); + return [Object.assign(style, stickyStyle), stickyClassName]; + }, []); + + const onCheckboxChange = React.useCallback(() => { + onCheck?.(item); + }, []); + + if (column.type === '__checkme') { + return ( + + + + ); + } else if (column.type === '__dragme') { + return ( + + {item.draggable ? : null} + + ); + } else if (column.type === '__expandme') { + return ( + + {item.expandable ? ( + + + + ) : null} + + ); + } + + let [prefix, affix, addtionalClassName] = React.useMemo(() => { + let prefix: React.ReactNode[] = []; + let affix: React.ReactNode[] = []; + let addtionalClassName = ''; + + if (column.isPrimary && store.isNested) { + addtionalClassName = 'Table-primayCell'; + prefix.push( + + ); + prefix.push( + item.expandable ? ( + + + + ) : ( + + ) + ); + } + + if ( + !ignoreDrag && + column.isPrimary && + store.isNested && + store.draggable && + item.draggable + ) { + affix.push( + + + + ); + } + return [prefix, affix, addtionalClassName]; + }, [item.expandable, item.expanded]); + const data = React.useMemo(() => item.locals, [JSON.stringify(item.locals)]); + + const finalCanAccessSuperData = + column.pristine.canAccessSuperData ?? canAccessSuperData; + const subProps: any = { + ...props, + // 操作列不下发loading,否则会导致操作栏里面的所有按钮都出现loading + loading: column.type === 'operation' ? false : props.loading, + btnDisabled: store.dragging, + data: data, + value: column.name + ? resolveVariable( + column.name, + finalCanAccessSuperData ? item.locals : item.data + ) + : column.value, + popOverContainer: popOverContainer, + rowSpan: item.rowSpans[column.name as string], + quickEditFormRef: quickEditFormRef, + cellPrefix: prefix, + cellAffix: affix, + onImageEnlarge: onImageEnlarge, + canAccessSuperData: finalCanAccessSuperData, + row: item, + itemBadge, + showBadge: + !props.isHead && + itemBadge && + store.firstToggledColumnIndex === props.colIndex, + onQuery: undefined, + style, + className: cx( + column.pristine.className, + stickyClassName, + addtionalClassName + ), + /** 给子节点的设置默认值,避免取到env.affixHeader的默认值,导致表头覆盖首行 */ + affixOffsetTop: 0 + }; + delete subProps.label; + + return render( + region, + { + ...column.pristine, + column: column.pristine, + type: 'cell' + }, + subProps + ); +} diff --git a/packages/amis/src/renderers/Table/index.tsx b/packages/amis/src/renderers/Table/index.tsx index 2b4370fbe..68d0e4a69 100644 --- a/packages/amis/src/renderers/Table/index.tsx +++ b/packages/amis/src/renderers/Table/index.tsx @@ -69,6 +69,7 @@ import omit from 'lodash/omit'; import ColGroup from './ColGroup'; import debounce from 'lodash/debounce'; import AutoFilterForm from './AutoFilterForm'; +import Cell from './Cell'; /** * 表格列,不指定类型时默认为文本类型。 @@ -2018,168 +2019,31 @@ export default class Table extends React.Component { classnames: cx, checkOnItemClick, popOverContainer, + canAccessSuperData, itemBadge } = this.props; - if (column.name && item.rowSpans[column.name] === 0) { - return null; - } - - const style: any = {...column.pristine.style}; - const [stickyStyle, stickyClassName] = store.getStickyStyles( - column, - store.filteredColumns - ); - Object.assign(style, stickyStyle); - - if (column.type === '__checkme') { - return ( - - - - ); - } else if (column.type === '__dragme') { - return ( - - {item.draggable ? : null} - - ); - } else if (column.type === '__expandme') { - return ( - - {item.expandable ? ( - - - - ) : null} - - ); - } - - let prefix: React.ReactNode[] = []; - let affix: React.ReactNode[] = []; - let addtionalClassName = ''; - - if (column.isPrimary && store.isNested) { - addtionalClassName = 'Table-primayCell'; - prefix.push( - - ); - prefix.push( - item.expandable ? ( - - - - ) : ( - - ) - ); - } - - if ( - !ignoreDrag && - column.isPrimary && - store.isNested && - store.draggable && - item.draggable - ) { - affix.push( - - - - ); - } - - const canAccessSuperData = - column.pristine.canAccessSuperData ?? this.props.canAccessSuperData; - const subProps: any = { - ...props, - // 操作列不下发loading,否则会导致操作栏里面的所有按钮都出现loading - loading: column.type === 'operation' ? false : props.loading, - btnDisabled: store.dragging, - data: item.locals, - value: column.name - ? resolveVariable( - column.name, - canAccessSuperData ? item.locals : item.data - ) - : column.value, - popOverContainer: this.getPopOverContainer, - rowSpan: item.rowSpans[column.name as string], - quickEditFormRef: this.subFormRef, - cellPrefix: prefix, - cellAffix: affix, - onImageEnlarge: this.handleImageEnlarge, - canAccessSuperData, - row: item, - itemBadge, - showBadge: - !props.isHead && - itemBadge && - store.firstToggledColumnIndex === props.colIndex, - onQuery: undefined, - style, - className: cx( - column.pristine.className, - stickyClassName, - addtionalClassName - ), - /** 给子节点的设置默认值,避免取到env.affixHeader的默认值,导致表头覆盖首行 */ - affixOffsetTop: 0 - }; - delete subProps.label; - - return render( - region, - { - ...column.pristine, - column: column.pristine, - type: 'cell' - }, - subProps + return ( + ); }