@expcat/tigercat-react 2.1.0 → 2.1.1

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 (137) hide show
  1. package/dist/{chunk-RUAPTIQ7.mjs → chunk-246DAUEF.mjs} +2 -2
  2. package/dist/{chunk-PU3JY6RE.mjs → chunk-2JMI7TCM.mjs} +1 -1
  3. package/dist/chunk-2YBLMVDT.mjs +428 -0
  4. package/dist/{chunk-25D5TXZH.mjs → chunk-32MCQMBJ.mjs} +8 -6
  5. package/dist/{chunk-M5MZWOHF.mjs → chunk-3HHEVMHE.mjs} +1 -1
  6. package/dist/{chunk-HSBN5MLS.mjs → chunk-3LACOSJQ.mjs} +1 -1
  7. package/dist/{chunk-F6WV53BS.mjs → chunk-3LDDXHW2.mjs} +28 -11
  8. package/dist/{chunk-IXQAECFP.mjs → chunk-3QNIFKVF.mjs} +12 -14
  9. package/dist/{chunk-UD4DTVJZ.mjs → chunk-4C2X5PZO.mjs} +57 -25
  10. package/dist/chunk-5JETWHLJ.mjs +28 -0
  11. package/dist/{chunk-VA6PZWOH.mjs → chunk-5SEMRHBD.mjs} +14 -6
  12. package/dist/{chunk-EKILTLUO.mjs → chunk-72CJNKDY.mjs} +1 -1
  13. package/dist/{chunk-XE4YFBOZ.mjs → chunk-AUD3VOLO.mjs} +1 -1
  14. package/dist/{chunk-I4MWOYJS.mjs → chunk-AYFKHWJS.mjs} +13 -7
  15. package/dist/{chunk-RPSHILHD.mjs → chunk-BXAH2GH3.mjs} +8 -2
  16. package/dist/{chunk-EW5EO7VE.mjs → chunk-BYD7EAWK.mjs} +1 -1
  17. package/dist/{chunk-GCY55TBC.mjs → chunk-CQOLQAB5.mjs} +105 -90
  18. package/dist/{chunk-L55UK45A.mjs → chunk-CRIEUKMD.mjs} +5 -2
  19. package/dist/{chunk-DKNVSQSV.mjs → chunk-CUAXRBKO.mjs} +12 -0
  20. package/dist/{chunk-NWVNTZOP.mjs → chunk-DECUASRW.mjs} +14 -16
  21. package/dist/{chunk-XMTEMBQV.mjs → chunk-EAAWB3CK.mjs} +16 -13
  22. package/dist/{chunk-IR7VA6AO.mjs → chunk-EG7EMDKK.mjs} +1 -1
  23. package/dist/{chunk-HOYBHB7B.mjs → chunk-FNK2VWPP.mjs} +1 -1
  24. package/dist/{chunk-RJPNBYK5.mjs → chunk-FQS24AUH.mjs} +12 -3
  25. package/dist/{chunk-LADKKOJT.mjs → chunk-GBEDWXLL.mjs} +16 -10
  26. package/dist/{chunk-2ENQZECC.mjs → chunk-HAXRHSCN.mjs} +4 -3
  27. package/dist/{chunk-K4GIKSZE.mjs → chunk-I2BENK5X.mjs} +2 -1
  28. package/dist/{chunk-DNOPEJ5I.mjs → chunk-JZZPLKTW.mjs} +7 -4
  29. package/dist/{chunk-7KCQMXJA.mjs → chunk-KDURW5AS.mjs} +4 -3
  30. package/dist/{chunk-TFMEHUVZ.mjs → chunk-KKN7KLTB.mjs} +0 -1
  31. package/dist/{chunk-6MGQAJ62.mjs → chunk-KL6YJIZ3.mjs} +24 -7
  32. package/dist/{chunk-PFL4HNWM.mjs → chunk-M6ZPTGBV.mjs} +1 -2
  33. package/dist/{chunk-PXRZ6CKY.mjs → chunk-MJVSZ2UJ.mjs} +46 -16
  34. package/dist/{chunk-LZKBDQE4.mjs → chunk-MYI3FPG4.mjs} +23 -4
  35. package/dist/{chunk-OIGEBCAS.mjs → chunk-NADODEZX.mjs} +69 -1
  36. package/dist/{chunk-UKY2EPS3.mjs → chunk-NJWTZ5MO.mjs} +54 -42
  37. package/dist/{chunk-773LH7BK.mjs → chunk-O6VYD4E4.mjs} +24 -2
  38. package/dist/{chunk-G7D4QV7A.mjs → chunk-O7TV5OKS.mjs} +33 -6
  39. package/dist/{chunk-DPWRXXXW.mjs → chunk-OJ6SHHOZ.mjs} +3 -3
  40. package/dist/{chunk-UYJJLHVA.mjs → chunk-PMQJ6AYT.mjs} +23 -21
  41. package/dist/{chunk-KC55B62J.mjs → chunk-PY2VUNEJ.mjs} +143 -46
  42. package/dist/{chunk-BEJZPJIK.mjs → chunk-QOAOOD53.mjs} +10 -4
  43. package/dist/{chunk-JQJM65RJ.mjs → chunk-QU3QXUTC.mjs} +49 -23
  44. package/dist/{chunk-7EMCZVJ2.mjs → chunk-QXSUG7SN.mjs} +3 -3
  45. package/dist/{chunk-RQ4PUK6G.mjs → chunk-R7YZ6FKP.mjs} +24 -13
  46. package/dist/{chunk-YI6YWH66.mjs → chunk-RE5ZLA5D.mjs} +6 -6
  47. package/dist/{chunk-UCBW5RJN.mjs → chunk-RGVU4EMA.mjs} +11 -6
  48. package/dist/{chunk-IBSOUQGB.mjs → chunk-RRGPDFDI.mjs} +7 -4
  49. package/dist/{chunk-ZH5ZBLAN.mjs → chunk-RUQ3F3MV.mjs} +34 -7
  50. package/dist/{chunk-PGD5RPKF.mjs → chunk-SVIJ2UZA.mjs} +2 -1
  51. package/dist/{chunk-UETARXIK.mjs → chunk-SXWEFZOF.mjs} +246 -53
  52. package/dist/{chunk-H6MVW5YD.mjs → chunk-TEVEXDY2.mjs} +24 -13
  53. package/dist/{chunk-DJOFM2VO.mjs → chunk-TO6MZFNQ.mjs} +52 -40
  54. package/dist/{chunk-ZCGIZOMT.mjs → chunk-V7HJ5HLC.mjs} +6 -10
  55. package/dist/{chunk-SIDDYP3O.mjs → chunk-VJWSKJLJ.mjs} +1 -1
  56. package/dist/{chunk-ZG56T75O.mjs → chunk-WTHWLCRL.mjs} +51 -11
  57. package/dist/{chunk-KP6DEYWB.mjs → chunk-X4L3W7RQ.mjs} +1 -1
  58. package/dist/{chunk-ZMRTETN2.mjs → chunk-X6C6MNG5.mjs} +4 -3
  59. package/dist/{chunk-OGG2TQDG.mjs → chunk-XVHTJQ4T.mjs} +12 -1
  60. package/dist/{chunk-FSMJLJFL.mjs → chunk-Y6UH3EKE.mjs} +1 -1
  61. package/dist/chunk-YJ5T4XZN.mjs +81 -0
  62. package/dist/{chunk-VVNFXJMN.mjs → chunk-YNDPQVEK.mjs} +8 -1
  63. package/dist/{chunk-QGZ32NFQ.mjs → chunk-Z23KOLNU.mjs} +4 -3
  64. package/dist/{chunk-5CKMYMTS.mjs → chunk-ZATZRXMW.mjs} +27 -8
  65. package/dist/components/ActivityFeed.mjs +2 -2
  66. package/dist/components/Affix.mjs +1 -1
  67. package/dist/components/Anchor.mjs +1 -1
  68. package/dist/components/AreaChart.mjs +4 -3
  69. package/dist/components/AutoComplete.mjs +1 -1
  70. package/dist/components/BarChart.mjs +4 -3
  71. package/dist/components/Calendar.mjs +1 -1
  72. package/dist/components/Cascader.mjs +1 -1
  73. package/dist/components/ChartCanvas.mjs +1 -1
  74. package/dist/components/ChatWindow.mjs +3 -3
  75. package/dist/components/Code.mjs +3 -1
  76. package/dist/components/CollapsePanel.mjs +1 -1
  77. package/dist/components/ColorPicker.mjs +1 -1
  78. package/dist/components/CommentThread.mjs +2 -2
  79. package/dist/components/DataExport.mjs +2 -2
  80. package/dist/components/DataTableWithToolbar.mjs +6 -6
  81. package/dist/components/DonutChart.mjs +4 -4
  82. package/dist/components/Dropdown.mjs +1 -1
  83. package/dist/components/FileManager.mjs +2 -1
  84. package/dist/components/FloatButton.mjs +1 -1
  85. package/dist/components/FormItem.mjs +1 -1
  86. package/dist/components/FormWizard.mjs +1 -1
  87. package/dist/components/FunnelChart.mjs +3 -3
  88. package/dist/components/Gantt.d.mts +3 -1
  89. package/dist/components/Gantt.mjs +2 -2
  90. package/dist/components/GaugeChart.mjs +2 -2
  91. package/dist/components/HeatmapChart.mjs +3 -3
  92. package/dist/components/Image.mjs +4 -4
  93. package/dist/components/ImageGroup.mjs +2 -2
  94. package/dist/components/ImagePreview.mjs +1 -1
  95. package/dist/components/Input.mjs +1 -1
  96. package/dist/components/InputNumber.d.mts +1 -1
  97. package/dist/components/InputNumber.mjs +1 -1
  98. package/dist/components/Kanban.mjs +2 -2
  99. package/dist/components/LineChart.mjs +4 -3
  100. package/dist/components/List.mjs +2 -2
  101. package/dist/components/Loading.mjs +1 -1
  102. package/dist/components/MaskInput.mjs +1 -1
  103. package/dist/components/NotificationCenter.mjs +4 -4
  104. package/dist/components/OrgChart.mjs +2 -2
  105. package/dist/components/Pagination.mjs +1 -1
  106. package/dist/components/PieChart.mjs +3 -3
  107. package/dist/components/Popconfirm.mjs +2 -2
  108. package/dist/components/Popover.mjs +2 -2
  109. package/dist/components/QRCode.d.mts +2 -2
  110. package/dist/components/QRCode.mjs +1 -1
  111. package/dist/components/RadarChart.mjs +3 -3
  112. package/dist/components/Rate.mjs +1 -1
  113. package/dist/components/ScatterChart.mjs +4 -3
  114. package/dist/components/ScrollSpy.mjs +1 -1
  115. package/dist/components/Signature.mjs +1 -1
  116. package/dist/components/SplitButton.mjs +2 -2
  117. package/dist/components/Splitter.mjs +1 -1
  118. package/dist/components/Stepper.d.mts +2 -0
  119. package/dist/components/Stepper.mjs +2 -1
  120. package/dist/components/SunburstChart.mjs +3 -3
  121. package/dist/components/Switch.d.mts +5 -1
  122. package/dist/components/Switch.mjs +2 -1
  123. package/dist/components/Table.mjs +2 -2
  124. package/dist/components/TaskBoard.mjs +1 -1
  125. package/dist/components/Textarea.mjs +1 -1
  126. package/dist/components/Tooltip.mjs +2 -2
  127. package/dist/components/Tour.mjs +1 -1
  128. package/dist/components/TreeMapChart.mjs +3 -3
  129. package/dist/components/TreeSelect.mjs +1 -1
  130. package/dist/components/Upload.mjs +1 -1
  131. package/dist/hooks/useChartInteraction.d.mts +5 -0
  132. package/dist/hooks/useChartInteraction.mjs +1 -1
  133. package/dist/index.d.mts +1 -1
  134. package/dist/index.mjs +51 -0
  135. package/package.json +2 -2
  136. package/dist/chunk-CB4SK5AU.mjs +0 -235
  137. package/dist/chunk-KPACLRQH.mjs +0 -55
@@ -28,11 +28,14 @@ import {
28
28
  kanbanSwimlaneCollapsedClasses,
29
29
  kanbanAddColumnClasses,
30
30
  filterColumns,
31
+ filterCards,
31
32
  groupBySwimlane,
32
33
  getColumnCardCount,
33
34
  moveCard,
35
+ mapVisibleCardIndexToSource,
34
36
  reorderColumns,
35
37
  isWipExceeded,
38
+ appendDefaultTaskBoardCard,
36
39
  createTaskBoardDragController,
37
40
  createDefaultDragSnapshot
38
41
  } from "@expcat/tigercat-core";
@@ -343,6 +346,17 @@ var TaskBoard = ({
343
346
  },
344
347
  [onColumnsChange]
345
348
  );
349
+ const consumerOnCardAdd = onCardAdd;
350
+ const showAddCard = Boolean(allowAddCard || consumerOnCardAdd);
351
+ const handleCardAdd = useCallback(
352
+ (columnId) => {
353
+ if (consumerOnCardAdd == null) {
354
+ updateColumns(appendDefaultTaskBoardCard(columnsRef.current, columnId));
355
+ }
356
+ consumerOnCardAdd?.(columnId);
357
+ },
358
+ [consumerOnCardAdd, updateColumns]
359
+ );
346
360
  const [dragSnap, setDragSnap] = useState(createDefaultDragSnapshot);
347
361
  const boardRef = useRef(null);
348
362
  const beforeCardMoveRef = useRef(beforeCardMove);
@@ -355,9 +369,17 @@ var TaskBoard = ({
355
369
  onColumnMoveRef.current = onColumnMove;
356
370
  const enforceWipLimitRef = useRef(enforceWipLimit);
357
371
  enforceWipLimitRef.current = enforceWipLimit;
372
+ const filterTextRef = useRef(filterText);
373
+ filterTextRef.current = filterText;
358
374
  const applyCardMove = useCallback(
359
375
  async (cardId, fromColumnId, toColumnId, toIdx) => {
360
- const result = moveCard(columnsRef.current, cardId, fromColumnId, toColumnId, toIdx, {
376
+ const sourceCol = columnsRef.current.find((c) => c.id === toColumnId);
377
+ const mappedIdx = sourceCol == null ? toIdx : mapVisibleCardIndexToSource(
378
+ sourceCol.cards,
379
+ filterCards(sourceCol.cards, filterTextRef.current),
380
+ toIdx
381
+ );
382
+ const result = moveCard(columnsRef.current, cardId, fromColumnId, toColumnId, mappedIdx, {
361
383
  enforceWipLimit: enforceWipLimitRef.current
362
384
  });
363
385
  if (!result) return;
@@ -442,7 +464,7 @@ var TaskBoard = ({
442
464
  renderColumnHeader,
443
465
  renderColumnFooter,
444
466
  renderEmptyColumn,
445
- onCardAdd,
467
+ onCardAdd: showAddCard ? handleCardAdd : void 0,
446
468
  dragType,
447
469
  dragCtrl,
448
470
  dragStateId,
@@ -9,13 +9,28 @@ import {
9
9
  floatButtonSizeClasses,
10
10
  floatButtonTypeClasses,
11
11
  floatButtonDisabledClasses,
12
- floatButtonGroupClasses,
12
+ floatButtonIconSizeClasses,
13
+ floatButtonPlusIconPath,
14
+ getFloatButtonGroupClasses,
13
15
  getViewportOffsetStyle,
14
16
  viewportFloatingBaseClasses,
15
17
  viewportPlacementClasses
16
18
  } from "@expcat/tigercat-core";
17
19
  import { jsx, jsxs } from "react/jsx-runtime";
18
20
  var FloatButtonGroupContext = createContext(null);
21
+ var DefaultPlusIcon = ({ size }) => /* @__PURE__ */ jsx(
22
+ "svg",
23
+ {
24
+ xmlns: "http://www.w3.org/2000/svg",
25
+ fill: "none",
26
+ viewBox: "0 0 24 24",
27
+ stroke: "currentColor",
28
+ strokeWidth: 2,
29
+ className: floatButtonIconSizeClasses[size],
30
+ "aria-hidden": "true",
31
+ children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: floatButtonPlusIconPath })
32
+ }
33
+ );
19
34
  var FloatButton = ({
20
35
  shape,
21
36
  size = "md",
@@ -58,11 +73,11 @@ var FloatButton = ({
58
73
  type: "button",
59
74
  disabled,
60
75
  style: buttonStyle,
61
- "aria-label": ariaLabel ?? tooltip,
76
+ "aria-label": children != null ? ariaLabel ?? tooltip : ariaLabel ?? tooltip ?? "Add",
62
77
  title: tooltip,
63
78
  onClick: disabled ? void 0 : onClick,
64
79
  ...props,
65
- children
80
+ children: children ?? /* @__PURE__ */ jsx(DefaultPlusIcon, { size })
66
81
  }
67
82
  );
68
83
  };
@@ -74,6 +89,10 @@ var FloatButtonGroup = ({
74
89
  children,
75
90
  className,
76
91
  onOpenChange,
92
+ placement = "bottom-right",
93
+ offset,
94
+ portal = true,
95
+ style,
77
96
  ...props
78
97
  }) => {
79
98
  const groupContextValue = useMemo(() => ({ shape: groupShape }), [groupShape]);
@@ -92,12 +111,20 @@ var FloatButtonGroup = ({
92
111
  setInternalOpen(false);
93
112
  onOpenChange?.(false);
94
113
  }, [onOpenChange]);
95
- const groupClasses = useMemo(() => classNames(floatButtonGroupClasses, className), [className]);
96
- if (!isBrowser()) return null;
114
+ const groupClasses = useMemo(
115
+ () => classNames(getFloatButtonGroupClasses({ placement, portal }), className),
116
+ [placement, portal, className]
117
+ );
118
+ const groupStyle = useMemo(
119
+ () => ({ ...getViewportOffsetStyle(placement, offset), ...style }),
120
+ [placement, offset, style]
121
+ );
122
+ if (portal && !isBrowser()) return null;
97
123
  const content = /* @__PURE__ */ jsx(FloatButtonGroupContext.Provider, { value: groupContextValue, children: /* @__PURE__ */ jsxs(
98
124
  "div",
99
125
  {
100
126
  className: groupClasses,
127
+ style: groupStyle,
101
128
  onMouseEnter: trigger === "hover" ? handleMouseEnter : void 0,
102
129
  onMouseLeave: trigger === "hover" ? handleMouseLeave : void 0,
103
130
  ...props,
@@ -107,7 +134,7 @@ var FloatButtonGroup = ({
107
134
  ]
108
135
  }
109
136
  ) });
110
- return ReactDOM.createPortal(content, document.body);
137
+ return portal ? ReactDOM.createPortal(content, document.body) : content;
111
138
  };
112
139
 
113
140
  export {
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  ImageGroupContext
3
- } from "./chunk-HSBN5MLS.mjs";
3
+ } from "./chunk-3LACOSJQ.mjs";
4
4
  import {
5
5
  ImagePreview
6
- } from "./chunk-ZCGIZOMT.mjs";
6
+ } from "./chunk-V7HJ5HLC.mjs";
7
7
  import {
8
8
  usePopup
9
- } from "./chunk-ZG56T75O.mjs";
9
+ } from "./chunk-WTHWLCRL.mjs";
10
10
  import {
11
11
  renderOverlayPortal
12
12
  } from "./chunk-HKAZXG74.mjs";
@@ -66,28 +66,30 @@ var Textarea = forwardRef(
66
66
  onChange?.(event);
67
67
  };
68
68
  const currentLength = currentValue?.length ?? 0;
69
+ const textarea = /* @__PURE__ */ jsx(
70
+ "textarea",
71
+ {
72
+ ref: setRefs,
73
+ className: textareaClasses,
74
+ value: currentValue,
75
+ disabled,
76
+ readOnly: readonly,
77
+ required,
78
+ placeholder,
79
+ rows,
80
+ maxLength,
81
+ minLength,
82
+ onInput: handleInput,
83
+ onChange: handleChange,
84
+ onFocus,
85
+ onBlur,
86
+ ...props
87
+ }
88
+ );
89
+ if (!showCount) return textarea;
69
90
  return /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
70
- /* @__PURE__ */ jsx(
71
- "textarea",
72
- {
73
- ref: setRefs,
74
- className: textareaClasses,
75
- value: currentValue,
76
- disabled,
77
- readOnly: readonly,
78
- required,
79
- placeholder,
80
- rows,
81
- maxLength,
82
- minLength,
83
- onInput: handleInput,
84
- onChange: handleChange,
85
- onFocus,
86
- onBlur,
87
- ...props
88
- }
89
- ),
90
- showCount && /* @__PURE__ */ jsx("div", { className: "mt-1 text-sm text-gray-500 text-right", children: maxLength ? `${currentLength}/${maxLength}` : currentLength })
91
+ textarea,
92
+ /* @__PURE__ */ jsx("div", { className: "mt-1 text-sm text-gray-500 text-right", children: maxLength ? `${currentLength}/${maxLength}` : currentLength })
91
93
  ] });
92
94
  }
93
95
  );
@@ -33,6 +33,7 @@ import {
33
33
  getPickerOptionAria,
34
34
  getPickerTriggerKeyAction,
35
35
  getPickerNavigationIndex,
36
+ getPickerOptionId,
36
37
  findFirstEnabledIndex,
37
38
  classNames,
38
39
  icon20ViewBox,
@@ -165,18 +166,17 @@ var TreeSelect = (props) => {
165
166
  commitActiveIndex(-1);
166
167
  return;
167
168
  }
168
- if (!virtual) return;
169
169
  commitActiveIndex(resolveActiveIndex());
170
- }, [isOpen, searchQuery, virtual, commitActiveIndex, resolveActiveIndex]);
170
+ }, [isOpen, searchQuery, commitActiveIndex, resolveActiveIndex]);
171
171
  useLayoutEffect(() => {
172
- if (!isOpen || !virtual) return;
172
+ if (!isOpen) return;
173
173
  const remapped = getTreeSelectVisibleIndex(visibleNodesRef.current, lastActiveKeyRef.current);
174
174
  if (remapped >= 0) setActiveIndex(remapped);
175
- }, [expandedKeys, treeData, isOpen, virtual]);
175
+ }, [expandedKeys, treeData, isOpen]);
176
176
  useLayoutEffect(() => {
177
- if (!isOpen || !virtual) return;
177
+ if (!isOpen) return;
178
178
  alignVirtualScroll(activeIndex);
179
- }, [activeIndex, isOpen, virtual, alignVirtualScroll, visibleNodes.length]);
179
+ }, [activeIndex, isOpen, alignVirtualScroll, visibleNodes.length]);
180
180
  function handleVirtualListKeyDown(e) {
181
181
  if (e.key !== "ArrowDown" && e.key !== "ArrowUp" && e.key !== "Home" && e.key !== "End") {
182
182
  return;
@@ -207,8 +207,7 @@ var TreeSelect = (props) => {
207
207
  if (isOpen) closeDropdown();
208
208
  else openDropdown();
209
209
  }
210
- function toggleExpand(key, e) {
211
- e.stopPropagation();
210
+ function toggleExpandKey(key) {
212
211
  setExpandedKeys((prev) => {
213
212
  const next = new Set(prev);
214
213
  if (next.has(key)) next.delete(key);
@@ -216,6 +215,10 @@ var TreeSelect = (props) => {
216
215
  return next;
217
216
  });
218
217
  }
218
+ function toggleExpand(key, e) {
219
+ e.stopPropagation();
220
+ toggleExpandKey(key);
221
+ }
219
222
  function isSelected(key) {
220
223
  if (multiple && Array.isArray(value)) {
221
224
  return value.includes(key);
@@ -239,7 +242,51 @@ var TreeSelect = (props) => {
239
242
  e.stopPropagation();
240
243
  onChange?.(multiple ? [] : void 0);
241
244
  }
245
+ function handleOpenListKeyDown(e, fromSearchInput = false) {
246
+ const key = e.key;
247
+ if (fromSearchInput && key === " ") return false;
248
+ if (key === "ArrowDown" || key === "ArrowUp" || key === "Home" || key === "End") {
249
+ e.preventDefault();
250
+ e.stopPropagation();
251
+ setActiveIndex((current) => {
252
+ const next = getPickerNavigationIndex(visibleNodes, current, key, isNodeDisabled);
253
+ lastActiveKeyRef.current = visibleNodes[next]?.node.key;
254
+ return next;
255
+ });
256
+ return true;
257
+ }
258
+ if (key === "Enter" || key === " ") {
259
+ e.preventDefault();
260
+ e.stopPropagation();
261
+ const item = visibleNodes[activeIndex];
262
+ if (item && !item.node.disabled) {
263
+ handleNodeSelect(item.node);
264
+ }
265
+ return true;
266
+ }
267
+ if (key === "ArrowRight") {
268
+ e.preventDefault();
269
+ e.stopPropagation();
270
+ const item = visibleNodes[activeIndex];
271
+ if (item?.hasChildren && !item.isExpanded) {
272
+ toggleExpandKey(item.node.key);
273
+ }
274
+ return true;
275
+ }
276
+ if (key === "ArrowLeft") {
277
+ e.preventDefault();
278
+ e.stopPropagation();
279
+ const item = visibleNodes[activeIndex];
280
+ if (item?.hasChildren && item.isExpanded) {
281
+ toggleExpandKey(item.node.key);
282
+ }
283
+ return true;
284
+ }
285
+ return false;
286
+ }
242
287
  function handleKeyDown(e) {
288
+ if (disabled) return;
289
+ if (isOpen && handleOpenListKeyDown(e)) return;
243
290
  const action = getPickerTriggerKeyAction(e.key, isOpen);
244
291
  if (action === "none") return;
245
292
  e.preventDefault();
@@ -252,15 +299,43 @@ var TreeSelect = (props) => {
252
299
  closeDropdown();
253
300
  }
254
301
  }
255
- function renderFlatNode(flatNode) {
302
+ function handleDropdownKeyDown(e) {
303
+ if (e.target instanceof HTMLInputElement) return;
304
+ if (!isOpen) return;
305
+ handleOpenListKeyDown(e);
306
+ }
307
+ function handleSearchKeyDown(e) {
308
+ switch (e.key) {
309
+ case " ":
310
+ e.stopPropagation();
311
+ return;
312
+ case "ArrowDown":
313
+ case "ArrowUp":
314
+ case "Enter":
315
+ handleOpenListKeyDown(e, true);
316
+ return;
317
+ case "Escape":
318
+ e.preventDefault();
319
+ e.stopPropagation();
320
+ closeDropdown();
321
+ triggerRef.current?.focus();
322
+ return;
323
+ default:
324
+ return;
325
+ }
326
+ }
327
+ function renderFlatNode(flatNode, index) {
256
328
  const { node, level, hasChildren, isExpanded } = flatNode;
257
329
  const selected = isSelected(node.key);
330
+ const isActive = index === activeIndex;
258
331
  const indent = level * 20;
259
332
  return /* @__PURE__ */ jsxs(
260
333
  "div",
261
334
  {
335
+ id: getPickerOptionId(listboxId, index),
336
+ "data-active": isActive || void 0,
262
337
  ...getPickerOptionAria({ selected, disabled: !!node.disabled }),
263
- className: getTreeSelectNodeClasses(selected, !!node.disabled, size),
338
+ className: getTreeSelectNodeClasses(selected || isActive, !!node.disabled, size),
264
339
  style: { paddingLeft: `${indent + 8}px`, height: virtual ? "100%" : void 0 },
265
340
  onClick: (e) => {
266
341
  e.stopPropagation();
@@ -285,45 +360,65 @@ var TreeSelect = (props) => {
285
360
  );
286
361
  }
287
362
  return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: classNames(treeSelectBaseClasses, className), ...divProps, children: [
288
- /* @__PURE__ */ jsxs(
363
+ /* @__PURE__ */ jsx(
289
364
  "button",
290
365
  {
291
366
  ref: triggerRef,
292
367
  type: "button",
293
- className: getTreeSelectTriggerClasses(size, disabled, isOpen),
294
- ...getPickerComboboxAria({ expanded: isOpen, listboxId }),
368
+ className: classNames(
369
+ getTreeSelectTriggerClasses(size, disabled, isOpen),
370
+ showClearButton ? "pr-14" : void 0
371
+ ),
372
+ ...getPickerComboboxAria({
373
+ expanded: isOpen,
374
+ listboxId,
375
+ activeIndex: isOpen ? activeIndex : -1
376
+ }),
295
377
  disabled,
296
378
  onClick: toggleDropdown,
297
379
  onKeyDown: handleKeyDown,
298
- children: [
299
- /* @__PURE__ */ jsx(
300
- "span",
380
+ children: /* @__PURE__ */ jsx(
381
+ "span",
382
+ {
383
+ className: classNames(
384
+ "flex-1 truncate",
385
+ !displayLabel ? "text-[var(--tiger-treeselect-placeholder,var(--tiger-text-muted,#9ca3af))]" : ""
386
+ ),
387
+ children: displayLabel || placeholder
388
+ }
389
+ )
390
+ }
391
+ ),
392
+ /* @__PURE__ */ jsxs("span", { className: "pointer-events-none absolute inset-y-0 right-3 flex items-center gap-1", children: [
393
+ showClearButton && /* @__PURE__ */ jsx(
394
+ "button",
395
+ {
396
+ type: "button",
397
+ className: "pointer-events-auto inline-flex rounded-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--tiger-treeselect-ring,var(--tiger-primary,#2563eb))] text-[var(--tiger-treeselect-clear,var(--tiger-text-muted,#9ca3af))] hover:text-[var(--tiger-treeselect-clear-hover,var(--tiger-text,#111827))]",
398
+ "data-tiger-treeselect-clear": "",
399
+ "aria-label": resolveLocaleText("Clear selection", mergedLocale?.common?.clearText),
400
+ onClick: handleClear,
401
+ children: /* @__PURE__ */ jsx(
402
+ "svg",
301
403
  {
302
- className: classNames(
303
- "flex-1 truncate",
304
- !displayLabel ? "text-[var(--tiger-treeselect-placeholder,var(--tiger-text-muted,#9ca3af))]" : ""
305
- ),
306
- children: displayLabel || placeholder
404
+ className: "w-4 h-4",
405
+ viewBox: icon20ViewBox,
406
+ fill: "currentColor",
407
+ xmlns: "http://www.w3.org/2000/svg",
408
+ children: /* @__PURE__ */ jsx("path", { d: closeSolidIcon20PathD, fillRule: "evenodd", clipRule: "evenodd" })
307
409
  }
410
+ )
411
+ }
412
+ ),
413
+ /* @__PURE__ */ jsx(
414
+ "span",
415
+ {
416
+ className: classNames(
417
+ "inline-flex text-[var(--tiger-text-muted,#9ca3af)]",
418
+ isOpen && "rotate-180"
308
419
  ),
309
- showClearButton ? /* @__PURE__ */ jsx(
310
- "span",
311
- {
312
- className: "absolute right-2 top-1/2 -translate-y-1/2 text-[var(--tiger-treeselect-clear,var(--tiger-text-muted,#9ca3af))] hover:text-[var(--tiger-treeselect-clear-hover,var(--tiger-text,#111827))]",
313
- "aria-label": resolveLocaleText("Clear selection", mergedLocale?.common?.clearText),
314
- onClick: handleClear,
315
- children: /* @__PURE__ */ jsx(
316
- "svg",
317
- {
318
- className: "w-4 h-4",
319
- viewBox: icon20ViewBox,
320
- fill: "currentColor",
321
- xmlns: "http://www.w3.org/2000/svg",
322
- children: /* @__PURE__ */ jsx("path", { d: closeSolidIcon20PathD, fillRule: "evenodd", clipRule: "evenodd" })
323
- }
324
- )
325
- }
326
- ) : /* @__PURE__ */ jsx("span", { className: "absolute right-2 top-1/2 -translate-y-1/2 text-[var(--tiger-text-muted,#9ca3af)] pointer-events-none", children: /* @__PURE__ */ jsx(
420
+ "aria-hidden": "true",
421
+ children: /* @__PURE__ */ jsx(
327
422
  "svg",
328
423
  {
329
424
  className: "w-4 h-4 transition-transform",
@@ -332,10 +427,10 @@ var TreeSelect = (props) => {
332
427
  xmlns: "http://www.w3.org/2000/svg",
333
428
  children: /* @__PURE__ */ jsx("path", { d: chevronDownSolidIcon20PathD, fillRule: "evenodd", clipRule: "evenodd" })
334
429
  }
335
- ) })
336
- ]
337
- }
338
- ),
430
+ )
431
+ }
432
+ )
433
+ ] }),
339
434
  renderOverlayPortal(
340
435
  isOpen ? /* @__PURE__ */ jsxs(
341
436
  "div",
@@ -345,6 +440,7 @@ var TreeSelect = (props) => {
345
440
  className: classNames(getTreeSelectDropdownClasses(virtual), overlay.floatingClasses),
346
441
  style: overlay.floatingStyles,
347
442
  "data-positioned": overlay.positioned,
443
+ onKeyDown: handleDropdownKeyDown,
348
444
  children: [
349
445
  searchable && /* @__PURE__ */ jsx(
350
446
  "input",
@@ -360,7 +456,8 @@ var TreeSelect = (props) => {
360
456
  "Search tree",
361
457
  mergedLocale?.common?.searchPlaceholder
362
458
  ),
363
- onChange: (e) => updateSearchValue(e.target.value)
459
+ onChange: (e) => updateSearchValue(e.target.value),
460
+ onKeyDown: handleSearchKeyDown
364
461
  }
365
462
  ),
366
463
  visibleNodes.length > 0 ? virtual ? /* @__PURE__ */ jsx(
@@ -378,12 +475,12 @@ var TreeSelect = (props) => {
378
475
  height,
379
476
  renderItem: ({ index }) => {
380
477
  const item = visibleNodes[index];
381
- return item ? renderFlatNode(item) : null;
478
+ return item ? renderFlatNode(item, index) : null;
382
479
  }
383
480
  }
384
481
  )
385
482
  }
386
- ) : visibleNodes.map((flatNode) => renderFlatNode(flatNode)) : /* @__PURE__ */ jsx("div", { className: treeSelectEmptyClasses, children: resolveLocaleText("No data", emptyText, mergedLocale?.common?.emptyText) })
483
+ ) : visibleNodes.map((flatNode, index) => renderFlatNode(flatNode, index)) : /* @__PURE__ */ jsx("div", { className: treeSelectEmptyClasses, children: resolveLocaleText("No data", emptyText, mergedLocale?.common?.emptyText) })
387
484
  ]
388
485
  }
389
486
  ) : null,
@@ -13,6 +13,7 @@ import {
13
13
  calendarWeekdayClasses,
14
14
  getCalendarDayClasses,
15
15
  getCalendarMonthClasses,
16
+ isCalendarMonthDisabled,
16
17
  isSameDay,
17
18
  getMonthDays,
18
19
  getShortDayNames,
@@ -91,10 +92,13 @@ var Calendar = ({
91
92
  );
92
93
  const selectMonth = useCallback(
93
94
  (monthIdx) => {
95
+ if (isCalendarMonthDisabled(viewYear, monthIdx, disabledDate)) return;
94
96
  setViewMonth(monthIdx);
95
- onPanelChange?.(new Date(viewYear, monthIdx, 1), mode);
97
+ const date = new Date(viewYear, monthIdx, 1);
98
+ onChange?.(date);
99
+ onPanelChange?.(date, "month");
96
100
  },
97
- [viewYear, mode, onPanelChange]
101
+ [viewYear, disabledDate, onChange, onPanelChange]
98
102
  );
99
103
  const dayGridRef = useRef(null);
100
104
  const pendingFocusIsoRef = useRef(null);
@@ -256,14 +260,16 @@ var Calendar = ({
256
260
  ] }),
257
261
  mode === "year" ? /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-2", role: "grid", ref: monthGridRef, children: monthRows.map((row, ri) => /* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-2", role: "row", children: row.map((m, ci) => {
258
262
  const i = ri * 3 + ci;
263
+ const isDisabled = isCalendarMonthDisabled(viewYear, i, disabledDate);
259
264
  return /* @__PURE__ */ jsx(
260
265
  "button",
261
266
  {
262
267
  type: "button",
263
268
  role: "gridcell",
264
269
  "aria-selected": viewMonth === i,
265
- tabIndex: rovingMonthIdx === i ? 0 : -1,
266
- className: getCalendarMonthClasses(viewMonth === i),
270
+ disabled: isDisabled,
271
+ tabIndex: rovingMonthIdx === i && !isDisabled ? 0 : -1,
272
+ className: getCalendarMonthClasses(viewMonth === i, isDisabled),
267
273
  onClick: () => selectMonth(i),
268
274
  onFocus: () => setActiveMonthIdx(i),
269
275
  onKeyDown: (e) => handleMonthKeyDown(e, i),