Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/demo/column-sortable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: column-sortable
nav:
title: Demo
path: /demo
---

<code src="../examples/column-sortable.tsx"></code>
114 changes: 45 additions & 69 deletions docs/examples/column-resize.tsx
Original file line number Diff line number Diff line change
@@ -1,95 +1,71 @@
import React from 'react';
import { Resizable } from 'react-resizable';
import React, { useMemo, useState } from 'react';
import type { ColumnType, ColumnsType } from 'rc-table';
import Table from 'rc-table';
import { Resizable } from 'react-resizable';
import '../../assets/index.less';
import 'react-resizable/css/styles.css';
import type { ColumnType } from '@/interface';

const ResizableTitle = props => {
const { onResize, width, ...restProps } = props;

if (!width) {
return <th {...restProps} />;
}

return (
<Resizable width={width} height={0} onResize={onResize}>
<th {...restProps} />
</Resizable>
);
};

interface RecordType {
a: string;
b?: string;
c?: string;
d?: number;
key: string;
}
const data = [
{ a: '123', key: '1' },
{ a: 'cdd', b: 'edd', key: '2' },
{ a: '1333', c: 'eee', d: 2, key: '3' },
] as const;

interface DemoState {
columns: ColumnType<RecordType>[];
}
type RecordType = (typeof data)[number];

class Demo extends React.Component<{}, DemoState> {
state: DemoState = {
columns: [
{ title: 'title1', dataIndex: 'a', key: 'a', width: 100 },
{ title: 'title2', dataIndex: 'b', key: 'b', width: 100 },
{ title: 'title3', dataIndex: 'c', key: 'c', width: 200 },
{
title: 'Operations',
dataIndex: '',
key: 'd',
render() {
return <a href="#">Operations</a>;
},
const Demo = () => {
const [columns, setColumns] = useState<ColumnsType<RecordType>>([
{ title: 'title1', dataIndex: 'a', key: 'a', width: 100 },
{ title: 'title2', dataIndex: 'b', key: 'b', width: 100 },
{ title: 'title3', dataIndex: 'c', key: 'c', width: 200 },
{
title: 'Operations',
dataIndex: 'd',
key: 'd',
render() {
return <a href="#">Operations</a>;
},
],
};

components = {
header: {
cell: ResizableTitle,
},
};

data = [
{ a: '123', key: '1' },
{ a: 'cdd', b: 'edd', key: '2' },
{ a: '1333', c: 'eee', d: 2, key: '3' },
];

handleResize =
index =>
(e, { size }) => {
this.setState(({ columns }) => {
const nextColumns = [...columns];
nextColumns[index] = {
...nextColumns[index],
width: size.width,
};
return { columns: nextColumns };
});
]);
const handleResize = useMemo(() => {
return (index: number) => {
return (_: React.MouseEvent<HTMLTableCellElement>, { size }: { size: { width: number } }) => {
setColumns(prevColumns =>
prevColumns.map((col, i) => (i === index ? { ...col, width: size.width } : col)),
);
};
};

render() {
const columns = this.state.columns.map((col, index) => ({
}, []);
const columnsWithResizable = useMemo(() => {
return columns.map((col, index) => ({
...col,
onHeaderCell: (column: ColumnType<RecordType>) =>
({
width: column.width,
onResize: this.handleResize(index),
}) as any,
onHeaderCell: (column: ColumnType<RecordType>) => ({
width: column.width,
onResize: handleResize(index),
}),
}));
}, [columns, handleResize]);

return (
<div>
<h2>Integrate with react-resizable</h2>
<Table components={this.components} columns={columns} data={this.data} />
</div>
);
}
}
const tableProps = useMemo(() => {
return {
components: { header: { cell: ResizableTitle } },
columns: columnsWithResizable,
data,
};
}, [columnsWithResizable]);
return <Table {...tableProps} />;
};

export default Demo;
93 changes: 93 additions & 0 deletions docs/examples/column-sortable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import type { DragEndEvent } from '@dnd-kit/core';
import { DndContext, closestCenter } from '@dnd-kit/core';
import { restrictToHorizontalAxis } from '@dnd-kit/modifiers';
import { SortableContext, arrayMove, rectSwappingStrategy, useSortable } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import Table from 'rc-table';
import React, { useCallback, useMemo, useState } from 'react';
import 'react-resizable/css/styles.css';
import '../../assets/index.less';
const SortableHeaderCell = props => {
const { style: styleProps, ...restProps } = props;

const { attributes, listeners, setNodeRef, transform, transition } = useSortable({
id: props.id as string,
});

const style = {
...styleProps,
transform: CSS.Transform.toString(transform),
transition,
cursor: 'move',
};

return <th ref={setNodeRef} style={style} {...attributes} {...listeners} {...restProps} />;
};

const data = [
{ a: '123', key: '1' },
{ a: 'cdd', b: 'edd', key: '2' },
{ a: '1333', c: 'eee', d: 2, key: '3' },
] as const;

const Demo = () => {
const [columns, setColumns] = useState([
{ title: 'title1', dataIndex: 'a', key: 'a', width: 100 },
{ title: 'title2', dataIndex: 'b', key: 'b', width: 100 },
{ title: 'title3', dataIndex: 'c', key: 'c', width: 200 },
{
title: 'Operations',
dataIndex: 'd',
key: 'd',
render() {
return <a href="#">Operations</a>;
},
},
]);

const columnsWithSortable = useMemo(() => {
return columns.map(col => ({
...col,
onHeaderCell: () => ({
id: col.dataIndex?.toString(),
}),
}));
}, [columns]);

const tableProps = useMemo(() => {
return {
components: { header: { cell: SortableHeaderCell } },
columns: columnsWithSortable,
data,
};
}, [columnsWithSortable]);
const handleDragEnd = useCallback((e: DragEndEvent) => {
const { active, over } = e;
if (over) {
setColumns(prevColumns => {
const activeIndex = prevColumns.findIndex(col => col.dataIndex === active.id);
const overIndex = prevColumns.findIndex(col => col.dataIndex === over.id);
if (activeIndex === -1 || overIndex === -1) {
return prevColumns;
}
return arrayMove([...prevColumns], activeIndex, overIndex);
});
}
}, []);
return (
<DndContext
collisionDetection={closestCenter}
onDragEnd={handleDragEnd}
modifiers={[restrictToHorizontalAxis]}
>
<SortableContext
items={columns.map(col => col.dataIndex?.toString())}
strategy={rectSwappingStrategy}
>
<Table {...tableProps} />;
</SortableContext>
</DndContext>
);
};

export default Demo;
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@
"rc-virtual-list": "^3.14.2"
},
"devDependencies": {
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/modifiers": "^9.0.0",
"@dnd-kit/sortable": "^10.0.0",
"@rc-component/father-plugin": "^2.0.1",
"@rc-component/np": "^1.0.3",
"@testing-library/dom": "^10.4.1",
Expand Down