@fangxinyan/lumina 0.6.8 → 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.
package/README.md CHANGED
@@ -19,11 +19,20 @@
19
19
 
20
20
  - **TypeScript 优先** — 全量类型定义,IDE 智能提示完善
21
21
  - **拟态设计语言** — 统一的凸起/凹陷/柔光阴影系统,通过 CSS 变量自定义
22
- - **25+ 基础组件** — Button、Input、Table、Modal、Toast、Calendar …
22
+ - **45+ 公共组件** — Button、Input、Table、Modal、Message、Calendar …
23
23
  - **Electron 原生感** — `TitleBar`、`Sidebar`、`AppShell` 直接拼出窗口布局
24
24
  - **主题化** — 明/暗模式、6 套强调色、3 档密度(紧凑/标准/宽松)
25
25
  - **零运行时依赖** — 只依赖 React;样式纯 CSS 变量驱动
26
26
 
27
+ ## Why Lumina matters for AI-assisted development
28
+
29
+ Lumina 不只是把组件打成 npm 包,也把“AI 能按需读懂组件”的上下文一起发布出去。
30
+
31
+ - **内置 LLM 文档** — 每个组件都有独立 `docs/llms/<id>.md`,覆盖导入方式、可复制示例和完整 Props 表,AI 不必一次读取整份 API。
32
+ - **按需组件文档** — `@fangxinyan/lumina/llms.md` 提供全局约定和组件索引,`@fangxinyan/lumina/llms/button.md` 这类子路径可直接定位到单组件。
33
+ - **零运行时依赖** — 运行时只依赖 React / React DOM,组件逻辑、主题 token 和样式入口都更容易被 AI 审查、迁移和解释。
34
+ - **Electron 场景优先** — `TitleBar`、`WindowControls`、`Sidebar`、`StatusBar`、`AppShell` 等桌面应用原语减少了业务侧临时拼装窗口 UI 的成本。
35
+
27
36
  ## 📦 安装
28
37
 
29
38
  ```bash
@@ -60,7 +69,7 @@ export default function App() {
60
69
  ## 🛠 本地开发(下载即用)
61
70
 
62
71
  ```bash
63
- cd package
72
+ cd lumina
64
73
  npm install
65
74
  npm run dev # 启动 Playground(http://localhost:5173)
66
75
  npm run typecheck # 类型检查
@@ -73,16 +82,18 @@ npm run build:lib # 构建库 → dist/(ESM + CJS + .d.ts)
73
82
  项目结构:
74
83
 
75
84
  ```
76
- package/
85
+ lumina/
77
86
  ├── src/
78
- │ ├── components/ # 所有 .tsx 组件源码
87
+ │ ├── components/ # 每个组件一个目录,包含 .tsx / .css / index.ts
79
88
  │ ├── styles/
80
89
  │ │ ├── tokens.css # 设计令牌(主题 / 颜色 / 阴影 / 间距)
81
90
  │ │ ├── base.css # 基础样式(body / scrollbar / focus)
82
- │ │ └── components/ # 每个组件对应一个 .css 文件
91
+ │ │ ├── shared.css # 共享动画 / 跨组件样式
92
+ │ │ └── index.css # 完整样式入口
83
93
  │ └── index.ts # 公共出口
84
94
  ├── playground/ # 本地演示应用(Vite)
85
95
  ├── docs/ # 组件文档 & API 文档
96
+ ├── scripts/ # 文档生成 / 公开 API 校验脚本
86
97
  ├── tsup.config.ts # 库构建配置
87
98
  └── vite.config.ts # Playground 开发服务器
88
99
  ```
@@ -112,7 +123,7 @@ package/
112
123
 
113
124
  ## 📚 文档
114
125
 
115
- - **[🤖 AI / LLM 组件参考(索引)](./docs/llms.md)** — 全局约定 + 39 个组件的链接
126
+ - **[🤖 AI / LLM 组件参考(索引)](./docs/llms.md)** — 全局约定 + 完整组件索引
116
127
  - **[单组件文档](./docs/llms/)** — 每个组件一份 `.md`,AI 按需读取(例如 [`llms/button.md`](./docs/llms/button.md))
117
128
  - [设计令牌](./docs/tokens.md)
118
129
  - [Electron 集成](./docs/electron.md)
@@ -66,8 +66,10 @@
66
66
  border-radius: var(--r-md);
67
67
  display: grid;
68
68
  place-items: center;
69
- background: color-mix(in oklch, var(--bg) 82%, transparent);
70
- box-shadow: var(--neu-shadow-inset);
69
+ background: color-mix(in srgb, var(--bg) 72%, var(--bg-sunken));
70
+ box-shadow:
71
+ inset calc(var(--shadow-inset-offset) * 0.45) calc(var(--shadow-inset-offset) * 0.45) calc(var(--shadow-inset-blur) * 0.45) color-mix(in oklch, var(--shadow-dark) 55%, transparent),
72
+ inset calc(var(--shadow-inset-offset) * -0.45) calc(var(--shadow-inset-offset) * -0.45) calc(var(--shadow-inset-blur) * 0.45) color-mix(in oklch, var(--shadow-light) 72%, transparent);
71
73
  color: var(--fg-muted);
72
74
  z-index: 1;
73
75
  }
package/dist/Card.cjs CHANGED
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
 
3
- var chunkTDYJ5ECR_cjs = require('./chunk-TDYJ5ECR.cjs');
3
+ var chunkOUSJMIZX_cjs = require('./chunk-OUSJMIZX.cjs');
4
4
  require('./chunk-MZCKPLHQ.cjs');
5
5
 
6
6
 
7
7
 
8
8
  Object.defineProperty(exports, "Card", {
9
9
  enumerable: true,
10
- get: function () { return chunkTDYJ5ECR_cjs.Card; }
10
+ get: function () { return chunkOUSJMIZX_cjs.Card; }
11
11
  });
package/dist/Card.js CHANGED
@@ -1,2 +1,2 @@
1
- export { Card } from './chunk-BKI7JY4Z.js';
1
+ export { Card } from './chunk-HEBBQZUT.js';
2
2
  import './chunk-3GJZRYTD.js';
@@ -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,7 +1,7 @@
1
1
  import { Spin } from './chunk-3GJZRYTD.js';
2
2
  import './tokens-RGFJKRC7.css';
3
3
  import './shared-NJHRNLRH.css';
4
- import './Card-M6UMBDD2.css';
4
+ import './Card-4DKCXWFU.css';
5
5
  import * as React from 'react';
6
6
  import { jsxs, jsx } from 'react/jsx-runtime';
7
7
 
@@ -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
 
@@ -3,7 +3,7 @@
3
3
  var chunkMZCKPLHQ_cjs = require('./chunk-MZCKPLHQ.cjs');
4
4
  require('./tokens-RGFJKRC7.css');
5
5
  require('./shared-NJHRNLRH.css');
6
- require('./Card-M6UMBDD2.css');
6
+ require('./Card-4DKCXWFU.css');
7
7
  var React = require('react');
8
8
  var jsxRuntime = require('react/jsx-runtime');
9
9
 
@@ -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');
@@ -29,7 +29,7 @@ var chunkN4JH6HHA_cjs = require('./chunk-N4JH6HHA.cjs');
29
29
  var chunk3NSBPQBT_cjs = require('./chunk-3NSBPQBT.cjs');
30
30
  var chunkPEFIXNAV_cjs = require('./chunk-PEFIXNAV.cjs');
31
31
  var chunk4N64ZL5M_cjs = require('./chunk-4N64ZL5M.cjs');
32
- var chunkTDYJ5ECR_cjs = require('./chunk-TDYJ5ECR.cjs');
32
+ var chunkOUSJMIZX_cjs = require('./chunk-OUSJMIZX.cjs');
33
33
  var chunkMZCKPLHQ_cjs = require('./chunk-MZCKPLHQ.cjs');
34
34
  var chunkAA2FRQUQ_cjs = require('./chunk-AA2FRQUQ.cjs');
35
35
  var chunk5KGGB3EH_cjs = require('./chunk-5KGGB3EH.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.8";
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,
@@ -271,7 +271,7 @@ Object.defineProperty(exports, "List", {
271
271
  });
272
272
  Object.defineProperty(exports, "Card", {
273
273
  enumerable: true,
274
- get: function () { return chunkTDYJ5ECR_cjs.Card; }
274
+ get: function () { return chunkOUSJMIZX_cjs.Card; }
275
275
  });
276
276
  Object.defineProperty(exports, "Spin", {
277
277
  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.8";
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.8";
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';
@@ -27,7 +27,7 @@ export { Form, FormItem, useForm } from './chunk-ACZA7HHP.js';
27
27
  export { Image, ImageGrid, LayeredImage, SpriteImage } from './chunk-GEANNF4T.js';
28
28
  export { InputNumber } from './chunk-3VXBSLPT.js';
29
29
  export { List } from './chunk-Q77BWQNG.js';
30
- export { Card } from './chunk-BKI7JY4Z.js';
30
+ export { Card } from './chunk-HEBBQZUT.js';
31
31
  export { Spin } from './chunk-3GJZRYTD.js';
32
32
  export { Cascader } from './chunk-FPII6I52.js';
33
33
  export { Checkbox } from './chunk-PHONNUK2.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.8";
52
+ var VERSION = "0.6.10";
53
53
 
54
54
  export { VERSION };
package/dist/styles.css CHANGED
@@ -1199,8 +1199,10 @@ input, textarea, select { font-family: inherit; color: inherit; }
1199
1199
  border-radius: var(--r-md);
1200
1200
  display: grid;
1201
1201
  place-items: center;
1202
- background: color-mix(in oklch, var(--bg) 82%, transparent);
1203
- box-shadow: var(--neu-shadow-inset);
1202
+ background: color-mix(in srgb, var(--bg) 72%, var(--bg-sunken));
1203
+ box-shadow:
1204
+ inset calc(var(--shadow-inset-offset) * 0.45) calc(var(--shadow-inset-offset) * 0.45) calc(var(--shadow-inset-blur) * 0.45) color-mix(in oklch, var(--shadow-dark) 55%, transparent),
1205
+ inset calc(var(--shadow-inset-offset) * -0.45) calc(var(--shadow-inset-offset) * -0.45) calc(var(--shadow-inset-blur) * 0.45) color-mix(in oklch, var(--shadow-light) 72%, transparent);
1204
1206
  color: var(--fg-muted);
1205
1207
  z-index: 1;
1206
1208
  }
@@ -2091,11 +2093,27 @@ input, textarea, select { font-family: inherit; color: inherit; }
2091
2093
  /* Card-row variant: each row is its own raised pill */
2092
2094
  .table.cards {
2093
2095
  border-collapse: separate;
2094
- border-spacing: 0 10px;
2095
- padding: 10px;
2096
+ border-spacing: 0 14px;
2097
+ padding: 12px;
2096
2098
  background: transparent;
2097
2099
  box-shadow: none;
2098
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
+ }
2099
2117
  .table.cards thead th {
2100
2118
  background: transparent;
2101
2119
  border-bottom: none;
@@ -2103,22 +2121,24 @@ input, textarea, select { font-family: inherit; color: inherit; }
2103
2121
  padding-bottom: 6px;
2104
2122
  }
2105
2123
  .table.cards tbody td {
2106
- background: var(--bg);
2124
+ position: relative;
2125
+ z-index: 1;
2126
+ background: transparent;
2107
2127
  border-bottom: none;
2108
2128
  padding: 14px 18px;
2129
+ box-shadow: none;
2109
2130
  }
2110
2131
  .table.cards tbody td:first-child {
2111
2132
  border-radius: var(--r-md) 0 0 var(--r-md);
2112
- box-shadow: -4px 4px 8px var(--shadow-dark), -4px -4px 8px var(--shadow-light);
2113
2133
  }
2114
2134
  .table.cards tbody td:last-child {
2115
2135
  border-radius: 0 var(--r-md) var(--r-md) 0;
2116
- box-shadow: 4px 4px 8px var(--shadow-dark), 4px -4px 8px var(--shadow-light);
2117
2136
  }
2118
- .table.cards tbody td:not(:first-child):not(:last-child) {
2119
- 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);
2120
2139
  }
2121
- .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; }
2122
2142
  .table .row-check { width: 44px; }
2123
2143
  .table .row-check .checkbox { display: inline-flex; }
2124
2144
  .table .row-expand { width: 40px; text-align: center; }
@@ -2268,7 +2288,7 @@ input, textarea, select { font-family: inherit; color: inherit; }
2268
2288
  margin-top: 0;
2269
2289
  padding: 6px 16px;
2270
2290
  border-top: 1px solid var(--divider);
2271
- background: color-mix(in oklch, var(--bg-sunken) 30%, transparent);
2291
+ background: transparent;
2272
2292
  }
2273
2293
  .table-toolbar {
2274
2294
  display: flex;
@@ -2298,7 +2318,7 @@ input, textarea, select { font-family: inherit; color: inherit; }
2298
2318
  .table-footer {
2299
2319
  padding: 10px 16px;
2300
2320
  border-top: 1px solid var(--divider);
2301
- background: color-mix(in oklch, var(--bg-sunken) 30%, transparent);
2321
+ background: transparent;
2302
2322
  }
2303
2323
  /* ============ Pagination ============ */
2304
2324
  .pagination {
package/docs/llms/card.md CHANGED
@@ -61,10 +61,10 @@ bodyLayout 控制正文槽布局,bodyClassName / bodyStyle / bodyProps 直接
61
61
 
62
62
  ### 加载覆盖
63
63
 
64
- loading 会在正文区域显示内建 overlay;loadingOverlay 可替换默认 Spin。
64
+ loading 会在正文区域显示中性 overlay;默认 Spin 跟随主题色,loadingOverlay 可替换内容。
65
65
 
66
66
  ```tsx
67
- <Card loading loadingOverlay="正在同步...">
67
+ <Card loading>
68
68
  ...
69
69
  </Card>
70
70
  ```
@@ -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.8`
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.8",
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",