@fangxinyan/lumina 0.6.9 → 0.6.10

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.
@@ -69,11 +69,27 @@
69
69
  /* Card-row variant: each row is its own raised pill */
70
70
  .table.cards {
71
71
  border-collapse: separate;
72
- border-spacing: 0 10px;
73
- padding: 10px;
72
+ border-spacing: 0 14px;
73
+ padding: 12px;
74
74
  background: transparent;
75
75
  box-shadow: none;
76
76
  }
77
+ .table.cards tbody tr {
78
+ position: relative;
79
+ isolation: isolate;
80
+ transition: transform var(--dur-fast) var(--ease);
81
+ }
82
+ .table.cards tbody tr::before {
83
+ content: "";
84
+ position: absolute;
85
+ inset: 0;
86
+ z-index: 0;
87
+ border-radius: var(--r-md);
88
+ background: var(--bg);
89
+ box-shadow: var(--neu-shadow-control);
90
+ pointer-events: none;
91
+ transition: box-shadow var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
92
+ }
77
93
  .table.cards thead th {
78
94
  background: transparent;
79
95
  border-bottom: none;
@@ -81,22 +97,24 @@
81
97
  padding-bottom: 6px;
82
98
  }
83
99
  .table.cards tbody td {
84
- background: var(--bg);
100
+ position: relative;
101
+ z-index: 1;
102
+ background: transparent;
85
103
  border-bottom: none;
86
104
  padding: 14px 18px;
105
+ box-shadow: none;
87
106
  }
88
107
  .table.cards tbody td:first-child {
89
108
  border-radius: var(--r-md) 0 0 var(--r-md);
90
- box-shadow: -4px 4px 8px var(--shadow-dark), -4px -4px 8px var(--shadow-light);
91
109
  }
92
110
  .table.cards tbody td:last-child {
93
111
  border-radius: 0 var(--r-md) var(--r-md) 0;
94
- box-shadow: 4px 4px 8px var(--shadow-dark), 4px -4px 8px var(--shadow-light);
95
112
  }
96
- .table.cards tbody td:not(:first-child):not(:last-child) {
97
- box-shadow: 0 4px 8px var(--shadow-dark), 0 -4px 8px var(--shadow-light);
113
+ .table.cards.hoverable tbody tr:hover {
114
+ transform: translateY(-1px);
98
115
  }
99
- .table.cards.hoverable tbody tr:hover td { background: var(--bg); transform: translateY(-1px); }
116
+ .table.cards.hoverable tbody tr:hover::before { box-shadow: var(--neu-shadow-panel); }
117
+ .table.cards.hoverable tbody tr:hover td { background: transparent; }
100
118
 
101
119
  .table .row-check { width: 44px; }
102
120
  .table .row-check .checkbox { display: inline-flex; }
package/dist/Table.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkCPBFUKSX_cjs = require('./chunk-CPBFUKSX.cjs');
3
+ var chunkPPDPKPLE_cjs = require('./chunk-PPDPKPLE.cjs');
4
4
  require('./chunk-XVDD6JEU.cjs');
5
5
  require('./chunk-F65KYGPX.cjs');
6
6
  require('./chunk-76OH42CM.cjs');
@@ -14,5 +14,5 @@ require('./chunk-GJAEGIPM.cjs');
14
14
 
15
15
  Object.defineProperty(exports, "Table", {
16
16
  enumerable: true,
17
- get: function () { return chunkCPBFUKSX_cjs.Table; }
17
+ get: function () { return chunkPPDPKPLE_cjs.Table; }
18
18
  });
package/dist/Table.d.cts CHANGED
@@ -43,11 +43,11 @@ interface PaginationConfig {
43
43
  total?: number;
44
44
  /** Fired when user picks a page or changes page size. */
45
45
  onChange?: (page: number, pageSize: number) => void;
46
- /** Reserved for future: jump-to-page input. */
46
+ /** Show a jump-to-page input. */
47
47
  showQuickJumper?: boolean;
48
- /** Reserved for future: page size dropdown. */
48
+ /** Show a page size dropdown. */
49
49
  showSizeChanger?: boolean;
50
- /** Reserved for future: selectable page sizes. */
50
+ /** Selectable page sizes for the size dropdown. */
51
51
  pageSizeOptions?: number[];
52
52
  }
53
53
  interface RowSelectionConfig<Row = any> {
package/dist/Table.d.ts CHANGED
@@ -43,11 +43,11 @@ interface PaginationConfig {
43
43
  total?: number;
44
44
  /** Fired when user picks a page or changes page size. */
45
45
  onChange?: (page: number, pageSize: number) => void;
46
- /** Reserved for future: jump-to-page input. */
46
+ /** Show a jump-to-page input. */
47
47
  showQuickJumper?: boolean;
48
- /** Reserved for future: page size dropdown. */
48
+ /** Show a page size dropdown. */
49
49
  showSizeChanger?: boolean;
50
- /** Reserved for future: selectable page sizes. */
50
+ /** Selectable page sizes for the size dropdown. */
51
51
  pageSizeOptions?: number[];
52
52
  }
53
53
  interface RowSelectionConfig<Row = any> {
package/dist/Table.js CHANGED
@@ -1,4 +1,4 @@
1
- export { Table } from './chunk-FZITSOKH.js';
1
+ export { Table } from './chunk-QMZBOB7Q.js';
2
2
  import './chunk-5CWTC3I2.js';
3
3
  import './chunk-MOLKLUSQ.js';
4
4
  import './chunk-I5XCHN67.js';
@@ -11,7 +11,7 @@
11
11
  margin-top: 0;
12
12
  padding: 6px 16px;
13
13
  border-top: 1px solid var(--divider);
14
- background: color-mix(in oklch, var(--bg-sunken) 30%, transparent);
14
+ background: transparent;
15
15
  }
16
16
  .table-toolbar {
17
17
  display: flex;
@@ -41,5 +41,5 @@
41
41
  .table-footer {
42
42
  padding: 10px 16px;
43
43
  border-top: 1px solid var(--divider);
44
- background: color-mix(in oklch, var(--bg-sunken) 30%, transparent);
44
+ background: transparent;
45
45
  }
package/dist/TablePro.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkNUNPFMCM_cjs = require('./chunk-NUNPFMCM.cjs');
4
- require('./chunk-CPBFUKSX.cjs');
3
+ var chunkJ2KV6K23_cjs = require('./chunk-J2KV6K23.cjs');
4
+ require('./chunk-PPDPKPLE.cjs');
5
5
  require('./chunk-XVDD6JEU.cjs');
6
6
  require('./chunk-F65KYGPX.cjs');
7
7
  require('./chunk-76OH42CM.cjs');
@@ -15,5 +15,5 @@ require('./chunk-GJAEGIPM.cjs');
15
15
 
16
16
  Object.defineProperty(exports, "TablePro", {
17
17
  enumerable: true,
18
- get: function () { return chunkNUNPFMCM_cjs.TablePro; }
18
+ get: function () { return chunkJ2KV6K23_cjs.TablePro; }
19
19
  });
package/dist/TablePro.js CHANGED
@@ -1,5 +1,5 @@
1
- export { TablePro } from './chunk-N24KHD5B.js';
2
- import './chunk-FZITSOKH.js';
1
+ export { TablePro } from './chunk-KWIHEE4D.js';
2
+ import './chunk-QMZBOB7Q.js';
3
3
  import './chunk-5CWTC3I2.js';
4
4
  import './chunk-MOLKLUSQ.js';
5
5
  import './chunk-I5XCHN67.js';
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
- var chunkCPBFUKSX_cjs = require('./chunk-CPBFUKSX.cjs');
3
+ var chunkPPDPKPLE_cjs = require('./chunk-PPDPKPLE.cjs');
4
4
  require('./tokens-RGFJKRC7.css');
5
5
  require('./shared-NJHRNLRH.css');
6
- require('./TablePro-JRSBPXB5.css');
6
+ require('./TablePro-3NGWERWT.css');
7
7
  var React = require('react');
8
8
  var jsxRuntime = require('react/jsx-runtime');
9
9
 
@@ -71,7 +71,7 @@ var TableProInner = ({
71
71
  actions && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "table-toolbar-actions", children: actions })
72
72
  ] }),
73
73
  /* @__PURE__ */ jsxRuntime.jsx(
74
- chunkCPBFUKSX_cjs.Table,
74
+ chunkPPDPKPLE_cjs.Table,
75
75
  {
76
76
  columns,
77
77
  data,
@@ -1,7 +1,7 @@
1
- import { Table } from './chunk-FZITSOKH.js';
1
+ import { Table } from './chunk-QMZBOB7Q.js';
2
2
  import './tokens-RGFJKRC7.css';
3
3
  import './shared-NJHRNLRH.css';
4
- import './TablePro-JRSBPXB5.css';
4
+ import './TablePro-3NGWERWT.css';
5
5
  import * as React from 'react';
6
6
  import { jsxs, jsx } from 'react/jsx-runtime';
7
7
 
@@ -6,7 +6,7 @@ var chunkYB3IWIOJ_cjs = require('./chunk-YB3IWIOJ.cjs');
6
6
  var chunkGJAEGIPM_cjs = require('./chunk-GJAEGIPM.cjs');
7
7
  require('./tokens-RGFJKRC7.css');
8
8
  require('./shared-NJHRNLRH.css');
9
- require('./Table-IYJTPY6J.css');
9
+ require('./Table-5XJNZWLF.css');
10
10
  var React = require('react');
11
11
  var reactDom = require('react-dom');
12
12
  var jsxRuntime = require('react/jsx-runtime');
@@ -159,10 +159,21 @@ var TableInner = ({
159
159
  const start = (curPage - 1) * curPageSize;
160
160
  return filteredData.slice(start, start + curPageSize);
161
161
  }, [pagEnabled, filteredData, curPage, curPageSize, pagCfg.total, pageControlled]);
162
+ const skipNextPaginationChangeRef = React__namespace.useRef(false);
162
163
  const onPageChange = (p) => {
164
+ if (skipNextPaginationChangeRef.current) {
165
+ skipNextPaginationChangeRef.current = false;
166
+ return;
167
+ }
163
168
  if (!pageControlled) setInnerPage(p);
164
169
  pagCfg.onChange?.(p, curPageSize);
165
170
  };
171
+ const onPageSizeChange = (_current, size) => {
172
+ skipNextPaginationChangeRef.current = true;
173
+ if (!pageControlled) setInnerPage(1);
174
+ if (pagCfg.pageSize === void 0) setInnerPageSize(size);
175
+ pagCfg.onChange?.(1, size);
176
+ };
166
177
  const [innerExpanded, setInnerExpanded] = React__namespace.useState(
167
178
  expandable?.defaultExpandedRowKeys ?? []
168
179
  );
@@ -381,7 +392,11 @@ var TableInner = ({
381
392
  total: totalCount,
382
393
  pageSize: curPageSize,
383
394
  page: curPage,
384
- onChange: onPageChange
395
+ onChange: onPageChange,
396
+ showQuickJumper: pagCfg.showQuickJumper,
397
+ showSizeChanger: pagCfg.showSizeChanger,
398
+ pageSizeOptions: pagCfg.pageSizeOptions,
399
+ onShowSizeChange: onPageSizeChange
385
400
  }
386
401
  ) })
387
402
  ] });
@@ -4,7 +4,7 @@ import { useFloating } from './chunk-DUFRASGO.js';
4
4
  import { Icon } from './chunk-SNX4FZYB.js';
5
5
  import './tokens-RGFJKRC7.css';
6
6
  import './shared-NJHRNLRH.css';
7
- import './Table-IYJTPY6J.css';
7
+ import './Table-5XJNZWLF.css';
8
8
  import * as React from 'react';
9
9
  import { createPortal } from 'react-dom';
10
10
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
@@ -137,10 +137,21 @@ var TableInner = ({
137
137
  const start = (curPage - 1) * curPageSize;
138
138
  return filteredData.slice(start, start + curPageSize);
139
139
  }, [pagEnabled, filteredData, curPage, curPageSize, pagCfg.total, pageControlled]);
140
+ const skipNextPaginationChangeRef = React.useRef(false);
140
141
  const onPageChange = (p) => {
142
+ if (skipNextPaginationChangeRef.current) {
143
+ skipNextPaginationChangeRef.current = false;
144
+ return;
145
+ }
141
146
  if (!pageControlled) setInnerPage(p);
142
147
  pagCfg.onChange?.(p, curPageSize);
143
148
  };
149
+ const onPageSizeChange = (_current, size) => {
150
+ skipNextPaginationChangeRef.current = true;
151
+ if (!pageControlled) setInnerPage(1);
152
+ if (pagCfg.pageSize === void 0) setInnerPageSize(size);
153
+ pagCfg.onChange?.(1, size);
154
+ };
144
155
  const [innerExpanded, setInnerExpanded] = React.useState(
145
156
  expandable?.defaultExpandedRowKeys ?? []
146
157
  );
@@ -359,7 +370,11 @@ var TableInner = ({
359
370
  total: totalCount,
360
371
  pageSize: curPageSize,
361
372
  page: curPage,
362
- onChange: onPageChange
373
+ onChange: onPageChange,
374
+ showQuickJumper: pagCfg.showQuickJumper,
375
+ showSizeChanger: pagCfg.showSizeChanger,
376
+ pageSizeOptions: pagCfg.pageSizeOptions,
377
+ onShowSizeChange: onPageSizeChange
363
378
  }
364
379
  ) })
365
380
  ] });
package/dist/index.cjs CHANGED
@@ -12,8 +12,8 @@ var chunk4LOOWTRX_cjs = require('./chunk-4LOOWTRX.cjs');
12
12
  require('./chunk-6EOSMK34.cjs');
13
13
  var chunkDGB6KVU3_cjs = require('./chunk-DGB6KVU3.cjs');
14
14
  var chunkHFM4YKM5_cjs = require('./chunk-HFM4YKM5.cjs');
15
- var chunkNUNPFMCM_cjs = require('./chunk-NUNPFMCM.cjs');
16
- var chunkCPBFUKSX_cjs = require('./chunk-CPBFUKSX.cjs');
15
+ var chunkJ2KV6K23_cjs = require('./chunk-J2KV6K23.cjs');
16
+ var chunkPPDPKPLE_cjs = require('./chunk-PPDPKPLE.cjs');
17
17
  var chunkZ35Q432P_cjs = require('./chunk-Z35Q432P.cjs');
18
18
  var chunkZGDAYWWC_cjs = require('./chunk-ZGDAYWWC.cjs');
19
19
  var chunkXVDD6JEU_cjs = require('./chunk-XVDD6JEU.cjs');
@@ -51,7 +51,7 @@ var chunkHTW62OMX_cjs = require('./chunk-HTW62OMX.cjs');
51
51
  var chunkGJAEGIPM_cjs = require('./chunk-GJAEGIPM.cjs');
52
52
 
53
53
  // src/index.ts
54
- var VERSION = "0.6.9";
54
+ var VERSION = "0.6.10";
55
55
 
56
56
  Object.defineProperty(exports, "Tabs", {
57
57
  enumerable: true,
@@ -167,11 +167,11 @@ Object.defineProperty(exports, "Switch", {
167
167
  });
168
168
  Object.defineProperty(exports, "TablePro", {
169
169
  enumerable: true,
170
- get: function () { return chunkNUNPFMCM_cjs.TablePro; }
170
+ get: function () { return chunkJ2KV6K23_cjs.TablePro; }
171
171
  });
172
172
  Object.defineProperty(exports, "Table", {
173
173
  enumerable: true,
174
- get: function () { return chunkCPBFUKSX_cjs.Table; }
174
+ get: function () { return chunkPPDPKPLE_cjs.Table; }
175
175
  });
176
176
  Object.defineProperty(exports, "MessageContainer", {
177
177
  enumerable: true,
package/dist/index.d.cts CHANGED
@@ -49,6 +49,6 @@ import 'react/jsx-runtime';
49
49
  import 'react';
50
50
 
51
51
  /** Package version — bumped by release scripts. */
52
- declare const VERSION = "0.6.9";
52
+ declare const VERSION = "0.6.10";
53
53
 
54
54
  export { VERSION };
package/dist/index.d.ts CHANGED
@@ -49,6 +49,6 @@ import 'react/jsx-runtime';
49
49
  import 'react';
50
50
 
51
51
  /** Package version — bumped by release scripts. */
52
- declare const VERSION = "0.6.9";
52
+ declare const VERSION = "0.6.10";
53
53
 
54
54
  export { VERSION };
package/dist/index.js CHANGED
@@ -10,8 +10,8 @@ export { SURFACE_THEME_PRESETS, Surface } from './chunk-WIZVOZNO.js';
10
10
  import './chunk-6SPMHY54.js';
11
11
  export { ACCENT_PRESETS, ACCENT_PRESETS_DARK, FONT_STACKS, ThemeProvider, applyTheme, normalizeAccentInput, resolveThemeColorScheme, resolveThemeMode, useTheme, useThemeOptional } from './chunk-7ZCTEIOW.js';
12
12
  export { Switch } from './chunk-6VSNO7IH.js';
13
- export { TablePro } from './chunk-N24KHD5B.js';
14
- export { Table } from './chunk-FZITSOKH.js';
13
+ export { TablePro } from './chunk-KWIHEE4D.js';
14
+ export { Table } from './chunk-QMZBOB7Q.js';
15
15
  export { MessageContainer, ToastContainer, message, toast } from './chunk-62RPBEAW.js';
16
16
  export { Modal } from './chunk-SGNDIRZC.js';
17
17
  export { Pagination } from './chunk-5CWTC3I2.js';
@@ -49,6 +49,6 @@ export { Calendar } from './chunk-W72IIGOV.js';
49
49
  export { AimOutlined, AppstoreOutlined, BarChartOutlined, BlockOutlined, BorderOutlined, CameraOutlined, CaretDownOutlined, CaretUpOutlined, CheckCircleFilled, CheckCircleOutlined, CheckOutlined, ClockCircleFilled, CloseCircleOutlined, CloseOutlined, CopyOutlined, DashboardOutlined, DeleteOutlined, DownOutlined, EnvironmentOutlined, ExclamationCircleOutlined, FolderOpenOutlined, ICON_NAMES, Icon, LeftOutlined, LoadingOutlined, MinusCircleOutlined, MinusOutlined, NAMED_ICON_MAP, PictureOutlined, PlusOutlined, QqOutlined, ReloadOutlined, RightOutlined, RobotOutlined, SearchOutlined, SettingOutlined, StarFilled, StarOutlined, SwapOutlined, SwapRightOutlined, SyncOutlined, ThunderboltOutlined, TranslationOutlined, UnorderedListOutlined, UserOutlined, isIconName, renderIconSlot, resolveIconName } from './chunk-SNX4FZYB.js';
50
50
 
51
51
  // src/index.ts
52
- var VERSION = "0.6.9";
52
+ var VERSION = "0.6.10";
53
53
 
54
54
  export { VERSION };
package/dist/styles.css CHANGED
@@ -2093,11 +2093,27 @@ input, textarea, select { font-family: inherit; color: inherit; }
2093
2093
  /* Card-row variant: each row is its own raised pill */
2094
2094
  .table.cards {
2095
2095
  border-collapse: separate;
2096
- border-spacing: 0 10px;
2097
- padding: 10px;
2096
+ border-spacing: 0 14px;
2097
+ padding: 12px;
2098
2098
  background: transparent;
2099
2099
  box-shadow: none;
2100
2100
  }
2101
+ .table.cards tbody tr {
2102
+ position: relative;
2103
+ isolation: isolate;
2104
+ transition: transform var(--dur-fast) var(--ease);
2105
+ }
2106
+ .table.cards tbody tr::before {
2107
+ content: "";
2108
+ position: absolute;
2109
+ inset: 0;
2110
+ z-index: 0;
2111
+ border-radius: var(--r-md);
2112
+ background: var(--bg);
2113
+ box-shadow: var(--neu-shadow-control);
2114
+ pointer-events: none;
2115
+ transition: box-shadow var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
2116
+ }
2101
2117
  .table.cards thead th {
2102
2118
  background: transparent;
2103
2119
  border-bottom: none;
@@ -2105,22 +2121,24 @@ input, textarea, select { font-family: inherit; color: inherit; }
2105
2121
  padding-bottom: 6px;
2106
2122
  }
2107
2123
  .table.cards tbody td {
2108
- background: var(--bg);
2124
+ position: relative;
2125
+ z-index: 1;
2126
+ background: transparent;
2109
2127
  border-bottom: none;
2110
2128
  padding: 14px 18px;
2129
+ box-shadow: none;
2111
2130
  }
2112
2131
  .table.cards tbody td:first-child {
2113
2132
  border-radius: var(--r-md) 0 0 var(--r-md);
2114
- box-shadow: -4px 4px 8px var(--shadow-dark), -4px -4px 8px var(--shadow-light);
2115
2133
  }
2116
2134
  .table.cards tbody td:last-child {
2117
2135
  border-radius: 0 var(--r-md) var(--r-md) 0;
2118
- box-shadow: 4px 4px 8px var(--shadow-dark), 4px -4px 8px var(--shadow-light);
2119
2136
  }
2120
- .table.cards tbody td:not(:first-child):not(:last-child) {
2121
- box-shadow: 0 4px 8px var(--shadow-dark), 0 -4px 8px var(--shadow-light);
2137
+ .table.cards.hoverable tbody tr:hover {
2138
+ transform: translateY(-1px);
2122
2139
  }
2123
- .table.cards.hoverable tbody tr:hover td { background: var(--bg); transform: translateY(-1px); }
2140
+ .table.cards.hoverable tbody tr:hover::before { box-shadow: var(--neu-shadow-panel); }
2141
+ .table.cards.hoverable tbody tr:hover td { background: transparent; }
2124
2142
  .table .row-check { width: 44px; }
2125
2143
  .table .row-check .checkbox { display: inline-flex; }
2126
2144
  .table .row-expand { width: 40px; text-align: center; }
@@ -2270,7 +2288,7 @@ input, textarea, select { font-family: inherit; color: inherit; }
2270
2288
  margin-top: 0;
2271
2289
  padding: 6px 16px;
2272
2290
  border-top: 1px solid var(--divider);
2273
- background: color-mix(in oklch, var(--bg-sunken) 30%, transparent);
2291
+ background: transparent;
2274
2292
  }
2275
2293
  .table-toolbar {
2276
2294
  display: flex;
@@ -2300,7 +2318,7 @@ input, textarea, select { font-family: inherit; color: inherit; }
2300
2318
  .table-footer {
2301
2319
  padding: 10px 16px;
2302
2320
  border-top: 1px solid var(--divider);
2303
- background: color-mix(in oklch, var(--bg-sunken) 30%, transparent);
2321
+ background: transparent;
2304
2322
  }
2305
2323
  /* ============ Pagination ============ */
2306
2324
  .pagination {
@@ -16,13 +16,14 @@ import { Table } from "@fangxinyan/lumina";
16
16
  <Table rowKey="id" columns={[...]} data={data} />
17
17
  ```
18
18
 
19
- ### 样式变体
19
+ ### 样式变体 / hover
20
20
 
21
- 三种视觉变体:striped (条纹)、embossed (凸起)、cards (卡片行)。
21
+ 覆盖 variant 的四个取值,以及 striped 快捷属性和 hoverable 关闭状态。
22
22
 
23
23
  ```tsx
24
- <Table variant="striped" ... />
25
- <Table variant="embossed" ... />
24
+ <Table variant="default" ... />
25
+ <Table striped ... />
26
+ <Table variant="embossed" hoverable={false} ... />
26
27
  <Table variant="cards" ... />
27
28
  ```
28
29
 
@@ -34,11 +35,38 @@ import { Table } from "@fangxinyan/lumina";
34
35
  <Table
35
36
  rowKey="id"
36
37
  columns={[...]}
37
- data={data} // 24 rows
38
+ data={data}
38
39
  pagination={{ pageSize: 6 }}
39
40
  />
40
41
  ```
41
42
 
43
+ ### 分页配置
44
+
45
+ 覆盖 current / defaultCurrent / pageSize / defaultPageSize / total / onChange / showQuickJumper / showSizeChanger / pageSizeOptions。
46
+
47
+ ```tsx
48
+ <Table
49
+ data={serverPageData}
50
+ pagination={{
51
+ current,
52
+ pageSize,
53
+ total: allRows.length,
54
+ showQuickJumper: true,
55
+ showSizeChanger: true,
56
+ pageSizeOptions: [4, 5, 8],
57
+ onChange: (page, nextPageSize) => {
58
+ setCurrent(page);
59
+ setPageSize(nextPageSize);
60
+ },
61
+ }}
62
+ />
63
+
64
+ <Table
65
+ data={allRows}
66
+ pagination={{ defaultCurrent: 2, defaultPageSize: 4 }}
67
+ />
68
+ ```
69
+
42
70
  ### 固定表头 / 横向滚动
43
71
 
44
72
  scroll.y 固定表头并限制表体最大高度;scroll.x 设置内容最小宽度。
@@ -51,15 +79,35 @@ scroll.y 固定表头并限制表体最大高度;scroll.x 设置内容最小宽
51
79
  />
52
80
  ```
53
81
 
82
+ ### 受控排序 / 行点击
83
+
84
+ Table 负责渲染排序指示,排序后的 data 由外部状态计算后传入。
85
+
86
+ ```tsx
87
+ <Table
88
+ sortKey={sortKey}
89
+ sortDir={sortDir}
90
+ onSort={(key) => {
91
+ setSortKey(key);
92
+ setSortDir((dir) => (dir === "asc" ? "desc" : "asc"));
93
+ }}
94
+ onRowClick={(row, index) => setClicked(row.name)}
95
+ columns={[{ key: "salary", sortable: true, align: "right" }]}
96
+ />
97
+ ```
98
+
54
99
  ### 行选择 (rowSelection)
55
100
 
56
- rowSelection 提供表头全选、半选状态与按行禁用能力。
101
+ rowSelection 提供表头全选、半选状态、受控选中项、回传选中行与按行禁用能力。
57
102
 
58
103
  ```tsx
59
104
  <Table
60
105
  rowSelection={{
61
106
  selectedRowKeys,
62
- onChange: (keys, rows) => setSelectedKeys(keys),
107
+ onChange: (keys, rows) => {
108
+ setSelectedKeys(keys);
109
+ setSelectedRows(rows);
110
+ },
63
111
  getCheckboxProps: (row) => ({ disabled: row.status === "离线" }),
64
112
  }}
65
113
  columns={[...]}
@@ -69,7 +117,7 @@ rowSelection 提供表头全选、半选状态与按行禁用能力。
69
117
 
70
118
  ### 行选择 · 单选
71
119
 
72
- 设置 rowSelection.type = 'radio' 变成单选模式。
120
+ 设置 rowSelection.type = 'radio' 变成单选模式,defaultSelectedRowKeys 设置非受控初始值。
73
121
 
74
122
  ```tsx
75
123
  <Table
@@ -79,14 +127,29 @@ rowSelection 提供表头全选、半选状态与按行禁用能力。
79
127
  />
80
128
  ```
81
129
 
130
+ ### 旧版选择 API
131
+
132
+ selectable / selected / onSelect 保留向后兼容,新代码优先使用 rowSelection。
133
+
134
+ ```tsx
135
+ <Table
136
+ selectable
137
+ selected={selected}
138
+ onSelect={setSelected}
139
+ columns={[...]}
140
+ data={data}
141
+ />
142
+ ```
143
+
82
144
  ### 可展开行
83
145
 
84
- 点击左侧箭头按钮展开/收起,在行下方渲染自定义内容。
146
+ 点击左侧箭头按钮展开/收起,defaultExpandedRowKeys 设置非受控初始展开。
85
147
 
86
148
  ```tsx
87
149
  <Table
88
150
  expandable={{
89
- expandedRowRender: (row) => <div>…详情…</div>,
151
+ defaultExpandedRowKeys: [1],
152
+ expandedRowRender: (row) => <div>...详情...</div>,
90
153
  rowExpandable: (row) => row.status !== "离线",
91
154
  }}
92
155
  columns={[...]}
@@ -94,19 +157,36 @@ rowSelection 提供表头全选、半选状态与按行禁用能力。
94
157
  />
95
158
  ```
96
159
 
160
+ ### 受控展开
161
+
162
+ expandedRowKeys 由外部状态控制,onExpand 负责同步展开 key。
163
+
164
+ ```tsx
165
+ <Table
166
+ expandable={{
167
+ expandedRowKeys,
168
+ onExpand: (expanded, row) => setExpandedRowKeys(...),
169
+ expandedRowRender: (row) => <div>...</div>,
170
+ }}
171
+ />
172
+ ```
173
+
97
174
  ### 列筛选
98
175
 
99
- 在列上配置 filters 即可在列头显示漏斗图标;点击弹出勾选面板,勾选后过滤数据。
176
+ filters + onFilter 生成列头筛选菜单;defaultFilteredValue 可设置非受控初始筛选。
100
177
 
101
178
  ```tsx
102
179
  <Table
103
180
  columns={[
104
181
  {
105
- key: "role", title: "部门", dataIndex: "role",
182
+ key: "role",
183
+ title: "部门",
184
+ dataIndex: "role",
106
185
  filters: [
107
186
  { text: "设计", value: "设计" },
108
187
  { text: "研发", value: "研发" },
109
188
  ],
189
+ defaultFilteredValue: ["研发"],
110
190
  onFilter: (value, row) => row.role === value,
111
191
  },
112
192
  ]}
@@ -114,6 +194,41 @@ rowSelection 提供表头全选、半选状态与按行禁用能力。
114
194
  />
115
195
  ```
116
196
 
197
+ ### 受控筛选值
198
+
199
+ filteredValue 由外部状态控制,适合和工具栏筛选器或 URL 状态同步。
200
+
201
+ ```tsx
202
+ <Table
203
+ columns={[
204
+ {
205
+ key: "status",
206
+ filteredValue,
207
+ filters: [...],
208
+ onFilter: (value, row) => row.status === value,
209
+ },
210
+ ]}
211
+ />
212
+ ```
213
+
214
+ ### 空状态 / 原生属性
215
+
216
+ empty 自定义空态;className / style / id / data-* / aria-* 透传到表格外层容器;pagination={false} 显式关闭分页。
217
+
218
+ ```tsx
219
+ <Table
220
+ id="member-empty-table"
221
+ className="demo-member-table"
222
+ style={{ boxShadow: "var(--neu-in-sm)" }}
223
+ data-demo-table="empty"
224
+ aria-label="成员空表格"
225
+ rowKey={(row) => `member-${row.id}`}
226
+ data={[]}
227
+ empty={<Tag tone="neutral">没有匹配结果</Tag>}
228
+ pagination={false}
229
+ />
230
+ ```
231
+
117
232
  ## API
118
233
 
119
234
  **Table**
@@ -122,15 +237,23 @@ rowSelection 提供表头全选、半选状态与按行禁用能力。
122
237
  | --- | --- | --- | --- |
123
238
  | columns \* | `TableColumn[]` | — | 列定义 |
124
239
  | data \* | `Row[]` | — | 数据数组 |
125
- | rowKey | `string | (row) => key` | — | 行键 |
240
+ | rowKey | `keyof Row | (row) => key` | — | 行键;可传字段名或函数 |
126
241
  | variant | `"default" | "striped" | "embossed" | "cards"` | `"default"` | 视觉变体 |
127
- | pagination | `false | PaginationConfig` | — | 分页配置;false 关闭 |
128
- | scroll | `TableScrollConfig` | — | 滚动配置:{ x?, y? } |
242
+ | hoverable | `boolean` | `true` | 是否开启行 hover 态 |
243
+ | striped | `boolean` | — | 条纹快捷开关,等价于 variant='striped' |
244
+ | sortKey | `string` | — | 当前排序列 key |
245
+ | sortDir | `"asc" | "desc"` | `"asc"` | 当前排序方向 |
246
+ | onSort | `(key) => void` | — | 点击可排序表头时触发 |
129
247
  | rowSelection | `RowSelectionConfig` | — | 行选择配置 |
248
+ | selectable | `boolean` | — | 旧版多选开关,优先使用 rowSelection |
249
+ | selected | `(string | number)[]` | — | 旧版受控选中 key |
250
+ | onSelect | `(keys) => void` | — | 旧版选中变化回调 |
130
251
  | expandable | `ExpandableConfig` | — | 可展开行配置 |
131
- | sortKey / sortDir / onSort | `—` | — | 受控排序 |
132
- | onRowClick | `(row, i) => void` | — | 点击行 |
133
- | selectable / selected / onSelect | `—` | — | 旧版多选 API,优先使用 rowSelection |
252
+ | pagination | `false | PaginationConfig` | — | 分页配置;false 关闭 |
253
+ | scroll | `TableScrollConfig` | — | 滚动配置 |
254
+ | onRowClick | `(row, index) => void` | — | 点击行 |
255
+ | empty | `ReactNode` | `"暂无数据"` | 空数据占位内容 |
256
+ | className / style / id / data-* / aria-* | `native attrs` | — | 透传到外层 table-wrap 容器 |
134
257
 
135
258
 
136
259
  **TableColumn**
@@ -158,8 +281,19 @@ rowSelection 提供表头全选、半选状态与按行禁用能力。
158
281
  | defaultCurrent | `number` | `1` | 非受控初始页 |
159
282
  | pageSize | `number` | `10` | 每页条数 |
160
283
  | defaultPageSize | `number` | — | 非受控初始每页条数 |
161
- | total | `number` | — | 数据总量;默认为 data.length |
162
- | onChange | `(page, pageSize) => void` | — | 切页回调 |
284
+ | total | `number` | — | 数据总量;默认为过滤后的 data.length |
285
+ | onChange | `(page, pageSize) => void` | — | 切页或切换 pageSize 回调 |
286
+ | showQuickJumper | `boolean` | — | 显示跳页输入 |
287
+ | showSizeChanger | `boolean` | — | 显示每页条数下拉选择 |
288
+ | pageSizeOptions | `number[]` | — | 每页条数选项 |
289
+
290
+
291
+ **TableScrollConfig**
292
+
293
+ | Prop | 类型 | 默认 | 说明 |
294
+ | --- | --- | --- | --- |
295
+ | x | `number | string` | — | 横向滚动时内部 table 的最小宽度 |
296
+ | y | `number | string` | — | 纵向滚动时表体最大高度,并启用 sticky header |
163
297
 
164
298
 
165
299
  **RowSelectionConfig**
@@ -180,7 +314,7 @@ rowSelection 提供表头全选、半选状态与按行禁用能力。
180
314
  | expandedRowKeys | `(string | number)[]` | — | 受控已展开 key |
181
315
  | defaultExpandedRowKeys | `(string | number)[]` | — | 非受控初始展开 |
182
316
  | onExpand | `(expanded, row) => void` | — | 展开/收起回调 |
183
- | expandedRowRender | `(row, i) => ReactNode` | — | 展开面板渲染 |
317
+ | expandedRowRender | `(row, index) => ReactNode` | — | 展开面板渲染 |
184
318
  | rowExpandable | `(row) => boolean` | — | 该行是否可展开 |
185
319
 
186
320
 
@@ -25,6 +25,20 @@ import { TablePro } from "@fangxinyan/lumina";
25
25
  />
26
26
  ```
27
27
 
28
+ ### 卡片行分页
29
+
30
+ variant='cards' 与内置 pagination 共用 TablePro 容器背景,分页区不会单独变成另一块底色。
31
+
32
+ ```tsx
33
+ <TablePro
34
+ variant="cards"
35
+ rowKey="id"
36
+ data={rows}
37
+ pagination={{ pageSize: 4 }}
38
+ columns={[...]}
39
+ />
40
+ ```
41
+
28
42
  ### 带可展开行
29
43
 
30
44
  TablePro 直接透传 expandable 到 Table。
package/docs/llms.md CHANGED
@@ -3,7 +3,7 @@
3
3
  > 拟态风格的 React 18 组件库,目标是 Electron 桌面应用。**写给 AI 编程助手**的按需文档 —— 每个组件单独一个 `.md`,避免一次性读取全部。示例源自 playground 的 demo,可直接复制运行。
4
4
 
5
5
  - **包名**: `@fangxinyan/lumina`
6
- - **版本**: `0.6.9`
6
+ - **版本**: `0.6.10`
7
7
  - **React 最低版本**: 18
8
8
  - **环境**: 带打包器的 React 工程(Vite / Next.js / Webpack / Remix / Electron + Vite 等)
9
9
  - **零运行时依赖**: 只依赖 `react` / `react-dom` (peer deps)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fangxinyan/lumina",
3
- "version": "0.6.9",
3
+ "version": "0.6.10",
4
4
  "description": "Lumina — Neumorphic component library for Electron & React apps",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",