@rockshin/tao-ui 0.0.2 → 0.0.3

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 (49) hide show
  1. package/dist/components/breadcrumb/breadcrumb.css +3 -0
  2. package/dist/components/button/button.css +3 -0
  3. package/dist/components/checkbox/checkbox.css +3 -0
  4. package/dist/components/collapsible/collapsible.css +3 -0
  5. package/dist/components/context-menu/context-menu.css +4 -1
  6. package/dist/components/context-menu/context-menu.js +10 -8
  7. package/dist/components/date-picker/calendar/month-grid.d.ts +1 -1
  8. package/dist/components/date-picker/calendar/time-panel.d.ts +1 -1
  9. package/dist/components/date-picker/calendar/year-grid.d.ts +1 -1
  10. package/dist/components/date-picker/date-picker.css +43 -1
  11. package/dist/components/date-picker/date-picker.js +9 -7
  12. package/dist/components/date-picker/range-picker.js +9 -7
  13. package/dist/components/drawer/drawer.css +5 -2
  14. package/dist/components/drawer/drawer.js +27 -18
  15. package/dist/components/dropdown/dropdown.css +3 -0
  16. package/dist/components/dropdown/dropdown.js +17 -15
  17. package/dist/components/form-field/form.css +3 -0
  18. package/dist/components/input/input.css +42 -0
  19. package/dist/components/menu/menu-render.js +11 -8
  20. package/dist/components/menu/menu.css +4 -1
  21. package/dist/components/modal/modal.css +5 -2
  22. package/dist/components/modal/modal.js +27 -18
  23. package/dist/components/pagination/pagination.css +3 -0
  24. package/dist/components/pagination/pagination.js +3 -1
  25. package/dist/components/radio/radio.css +3 -0
  26. package/dist/components/scroll-area/scroll-area.css +3 -0
  27. package/dist/components/select/mobile-select.css +10 -0
  28. package/dist/components/select/mobile-select.d.ts +4 -1
  29. package/dist/components/select/mobile-select.js +103 -121
  30. package/dist/components/select/select.css +65 -11
  31. package/dist/components/select/select.d.ts +58 -4
  32. package/dist/components/select/select.js +356 -410
  33. package/dist/components/spinner/spinner.css +1084 -0
  34. package/dist/components/spinner/spinner.d.ts +26 -0
  35. package/dist/components/spinner/spinner.js +229 -0
  36. package/dist/components/splitter/splitter.css +3 -0
  37. package/dist/components/switch/switch.css +3 -0
  38. package/dist/components/table/table.css +3 -0
  39. package/dist/components/tabs/tabs.css +3 -0
  40. package/dist/components/tag/tag.css +3 -0
  41. package/dist/components/textarea/textarea.css +42 -0
  42. package/dist/index.d.ts +4 -3
  43. package/dist/index.js +4 -3
  44. package/dist/layouts/stack/layout.css +3 -0
  45. package/dist/provider/tao-provider.d.ts +17 -1
  46. package/dist/provider/tao-provider.js +53 -15
  47. package/dist/theme/control.css +42 -0
  48. package/dist/theme/theme.css +3 -0
  49. package/package.json +13 -13
@@ -314,6 +314,9 @@
314
314
  --tao-font-family: "Geist Sans", ui-sans-serif, system-ui, -apple-system, sans-serif;
315
315
  --tao-font-family-code: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
316
316
  --tao-motion-unit: .1s;
317
+ --tao-z-index-drawer: 1000;
318
+ --tao-z-index-modal: 1000;
319
+ --tao-z-index-popup: 1100;
317
320
  --tao-primary: var(--tao-color-primary);
318
321
  --tao-primary-hover: var(--tao-color-primary);
319
322
  }
@@ -253,7 +253,9 @@ function Pagination(t0) {
253
253
  let t26;
254
254
  if ($[52] !== goTo || $[53] !== pageSize || $[54] !== pageSizeOptions || $[55] !== resolvedDisabled || $[56] !== resolvedSize || $[57] !== showSizeChanger) {
255
255
  t26 = showSizeChanger && /*#__PURE__*/ jsx(Select, {
256
- "data-tao-pagination-sizer": "",
256
+ style: {
257
+ width: "auto"
258
+ },
257
259
  options: pageSizeOptions.map(_temp),
258
260
  value: String(pageSize),
259
261
  onChange: (val)=>{
@@ -314,6 +314,9 @@
314
314
  --tao-font-family: "Geist Sans", ui-sans-serif, system-ui, -apple-system, sans-serif;
315
315
  --tao-font-family-code: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
316
316
  --tao-motion-unit: .1s;
317
+ --tao-z-index-drawer: 1000;
318
+ --tao-z-index-modal: 1000;
319
+ --tao-z-index-popup: 1100;
317
320
  --tao-primary: var(--tao-color-primary);
318
321
  --tao-primary-hover: var(--tao-color-primary);
319
322
  }
@@ -314,6 +314,9 @@
314
314
  --tao-font-family: "Geist Sans", ui-sans-serif, system-ui, -apple-system, sans-serif;
315
315
  --tao-font-family-code: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
316
316
  --tao-motion-unit: .1s;
317
+ --tao-z-index-drawer: 1000;
318
+ --tao-z-index-modal: 1000;
319
+ --tao-z-index-popup: 1100;
317
320
  --tao-primary: var(--tao-color-primary);
318
321
  --tao-primary-hover: var(--tao-color-primary);
319
322
  }
@@ -314,6 +314,9 @@
314
314
  --tao-font-family: "Geist Sans", ui-sans-serif, system-ui, -apple-system, sans-serif;
315
315
  --tao-font-family-code: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
316
316
  --tao-motion-unit: .1s;
317
+ --tao-z-index-drawer: 1000;
318
+ --tao-z-index-modal: 1000;
319
+ --tao-z-index-popup: 1100;
317
320
  --tao-primary: var(--tao-color-primary);
318
321
  --tao-primary-hover: var(--tao-color-primary);
319
322
  }
@@ -831,6 +834,13 @@
831
834
  overflow-y: auto;
832
835
  }
833
836
 
837
+ [data-tao-sheet-group-label] {
838
+ padding: var(--tao-padding-sm) var(--tao-padding) var(--tao-padding-xxs);
839
+ font-size: var(--tao-font-size-sm);
840
+ font-weight: var(--tao-font-weight-medium);
841
+ color: var(--tao-color-text-tertiary);
842
+ }
843
+
834
844
  [data-tao-sheet-item] {
835
845
  min-height: 48px;
836
846
  padding-inline: var(--tao-padding);
@@ -9,9 +9,12 @@ interface MobileSelectContentProps {
9
9
  showSearch?: boolean;
10
10
  filterOption?: (input: string, option: SelectOption) => boolean;
11
11
  notFoundContent?: ReactNode;
12
+ optionRender?: (option: SelectOption, info: {
13
+ index: number;
14
+ }) => ReactNode;
12
15
  onClose: () => void;
13
16
  }
14
- export declare function MobileSelectContent({ options, value, onChange, showSearch, filterOption, notFoundContent, onClose, }: MobileSelectContentProps): import("react/jsx-runtime").JSX.Element;
17
+ export declare function MobileSelectContent({ options, value, onChange, showSearch, filterOption, notFoundContent, optionRender, onClose, }: MobileSelectContentProps): import("react/jsx-runtime").JSX.Element;
15
18
  export interface MobileSelectDrawerProps extends MobileSelectContentProps {
16
19
  open: boolean;
17
20
  }
@@ -1,140 +1,122 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
2
  import { c } from "react/compiler-runtime";
3
- import { useState } from "react";
3
+ import { useCallback, useMemo, useState } from "react";
4
4
  import { Drawer } from "../drawer/drawer.js";
5
5
  import "./mobile-select.css";
6
6
  const defaultFilter = (input, option)=>{
7
7
  const label = 'string' == typeof option.label ? option.label : String(option.label);
8
8
  return label.toLowerCase().includes(input.toLowerCase());
9
9
  };
10
- function MobileSelectContent(t0) {
11
- const $ = c(23);
12
- const { options, value, onChange, showSearch, filterOption, notFoundContent: t1, onClose } = t0;
13
- const notFoundContent = void 0 === t1 ? "No results" : t1;
14
- const [search, setSearch] = useState("");
15
- let t2;
16
- bb0: {
17
- if (!showSearch || !search) {
18
- t2 = options;
19
- break bb0;
20
- }
10
+ function filterTree(options, fn, input) {
11
+ const result = [];
12
+ for (const o of options)if (o.options) {
13
+ const kids = filterTree(o.options, fn, input);
14
+ if (kids.length) result.push({
15
+ ...o,
16
+ options: kids
17
+ });
18
+ } else if (fn(input, o)) result.push(o);
19
+ return result;
20
+ }
21
+ function countLeaves(options) {
22
+ return options.reduce((n, o)=>n + (o.options ? countLeaves(o.options) : 1), 0);
23
+ }
24
+ function MobileSelectContent({ options, value, onChange, showSearch, filterOption, notFoundContent = 'No results', optionRender, onClose }) {
25
+ const [search, setSearch] = useState('');
26
+ const filteredOptions = useMemo(()=>{
27
+ if (!showSearch || !search) return options;
21
28
  const fn = filterOption ?? defaultFilter;
22
- let t3;
23
- if ($[0] !== fn || $[1] !== options || $[2] !== search) {
24
- let t4;
25
- if ($[4] !== fn || $[5] !== search) {
26
- t4 = (o)=>fn(search, o);
27
- $[4] = fn;
28
- $[5] = search;
29
- $[6] = t4;
30
- } else t4 = $[6];
31
- t3 = options.filter(t4);
32
- $[0] = fn;
33
- $[1] = options;
34
- $[2] = search;
35
- $[3] = t3;
36
- } else t3 = $[3];
37
- t2 = t3;
38
- }
39
- const filteredOptions = t2;
40
- let t3;
41
- if ($[7] !== onChange || $[8] !== onClose) {
42
- t3 = (optValue)=>{
43
- onChange?.(optValue);
44
- onClose();
45
- };
46
- $[7] = onChange;
47
- $[8] = onClose;
48
- $[9] = t3;
49
- } else t3 = $[9];
50
- const handleSelect = t3;
51
- let t4;
52
- if ($[10] !== search || $[11] !== showSearch) {
53
- t4 = showSearch && /*#__PURE__*/ jsxs("div", {
54
- "data-tao-sheet-search": "",
29
+ return filterTree(options, fn, search);
30
+ }, [
31
+ options,
32
+ search,
33
+ showSearch,
34
+ filterOption
35
+ ]);
36
+ const handleSelect = useCallback((optValue)=>{
37
+ onChange?.(optValue);
38
+ onClose();
39
+ }, [
40
+ onChange,
41
+ onClose
42
+ ]);
43
+ let optIndex = 0;
44
+ const renderItem = (opt)=>{
45
+ const index = optIndex++;
46
+ const isSelected = opt.value === value;
47
+ return /*#__PURE__*/ jsxs("div", {
48
+ "data-tao-sheet-item": "",
49
+ "data-tao-selected": isSelected || void 0,
50
+ "data-tao-disabled": opt.disabled || void 0,
51
+ onClick: ()=>{
52
+ if (!opt.disabled) handleSelect(opt.value);
53
+ },
54
+ "data-tao-has-desc": null != opt.description || void 0,
55
55
  children: [
56
- /*#__PURE__*/ jsx(SearchIcon, {}),
57
- /*#__PURE__*/ jsx("input", {
58
- "data-tao-sheet-search-input": "",
59
- value: search,
60
- onChange: (e)=>setSearch(e.target.value),
61
- placeholder: "Search...",
62
- autoFocus: true
56
+ optionRender ? optionRender(opt, {
57
+ index
58
+ }) : /*#__PURE__*/ jsxs(Fragment, {
59
+ children: [
60
+ null != opt.icon && /*#__PURE__*/ jsx("span", {
61
+ "data-tao-sheet-item-icon": "",
62
+ children: opt.icon
63
+ }),
64
+ /*#__PURE__*/ jsxs("span", {
65
+ "data-tao-sheet-item-main": "",
66
+ children: [
67
+ /*#__PURE__*/ jsx("span", {
68
+ "data-tao-sheet-item-label": "",
69
+ children: opt.label
70
+ }),
71
+ null != opt.description && /*#__PURE__*/ jsx("span", {
72
+ "data-tao-sheet-item-desc": "",
73
+ children: opt.description
74
+ })
75
+ ]
76
+ })
77
+ ]
78
+ }),
79
+ isSelected && /*#__PURE__*/ jsx("span", {
80
+ "data-tao-sheet-item-check": "",
81
+ children: /*#__PURE__*/ jsx(CheckIcon, {})
63
82
  })
64
83
  ]
65
- });
66
- $[10] = search;
67
- $[11] = showSearch;
68
- $[12] = t4;
69
- } else t4 = $[12];
70
- let t5;
71
- if ($[13] !== filteredOptions || $[14] !== handleSelect || $[15] !== notFoundContent || $[16] !== value) {
72
- t5 = filteredOptions.length > 0 ? filteredOptions.map((opt)=>{
73
- const isSelected = opt.value === value;
74
- return /*#__PURE__*/ jsxs("div", {
75
- "data-tao-sheet-item": "",
76
- "data-tao-selected": isSelected || void 0,
77
- "data-tao-disabled": opt.disabled || void 0,
78
- onClick: ()=>{
79
- if (!opt.disabled) handleSelect(opt.value);
80
- },
81
- "data-tao-has-desc": null != opt.description || void 0,
84
+ }, opt.value);
85
+ };
86
+ const renderTree = (opts)=>opts.map((o)=>o.options ? /*#__PURE__*/ jsxs("div", {
87
+ "data-tao-sheet-group": "",
82
88
  children: [
83
- null != opt.icon && /*#__PURE__*/ jsx("span", {
84
- "data-tao-sheet-item-icon": "",
85
- children: opt.icon
86
- }),
87
- /*#__PURE__*/ jsxs("span", {
88
- "data-tao-sheet-item-main": "",
89
- children: [
90
- /*#__PURE__*/ jsx("span", {
91
- "data-tao-sheet-item-label": "",
92
- children: opt.label
93
- }),
94
- null != opt.description && /*#__PURE__*/ jsx("span", {
95
- "data-tao-sheet-item-desc": "",
96
- children: opt.description
97
- })
98
- ]
89
+ /*#__PURE__*/ jsx("div", {
90
+ "data-tao-sheet-group-label": "",
91
+ children: o.label
99
92
  }),
100
- isSelected && /*#__PURE__*/ jsx("span", {
101
- "data-tao-sheet-item-check": "",
102
- children: /*#__PURE__*/ jsx(CheckIcon, {})
93
+ o.options.map(renderItem)
94
+ ]
95
+ }, o.value) : renderItem(o));
96
+ return /*#__PURE__*/ jsxs(Fragment, {
97
+ children: [
98
+ showSearch && /*#__PURE__*/ jsxs("div", {
99
+ "data-tao-sheet-search": "",
100
+ children: [
101
+ /*#__PURE__*/ jsx(SearchIcon, {}),
102
+ /*#__PURE__*/ jsx("input", {
103
+ "data-tao-sheet-search-input": "",
104
+ value: search,
105
+ onChange: (e)=>setSearch(e.target.value),
106
+ placeholder: "Search...",
107
+ autoFocus: true
103
108
  })
104
109
  ]
105
- }, opt.value);
106
- }) : /*#__PURE__*/ jsx("div", {
107
- "data-tao-sheet-empty": "",
108
- children: notFoundContent
109
- });
110
- $[13] = filteredOptions;
111
- $[14] = handleSelect;
112
- $[15] = notFoundContent;
113
- $[16] = value;
114
- $[17] = t5;
115
- } else t5 = $[17];
116
- let t6;
117
- if ($[18] !== t5) {
118
- t6 = /*#__PURE__*/ jsx("div", {
119
- "data-tao-sheet-list": "",
120
- children: t5
121
- });
122
- $[18] = t5;
123
- $[19] = t6;
124
- } else t6 = $[19];
125
- let t7;
126
- if ($[20] !== t4 || $[21] !== t6) {
127
- t7 = /*#__PURE__*/ jsxs(Fragment, {
128
- children: [
129
- t4,
130
- t6
131
- ]
132
- });
133
- $[20] = t4;
134
- $[21] = t6;
135
- $[22] = t7;
136
- } else t7 = $[22];
137
- return t7;
110
+ }),
111
+ /*#__PURE__*/ jsx("div", {
112
+ "data-tao-sheet-list": "",
113
+ children: countLeaves(filteredOptions) > 0 ? renderTree(filteredOptions) : /*#__PURE__*/ jsx("div", {
114
+ "data-tao-sheet-empty": "",
115
+ children: notFoundContent
116
+ })
117
+ })
118
+ ]
119
+ });
138
120
  }
139
121
  function MobileSelectDrawer(t0) {
140
122
  const $ = c(14);
@@ -356,6 +356,9 @@
356
356
  --tao-font-family: "Geist Sans", ui-sans-serif, system-ui, -apple-system, sans-serif;
357
357
  --tao-font-family-code: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
358
358
  --tao-motion-unit: .1s;
359
+ --tao-z-index-drawer: 1000;
360
+ --tao-z-index-modal: 1000;
361
+ --tao-z-index-popup: 1100;
359
362
  --tao-primary: var(--tao-color-primary);
360
363
  --tao-primary-hover: var(--tao-color-primary);
361
364
  }
@@ -878,6 +881,25 @@
878
881
  box-shadow: 0 0 0 2px var(--tao-color-error-outline);
879
882
  }
880
883
 
884
+ [data-tao-control][data-tao-variant="outlined"][data-tao-warning] {
885
+ border-color: var(--tao-warning);
886
+ }
887
+
888
+ [data-tao-control][data-tao-variant="outlined"][data-tao-warning]:hover:not([data-disabled]):not(:focus-within) {
889
+ border-color: var(--tao-color-warning);
890
+ }
891
+
892
+ @supports (color: color-mix(in lab, red, red)) {
893
+ [data-tao-control][data-tao-variant="outlined"][data-tao-warning]:hover:not([data-disabled]):not(:focus-within) {
894
+ border-color: color-mix(in oklch, var(--tao-color-warning) 80%, white);
895
+ }
896
+ }
897
+
898
+ [data-tao-control][data-tao-variant="outlined"][data-tao-warning]:focus-within, [data-tao-control][data-tao-variant="outlined"][data-tao-warning][data-state="open"] {
899
+ border-color: var(--tao-warning);
900
+ box-shadow: 0 0 0 2px var(--tao-color-warning-outline);
901
+ }
902
+
881
903
  [data-tao-control][data-tao-variant="outlined"][data-disabled], [data-tao-control][data-tao-variant="outlined"]:has(input:disabled) {
882
904
  background: var(--tao-color-bg-disabled);
883
905
  border-color: var(--tao-color-border);
@@ -922,6 +944,26 @@
922
944
  box-shadow: 0 0 0 2px var(--tao-color-error-outline);
923
945
  }
924
946
 
947
+ [data-tao-control][data-tao-variant="filled"][data-tao-warning] {
948
+ background: var(--tao-warning-bg);
949
+ }
950
+
951
+ [data-tao-control][data-tao-variant="filled"][data-tao-warning]:hover:not([data-disabled]):not(:focus-within) {
952
+ background: var(--tao-color-warning);
953
+ }
954
+
955
+ @supports (color: color-mix(in lab, red, red)) {
956
+ [data-tao-control][data-tao-variant="filled"][data-tao-warning]:hover:not([data-disabled]):not(:focus-within) {
957
+ background: color-mix(in oklch, var(--tao-color-warning) 10%, var(--tao-color-bg-base));
958
+ }
959
+ }
960
+
961
+ [data-tao-control][data-tao-variant="filled"][data-tao-warning]:focus-within, [data-tao-control][data-tao-variant="filled"][data-tao-warning][data-state="open"] {
962
+ background: var(--tao-color-bg-container);
963
+ border-color: var(--tao-warning);
964
+ box-shadow: 0 0 0 2px var(--tao-color-warning-outline);
965
+ }
966
+
925
967
  [data-tao-control][data-tao-variant="filled"][data-disabled], [data-tao-control][data-tao-variant="filled"]:has(input:disabled) {
926
968
  background: var(--tao-color-bg-disabled);
927
969
  border-color: var(--tao-color-border);
@@ -998,15 +1040,6 @@ button[data-tao-select] {
998
1040
  border-radius: var(--tao-radius-md);
999
1041
  }
1000
1042
 
1001
- [data-tao-select] > span:first-of-type {
1002
- text-align: start;
1003
- text-overflow: ellipsis;
1004
- white-space: nowrap;
1005
- flex: 1;
1006
- min-width: 0;
1007
- overflow: hidden;
1008
- }
1009
-
1010
1043
  [data-tao-select-prefix] {
1011
1044
  color: var(--tao-color-text-tertiary);
1012
1045
  flex-shrink: 0;
@@ -1058,6 +1091,10 @@ button[data-tao-select] {
1058
1091
  transform: rotate(180deg);
1059
1092
  }
1060
1093
 
1094
+ [data-tao-select][data-state="open"] [data-tao-select-icon][data-tao-custom-suffix], [data-tao-select][data-state="open"] [data-tao-select-icon][data-tao-select-loading-slot] {
1095
+ transform: none;
1096
+ }
1097
+
1061
1098
  [data-tao-select-clear] {
1062
1099
  color: var(--tao-color-text-quaternary);
1063
1100
  cursor: pointer;
@@ -1069,7 +1106,7 @@ button[data-tao-select] {
1069
1106
  }
1070
1107
 
1071
1108
  [data-tao-select-loading] {
1072
- color: var(--tao-color-text-quaternary);
1109
+ color: var(--tao-color-text-tertiary);
1073
1110
  animation: .8s linear infinite tao-spin;
1074
1111
  }
1075
1112
 
@@ -1092,7 +1129,7 @@ button[data-tao-select] {
1092
1129
  border: var(--tao-line-width) solid var(--tao-color-border);
1093
1130
  border-radius: var(--tao-radius-lg);
1094
1131
  box-shadow: var(--tao-box-shadow-secondary);
1095
- z-index: 1000;
1132
+ z-index: var(--tao-z-index-popup);
1096
1133
  min-width: var(--radix-select-trigger-width);
1097
1134
  animation-duration: var(--tao-motion-duration-fast);
1098
1135
  animation-timing-function: var(--tao-motion-ease-out-quint);
@@ -1103,6 +1140,10 @@ button[data-tao-select] {
1103
1140
  animation-name: tao-select-in;
1104
1141
  }
1105
1142
 
1143
+ [data-tao-select-content][data-tao-popup-width="content"] {
1144
+ min-width: max-content;
1145
+ }
1146
+
1106
1147
  @keyframes tao-select-in {
1107
1148
  0% {
1108
1149
  opacity: 0;
@@ -1144,6 +1185,19 @@ button[data-tao-select] {
1144
1185
  max-height: 256px;
1145
1186
  }
1146
1187
 
1188
+ [data-tao-select-group]:not(:first-child) {
1189
+ margin-block-start: var(--tao-padding-xxs);
1190
+ }
1191
+
1192
+ [data-tao-select-group-label] {
1193
+ padding: var(--tao-padding-xs) var(--tao-padding-sm) var(--tao-padding-xxs);
1194
+ font-size: var(--tao-font-size-xs);
1195
+ font-weight: var(--tao-font-weight-medium);
1196
+ color: var(--tao-color-text-tertiary);
1197
+ -webkit-user-select: none;
1198
+ user-select: none;
1199
+ }
1200
+
1147
1201
  [data-tao-select-item] {
1148
1202
  min-height: var(--tao-control-height);
1149
1203
  padding-inline: var(--tao-padding-sm);
@@ -1,5 +1,6 @@
1
- import { type ReactNode } from 'react';
1
+ import { type CSSProperties, type ReactNode } from 'react';
2
2
  import { type TaoSize, type TaoVariant } from '../../provider/tao-provider';
3
+ import { type SemanticClassNames, type SemanticStyles } from '../../utils/semantic';
3
4
  import './select.css';
4
5
  export interface SelectOption {
5
6
  label: ReactNode;
@@ -9,28 +10,81 @@ export interface SelectOption {
9
10
  icon?: ReactNode;
10
11
  /** Secondary description line shown under the label in the option row. */
11
12
  description?: ReactNode;
13
+ /** Nested options turn this entry into a group; `label` becomes the group title. */
14
+ options?: SelectOption[];
12
15
  }
16
+ export type SelectSemanticPart = 'root' | 'prefix' | 'suffix' | 'placeholder' | 'clear' | 'popup' | 'search' | 'group' | 'groupLabel' | 'item' | 'itemIcon' | 'itemLabel' | 'itemDesc' | 'empty';
17
+ export type SelectPlacement = 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topRight';
13
18
  export interface SelectProps {
14
19
  options: SelectOption[];
15
20
  value?: string;
16
- onChange?: (value: string) => void;
21
+ defaultValue?: string;
22
+ /** Fired on selection or clear. `option` is undefined when cleared. */
23
+ onChange?: (value: string, option?: SelectOption) => void;
24
+ /** Fired only when an option is picked (not on clear). */
25
+ onSelect?: (value: string, option: SelectOption) => void;
26
+ /** Fired when the value is cleared via the clear button. */
27
+ onClear?: () => void;
17
28
  placeholder?: string;
18
29
  size?: TaoSize;
19
30
  variant?: TaoVariant;
20
31
  disabled?: boolean;
32
+ /** Validation status. */
33
+ status?: 'error' | 'warning';
21
34
  /** Show search input in dropdown */
22
35
  showSearch?: boolean;
23
36
  /** Custom filter function, default matches label string */
24
37
  filterOption?: (input: string, option: SelectOption) => boolean;
25
- /** Allow clearing the value */
26
- allowClear?: boolean;
38
+ /** Controlled search text. */
39
+ searchValue?: string;
40
+ /** Fired when the search text changes. */
41
+ onSearch?: (value: string) => void;
42
+ /** Allow clearing the value; pass an object to customize the clear icon. */
43
+ allowClear?: boolean | {
44
+ clearIcon?: ReactNode;
45
+ };
27
46
  /** Show loading spinner */
28
47
  loading?: boolean;
48
+ /** Custom loading icon. */
49
+ loadingIcon?: ReactNode;
29
50
  /** Content when no options match */
30
51
  notFoundContent?: ReactNode;
31
52
  /** Prefix icon/element */
32
53
  prefix?: ReactNode;
54
+ /** Custom suffix (arrow) icon. */
55
+ suffixIcon?: ReactNode;
56
+ autoFocus?: boolean;
57
+ id?: string;
58
+ /** Name for hidden form field. */
59
+ name?: string;
60
+ /** Controlled open state of the dropdown. */
61
+ open?: boolean;
62
+ defaultOpen?: boolean;
63
+ onOpenChange?: (open: boolean) => void;
64
+ /** Dropdown position. Defaults to `bottomLeft`. */
65
+ placement?: SelectPlacement;
66
+ /** Match popup width to trigger (true), a fixed px width (number), or fit content (false). */
67
+ popupMatchSelectWidth?: boolean | number;
68
+ /** Max height of the option list. Defaults to 256. */
69
+ listHeight?: number;
70
+ /** Parent node the popup renders into. Defaults to body. */
71
+ getPopupContainer?: (trigger: HTMLElement) => HTMLElement;
72
+ /** Customize the rendering of each dropdown option. */
73
+ optionRender?: (option: SelectOption, info: {
74
+ index: number;
75
+ }) => ReactNode;
76
+ /** Customize the selected label shown in the trigger. */
77
+ labelRender?: (option: SelectOption) => ReactNode;
78
+ /** Wrap/customize the dropdown content. */
79
+ popupRender?: (menu: ReactNode) => ReactNode;
33
80
  /** Force mobile mode (bottom sheet) regardless of screen size */
34
81
  mobile?: boolean;
82
+ /** Merged onto the trigger root; use to override width etc. */
83
+ className?: string;
84
+ style?: CSSProperties;
85
+ classNames?: SemanticClassNames<SelectSemanticPart>;
86
+ styles?: SemanticStyles<SelectSemanticPart>;
35
87
  }
36
88
  export declare function Select(props: SelectProps): import("react/jsx-runtime").JSX.Element;
89
+ /** Double chevron (↕) for a switcher-style trigger. Pass to `suffixIcon`. */
90
+ export declare function ChevronsUpDownIcon(): import("react/jsx-runtime").JSX.Element;