From e9d89eddeff9883aead84eea77bc171539f93de6 Mon Sep 17 00:00:00 2001 From: thinkasany <480968828@qq.com> Date: Tue, 22 Apr 2025 16:42:13 +0800 Subject: [PATCH 1/2] feat: support classNames and styles --- docs/examples/className.tsx | 14 +++++ src/Cell/index.tsx | 12 ++-- src/FixedHolder/index.tsx | 2 + src/Panel/index.tsx | 5 +- src/Table.tsx | 27 ++++++--- src/context/TableContext.tsx | 4 ++ tests/semantic.spec.tsx | 112 +++++++++++++++++++++++++++++++++++ 7 files changed, 160 insertions(+), 16 deletions(-) create mode 100644 tests/semantic.spec.tsx diff --git a/docs/examples/className.tsx b/docs/examples/className.tsx index 82beacdcf..8deffd2b1 100644 --- a/docs/examples/className.tsx +++ b/docs/examples/className.tsx @@ -52,6 +52,20 @@ const Demo = () => ( expandedRowClassName={(record, i) => `ex-row-${i}`} data={data} className="table" + title={() => title} + footer={() => footer} + /> +

scroll

+ `row-${i}`} + expandedRowRender={record =>

extra: {record.a}

} + expandedRowClassName={(record, i) => `ex-row-${i}`} + data={Array(5).fill(data)} + className="table" + scroll={{ x: 'calc(700px + 50%)', y: 47 * 5 }} + title={() => title} + footer={() => footer} /> ); diff --git a/src/Cell/index.tsx b/src/Cell/index.tsx index 9a7a6166a..a71e6525f 100644 --- a/src/Cell/index.tsx +++ b/src/Cell/index.tsx @@ -1,5 +1,5 @@ import { useContext } from '@rc-component/context'; -import classNames from 'classnames'; +import cls from 'classnames'; import * as React from 'react'; import TableContext from '../context/TableContext'; import devRenderTimes from '../hooks/useRenderTimes'; @@ -122,10 +122,8 @@ function Cell(props: CellProps) { } = props; const cellPrefixCls = `${prefixCls}-cell`; - const { allColumnsFixedLeft, rowHoverable } = useContext(TableContext, [ - 'allColumnsFixedLeft', - 'rowHoverable', - ]); + + const { allColumnsFixedLeft, rowHoverable, classNames, styles } = useContext(TableContext); // ====================== Value ======================= const [childNode, legacyCellProps] = useCellRender( @@ -212,8 +210,9 @@ function Cell(props: CellProps) { }); // >>>>> ClassName - const mergedClassName = classNames( + const mergedClassName = cls( cellPrefixCls, + classNames?.item, className, { // Fixed @@ -249,6 +248,7 @@ function Cell(props: CellProps) { ...fixedStyle, ...alignStyle, ...additionalProps.style, + ...styles?.item, }; // >>>>> Children Node diff --git a/src/FixedHolder/index.tsx b/src/FixedHolder/index.tsx index f2a4a6331..29ccee089 100644 --- a/src/FixedHolder/index.tsx +++ b/src/FixedHolder/index.tsx @@ -46,6 +46,7 @@ const FixedHolder = React.forwardRef>((pro const { className, + style, noData, columns, flattenColumns, @@ -159,6 +160,7 @@ const FixedHolder = React.forwardRef>((pro style={{ overflow: 'hidden', ...(isSticky ? { top: stickyTopOffset, bottom: stickyBottomOffset } : {}), + ...style, }} ref={setScrollRef} className={classNames(className, { diff --git a/src/Panel/index.tsx b/src/Panel/index.tsx index 606bf65a7..3cd57e21e 100644 --- a/src/Panel/index.tsx +++ b/src/Panel/index.tsx @@ -3,10 +3,11 @@ import * as React from 'react'; export interface TitleProps { className: string; children: React.ReactNode; + style: React.CSSProperties; } -function Panel({ className, children }: TitleProps) { - return
{children}
; +function Panel({ className, style, children }: TitleProps) { + return
{children}
; } export default Panel; diff --git a/src/Table.tsx b/src/Table.tsx index c617ba494..2031bc980 100644 --- a/src/Table.tsx +++ b/src/Table.tsx @@ -25,7 +25,7 @@ */ import type { CompareProps } from '@rc-component/context/lib/Immutable'; -import classNames from 'classnames'; +import cls from 'classnames'; import ResizeObserver from '@rc-component/resize-observer'; import isVisible from '@rc-component/util/lib/Dom/isVisible'; import { getTargetScrollBarSize } from '@rc-component/util/lib/getScrollBarSize'; @@ -85,11 +85,14 @@ const EMPTY_DATA = []; // Used for customize scroll const EMPTY_SCROLL_TARGET = {}; +export type SemanticName = 'section'| 'header' | 'title' | 'footer' | 'body' | 'content' | 'item'; export interface TableProps extends Omit, 'showExpandColumn'> { prefixCls?: string; className?: string; style?: React.CSSProperties; + classNames?: Partial>; + styles?: Partial>; children?: React.ReactNode; data?: readonly RecordType[]; columns?: ColumnsType; @@ -190,6 +193,8 @@ function Table( className, rowClassName, style, + classNames, + styles, data, rowKey, scroll, @@ -655,10 +660,11 @@ function Table( style={{ ...scrollXStyle, ...scrollYStyle, + ...styles?.body, }} onScroll={onBodyScroll} ref={scrollBodyRef} - className={classNames(`${prefixCls}-body`)} + className={cls(`${prefixCls}-body`, classNames?.body)} > ( {renderFixedHeaderTable} @@ -739,8 +746,9 @@ function Table( style={{ ...scrollXStyle, ...scrollYStyle, + ...styles?.content, }} - className={classNames(`${prefixCls}-content`)} + className={cls(`${prefixCls}-content`, classNames?.content)} onScroll={onInternalScroll} ref={scrollBodyRef} > @@ -773,7 +781,7 @@ function Table( let fullTable = (
( ref={fullTableRef} {...dataProps} > - {title && {title(mergedData)}} -
+ {title && {title(mergedData)}} +
{groupTableNode}
- {footer && {footer(mergedData)}} + {footer && {footer(mergedData)}}
); @@ -812,6 +820,9 @@ function Table( scrollX: mergedScrollX, scrollInfo, + classNames, + styles, + // Table prefixCls, getComponent, diff --git a/src/context/TableContext.tsx b/src/context/TableContext.tsx index cce41f90b..de9783ea1 100644 --- a/src/context/TableContext.tsx +++ b/src/context/TableContext.tsx @@ -14,6 +14,7 @@ import type { TriggerEventHandler, } from '../interface'; import type { FixedInfo } from '../utils/fixUtil'; +import { SemanticName } from '../Table'; const { makeImmutable, responseImmutable, useImmutableMark } = createImmutable(); export { makeImmutable, responseImmutable, useImmutableMark }; @@ -23,6 +24,9 @@ export type ScrollInfoType = [scrollLeft: number, scrollRange: number]; export interface TableContextProps { // Scroll scrollX: number | string | true; + style?: React.CSSProperties; + classNames?: Partial>; + styles?: Partial>; // Table prefixCls: string; diff --git a/tests/semantic.spec.tsx b/tests/semantic.spec.tsx new file mode 100644 index 000000000..2a47c5dfd --- /dev/null +++ b/tests/semantic.spec.tsx @@ -0,0 +1,112 @@ +import { render, fireEvent } from '@testing-library/react'; +import React from 'react'; +import Table, { TableProps } from '../src'; +describe('support classNames and styles', () => { + const columns: TableProps['columns'] = [ + { + title: 'title1', + dataIndex: 'a', + className: 'a', + key: 'a', + width: 100, + }, + { + title: 'title2', + dataIndex: 'b', + className: 'b', + key: 'b', + width: 100, + }, + { + title: 'title3', + dataIndex: 'c', + className: 'c', + key: 'c', + width: 200, + }, + { + title: 'Operations', + dataIndex: '', + className: 'd', + key: 'd', + render() { + return Operations; + }, + }, + ]; + + const data = [ + { a: '123', key: '1' }, + { a: 'cdd', b: 'edd', key: '2' }, + { a: '1333', c: 'eee', d: 2, key: '3' }, + ]; + const commonTableProps = { + columns: columns, + rowClassName: (record, i) => `row-${i}`, + expandedRowRender: (record) =>

extra: {record.a}

, + expandedRowClassName: (record, i) => `ex-row-${i}`, + className: "table", + title: () => title, + footer: () => footer, + }; + it('should support className and style', () => { + const testClassNames = { + section: 'test-section', + header: 'test-header', + title: 'test-title', + body: 'test-body', + footer: 'test-footer', + content: 'test-content', + item: 'test-item', + } + const testStyles = { + section: { background: 'red' }, + header: { background: 'blue' }, + title: { background: 'green' }, + body: { background: 'yellow' }, + footer: { background: 'pink' }, + content: { background: 'purple' }, + item: { background: 'orange' }, + } + const { container } = render( +
+ ) + const section = container.querySelector('.rc-table-container'); + const title = container.querySelector('.rc-table-title'); + const footer = container.querySelector('.rc-table-footer'); + const content = container.querySelector('.rc-table-content'); + const item = container.querySelector('.rc-table-cell'); + expect(section).toHaveClass(testClassNames.section); + expect(section).toHaveStyle(testStyles.section); + expect(title).toHaveClass(testClassNames.title); + expect(title).toHaveStyle(testStyles.title); + expect(footer).toHaveClass(testClassNames.footer); + expect(footer).toHaveStyle(testStyles.footer); + expect(content).toHaveClass(testClassNames.content); + expect(content).toHaveStyle(testStyles.content); + expect(item).toHaveClass(testClassNames.item); + expect(item).toHaveStyle(testStyles.item); + + const { container: scrollContainer } = render( +
+ ) + const header = scrollContainer.querySelector('.rc-table-header'); + const body = scrollContainer.querySelector('.rc-table-body'); + expect(header).toHaveClass(testClassNames.header); + expect(header).toHaveStyle(testStyles.header); + expect(body).toHaveClass(testClassNames.body); + expect(body).toHaveStyle(testStyles.body); + }) +}) + From 8fd21eaf7d22a9a345b4ac441944fb1930338699 Mon Sep 17 00:00:00 2001 From: thinkasany <480968828@qq.com> Date: Sat, 26 Apr 2025 00:42:31 +0800 Subject: [PATCH 2/2] fix test --- src/Cell/index.tsx | 7 ++++++- src/FixedHolder/index.tsx | 1 + src/context/TableContext.tsx | 1 - 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Cell/index.tsx b/src/Cell/index.tsx index a71e6525f..b21f664ce 100644 --- a/src/Cell/index.tsx +++ b/src/Cell/index.tsx @@ -123,7 +123,12 @@ function Cell(props: CellProps) { const cellPrefixCls = `${prefixCls}-cell`; - const { allColumnsFixedLeft, rowHoverable, classNames, styles } = useContext(TableContext); + const { allColumnsFixedLeft, rowHoverable, classNames, styles } = useContext(TableContext, [ + 'allColumnsFixedLeft', + 'rowHoverable', + 'classNames', + 'styles', + ]); // ====================== Value ======================= const [childNode, legacyCellProps] = useCellRender( diff --git a/src/FixedHolder/index.tsx b/src/FixedHolder/index.tsx index 29ccee089..4e07f162c 100644 --- a/src/FixedHolder/index.tsx +++ b/src/FixedHolder/index.tsx @@ -26,6 +26,7 @@ function useColumnWidth(colWidths: readonly number[], columCount: number) { export interface FixedHeaderProps extends HeaderProps { className: string; + style?: React.CSSProperties; noData: boolean; maxContentScroll: boolean; colWidths: readonly number[]; diff --git a/src/context/TableContext.tsx b/src/context/TableContext.tsx index de9783ea1..a07425cc0 100644 --- a/src/context/TableContext.tsx +++ b/src/context/TableContext.tsx @@ -24,7 +24,6 @@ export type ScrollInfoType = [scrollLeft: number, scrollRange: number]; export interface TableContextProps { // Scroll scrollX: number | string | true; - style?: React.CSSProperties; classNames?: Partial>; styles?: Partial>;