@rainbow-oh/yee-c 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/cjs/Descriptions/descriptions.js +8 -1
  2. package/dist/cjs/Descriptions/interface.d.ts +1 -1
  3. package/dist/cjs/Select/demo/size.js +2 -0
  4. package/dist/cjs/Select/interface.d.ts +2 -1
  5. package/dist/cjs/Selector/style/index.less +8 -0
  6. package/dist/cjs/Table/demo/components-override.d.ts +3 -0
  7. package/dist/cjs/Table/demo/components-override.js +54 -0
  8. package/dist/cjs/Table/demo/grouping.d.ts +3 -0
  9. package/dist/cjs/Table/demo/grouping.js +129 -0
  10. package/dist/cjs/Table/hooks/useColumns.d.ts +2 -2
  11. package/dist/cjs/Table/hooks/useColumns.js +15 -37
  12. package/dist/cjs/Table/index.d.ts +1 -1
  13. package/dist/cjs/Table/interface.d.ts +59 -8
  14. package/dist/cjs/Table/style/index.less +19 -1
  15. package/dist/cjs/Table/table.js +5 -7
  16. package/dist/cjs/Table/tbody/cell.d.ts +0 -1
  17. package/dist/cjs/Table/tbody/cell.js +0 -4
  18. package/dist/cjs/Table/tbody/index.js +19 -2
  19. package/dist/cjs/Table/tbody/row.js +15 -11
  20. package/dist/cjs/Table/theader/cell.js +7 -1
  21. package/dist/cjs/Table/theader/index.d.ts +5 -5
  22. package/dist/cjs/Table/theader/index.js +41 -27
  23. package/dist/cjs/Table/util/header.d.ts +23 -0
  24. package/dist/cjs/Table/util/header.js +109 -0
  25. package/dist/cjs/style/size.css +4 -0
  26. package/dist/cjs/style/themes.css +1 -1
  27. package/dist/cjs/style/variables.css +5 -1
  28. package/dist/cjs/version.d.ts +1 -1
  29. package/dist/cjs/version.js +1 -1
  30. package/dist/esm/Descriptions/descriptions.js +2 -1
  31. package/dist/esm/Descriptions/interface.d.ts +1 -1
  32. package/dist/esm/Select/demo/size.js +2 -0
  33. package/dist/esm/Select/interface.d.ts +2 -1
  34. package/dist/esm/Selector/style/index.less +8 -0
  35. package/dist/esm/Table/demo/components-override.d.ts +3 -0
  36. package/dist/esm/Table/demo/components-override.js +86 -0
  37. package/dist/esm/Table/demo/grouping.d.ts +3 -0
  38. package/dist/esm/Table/demo/grouping.js +102 -0
  39. package/dist/esm/Table/hooks/useColumns.d.ts +2 -2
  40. package/dist/esm/Table/hooks/useColumns.js +24 -50
  41. package/dist/esm/Table/index.d.ts +1 -1
  42. package/dist/esm/Table/interface.d.ts +59 -8
  43. package/dist/esm/Table/style/index.less +19 -1
  44. package/dist/esm/Table/table.js +5 -7
  45. package/dist/esm/Table/tbody/cell.d.ts +0 -1
  46. package/dist/esm/Table/tbody/cell.js +0 -5
  47. package/dist/esm/Table/tbody/index.js +21 -2
  48. package/dist/esm/Table/tbody/row.js +19 -15
  49. package/dist/esm/Table/theader/cell.js +6 -2
  50. package/dist/esm/Table/theader/index.d.ts +5 -5
  51. package/dist/esm/Table/theader/index.js +48 -35
  52. package/dist/esm/Table/util/header.d.ts +23 -0
  53. package/dist/esm/Table/util/header.js +107 -0
  54. package/dist/esm/style/size.css +4 -0
  55. package/dist/esm/style/themes.css +1 -1
  56. package/dist/esm/style/variables.css +5 -1
  57. package/dist/esm/version.d.ts +1 -1
  58. package/dist/esm/version.js +1 -1
  59. package/dist/umd/yee-c.min.css +2 -2
  60. package/dist/umd/yee-c.min.js +1 -1
  61. package/package.json +1 -1
  62. package/src/Descriptions/descriptions.tsx +4 -1
  63. package/src/Descriptions/interface.ts +7 -1
  64. package/src/Select/demo/size.tsx +2 -0
  65. package/src/Select/interface.ts +3 -1
  66. package/src/Selector/style/index.less +8 -0
  67. package/src/Table/demo/components-override.tsx +49 -0
  68. package/src/Table/demo/grouping.tsx +104 -0
  69. package/src/Table/hooks/useColumns.ts +29 -46
  70. package/src/Table/index.en-US.md +31 -3
  71. package/src/Table/index.ts +4 -0
  72. package/src/Table/index.zh-CN.md +30 -2
  73. package/src/Table/interface.ts +66 -8
  74. package/src/Table/style/index.less +19 -1
  75. package/src/Table/table.tsx +5 -7
  76. package/src/Table/tbody/cell.tsx +0 -6
  77. package/src/Table/tbody/index.tsx +21 -2
  78. package/src/Table/tbody/row.tsx +25 -14
  79. package/src/Table/theader/cell.tsx +4 -0
  80. package/src/Table/theader/index.tsx +61 -42
  81. package/src/Table/util/header.ts +111 -0
  82. package/src/style/size.css +4 -0
  83. package/src/version.ts +1 -1
@@ -75,7 +75,7 @@ const Table = React.forwardRef<HTMLDivElement, TableProps>((baseprops, ref) => {
75
75
  : [];
76
76
  }, [dataSource, rowKey, getRowKey]);
77
77
 
78
- const { wrapedColumns, columns } = useColumns({
78
+ const { wrapedColumns, headerRows } = useColumns({
79
79
  children,
80
80
  columns: propColumns,
81
81
  expandable,
@@ -92,7 +92,7 @@ const Table = React.forwardRef<HTMLDivElement, TableProps>((baseprops, ref) => {
92
92
  data: sortedData,
93
93
  sorters,
94
94
  onSort,
95
- } = useSorter({ data: filteredData, columns });
95
+ } = useSorter({ data: filteredData, columns: wrapedColumns });
96
96
  // Pagination
97
97
  const { pageData, current, pageSize, pagination } = usePagination({
98
98
  data: sortedData,
@@ -120,7 +120,6 @@ const Table = React.forwardRef<HTMLDivElement, TableProps>((baseprops, ref) => {
120
120
  const {
121
121
  selectedRowKeys,
122
122
  checkedAll,
123
- pageDataRowKeys,
124
123
  onCheckAll,
125
124
  onChange: onSelectionChange,
126
125
  } = useSelection({ pageData, dataSource, getRowKey, rowSelection, allKeys });
@@ -180,7 +179,7 @@ const Table = React.forwardRef<HTMLDivElement, TableProps>((baseprops, ref) => {
180
179
  prefixCls={prefixCls}
181
180
  header={header}
182
181
  download={download}
183
- columns={columns}
182
+ columns={wrapedColumns}
184
183
  pageData={pageData}
185
184
  dataSource={dataSource}
186
185
  />
@@ -195,8 +194,7 @@ const Table = React.forwardRef<HTMLDivElement, TableProps>((baseprops, ref) => {
195
194
  return (
196
195
  <THeader
197
196
  {...ths}
198
- columns={wrapedColumns}
199
- pageDataRowKeys={pageDataRowKeys}
197
+ headerRows={headerRows}
200
198
  checkedAll={checkedAll}
201
199
  sorters={sorters}
202
200
  onSort={onSort}
@@ -243,7 +241,7 @@ const Table = React.forwardRef<HTMLDivElement, TableProps>((baseprops, ref) => {
243
241
  <TableCtx.Provider
244
242
  value={{
245
243
  prefixCls,
246
- columns,
244
+ columns: wrapedColumns,
247
245
  classNames,
248
246
  styles,
249
247
  components,
@@ -11,7 +11,6 @@ export interface BodyCellProps {
11
11
  fixedToLeft?: number;
12
12
  current: number;
13
13
  pageSize: number;
14
- children?: (record: Record<string, any>, index: number) => React.ReactNode;
15
14
  }
16
15
 
17
16
  const TableCell: React.FC<BodyCellProps> = (props) => {
@@ -27,7 +26,6 @@ const TableCell: React.FC<BodyCellProps> = (props) => {
27
26
  className,
28
27
  styles,
29
28
  classNames,
30
- children,
31
29
  onCell,
32
30
  render,
33
31
  } = column;
@@ -38,10 +36,6 @@ const TableCell: React.FC<BodyCellProps> = (props) => {
38
36
  if (render) {
39
37
  return typeof render === 'function' ? render(record, rowIndex) : render;
40
38
  }
41
- if (typeof children === 'function') {
42
- // @ts-ignore
43
- return children(record, rowIndex);
44
- }
45
39
  return (
46
40
  <div
47
41
  className={clsx(`${prefixCls}-cell-inner`, classNames?.inner)}
@@ -8,7 +8,7 @@ import TableRow from './row';
8
8
  const TableBody: React.FC<TableBodyProps> = (props) => {
9
9
  const { columns, pageData, lazyLoad, ...rest } = props;
10
10
 
11
- const { prefixCls } = React.useContext(TableCtx);
11
+ const { prefixCls, components, rowKey } = React.useContext(TableCtx);
12
12
  const { locale } = useLocale();
13
13
  const { table: tableLocale } = locale;
14
14
 
@@ -23,11 +23,30 @@ const TableBody: React.FC<TableBodyProps> = (props) => {
23
23
  const dataLength = pageData.length;
24
24
  if (dataLength === 0) return empty;
25
25
 
26
+ const BodyWrapper = components?.body?.tbody ?? 'tbody';
27
+ const RowRenderer = components?.body?.row;
28
+
29
+ const resolveRowKey = (record: Record<string, any>) =>
30
+ typeof rowKey === 'function' ? rowKey(record) : record[rowKey];
31
+
26
32
  const getRenderRows = () => {
27
33
  if (lazyLoad) {
28
34
  return <LazyRow {...rest} pageData={pageData} columns={columns} />;
29
35
  }
30
36
  return pageData.map((record: Record<string, any>, index: number) => {
37
+ // 整行接管:由外部组件渲染 <tr> + 单元格(可放拖拽手柄等)
38
+ if (RowRenderer) {
39
+ const rk = resolveRowKey(record);
40
+ return (
41
+ <RowRenderer
42
+ key={rk ?? index}
43
+ record={record}
44
+ index={index}
45
+ columns={columns}
46
+ rowKey={rk}
47
+ />
48
+ );
49
+ }
31
50
  return (
32
51
  <TableRow
33
52
  {...rest}
@@ -41,7 +60,7 @@ const TableBody: React.FC<TableBodyProps> = (props) => {
41
60
  };
42
61
 
43
62
  const tbody = (
44
- <tbody className={`${prefixCls}-tbody`}>{getRenderRows()}</tbody>
63
+ <BodyWrapper className={`${prefixCls}-tbody`}>{getRenderRows()}</BodyWrapper>
45
64
  );
46
65
 
47
66
  return tbody;
@@ -56,27 +56,38 @@ const TableRow: React.FC<TableRowProps> = (props) => {
56
56
  };
57
57
 
58
58
  const getSelection = (column: WrapedColumnProps) => {
59
- const { type, onCell, ...restCol } = column;
60
- const key = record[rowKey];
61
- const props = onCell ? onCell(record, index) : {};
62
- const checked = selectedRowKeys?.includes(key);
63
-
59
+ const { type, disabled: colDisabled, onCell } = column;
60
+ const rowKeyValue = record[rowKey];
61
+ const props = (onCell?.(record, index) || {}) as Record<string, unknown>;
62
+ const checked = selectedRowKeys?.includes(rowKeyValue);
63
+
64
+ // rowSelection.disabled may be a boolean, a per-row array, or a function
65
+ const disabled =
66
+ typeof colDisabled === 'function'
67
+ ? colDisabled(record, index)
68
+ : Array.isArray(colDisabled)
69
+ ? colDisabled[index]
70
+ : !!colDisabled;
71
+
72
+ // Only forward input-relevant props. Spreading the whole column would leak
73
+ // rowSelection fields (selectedRowKeys/selectAll/...) and the synthetic
74
+ // `key` onto the DOM <input>.
64
75
  const commonProps = {
65
- // ...rest,
66
- ...restCol,
67
- ...props,
68
76
  checked,
69
- value: key,
77
+ value: rowKeyValue,
70
78
  onChange: onSelectionChange,
79
+ disabled,
80
+ ...props,
71
81
  };
72
82
 
73
83
  if (type === 'checkbox') {
74
- // @ts-ignore
75
- return <Checkbox {...commonProps} />;
76
- } else {
77
- // @ts-ignore
78
- return <Radio {...commonProps} />;
84
+ return (
85
+ <Checkbox
86
+ {...(commonProps as React.ComponentProps<typeof Checkbox>)}
87
+ />
88
+ );
79
89
  }
90
+ return <Radio {...(commonProps as React.ComponentProps<typeof Radio>)} />;
80
91
  };
81
92
 
82
93
  let colSpanStart = Infinity;
@@ -26,6 +26,8 @@ const HeadCell: React.FC<HeadCellProps> = (props) => {
26
26
  internalFilters,
27
27
  style,
28
28
  width,
29
+ colSpan,
30
+ rowSpan,
29
31
  onHeaderCell,
30
32
  onSort,
31
33
  onInternalFilter,
@@ -141,6 +143,8 @@ const HeadCell: React.FC<HeadCellProps> = (props) => {
141
143
  className: cls,
142
144
  scope: 'col',
143
145
  style: styles,
146
+ colSpan,
147
+ rowSpan,
144
148
  };
145
149
  };
146
150
 
@@ -1,65 +1,84 @@
1
1
  import clsx from 'clsx';
2
2
  import React, { memo, useContext } from 'react';
3
3
  import Checkbox from '../../Checkbox';
4
- import { HeadCellProps, WrapedColumnProps } from '../interface';
4
+ import type { HeaderCell } from '../interface';
5
5
  import { TableCtx } from '../table';
6
6
  import HeadCell from './cell';
7
7
 
8
8
  export interface TableHeadProps {
9
- children?: React.ReactNode;
10
- columns?: Array<HeadCellProps>;
11
- isExpandable?: boolean;
12
- expandedColumn?: number;
9
+ /**
10
+ * Resolved 2D header rows (one array per header row), produced by parseHeaderRows
11
+ */
12
+ headerRows?: HeaderCell[][];
13
13
  }
14
14
 
15
15
  const TableHead: React.FC<any> = (props) => {
16
- const { columns, onCheckAll, checkedAll, onHeaderRow, ...rest } = props;
16
+ const { headerRows = [], onCheckAll, checkedAll, onHeaderRow, ...rest } =
17
+ props;
17
18
 
18
19
  const { prefixCls } = useContext(TableCtx);
19
20
 
20
- const renderHeadCell = () => {
21
- return columns.map((column: WrapedColumnProps, index: number) => {
22
- const { key, type, visible } = column;
23
- if (key === 'YEE_SELECTION_COL') {
24
- const common = {
25
- className: `${prefixCls}-cell ${prefixCls}-selection-col`,
26
- scope: 'col',
27
- key: 'title-column-selection',
28
- };
29
- return (
30
- <th {...common} key={column.key || column.dataIndex}>
31
- {type === 'checkbox' ? (
32
- <Checkbox checked={checkedAll} onChange={onCheckAll} />
33
- ) : null}
34
- </th>
35
- );
36
- }
37
- if (key === 'YEE_EXPAND_COL' && visible !== false) {
38
- return (
39
- <th
40
- className={clsx(`${prefixCls}-cell`, `${prefixCls}-expand-col`)}
41
- scope="col"
42
- key="title-column-expandable"
43
- ></th>
44
- );
45
- }
21
+ const renderCell = (
22
+ cell: HeaderCell,
23
+ rowIndex: number,
24
+ colIndex: number,
25
+ ) => {
26
+ const { column, colSpan, rowSpan } = cell;
27
+ const { key, type, visible } = column;
28
+ const cellKey =
29
+ 'title-column-' +
30
+ (column.key || column.dataIndex || `${rowIndex}-${colIndex}`);
31
+
32
+ if (key === 'YEE_SELECTION_COL') {
46
33
  return (
47
- <HeadCell
48
- {...rest}
49
- {...column}
50
- key={'title-column-' + (column.key || column.dataIndex || index)}
34
+ <th
35
+ className={`${prefixCls}-cell ${prefixCls}-selection-col`}
36
+ scope="col"
37
+ key={cellKey}
38
+ colSpan={colSpan}
39
+ rowSpan={rowSpan}
40
+ >
41
+ {type === 'checkbox' ? (
42
+ <Checkbox checked={checkedAll} onChange={onCheckAll} />
43
+ ) : null}
44
+ </th>
45
+ );
46
+ }
47
+ if (key === 'YEE_EXPAND_COL' && visible !== false) {
48
+ return (
49
+ <th
50
+ className={clsx(`${prefixCls}-cell`, `${prefixCls}-expand-col`)}
51
+ scope="col"
52
+ key={cellKey}
53
+ colSpan={colSpan}
54
+ rowSpan={rowSpan}
51
55
  />
52
56
  );
53
- });
57
+ }
58
+ return (
59
+ <HeadCell
60
+ {...rest}
61
+ {...column}
62
+ colSpan={colSpan}
63
+ rowSpan={rowSpan}
64
+ key={cellKey}
65
+ />
66
+ );
54
67
  };
55
68
 
56
- const rowProps = onHeaderRow ? onHeaderRow(columns) : {};
57
-
58
69
  return (
59
70
  <thead className={clsx(`${prefixCls}-thead`)}>
60
- <tr {...rowProps} key="thead">
61
- {renderHeadCell()}
62
- </tr>
71
+ {headerRows.map((row: HeaderCell[], rowIndex: number) => {
72
+ const rowColumns = row.map((cell) => cell.column);
73
+ const rowProps = onHeaderRow ? onHeaderRow(rowColumns) : {};
74
+ return (
75
+ <tr {...rowProps} key={`thead-row-${rowIndex}`}>
76
+ {row.map((cell, colIndex) =>
77
+ renderCell(cell, rowIndex, colIndex),
78
+ )}
79
+ </tr>
80
+ );
81
+ })}
63
82
  </thead>
64
83
  );
65
84
  };
@@ -0,0 +1,111 @@
1
+ import type {
2
+ ColumnProps,
3
+ ExpandableType,
4
+ HeaderCell,
5
+ RowSelectionType,
6
+ WrapedColumnProps,
7
+ } from '../interface';
8
+
9
+ type FixedType = ColumnProps['fixed'];
10
+
11
+ /**
12
+ * Recursively flatten a (possibly grouped) column tree into its leaf columns.
13
+ * A parent's `fixed` is inherited by its children when the child does not set its own.
14
+ */
15
+ export function flattenLeafColumns(
16
+ columns: WrapedColumnProps[],
17
+ parentFixed?: FixedType,
18
+ ): WrapedColumnProps[] {
19
+ return columns.reduce<WrapedColumnProps[]>((list, column) => {
20
+ const fixed = column.fixed ?? parentFixed;
21
+ const subColumns = column.children as WrapedColumnProps[] | undefined;
22
+ if (subColumns && subColumns.length > 0) {
23
+ return [...list, ...flattenLeafColumns(subColumns, fixed)];
24
+ }
25
+ return [...list, { ...column, fixed }];
26
+ }, []);
27
+ }
28
+
29
+ /**
30
+ * Convert a column tree into a 2D array of header cells (one array per header row),
31
+ * computing each cell's colSpan/rowSpan. Mirrors rc-table's parseHeaderRows.
32
+ *
33
+ * - Pass 1 (DFS): place each column into the row matching its depth; a group's
34
+ * colSpan equals the sum of its children's colSpans.
35
+ * - Pass 2: leaf cells (no sub-columns) get rowSpan = rowCount - rowIndex so
36
+ * they stretch down to the last header row; group cells keep rowSpan = 1.
37
+ */
38
+ export function parseHeaderRows(
39
+ rootColumns: WrapedColumnProps[],
40
+ ): HeaderCell[][] {
41
+ const rows: HeaderCell[][] = [];
42
+
43
+ const fillRowCells = (
44
+ columns: WrapedColumnProps[],
45
+ rowIndex: number,
46
+ ): number => {
47
+ rows[rowIndex] = rows[rowIndex] || [];
48
+ let colSpanTotal = 0;
49
+ columns.filter(Boolean).forEach((column) => {
50
+ const cell: HeaderCell = {
51
+ column,
52
+ colSpan: 1,
53
+ rowSpan: 1,
54
+ };
55
+ const subColumns = column.children as WrapedColumnProps[] | undefined;
56
+ if (subColumns && subColumns.length > 0) {
57
+ cell.colSpan = fillRowCells(subColumns, rowIndex + 1);
58
+ cell.hasSubColumns = true;
59
+ }
60
+ rows[rowIndex].push(cell);
61
+ colSpanTotal += cell.colSpan;
62
+ });
63
+ return colSpanTotal;
64
+ };
65
+
66
+ fillRowCells(rootColumns, 0);
67
+
68
+ const rowCount = rows.length;
69
+ for (let rowIndex = 0; rowIndex < rowCount; rowIndex += 1) {
70
+ rows[rowIndex].forEach((cell) => {
71
+ // Leaf cells stretch to the bottom row; group cells stay at rowSpan = 1.
72
+ if (!cell.hasSubColumns) {
73
+ cell.rowSpan = rowCount - rowIndex;
74
+ }
75
+ });
76
+ }
77
+
78
+ return rows;
79
+ }
80
+
81
+ /**
82
+ * Inject selection / expand columns into the top level of the column tree.
83
+ * `index` is a 1-based position among the top-level columns.
84
+ */
85
+ export function injectSelectionExpand(
86
+ columns: WrapedColumnProps[],
87
+ rowSelection?: RowSelectionType,
88
+ expandable?: ExpandableType,
89
+ ): WrapedColumnProps[] {
90
+ const result = [...columns];
91
+ if (rowSelection) {
92
+ const { index = 1 } = rowSelection;
93
+ result.splice(index - 1, 0, {
94
+ width: 50,
95
+ ...rowSelection,
96
+ key: 'YEE_SELECTION_COL',
97
+ } as WrapedColumnProps);
98
+ }
99
+ if (expandable) {
100
+ const { index = 1, visible = true } = expandable;
101
+ const loc = index ? index - 1 : rowSelection ? 1 : 0;
102
+ if (visible !== false) {
103
+ result.splice(loc, 0, {
104
+ width: 50,
105
+ ...expandable,
106
+ key: 'YEE_EXPAND_COL',
107
+ } as WrapedColumnProps);
108
+ }
109
+ }
110
+ return result;
111
+ }
@@ -482,6 +482,10 @@
482
482
  --yee-selector-arrow-right: 8px;
483
483
  --yee-selector-clear-right: 8px;
484
484
  --yee-selector-clear-padding: 1px;
485
+ --yee-selector-small-padding: 0 6px;
486
+ --yee-selector-small-height: 24px;
487
+ --yee-selector-large-padding: 4px 12px;
488
+ --yee-selector-large-height: 40px;
485
489
  --yee-tags-height: 32px;
486
490
  --yee-tags-input-font-size: 14px;
487
491
  --yee-tags-input-line-height: 22px;
package/src/version.ts CHANGED
@@ -4,7 +4,7 @@ declare global {
4
4
  }
5
5
  }
6
6
 
7
- export const version = "0.5.0";
7
+ export const version = "0.6.0";
8
8
 
9
9
  if (typeof window !== 'undefined') {
10
10
  window.__yee_c_version__ = version;