@rockshin/tao-ui 0.0.6 → 0.0.8

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.
@@ -1,8 +1,24 @@
1
1
  [data-tao-select] {
2
- align-items: center;
2
+ --tao-select-height: var(--tao-control-height);
3
+ --tao-select-font-size: var(--tao-font-size-base);
4
+ --tao-select-line-height: var(--tao-line-height);
5
+ --tao-select-padding-inline: var(--tao-padding-sm);
6
+ --tao-select-padding-block: calc((
7
+ var(--tao-select-height) -
8
+ var(--tao-select-font-size) *
9
+ var(--tao-select-line-height)
10
+ ) /
11
+ 2 -
12
+ var(--tao-line-width));
13
+ align-items: flex-start;
3
14
  gap: var(--tao-padding-xs);
4
15
  width: 100%;
5
16
  font-family: var(--tao-font-family);
17
+ font-size: var(--tao-select-font-size);
18
+ line-height: var(--tao-select-line-height);
19
+ height: var(--tao-select-height);
20
+ padding-block: max(var(--tao-select-padding-block), 0px);
21
+ padding-inline: var(--tao-select-padding-inline);
6
22
  cursor: pointer;
7
23
  outline: none;
8
24
  display: flex;
@@ -18,39 +34,44 @@ button[data-tao-select] {
18
34
  white-space: nowrap;
19
35
  min-width: 0;
20
36
  color: var(--tao-color-text);
37
+ line-height: var(--tao-select-line-height);
21
38
  flex: 1;
39
+ align-self: center;
40
+ display: block;
22
41
  overflow: hidden;
23
42
  }
24
43
 
25
44
  [data-tao-select-placeholder] {
26
45
  color: var(--tao-color-text-placeholder);
46
+ line-height: var(--tao-select-line-height);
27
47
  }
28
48
 
29
49
  [data-tao-select][data-tao-size="small"] {
30
- height: var(--tao-control-height-sm);
31
- padding-inline: var(--tao-padding-xs);
32
- font-size: var(--tao-font-size-sm);
50
+ --tao-select-height: var(--tao-control-height-sm);
51
+ --tao-select-font-size: var(--tao-font-size-sm);
52
+ --tao-select-line-height: var(--tao-line-height-sm);
53
+ --tao-select-padding-inline: var(--tao-padding-xs);
33
54
  border-radius: var(--tao-radius-sm);
34
55
  }
35
56
 
36
57
  [data-tao-select][data-tao-size="medium"] {
37
- height: var(--tao-control-height);
38
- padding-inline: var(--tao-padding-sm);
39
- font-size: var(--tao-font-size-base);
40
58
  border-radius: var(--tao-radius-md);
41
59
  }
42
60
 
43
61
  [data-tao-select][data-tao-size="large"] {
44
- height: var(--tao-control-height-lg);
45
- padding-inline: var(--tao-padding-sm);
46
- font-size: var(--tao-font-size-lg);
62
+ --tao-select-height: var(--tao-control-height-lg);
63
+ --tao-select-font-size: var(--tao-font-size-lg);
64
+ --tao-select-line-height: var(--tao-line-height-lg);
47
65
  border-radius: var(--tao-radius-md);
48
66
  }
49
67
 
50
68
  [data-tao-select-prefix] {
51
69
  color: var(--tao-color-text-tertiary);
52
70
  flex-shrink: 0;
71
+ justify-content: center;
72
+ align-self: center;
53
73
  align-items: center;
74
+ line-height: 0;
54
75
  display: flex;
55
76
  }
56
77
 
@@ -58,6 +79,7 @@ button[data-tao-select] {
58
79
  border-radius: var(--tao-radius-sm);
59
80
  flex: none;
60
81
  justify-content: center;
82
+ align-self: center;
61
83
  align-items: center;
62
84
  width: 1.25rem;
63
85
  height: 1.25rem;
@@ -73,9 +95,12 @@ button[data-tao-select] {
73
95
 
74
96
  [data-tao-select-icons] {
75
97
  flex-shrink: 0;
98
+ justify-content: center;
99
+ align-self: center;
76
100
  align-items: center;
77
101
  gap: 4px;
78
102
  margin-inline-start: auto;
103
+ line-height: 0;
79
104
  display: flex;
80
105
  position: relative;
81
106
  }
@@ -167,14 +192,17 @@ button[data-tao-select] {
167
192
  [data-tao-select-search] {
168
193
  align-items: center;
169
194
  gap: var(--tao-padding-xs);
195
+ min-height: var(--tao-control-height);
170
196
  padding: var(--tao-padding-xs) var(--tao-padding-sm);
171
197
  border-block-end: var(--tao-line-width) solid
172
198
  var(--tao-color-border-secondary);
173
199
  color: var(--tao-color-text-tertiary);
200
+ line-height: 1;
174
201
  display: flex;
175
202
  }
176
203
 
177
204
  [data-tao-select-search-input] {
205
+ height: calc(var(--tao-control-height) - var(--tao-padding-xs) * 2);
178
206
  font-family: var(--tao-font-family);
179
207
  font-size: var(--tao-font-size-base);
180
208
  color: var(--tao-color-text);
@@ -183,6 +211,7 @@ button[data-tao-select] {
183
211
  outline: none;
184
212
  flex: 1;
185
213
  min-width: 0;
214
+ line-height: 1;
186
215
  }
187
216
 
188
217
  [data-tao-select-search-input]::placeholder {
@@ -221,6 +250,7 @@ button[data-tao-select] {
221
250
  var(--tao-motion-ease-out);
222
251
  outline: none;
223
252
  align-items: center;
253
+ line-height: 1;
224
254
  display: flex;
225
255
  }
226
256
 
@@ -265,7 +295,9 @@ button[data-tao-select] {
265
295
  [data-tao-select-item-main] {
266
296
  flex-direction: column;
267
297
  flex: 1;
298
+ justify-content: center;
268
299
  min-width: 0;
300
+ line-height: 1;
269
301
  display: flex;
270
302
  }
271
303
 
@@ -95,8 +95,7 @@ function Select(props) {
95
95
  isSearchControlled,
96
96
  onSearch
97
97
  ]);
98
- const handleClear = useCallback((e)=>{
99
- e.stopPropagation();
98
+ const clearValue = useCallback(()=>{
100
99
  if (!isValueControlled) setValueInternal(void 0);
101
100
  onChange?.('', void 0);
102
101
  onClear?.();
@@ -105,6 +104,12 @@ function Select(props) {
105
104
  onChange,
106
105
  onClear
107
106
  ]);
107
+ const handleClear = useCallback((e)=>{
108
+ e.stopPropagation();
109
+ clearValue();
110
+ }, [
111
+ clearValue
112
+ ]);
108
113
  const filteredOptions = useMemo(()=>{
109
114
  if (!showSearch || !search) return options;
110
115
  const fn = filterOption ?? defaultFilter;
@@ -141,7 +146,15 @@ function Select(props) {
141
146
  style: styles?.clear,
142
147
  onPointerDown: (e_0)=>e_0.stopPropagation(),
143
148
  onClick: handleClear,
149
+ onKeyDown: (e_1)=>{
150
+ if ('Enter' === e_1.key || ' ' === e_1.key) {
151
+ e_1.preventDefault();
152
+ e_1.stopPropagation();
153
+ clearValue();
154
+ }
155
+ },
144
156
  role: "button",
157
+ tabIndex: 0,
145
158
  "aria-label": "Clear",
146
159
  children: clearIcon
147
160
  }) : /*#__PURE__*/ jsx("span", {
@@ -293,7 +306,7 @@ function Select(props) {
293
306
  /*#__PURE__*/ jsx("input", {
294
307
  "data-tao-select-search-input": "",
295
308
  value: search,
296
- onChange: (e_1)=>handleSearchChange(e_1.target.value),
309
+ onChange: (e_2)=>handleSearchChange(e_2.target.value),
297
310
  placeholder: "Search...",
298
311
  autoFocus: true
299
312
  })
@@ -389,6 +402,8 @@ function ChevronDownIcon() {
389
402
  strokeWidth: "2",
390
403
  strokeLinecap: "round",
391
404
  strokeLinejoin: "round",
405
+ "aria-hidden": "true",
406
+ role: "presentation",
392
407
  children: /*#__PURE__*/ jsx("path", {
393
408
  d: "m6 9 6 6 6-6"
394
409
  })
@@ -432,6 +447,8 @@ function CheckIcon() {
432
447
  strokeWidth: "2.5",
433
448
  strokeLinecap: "round",
434
449
  strokeLinejoin: "round",
450
+ "aria-hidden": "true",
451
+ role: "presentation",
435
452
  children: /*#__PURE__*/ jsx("polyline", {
436
453
  points: "20 6 9 17 4 12"
437
454
  })
@@ -453,6 +470,8 @@ function CloseIcon() {
453
470
  strokeWidth: "2",
454
471
  strokeLinecap: "round",
455
472
  strokeLinejoin: "round",
473
+ "aria-hidden": "true",
474
+ role: "presentation",
456
475
  children: /*#__PURE__*/ jsx("path", {
457
476
  d: "M18 6 6 18M6 6l12 12"
458
477
  })
@@ -474,6 +493,8 @@ function SearchIcon() {
474
493
  strokeWidth: "2",
475
494
  strokeLinecap: "round",
476
495
  strokeLinejoin: "round",
496
+ "aria-hidden": "true",
497
+ role: "presentation",
477
498
  children: [
478
499
  /*#__PURE__*/ jsx("circle", {
479
500
  cx: "11",
@@ -503,6 +524,8 @@ function LoadingIcon() {
503
524
  strokeWidth: "2",
504
525
  strokeLinecap: "round",
505
526
  strokeLinejoin: "round",
527
+ "aria-hidden": "true",
528
+ role: "presentation",
506
529
  children: /*#__PURE__*/ jsx("path", {
507
530
  d: "M21 12a9 9 0 1 1-6.219-8.56"
508
531
  })
@@ -4,19 +4,42 @@
4
4
  --tao-table-cell-bg: transparent;
5
5
  --tao-table-header-bg: transparent;
6
6
  --tao-table-header-color: var(--tao-color-text-secondary);
7
- --tao-table-row-hover-bg: oklch(0% 0 0 / .02);
7
+ --tao-table-row-hover-bg: #fafafa;
8
8
  --tao-table-row-selected-bg: oklch(0% 0 0 / .05);
9
9
  --tao-table-row-selected-hover-bg: oklch(0% 0 0 / .07);
10
+ --tao-table-border-color: var(--tao-color-border-secondary);
11
+ --tao-table-frame-radius: var(--tao-radius-md);
12
+ --tao-table-cell-padding-block: var(--tao-padding-sm);
13
+ --tao-table-cell-padding-inline: var(--tao-padding);
14
+ --tao-table-cell-font-size: var(--tao-font-size-base);
15
+ --tao-table-cell-line-height: var(--tao-line-height);
16
+ --tao-table-header-cell-padding-block: var(--tao-table-cell-padding-block);
17
+ --tao-table-header-cell-padding-inline: var(--tao-table-cell-padding-inline);
18
+ --tao-table-header-font-size: var(--tao-table-cell-font-size);
19
+ --tao-table-header-font-weight: var(--tao-font-weight-medium);
20
+ --tao-table-header-letter-spacing: normal;
21
+ --tao-table-header-text-transform: none;
22
+ --tao-table-empty-padding-block: var(--tao-padding-xl);
23
+ --tao-table-empty-padding-inline: var(--tao-padding);
24
+ --tao-table-empty-color: var(--tao-color-text-tertiary);
10
25
  position: relative;
11
26
  }
12
27
 
13
28
  [data-tao-table-wrapper][data-tao-variant="filled"], [data-tao-table-wrapper][data-tao-variant="outlined"] {
14
29
  --tao-table-header-bg: oklch(98.5% 0 0);
15
- --tao-table-row-hover-bg: oklch(98.5% 0 0);
16
30
  --tao-table-row-selected-bg: var(--tao-primary-bg);
17
31
  --tao-table-row-selected-hover-bg: var(--tao-primary-bg-hover);
18
32
  }
19
33
 
34
+ [data-tao-table-wrapper][data-tao-variant="modern"] {
35
+ --tao-table-header-bg: var(--tao-color-bg-container);
36
+ --tao-table-header-color: var(--tao-color-text-secondary);
37
+ --tao-table-row-selected-bg: var(--tao-primary-bg);
38
+ --tao-table-row-selected-hover-bg: var(--tao-primary-bg-hover);
39
+ --tao-table-border-color: var(--tao-color-border);
40
+ --tao-table-frame-radius: var(--tao-radius-md);
41
+ }
42
+
20
43
  [data-tao-table-wrapper][data-tao-header-bg="off"] {
21
44
  --tao-table-header-bg: transparent;
22
45
  }
@@ -26,6 +49,12 @@
26
49
  overflow-x: auto;
27
50
  }
28
51
 
52
+ [data-tao-table-wrapper][data-tao-variant="modern"] [data-tao-table-scroll] {
53
+ border: var(--tao-line-width) solid var(--tao-table-border-color);
54
+ border-radius: var(--tao-table-frame-radius);
55
+ background: var(--tao-color-bg-container);
56
+ }
57
+
29
58
  [data-tao-table] {
30
59
  border-collapse: collapse;
31
60
  table-layout: auto;
@@ -37,9 +66,12 @@
37
66
  }
38
67
 
39
68
  [data-tao-table-cell] {
40
- padding: var(--tao-padding-sm) var(--tao-padding);
69
+ padding: var(--tao-table-cell-padding-block)
70
+ var(--tao-table-cell-padding-inline);
71
+ font-size: var(--tao-table-cell-font-size);
72
+ line-height: var(--tao-table-cell-line-height);
41
73
  text-align: left;
42
- border-bottom: var(--tao-line-width) solid var(--tao-color-border-secondary);
74
+ border-bottom: var(--tao-line-width) solid var(--tao-table-border-color);
43
75
  background: var(--tao-table-cell-bg);
44
76
  transition: background-color var(--tao-motion-duration-fast)
45
77
  var(--tao-motion-ease-out);
@@ -60,18 +92,35 @@
60
92
  }
61
93
 
62
94
  [data-tao-table-thead] [data-tao-table-cell] {
63
- font-weight: var(--tao-font-weight-medium);
95
+ padding: var(--tao-table-header-cell-padding-block)
96
+ var(--tao-table-header-cell-padding-inline);
97
+ font-size: var(--tao-table-header-font-size);
98
+ font-weight: var(--tao-table-header-font-weight);
99
+ letter-spacing: var(--tao-table-header-letter-spacing);
100
+ text-transform: var(--tao-table-header-text-transform);
64
101
  color: var(--tao-table-header-color);
65
102
  background: var(--tao-table-header-bg);
66
103
  white-space: nowrap;
67
104
  }
68
105
 
106
+ [data-tao-table-wrapper][data-tao-variant="modern"] [data-tao-table-thead] [data-tao-table-cell] {
107
+ --tao-table-header-font-size: var(--tao-font-size-sm);
108
+ }
109
+
69
110
  [data-tao-table-header-content] {
70
111
  align-items: center;
71
112
  gap: var(--tao-padding-xxs);
72
113
  display: flex;
73
114
  }
74
115
 
116
+ [data-tao-table-cell][data-tao-align="center"] [data-tao-table-header-content] {
117
+ justify-content: center;
118
+ }
119
+
120
+ [data-tao-table-cell][data-tao-align="right"] [data-tao-table-header-content] {
121
+ justify-content: flex-end;
122
+ }
123
+
75
124
  [data-tao-table-header-title] {
76
125
  align-items: center;
77
126
  gap: 2px;
@@ -248,8 +297,9 @@
248
297
 
249
298
  [data-tao-table-empty] {
250
299
  text-align: center;
251
- padding: var(--tao-padding-xl) var(--tao-padding);
252
- color: var(--tao-color-text-tertiary);
300
+ padding: var(--tao-table-empty-padding-block)
301
+ var(--tao-table-empty-padding-inline);
302
+ color: var(--tao-table-empty-color);
253
303
  }
254
304
 
255
305
  [data-tao-table-loading] {
@@ -277,31 +327,46 @@
277
327
  }
278
328
 
279
329
  [data-tao-table-wrapper][data-tao-bordered] [data-tao-table] {
280
- border: var(--tao-line-width) solid var(--tao-color-border-secondary);
281
- border-radius: var(--tao-radius-md);
330
+ border: var(--tao-line-width) solid var(--tao-table-border-color);
331
+ border-radius: var(--tao-table-frame-radius);
282
332
  }
283
333
 
284
334
  [data-tao-table-wrapper][data-tao-bordered] [data-tao-table-cell] {
285
- border-right: var(--tao-line-width) solid var(--tao-color-border-secondary);
335
+ border-right: var(--tao-line-width) solid var(--tao-table-border-color);
286
336
  }
287
337
 
288
338
  [data-tao-table-wrapper][data-tao-bordered] tr > [data-tao-table-cell]:last-child {
289
339
  border-right: none;
290
340
  }
291
341
 
342
+ [data-tao-table-wrapper][data-tao-variant="modern"][data-tao-bordered] [data-tao-table] {
343
+ border: none;
344
+ }
345
+
346
+ [data-tao-table-wrapper][data-tao-variant="modern"][data-tao-bordered] [data-tao-table-cell] {
347
+ border-right: none;
348
+ }
349
+
350
+ [data-tao-table-wrapper][data-tao-variant="modern"] [data-tao-table-tbody] tr:last-child [data-tao-table-cell] {
351
+ border-bottom: none;
352
+ }
353
+
292
354
  [data-tao-table-wrapper][data-tao-size="small"] [data-tao-table-cell] {
293
- padding: var(--tao-padding-xxs) var(--tao-padding-xs);
294
- font-size: var(--tao-font-size-sm);
355
+ --tao-table-cell-padding-block: var(--tao-padding-xxs);
356
+ --tao-table-cell-padding-inline: var(--tao-padding-xs);
357
+ --tao-table-cell-font-size: var(--tao-font-size-sm);
295
358
  }
296
359
 
297
360
  [data-tao-table-wrapper][data-tao-size="medium"] [data-tao-table-cell] {
298
- padding: var(--tao-padding-sm) var(--tao-padding);
299
- font-size: var(--tao-font-size-base);
361
+ --tao-table-cell-padding-block: var(--tao-padding-sm);
362
+ --tao-table-cell-padding-inline: var(--tao-padding);
363
+ --tao-table-cell-font-size: var(--tao-font-size-base);
300
364
  }
301
365
 
302
366
  [data-tao-table-wrapper][data-tao-size="large"] [data-tao-table-cell] {
303
- padding: var(--tao-padding) var(--tao-padding-md);
304
- font-size: var(--tao-font-size-base);
367
+ --tao-table-cell-padding-block: var(--tao-padding);
368
+ --tao-table-cell-padding-inline: var(--tao-padding-md);
369
+ --tao-table-cell-font-size: var(--tao-font-size-base);
305
370
  }
306
371
 
307
372
  [data-tao-table-pagination] {
@@ -1,8 +1,9 @@
1
- import { type ReactNode } from 'react';
1
+ import { type CSSProperties, type HTMLAttributes, type ReactNode, type TdHTMLAttributes, type ThHTMLAttributes } from 'react';
2
2
  import { type TaoSize, type TaoVariant } from '../../provider/tao-provider';
3
3
  import { type SemanticClassNames, type SemanticStyles } from '../../utils/semantic';
4
4
  import './table.css';
5
- export type TableSemanticPart = 'root' | 'header.cell' | 'body.row' | 'body.cell' | 'pagination';
5
+ export type TableSemanticPart = 'root' | 'scroll' | 'table' | 'header.wrapper' | 'header.row' | 'header.cell' | 'header.content' | 'header.title' | 'body.row' | 'body.cell' | 'selection.cell' | 'empty' | 'pagination';
6
+ export type TableVariant = TaoVariant | 'modern';
6
7
  export type SortOrder = 'ascend' | 'descend' | null;
7
8
  export interface TableFilterItem {
8
9
  text: ReactNode;
@@ -17,6 +18,8 @@ export interface TableColumn<T = any> {
17
18
  align?: 'left' | 'center' | 'right';
18
19
  fixed?: 'left' | 'right';
19
20
  ellipsis?: boolean;
21
+ onCell?: (record: T, index: number) => TdHTMLAttributes<HTMLTableCellElement>;
22
+ onHeaderCell?: (column: TableColumn<T>) => ThHTMLAttributes<HTMLTableCellElement>;
20
23
  sorter?: ((a: T, b: T) => number) | boolean;
21
24
  sortOrder?: SortOrder;
22
25
  defaultSortOrder?: SortOrder;
@@ -49,6 +52,11 @@ export interface SorterResult<T = any> {
49
52
  order: SortOrder;
50
53
  field?: string;
51
54
  }
55
+ export type TableSemanticInfo<T = any> = {
56
+ props: TableProps<T>;
57
+ };
58
+ export type TableSemanticClassNames<T = any> = SemanticClassNames<TableSemanticPart> | ((info: TableSemanticInfo<T>) => SemanticClassNames<TableSemanticPart>);
59
+ export type TableSemanticStyles<T = any> = SemanticStyles<TableSemanticPart> | ((info: TableSemanticInfo<T>) => SemanticStyles<TableSemanticPart>);
52
60
  export interface TableProps<T = any> {
53
61
  columns: TableColumn<T>[];
54
62
  dataSource: T[];
@@ -63,17 +71,22 @@ export interface TableProps<T = any> {
63
71
  x?: number | string;
64
72
  };
65
73
  rowSelection?: TableRowSelection<T>;
74
+ rowClassName?: string | ((record: T, index: number) => string);
75
+ rowStyle?: CSSProperties | ((record: T, index: number) => CSSProperties);
76
+ onRow?: (record: T, index: number) => HTMLAttributes<HTMLTableRowElement>;
77
+ onHeaderRow?: (columns: TableColumn<T>[], index: number) => HTMLAttributes<HTMLTableRowElement>;
66
78
  size?: TaoSize;
67
79
  /**
68
80
  * 表面风格。
69
81
  * - `borderless`(极简):无表头底色、单元格透明、仅行底分隔线。
70
- * - `filled`:表头灰底(库的默认表现)。
82
+ * - `filled`:表头灰底。
71
83
  * - `outlined`:filled + 整体外框 + 列分隔线。
84
+ * - `modern`:轻外框、圆角、克制表头,更接近 shadcn 的表格视觉。
72
85
  *
73
86
  * 不传时继承 TaoProvider 的 variant;当继承到框架默认 `outlined` 时,
74
- * Table 回落为 `filled` 以保持向后兼容(裸用 `<Table>` 仍是灰底表头)。
87
+ * Table 回落为 `modern`,让裸用 `<Table>` 默认呈现现代轻外框风格。
75
88
  */
76
- variant?: TaoVariant;
89
+ variant?: TableVariant;
77
90
  /**
78
91
  * 表头灰底开关,默认 `true`。设为 `false` 关掉表头底色(极简表头),
79
92
  * 不影响外框 / 列分隔线等其它 variant 表现。
@@ -82,7 +95,8 @@ export interface TableProps<T = any> {
82
95
  emptyText?: ReactNode;
83
96
  bordered?: boolean;
84
97
  className?: string;
85
- classNames?: SemanticClassNames<TableSemanticPart>;
86
- styles?: SemanticStyles<TableSemanticPart>;
98
+ style?: CSSProperties;
99
+ classNames?: TableSemanticClassNames<T>;
100
+ styles?: TableSemanticStyles<T>;
87
101
  }
88
- export declare function Table<T = any>({ columns, dataSource, rowKey, loading, pagination: paginationProp, onChange, scroll, rowSelection, size, variant, headerBackground, emptyText, bordered, className, classNames, styles, }: TableProps<T>): import("react/jsx-runtime").JSX.Element;
102
+ export declare function Table<T = any>({ columns, dataSource, rowKey, loading, pagination: paginationProp, onChange, scroll, rowSelection, size, variant, headerBackground, emptyText, bordered, className, style, classNames, styles, rowClassName, rowStyle, onRow, onHeaderRow, }: TableProps<T>): import("react/jsx-runtime").JSX.Element;