Skip to content

Commit

Permalink
refactor: extract func
Browse files Browse the repository at this point in the history
  • Loading branch information
zombieJ committed Aug 17, 2023
1 parent e921da7 commit 015ff4e
Show file tree
Hide file tree
Showing 9 changed files with 216 additions and 107 deletions.
6 changes: 4 additions & 2 deletions assets/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,11 @@

// ================== Cell ==================
&-cell {
background: #f4f4f4;

&-fix-left,
&-fix-right {
z-index: 1;
z-index: 2;
}

&-fix-right:last-child:not(&-fix-sticky) {
Expand Down Expand Up @@ -139,7 +141,7 @@
}

&&-row-hover {
background: rgba(255, 0, 0, 0.05);
background: #fff4f4;
}
}

Expand Down
2 changes: 1 addition & 1 deletion docs/examples/virtual.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const Demo = () => {
const [scrollY, setScrollY] = React.useState(true);

return (
<div style={{ width: 800 }}>
<div style={{ width: 800, padding: 64 }}>
<label>
<input type="checkbox" checked={scrollY} onChange={() => setScrollY(!scrollY)} />
Scroll Y
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"classnames": "^2.2.5",
"rc-resize-observer": "^1.1.0",
"rc-util": "^5.27.1",
"rc-virtual-list": "^3.5.3"
"rc-virtual-list": "^3.7.0"
},
"devDependencies": {
"@rc-component/father-plugin": "^1.0.2",
Expand Down
215 changes: 143 additions & 72 deletions src/Body/BodyRow.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
import { responseImmutable, useContext } from '@rc-component/context';
import classNames from 'classnames';
import { useEvent } from 'rc-util';
import * as React from 'react';
import Cell from '../Cell';
import TableContext from '../context/TableContext';
import TableContext, { type TableContextProps } from '../context/TableContext';
import devRenderTimes from '../hooks/useRenderTimes';
import type {
ColumnType,
CustomizeComponent,
GetComponentProps,
GetRowKey,
Key,
} from '../interface';
import type { ColumnType, CustomizeComponent, GetComponentProps, GetRowKey } from '../interface';
import { getColumnsKey } from '../utils/valueUtil';
import ExpandedRow from './ExpandedRow';

Expand All @@ -20,7 +15,6 @@ export interface BodyRowProps<RecordType> {
renderIndex: number;
className?: string;
style?: React.CSSProperties;
expandedKeys: Set<Key>;
rowComponent: CustomizeComponent;
cellComponent: CustomizeComponent;
scopeCellComponent: CustomizeComponent;
Expand All @@ -29,7 +23,131 @@ export interface BodyRowProps<RecordType> {
indent?: number;
rowKey: React.Key;
getRowKey: GetRowKey<RecordType>;
childrenColumnName: string;
}

export function useRowInfo<RecordType>(
record: RecordType,
rowKey: React.Key,
): Pick<
TableContextProps,
| 'prefixCls'
| 'fixedInfoList'
| 'flattenColumns'
| 'expandableType'
| 'expandRowByClick'
| 'onTriggerExpand'
| 'rowClassName'
| 'expandedRowClassName'
| 'indentSize'
| 'expandIcon'
| 'expandedRowRender'
| 'expandIconColumnIndex'
| 'expandedKeys'
| 'childrenColumnName'
> & {
columnsKey: React.Key[];
nestExpandable: boolean;
expanded: boolean;
hasNestChildren: boolean;
record: RecordType;
} {
const context: TableContextProps = useContext(TableContext, [
'prefixCls',
'fixedInfoList',
'flattenColumns',
'expandableType',
'expandRowByClick',
'onTriggerExpand',
'rowClassName',
'expandedRowClassName',
'indentSize',
'expandIcon',
'expandedRowRender',
'expandIconColumnIndex',
'expandedKeys',
'childrenColumnName',
]);

const { flattenColumns, expandableType, expandedKeys, childrenColumnName, onTriggerExpand } =
context;

const columnsKey = getColumnsKey(flattenColumns);

// Only when row is not expandable and `children` exist in record
const nestExpandable = expandableType === 'nest';

const expanded = expandedKeys && expandedKeys.has(rowKey);

const hasNestChildren = childrenColumnName && record && record[childrenColumnName];

const onInternalTriggerExpand = useEvent(onTriggerExpand);

return {
...context,
columnsKey,
nestExpandable,
expanded,
hasNestChildren,
record,
onTriggerExpand: onInternalTriggerExpand,
};
}

export function getCellProps<RecordType>(
rowInfo: ReturnType<typeof useRowInfo<RecordType>>,
column: ColumnType<RecordType>,
colIndex: number,
indent: number,
index: number,
) {
const {
record,
prefixCls,
columnsKey,
fixedInfoList,
expandIconColumnIndex,
nestExpandable,
indentSize,
expandIcon,
expanded,
hasNestChildren,
onTriggerExpand,
} = rowInfo;

const key = columnsKey[colIndex];
const fixedInfo = fixedInfoList[colIndex];

// ============= Used for nest expandable =============
let appendCellNode: React.ReactNode;
if (colIndex === (expandIconColumnIndex || 0) && nestExpandable) {
appendCellNode = (
<>
<span
style={{ paddingLeft: `${indentSize * indent}px` }}
className={`${prefixCls}-row-indent indent-level-${indent}`}
/>
{expandIcon({
prefixCls,
expanded,
expandable: hasNestChildren,
record,
onExpand: onTriggerExpand,
})}
</>
);
}

let additionalCellProps: React.HTMLAttributes<HTMLElement>;
if (column.onCell) {
additionalCellProps = column.onCell(record, index);
}

return {
key,
fixedInfo,
appendCellNode,
additionalCellProps,
};
}

function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
Expand All @@ -47,75 +165,49 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
renderIndex,
rowKey,
rowExpandable,
expandedKeys,
onRow,
indent = 0,
rowComponent: RowComponent,
cellComponent,
scopeCellComponent,
childrenColumnName,
} = props;
const rowInfo = useRowInfo(record, rowKey);
const {
prefixCls,
fixedInfoList,
flattenColumns,
expandableType,
expandRowByClick,
onTriggerExpand,
rowClassName,
expandedRowClassName,
indentSize,
expandIcon,
expandedRowRender,
expandIconColumnIndex,
} = useContext(TableContext, [
'prefixCls',
'fixedInfoList',
'flattenColumns',
'expandableType',
'expandRowByClick',
'onTriggerExpand',
'rowClassName',
'expandedRowClassName',
'indentSize',
'expandIcon',
'expandedRowRender',
'expandIconColumnIndex',
]);

// Misc
nestExpandable,
expanded,
} = rowInfo;

const [expandRended, setExpandRended] = React.useState(false);

if (process.env.NODE_ENV !== 'production') {
devRenderTimes(props);
}

const expanded = expandedKeys && expandedKeys.has(rowKey);

React.useEffect(() => {
if (expanded) {
setExpandRended(true);
}
}, [expanded]);

const rowSupportExpand = expandableType === 'row' && (!rowExpandable || rowExpandable(record));
// Only when row is not expandable and `children` exist in record
const nestExpandable = expandableType === 'nest';
const hasNestChildren = childrenColumnName && record && record[childrenColumnName];
const mergedExpandable = rowSupportExpand || nestExpandable;

// ======================== Expandable =========================
const onExpandRef = React.useRef(onTriggerExpand);
onExpandRef.current = onTriggerExpand;

const onInternalTriggerExpand = (...args: Parameters<typeof onTriggerExpand>) => {
onExpandRef.current(...args);
};

// =========================== onRow ===========================
const additionalProps = onRow?.(record, index);

const onClick: React.MouseEventHandler<HTMLElement> = (event, ...args) => {
if (expandRowByClick && mergedExpandable) {
onInternalTriggerExpand(record, event);
onTriggerExpand(record, event);
}

additionalProps?.onClick?.(event, ...args);
Expand All @@ -129,7 +221,6 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
computeRowClassName = rowClassName(record, index, indent);
}

const columnsKey = getColumnsKey(flattenColumns);
const baseRowNode = (
<RowComponent
{...additionalProps}
Expand All @@ -150,33 +241,13 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
{flattenColumns.map((column: ColumnType<RecordType>, colIndex) => {
const { render, dataIndex, className: columnClassName } = column;

const key = columnsKey[colIndex];
const fixedInfo = fixedInfoList[colIndex];

// ============= Used for nest expandable =============
let appendCellNode: React.ReactNode;
if (colIndex === (expandIconColumnIndex || 0) && nestExpandable) {
appendCellNode = (
<>
<span
style={{ paddingLeft: `${indentSize * indent}px` }}
className={`${prefixCls}-row-indent indent-level-${indent}`}
/>
{expandIcon({
prefixCls,
expanded,
expandable: hasNestChildren,
record,
onExpand: onInternalTriggerExpand,
})}
</>
);
}

let additionalCellProps: React.HTMLAttributes<HTMLElement>;
if (column.onCell) {
additionalCellProps = column.onCell(record, index);
}
const { key, fixedInfo, appendCellNode, additionalCellProps } = getCellProps(
rowInfo,
column,
colIndex,
indent,
index,
);

return (
<Cell
Expand Down
Loading

0 comments on commit 015ff4e

Please sign in to comment.