Skip to content

Commit

Permalink
feat: table: add rowexpanddisabled prop (#731)
Browse files Browse the repository at this point in the history
  • Loading branch information
dkilgore-eightfold authored Oct 19, 2023
1 parent 2688ead commit b0b7640
Show file tree
Hide file tree
Showing 14 changed files with 258 additions and 149 deletions.
23 changes: 15 additions & 8 deletions src/components/Table/ExpandIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import { mergeClasses } from '../../shared/utilities';
import styles from './Styles/table.module.scss';

interface DefaultExpandIconProps<RecordType> {
expandable: boolean;
expanded: boolean;
onExpand: (record: RecordType, e: React.MouseEvent<HTMLElement>) => void;
record: RecordType;
expanded: boolean;
expandable: boolean;
disabled?: boolean;
}

function renderExpandIcon(collapseText: string, expandText: string) {
Expand All @@ -16,23 +17,29 @@ function renderExpandIcon(collapseText: string, expandText: string) {
record,
expanded,
expandable,
disabled,
}: DefaultExpandIconProps<RecordType>) {
return (
<button
type="button"
onClick={(e) => {
onExpand(record, e!);
e.stopPropagation();
}}
aria-label={expanded ? collapseText : expandText}
className={mergeClasses([
styles.tableRowExpandIcon,
{ [styles.tableRowExpandIconSpaced]: !expandable },
{ [styles.tableExpandedRow]: expandable && expanded },
{
[styles.tableRowExpandIconCollapsed]: expandable && !expanded,
},
{ [styles.tableRowExpandIconDisabled]: !!disabled },
])}
aria-label={expanded ? collapseText : expandText}
disabled={disabled}
onClick={(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
if (disabled) {
return;
}
onExpand(record, e!);
e?.stopPropagation();
}}
type="button"
/>
);
};
Expand Down
2 changes: 2 additions & 0 deletions src/components/Table/Internal/Body/Body.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export interface BodyRowProps<RecordType> {
cellComponent: CustomizeComponent;
onRow: GetComponentProps<RecordType>;
rowExpandable: (record: RecordType) => boolean;
rowExpandDisabled?: (record: RecordType) => boolean;
indent?: number;
rowKey: React.Key;
getRowKey: GetRowKey<RecordType>;
Expand Down Expand Up @@ -72,6 +73,7 @@ export interface BodyProps<RecordType> {
expandedKeys: Set<Key>;
onRow: GetComponentProps<RecordType>;
rowExpandable: (record: RecordType) => boolean;
rowExpandDisabled?: (record: RecordType) => boolean;
emptyNode: React.ReactNode;
childrenColumnName: string;
/**
Expand Down
142 changes: 80 additions & 62 deletions src/components/Table/Internal/Body/BodyRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ import Cell from '../Cell';
import TableContext from '../Context/TableContext';
import BodyContext from '../Context/BodyContext';
import { getColumnsKey } from '../Utilities/valueUtil';
import type { ColumnType } from '../OcTable.types';
import type {
ColumnType,
DefaultRecordType,
TriggerEventHandler,
} from '../OcTable.types';
import { BodyRowProps } from './Body.types';
import ExpandedRow from './ExpandedRow';
import { FixedInfo } from '../Utilities/fixUtil';

import styles from '../octable.module.scss';

Expand All @@ -21,6 +26,7 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
renderIndex,
rowKey,
rowExpandable,
rowExpandDisabled,
expandedKeys,
onRow,
indent = 0,
Expand All @@ -42,26 +48,32 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
expandIcon,
expandedRowRender,
} = useContext(BodyContext);
const [expandRended, setExpandRended] = useState(false);
const [expandRended, setExpandRended] = useState<boolean>(false);

const expanded = expandedKeys && expandedKeys.has(props.recordKey);
const expanded: boolean = expandedKeys?.has(props.recordKey);

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

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

// ======================== Expandable =========================
const onExpandRef = useRef(onTriggerExpand);
const onExpandRef: React.MutableRefObject<
TriggerEventHandler<DefaultRecordType>
> = useRef(onTriggerExpand);
onExpandRef.current = onTriggerExpand;

const onInternalTriggerExpand = (
Expand Down Expand Up @@ -92,7 +104,7 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
computeRowClassName = rowClassName(record, index, indent);
}

const columnsKey = getColumnsKey(flattenColumns);
const columnsKey: React.Key[] = getColumnsKey(flattenColumns);
const baseRowNode = (
<RowComponent
{...additionalProps}
Expand All @@ -102,7 +114,7 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
'table-row',
`table-row-level-${indent}`,
computeRowClassName,
additionalProps && additionalProps.className,
additionalProps?.className,
])}
style={{
...style,
Expand All @@ -118,59 +130,62 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
additionalProps?.onMouseLeave(e);
}}
>
{flattenColumns.map((column: ColumnType<RecordType>, colIndex) => {
const { render, dataIndex, classNames: columnClassName } = column;

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

// ============= Used for nest expandable =============
let appendCellNode: React.ReactNode;
if (colIndex === 0 && nestExpandable) {
appendCellNode = (
<>
<span
style={{
paddingLeft: `${indentSize * indent}px`,
}}
className={`table-row-indent indent-level-${indent}`}
/>
{expandIcon({
expanded,
expandable: hasNestChildren,
record,
onExpand: onInternalTriggerExpand,
})}
</>
{flattenColumns.map(
(column: ColumnType<RecordType>, colIndex: number) => {
const { render, dataIndex, classNames: columnClassName } = column;

const key: React.Key = columnsKey[colIndex];
const fixedInfo: FixedInfo = fixedInfoList[colIndex];

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

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

return (
<Cell
classNames={columnClassName}
ellipsis={column.ellipsis}
align={column.align}
verticalAlign={column.verticalAlign}
component={cellComponent}
key={key}
record={record}
index={index}
renderIndex={renderIndex}
dataIndex={dataIndex}
render={render}
shouldCellUpdate={column.shouldCellUpdate}
expanded={appendCellNode && expanded}
{...fixedInfo}
appendNode={appendCellNode}
additionalProps={additionalCellProps}
/>
);
}

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

return (
<Cell
classNames={columnClassName}
ellipsis={column.ellipsis}
align={column.align}
verticalAlign={column.verticalAlign}
component={cellComponent}
key={key}
record={record}
index={index}
renderIndex={renderIndex}
dataIndex={dataIndex}
render={render}
shouldCellUpdate={column.shouldCellUpdate}
expanded={appendCellNode && expanded}
{...fixedInfo}
appendNode={appendCellNode}
additionalProps={additionalCellProps}
/>
);
})}
)}
</RowComponent>
);

Expand All @@ -183,8 +198,11 @@ function BodyRow<RecordType extends { children?: readonly RecordType[] }>(
indent + 1,
expanded
);
const computedExpandedRowClassName =
expandedRowClassName && expandedRowClassName(record, index, indent);
const computedExpandedRowClassName: string = expandedRowClassName?.(
record,
index,
indent
);
expandRowNode = (
<ExpandedRow
expanded={expanded}
Expand Down
3 changes: 3 additions & 0 deletions src/components/Table/Internal/Body/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ function Body<RecordType>({
expandedKeys,
onRow,
rowExpandable,
rowExpandDisabled,
emptyNode,
childrenColumnName,
onRowHoverEnter,
Expand Down Expand Up @@ -91,6 +92,7 @@ function Body<RecordType>({
onRow={onRow}
getRowKey={getRowKey}
rowExpandable={rowExpandable}
rowExpandDisabled={rowExpandDisabled}
childrenColumnName={childrenColumnName}
indent={indent}
onRowHoverEnter={onRowHoverEnter}
Expand Down Expand Up @@ -137,6 +139,7 @@ function Body<RecordType>({
childrenColumnName,
onColumnResize,
rowExpandable,
rowExpandDisabled,
flattenData,
]);

Expand Down
Loading

0 comments on commit b0b7640

Please sign in to comment.