@expcat/tigercat-react 2.0.19 → 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 (186) hide show
  1. package/README.md +25 -16
  2. package/dist/chunk-246DAUEF.mjs +181 -0
  3. package/dist/{chunk-PU3JY6RE.mjs → chunk-2JMI7TCM.mjs} +1 -1
  4. package/dist/chunk-2YBLMVDT.mjs +428 -0
  5. package/dist/chunk-2YOP55OF.mjs +639 -0
  6. package/dist/{chunk-25D5TXZH.mjs → chunk-32MCQMBJ.mjs} +8 -6
  7. package/dist/chunk-3HHEVMHE.mjs +180 -0
  8. package/dist/{chunk-HSBN5MLS.mjs → chunk-3LACOSJQ.mjs} +1 -1
  9. package/dist/{chunk-F6WV53BS.mjs → chunk-3LDDXHW2.mjs} +28 -11
  10. package/dist/{chunk-IXQAECFP.mjs → chunk-3QNIFKVF.mjs} +12 -14
  11. package/dist/{chunk-UD4DTVJZ.mjs → chunk-4C2X5PZO.mjs} +57 -25
  12. package/dist/chunk-5JETWHLJ.mjs +28 -0
  13. package/dist/{chunk-VA6PZWOH.mjs → chunk-5SEMRHBD.mjs} +14 -6
  14. package/dist/{chunk-EKILTLUO.mjs → chunk-72CJNKDY.mjs} +1 -1
  15. package/dist/{chunk-XE4YFBOZ.mjs → chunk-AUD3VOLO.mjs} +1 -1
  16. package/dist/{chunk-UT5BV2VO.mjs → chunk-AYFKHWJS.mjs} +16 -10
  17. package/dist/{chunk-RPSHILHD.mjs → chunk-BXAH2GH3.mjs} +8 -2
  18. package/dist/{chunk-EW5EO7VE.mjs → chunk-BYD7EAWK.mjs} +1 -1
  19. package/dist/{chunk-BOGOQ44C.mjs → chunk-CQOLQAB5.mjs} +105 -90
  20. package/dist/{chunk-L55UK45A.mjs → chunk-CRIEUKMD.mjs} +5 -2
  21. package/dist/{chunk-DKNVSQSV.mjs → chunk-CUAXRBKO.mjs} +12 -0
  22. package/dist/{chunk-E7OTDBI6.mjs → chunk-DECUASRW.mjs} +17 -19
  23. package/dist/{chunk-XMTEMBQV.mjs → chunk-EAAWB3CK.mjs} +16 -13
  24. package/dist/{chunk-D33BIMGK.mjs → chunk-EG7EMDKK.mjs} +12 -2
  25. package/dist/chunk-EW43YBPV.mjs +457 -0
  26. package/dist/{chunk-HOYBHB7B.mjs → chunk-FNK2VWPP.mjs} +1 -1
  27. package/dist/{chunk-RJPNBYK5.mjs → chunk-FQS24AUH.mjs} +12 -3
  28. package/dist/{chunk-LADKKOJT.mjs → chunk-GBEDWXLL.mjs} +16 -10
  29. package/dist/chunk-GR3Y3XWP.mjs +47 -0
  30. package/dist/{chunk-2ENQZECC.mjs → chunk-HAXRHSCN.mjs} +4 -3
  31. package/dist/{chunk-K4GIKSZE.mjs → chunk-I2BENK5X.mjs} +2 -1
  32. package/dist/chunk-IGBQGR6G.mjs +234 -0
  33. package/dist/chunk-J76R2S62.mjs +161 -0
  34. package/dist/{chunk-DNOPEJ5I.mjs → chunk-JZZPLKTW.mjs} +7 -4
  35. package/dist/{chunk-7KCQMXJA.mjs → chunk-KDURW5AS.mjs} +4 -3
  36. package/dist/{chunk-TFMEHUVZ.mjs → chunk-KKN7KLTB.mjs} +0 -1
  37. package/dist/{chunk-6MGQAJ62.mjs → chunk-KL6YJIZ3.mjs} +24 -7
  38. package/dist/chunk-KRDHM5KB.mjs +259 -0
  39. package/dist/{chunk-HHIW7V7B.mjs → chunk-M6ZPTGBV.mjs} +2 -10
  40. package/dist/chunk-MFPVVGNA.mjs +248 -0
  41. package/dist/{chunk-PXRZ6CKY.mjs → chunk-MJVSZ2UJ.mjs} +46 -16
  42. package/dist/{chunk-LZKBDQE4.mjs → chunk-MYI3FPG4.mjs} +23 -4
  43. package/dist/{chunk-OIGEBCAS.mjs → chunk-NADODEZX.mjs} +69 -1
  44. package/dist/{chunk-KMP5CVNK.mjs → chunk-NJWTZ5MO.mjs} +57 -45
  45. package/dist/chunk-NLGLBTSM.mjs +138 -0
  46. package/dist/chunk-NT7GW2FD.mjs +40 -0
  47. package/dist/{chunk-773LH7BK.mjs → chunk-O6VYD4E4.mjs} +24 -2
  48. package/dist/{chunk-G7D4QV7A.mjs → chunk-O7TV5OKS.mjs} +33 -6
  49. package/dist/{chunk-DPWRXXXW.mjs → chunk-OJ6SHHOZ.mjs} +3 -3
  50. package/dist/chunk-OKYMTHFQ.mjs +279 -0
  51. package/dist/{chunk-UYJJLHVA.mjs → chunk-PMQJ6AYT.mjs} +23 -21
  52. package/dist/chunk-PY2VUNEJ.mjs +494 -0
  53. package/dist/{chunk-BEJZPJIK.mjs → chunk-QOAOOD53.mjs} +10 -4
  54. package/dist/{chunk-2WGEHH5A.mjs → chunk-QU3QXUTC.mjs} +49 -23
  55. package/dist/{chunk-V6P7ZK6O.mjs → chunk-QXSUG7SN.mjs} +3 -3
  56. package/dist/{chunk-FYINJRYN.mjs → chunk-R7YZ6FKP.mjs} +27 -16
  57. package/dist/{chunk-YI6YWH66.mjs → chunk-RE5ZLA5D.mjs} +6 -6
  58. package/dist/{chunk-UCBW5RJN.mjs → chunk-RGVU4EMA.mjs} +11 -6
  59. package/dist/{chunk-IBSOUQGB.mjs → chunk-RRGPDFDI.mjs} +7 -4
  60. package/dist/{chunk-ZH5ZBLAN.mjs → chunk-RUQ3F3MV.mjs} +34 -7
  61. package/dist/chunk-SEOG5AGS.mjs +72 -0
  62. package/dist/{chunk-PGD5RPKF.mjs → chunk-SVIJ2UZA.mjs} +2 -1
  63. package/dist/chunk-SXWEFZOF.mjs +766 -0
  64. package/dist/{chunk-NCHUEGUW.mjs → chunk-TEVEXDY2.mjs} +27 -16
  65. package/dist/{chunk-DJOFM2VO.mjs → chunk-TO6MZFNQ.mjs} +52 -40
  66. package/dist/chunk-TQ6RIFWR.mjs +135 -0
  67. package/dist/chunk-U4M3DC2P.mjs +48 -0
  68. package/dist/{chunk-ZCGIZOMT.mjs → chunk-V7HJ5HLC.mjs} +6 -10
  69. package/dist/{chunk-SIDDYP3O.mjs → chunk-VJWSKJLJ.mjs} +1 -1
  70. package/dist/{chunk-ZG56T75O.mjs → chunk-WTHWLCRL.mjs} +51 -11
  71. package/dist/{chunk-KP6DEYWB.mjs → chunk-X4L3W7RQ.mjs} +1 -1
  72. package/dist/{chunk-ZMRTETN2.mjs → chunk-X6C6MNG5.mjs} +4 -3
  73. package/dist/chunk-XT43B7ZI.mjs +58 -0
  74. package/dist/{chunk-OGG2TQDG.mjs → chunk-XVHTJQ4T.mjs} +12 -1
  75. package/dist/{chunk-QJE3MZBO.mjs → chunk-Y6UH3EKE.mjs} +1 -1
  76. package/dist/chunk-YJ5T4XZN.mjs +81 -0
  77. package/dist/{chunk-VVNFXJMN.mjs → chunk-YNDPQVEK.mjs} +8 -1
  78. package/dist/{chunk-QGZ32NFQ.mjs → chunk-Z23KOLNU.mjs} +4 -3
  79. package/dist/{chunk-5CKMYMTS.mjs → chunk-ZATZRXMW.mjs} +27 -8
  80. package/dist/components/ActivityFeed.mjs +3 -3
  81. package/dist/components/Affix.mjs +1 -1
  82. package/dist/components/Anchor.mjs +1 -1
  83. package/dist/components/AreaChart.mjs +5 -4
  84. package/dist/components/AspectRatio.d.mts +10 -0
  85. package/dist/components/AspectRatio.mjs +8 -0
  86. package/dist/components/AutoComplete.mjs +1 -1
  87. package/dist/components/BarChart.mjs +5 -4
  88. package/dist/components/Calendar.mjs +1 -1
  89. package/dist/components/Cascader.mjs +1 -1
  90. package/dist/components/ChartCanvas.mjs +1 -1
  91. package/dist/components/ChatWindow.mjs +4 -4
  92. package/dist/components/Code.mjs +3 -1
  93. package/dist/components/CollapsePanel.mjs +1 -1
  94. package/dist/components/ColorPicker.mjs +1 -1
  95. package/dist/components/CommentThread.mjs +2 -2
  96. package/dist/components/ContextMenu.d.mts +36 -0
  97. package/dist/components/ContextMenu.mjs +17 -0
  98. package/dist/components/DataExport.mjs +2 -2
  99. package/dist/components/DataTableWithToolbar.mjs +7 -7
  100. package/dist/components/DonutChart.mjs +4 -4
  101. package/dist/components/Dropdown.mjs +1 -1
  102. package/dist/components/FileManager.mjs +2 -1
  103. package/dist/components/FloatButton.mjs +1 -1
  104. package/dist/components/FormItem.mjs +1 -1
  105. package/dist/components/FormWizard.mjs +1 -1
  106. package/dist/components/FunnelChart.mjs +3 -3
  107. package/dist/components/Gantt.d.mts +3 -1
  108. package/dist/components/Gantt.mjs +2 -2
  109. package/dist/components/GaugeChart.mjs +2 -2
  110. package/dist/components/HeatmapChart.mjs +3 -3
  111. package/dist/components/Highlight.d.mts +11 -0
  112. package/dist/components/Highlight.mjs +8 -0
  113. package/dist/components/Image.mjs +4 -4
  114. package/dist/components/ImageCompare.d.mts +15 -0
  115. package/dist/components/ImageCompare.mjs +8 -0
  116. package/dist/components/ImageGroup.mjs +2 -2
  117. package/dist/components/ImagePreview.mjs +1 -1
  118. package/dist/components/Input.mjs +1 -1
  119. package/dist/components/InputNumber.d.mts +1 -1
  120. package/dist/components/InputNumber.mjs +1 -1
  121. package/dist/components/InputOTP.d.mts +33 -0
  122. package/dist/components/InputOTP.mjs +12 -0
  123. package/dist/components/Kanban.mjs +2 -2
  124. package/dist/components/Kbd.d.mts +10 -0
  125. package/dist/components/Kbd.mjs +8 -0
  126. package/dist/components/LineChart.mjs +5 -4
  127. package/dist/components/List.mjs +2 -2
  128. package/dist/components/Loading.mjs +1 -1
  129. package/dist/components/LoadingBar.d.mts +8 -0
  130. package/dist/components/LoadingBar.mjs +138 -0
  131. package/dist/components/LoadingBarContainer.d.mts +8 -0
  132. package/dist/components/LoadingBarContainer.mjs +8 -0
  133. package/dist/components/LoadingBarRoot.d.mts +6 -0
  134. package/dist/components/LoadingBarRoot.mjs +6 -0
  135. package/dist/components/Marquee.d.mts +10 -0
  136. package/dist/components/Marquee.mjs +8 -0
  137. package/dist/components/MaskInput.d.mts +37 -0
  138. package/dist/components/MaskInput.mjs +10 -0
  139. package/dist/components/Masonry.d.mts +10 -0
  140. package/dist/components/Masonry.mjs +8 -0
  141. package/dist/components/NavigationMenu.d.mts +84 -0
  142. package/dist/components/NavigationMenu.mjs +23 -0
  143. package/dist/components/NotificationCenter.mjs +4 -4
  144. package/dist/components/OrgChart.mjs +2 -2
  145. package/dist/components/PageHeader.d.mts +34 -0
  146. package/dist/components/PageHeader.mjs +11 -0
  147. package/dist/components/Pagination.mjs +1 -1
  148. package/dist/components/PieChart.mjs +3 -3
  149. package/dist/components/Popconfirm.mjs +2 -2
  150. package/dist/components/Popover.mjs +2 -2
  151. package/dist/components/QRCode.d.mts +2 -2
  152. package/dist/components/QRCode.mjs +1 -1
  153. package/dist/components/RadarChart.mjs +4 -4
  154. package/dist/components/Rate.mjs +1 -1
  155. package/dist/components/ScatterChart.mjs +5 -4
  156. package/dist/components/ScrollArea.d.mts +10 -0
  157. package/dist/components/ScrollArea.mjs +8 -0
  158. package/dist/components/ScrollSpy.mjs +1 -1
  159. package/dist/components/Signature.mjs +1 -1
  160. package/dist/components/SplitButton.d.mts +38 -0
  161. package/dist/components/SplitButton.mjs +12 -0
  162. package/dist/components/Splitter.mjs +1 -1
  163. package/dist/components/Stepper.d.mts +2 -0
  164. package/dist/components/Stepper.mjs +2 -1
  165. package/dist/components/SunburstChart.mjs +3 -3
  166. package/dist/components/Switch.d.mts +5 -1
  167. package/dist/components/Switch.mjs +2 -1
  168. package/dist/components/Table.mjs +2 -2
  169. package/dist/components/TagsInput.d.mts +41 -0
  170. package/dist/components/TagsInput.mjs +13 -0
  171. package/dist/components/TaskBoard.mjs +1 -1
  172. package/dist/components/Textarea.mjs +1 -1
  173. package/dist/components/Tooltip.mjs +2 -2
  174. package/dist/components/Tour.mjs +1 -1
  175. package/dist/components/TreeMapChart.mjs +3 -3
  176. package/dist/components/TreeSelect.mjs +2 -1
  177. package/dist/components/Upload.mjs +1 -1
  178. package/dist/hooks/useChartInteraction.d.mts +5 -0
  179. package/dist/hooks/useChartInteraction.mjs +1 -1
  180. package/dist/index.d.mts +17 -1
  181. package/dist/index.mjs +406 -0
  182. package/package.json +117 -2
  183. package/dist/chunk-7AFRHC7P.mjs +0 -312
  184. package/dist/chunk-CB4SK5AU.mjs +0 -235
  185. package/dist/chunk-KPACLRQH.mjs +0 -55
  186. package/dist/chunk-YIB6ZXZF.mjs +0 -386
@@ -0,0 +1,259 @@
1
+ import {
2
+ useFormItemControlContext
3
+ } from "./chunk-F6T3OLTQ.mjs";
4
+ import {
5
+ useControlledState
6
+ } from "./chunk-MEFARVQI.mjs";
7
+ import {
8
+ Tag
9
+ } from "./chunk-7EXOY7GD.mjs";
10
+ import {
11
+ useTigerConfig
12
+ } from "./chunk-YSIXURBW.mjs";
13
+
14
+ // src/components/TagsInput.tsx
15
+ import { useEffect, useId, useRef, useState } from "react";
16
+ import {
17
+ addTags,
18
+ classNames,
19
+ extractTagCandidates,
20
+ formatRemoveTagLabel,
21
+ getTagsInputClearButtonClasses,
22
+ getTagsInputContainerClasses,
23
+ getTagsInputErrorClasses,
24
+ getTagsInputHighlightClasses,
25
+ getTagsInputInnerInputClasses,
26
+ getTagsInputLabels,
27
+ injectShakeStyle,
28
+ removeTagAt,
29
+ SHAKE_CLASS,
30
+ splitTagInput
31
+ } from "@expcat/tigercat-core";
32
+ import { jsx, jsxs } from "react/jsx-runtime";
33
+ var TagsInput = ({
34
+ size = "md",
35
+ status: statusProp,
36
+ errorMessage: errorMessageProp,
37
+ _shakeTrigger: shakeTriggerProp,
38
+ value,
39
+ defaultValue,
40
+ placeholder = "",
41
+ allowDuplicates = false,
42
+ max,
43
+ delimiters = [","],
44
+ addOnBlur = false,
45
+ beforeAdd,
46
+ clearable = false,
47
+ disabled = false,
48
+ readonly = false,
49
+ name,
50
+ id,
51
+ removeTagAriaLabel,
52
+ onChange,
53
+ onAdd,
54
+ onRemove,
55
+ onClear,
56
+ onFocus,
57
+ onBlur,
58
+ className,
59
+ style,
60
+ ...rest
61
+ }) => {
62
+ injectShakeStyle();
63
+ const config = useTigerConfig();
64
+ const formItemControl = useFormItemControlContext();
65
+ const status = statusProp ?? formItemControl?.status ?? "default";
66
+ const errorMessage = errorMessageProp ?? formItemControl?.errorMessage;
67
+ const shakeTrigger = shakeTriggerProp ?? formItemControl?.shakeTrigger;
68
+ const labels = getTagsInputLabels(config.locale);
69
+ const reactId = useId();
70
+ const errorMsgId = `tiger-tags-input-error-${reactId}`;
71
+ const containerRef = useRef(null);
72
+ const inputRef = useRef(null);
73
+ const [tags, setTags] = useControlledState(value, defaultValue ?? [], onChange);
74
+ const [inputText, setInputText] = useState("");
75
+ const [highlightedIndex, setHighlightedIndex] = useState(null);
76
+ useEffect(() => {
77
+ if (status === "error" && containerRef.current) {
78
+ const el = containerRef.current;
79
+ el.classList.remove(SHAKE_CLASS);
80
+ void el.offsetWidth;
81
+ el.classList.add(SHAKE_CLASS);
82
+ }
83
+ }, [status, shakeTrigger]);
84
+ const isInteractive = !disabled && !readonly;
85
+ const commitCandidates = (candidates) => {
86
+ const prepared = [];
87
+ for (const raw of candidates) {
88
+ if (!beforeAdd) {
89
+ prepared.push(raw);
90
+ continue;
91
+ }
92
+ const result = beforeAdd(raw.trim());
93
+ if (result === false) continue;
94
+ prepared.push(typeof result === "string" ? result : raw);
95
+ }
96
+ if (prepared.length === 0) return { added: [] };
97
+ const { tags: nextTags, added } = addTags(tags, prepared, { allowDuplicates, max });
98
+ if (added.length > 0) {
99
+ setTags(nextTags);
100
+ added.forEach((tag) => onAdd?.(tag));
101
+ }
102
+ return { added };
103
+ };
104
+ const handleInputChange = (event) => {
105
+ if (!isInteractive) return;
106
+ setHighlightedIndex(null);
107
+ const { candidates, pending } = extractTagCandidates(event.currentTarget.value, delimiters);
108
+ if (candidates.length > 0) commitCandidates(candidates);
109
+ setInputText(pending);
110
+ };
111
+ const removeAt = (index) => {
112
+ const tag = tags[index];
113
+ if (tag === void 0) return;
114
+ setTags(removeTagAt(tags, index));
115
+ onRemove?.(tag, index);
116
+ };
117
+ const handleKeyDown = (event) => {
118
+ if (!isInteractive) return;
119
+ if (event.key === "Enter") {
120
+ event.preventDefault();
121
+ if (inputText.trim()) {
122
+ const { added } = commitCandidates([inputText]);
123
+ if (added.length > 0) setInputText("");
124
+ }
125
+ return;
126
+ }
127
+ if (event.key === "Backspace" && inputText === "") {
128
+ if (highlightedIndex !== null) {
129
+ removeAt(highlightedIndex);
130
+ setHighlightedIndex(null);
131
+ } else if (tags.length > 0) {
132
+ setHighlightedIndex(tags.length - 1);
133
+ }
134
+ return;
135
+ }
136
+ if (event.key === "ArrowLeft" && inputText === "" && tags.length > 0) {
137
+ setHighlightedIndex((prev) => {
138
+ if (prev === null) return tags.length - 1;
139
+ return Math.max(0, prev - 1);
140
+ });
141
+ return;
142
+ }
143
+ if (event.key === "ArrowRight" && highlightedIndex !== null) {
144
+ setHighlightedIndex((prev) => {
145
+ if (prev === null || prev >= tags.length - 1) return null;
146
+ return prev + 1;
147
+ });
148
+ return;
149
+ }
150
+ if (event.key === "Escape" && highlightedIndex !== null) {
151
+ setHighlightedIndex(null);
152
+ return;
153
+ }
154
+ if (highlightedIndex !== null) setHighlightedIndex(null);
155
+ };
156
+ const handlePaste = (event) => {
157
+ if (!isInteractive) return;
158
+ const text = event.clipboardData.getData("text");
159
+ const candidates = splitTagInput(text, delimiters);
160
+ if (candidates.length <= 1) return;
161
+ event.preventDefault();
162
+ commitCandidates(candidates);
163
+ setInputText("");
164
+ };
165
+ const handleBlur = (event) => {
166
+ setHighlightedIndex(null);
167
+ if (addOnBlur && inputText.trim() && isInteractive) {
168
+ const { added } = commitCandidates([inputText]);
169
+ if (added.length > 0) setInputText("");
170
+ }
171
+ onBlur?.(event);
172
+ };
173
+ const handleClear = () => {
174
+ if (!isInteractive || tags.length === 0) return;
175
+ setTags([]);
176
+ setInputText("");
177
+ setHighlightedIndex(null);
178
+ onClear?.();
179
+ inputRef.current?.focus();
180
+ };
181
+ const focusInput = (event) => {
182
+ if (event.target === containerRef.current) inputRef.current?.focus();
183
+ };
184
+ const activeError = status === "error" && !!errorMessage;
185
+ const isFull = max !== void 0 && tags.length >= max;
186
+ const removeLabelTemplate = removeTagAriaLabel ?? labels.removeTagLabel;
187
+ const containerNode = /* @__PURE__ */ jsxs(
188
+ "div",
189
+ {
190
+ ...rest,
191
+ ref: containerRef,
192
+ id,
193
+ className: classNames(getTagsInputContainerClasses(size, status, { disabled }), className),
194
+ style,
195
+ "data-state": isFull ? "full" : void 0,
196
+ onClick: focusInput,
197
+ children: [
198
+ tags.map((tag, index) => /* @__PURE__ */ jsx(
199
+ Tag,
200
+ {
201
+ size: size === "lg" ? "md" : "sm",
202
+ closable: isInteractive,
203
+ closeAriaLabel: formatRemoveTagLabel(removeLabelTemplate, tag),
204
+ className: index === highlightedIndex ? getTagsInputHighlightClasses() : void 0,
205
+ onClose: (event) => {
206
+ event.preventDefault();
207
+ removeAt(index);
208
+ },
209
+ children: tag
210
+ },
211
+ `${tag}-${index}`
212
+ )),
213
+ /* @__PURE__ */ jsx(
214
+ "input",
215
+ {
216
+ ref: inputRef,
217
+ className: getTagsInputInnerInputClasses(),
218
+ type: "text",
219
+ value: inputText,
220
+ placeholder: tags.length === 0 ? placeholder : "",
221
+ disabled,
222
+ readOnly: readonly,
223
+ id: id ? `${id}-input` : void 0,
224
+ ...status === "error" ? { "aria-invalid": true } : {},
225
+ ...activeError ? { "aria-describedby": errorMsgId } : {},
226
+ onChange: handleInputChange,
227
+ onKeyDown: handleKeyDown,
228
+ onPaste: handlePaste,
229
+ onFocus,
230
+ onBlur: handleBlur
231
+ }
232
+ ),
233
+ clearable && tags.length > 0 && isInteractive && /* @__PURE__ */ jsx(
234
+ "button",
235
+ {
236
+ type: "button",
237
+ className: getTagsInputClearButtonClasses(),
238
+ onClick: handleClear,
239
+ "aria-label": labels.clearAllLabel,
240
+ tabIndex: -1,
241
+ children: "\u2715"
242
+ }
243
+ ),
244
+ name && /* @__PURE__ */ jsx("input", { type: "hidden", name, value: tags.join(",") })
245
+ ]
246
+ }
247
+ );
248
+ if (!activeError) return containerNode;
249
+ return /* @__PURE__ */ jsxs("div", { children: [
250
+ containerNode,
251
+ /* @__PURE__ */ jsx("div", { id: errorMsgId, className: getTagsInputErrorClasses(), children: errorMessage })
252
+ ] });
253
+ };
254
+ var TagsInput_default = TagsInput;
255
+
256
+ export {
257
+ TagsInput,
258
+ TagsInput_default
259
+ };
@@ -10,7 +10,6 @@ import {
10
10
  getPageRange,
11
11
  validateCurrentPage,
12
12
  getPageNumbers,
13
- defaultTotalText,
14
13
  formatPaginationTotal,
15
14
  getPaginationContainerClasses,
16
15
  getPaginationButtonBaseClasses,
@@ -135,14 +134,7 @@ var Pagination = ({
135
134
  }
136
135
  onPageSizeChange?.(newPage, newPageSize);
137
136
  },
138
- [
139
- disabled,
140
- total,
141
- validatedCurrentPage,
142
- controlledPageSize,
143
- controlledCurrent,
144
- onPageSizeChange
145
- ]
137
+ [disabled, total, validatedCurrentPage, controlledPageSize, controlledCurrent, onPageSizeChange]
146
138
  );
147
139
  const handleQuickJumperSubmit = useCallback(() => {
148
140
  quickJumperValidationSchedulerRef.current?.cancel();
@@ -186,7 +178,7 @@ var Pagination = ({
186
178
  const nextDisabled = validatedCurrentPage >= totalPages || disabled;
187
179
  const elements = [];
188
180
  if (showTotal) {
189
- const totalTextFn = totalText || (labelsOverride?.totalText || mergedLocale?.pagination?.totalText ? (value, range) => formatPaginationTotal(labels.totalText, value, range, localeCode) : defaultTotalText);
181
+ const totalTextFn = totalText || ((value, range) => formatPaginationTotal(labels.totalText, value, range, localeCode));
190
182
  elements.push(
191
183
  /* @__PURE__ */ jsx("span", { className: getTotalTextClasses(size), children: totalTextFn(total, pageRange) }, "total")
192
184
  );
@@ -0,0 +1,248 @@
1
+ // src/components/ScrollArea.tsx
2
+ import {
3
+ forwardRef,
4
+ useCallback,
5
+ useEffect,
6
+ useImperativeHandle,
7
+ useMemo,
8
+ useRef,
9
+ useState
10
+ } from "react";
11
+ import {
12
+ classNames,
13
+ computeScrollAreaState,
14
+ computeScrollFromThumbOffset,
15
+ computeScrollFromTrackPoint,
16
+ createDocumentDragSession,
17
+ createEmptyScrollAreaState,
18
+ getScrollAreaBoxStyle,
19
+ getScrollAreaContentClasses,
20
+ getScrollAreaScrollbarClasses,
21
+ getScrollAreaShadowClasses,
22
+ getScrollAreaShadowSides,
23
+ getScrollAreaThumbClasses,
24
+ getScrollAreaThumbStyle,
25
+ getScrollAreaViewportClasses,
26
+ observeScrollAreaSize,
27
+ readScrollAreaMetrics,
28
+ scrollAreaRootClasses,
29
+ shouldRenderScrollAreaScrollbar,
30
+ SCROLL_AREA_MIN_THUMB_SIZE
31
+ } from "@expcat/tigercat-core";
32
+ import { jsx, jsxs } from "react/jsx-runtime";
33
+ var ScrollArea = forwardRef(
34
+ ({
35
+ direction = "vertical",
36
+ scrollbar = "auto",
37
+ scrollbarSize = "md",
38
+ shadow = false,
39
+ minThumbSize = SCROLL_AREA_MIN_THUMB_SIZE,
40
+ height,
41
+ maxHeight,
42
+ width,
43
+ maxWidth,
44
+ ariaLabel,
45
+ className,
46
+ viewportClassName,
47
+ children,
48
+ onScroll,
49
+ ...rest
50
+ }, ref) => {
51
+ const viewportRef = useRef(null);
52
+ const contentRef = useRef(null);
53
+ const dragSessionRef = useRef(null);
54
+ const stateRef = useRef(createEmptyScrollAreaState());
55
+ const [state, setState] = useState(stateRef.current);
56
+ const [draggingAxis, setDraggingAxis] = useState(null);
57
+ const onScrollRef = useRef(onScroll);
58
+ onScrollRef.current = onScroll;
59
+ const syncState = useCallback(() => {
60
+ const viewport = viewportRef.current;
61
+ if (!viewport) return;
62
+ const next = computeScrollAreaState(readScrollAreaMetrics(viewport), minThumbSize);
63
+ stateRef.current = next;
64
+ setState(next);
65
+ }, [minThumbSize]);
66
+ const handleScroll = useCallback(() => {
67
+ const viewport = viewportRef.current;
68
+ if (!viewport) return;
69
+ syncState();
70
+ onScrollRef.current?.({
71
+ scrollTop: viewport.scrollTop,
72
+ scrollLeft: viewport.scrollLeft,
73
+ state: stateRef.current
74
+ });
75
+ }, [syncState]);
76
+ const applyScroll = useCallback(
77
+ (axis, position) => {
78
+ const viewport = viewportRef.current;
79
+ if (!viewport) return;
80
+ if (axis === "y") viewport.scrollTop = position;
81
+ else viewport.scrollLeft = position;
82
+ handleScroll();
83
+ },
84
+ [handleScroll]
85
+ );
86
+ const startThumbDrag = useCallback(
87
+ (axis, event) => {
88
+ const viewport = viewportRef.current;
89
+ if (!viewport) return;
90
+ event.preventDefault();
91
+ event.stopPropagation();
92
+ const axisState = axis === "y" ? stateRef.current.y : stateRef.current.x;
93
+ const startOffset = axisState.thumbOffset;
94
+ const startPoint = axis === "y" ? event.clientY : event.clientX;
95
+ dragSessionRef.current?.dispose();
96
+ setDraggingAxis(axis);
97
+ dragSessionRef.current = createDocumentDragSession({
98
+ startX: event.clientX,
99
+ startY: event.clientY,
100
+ ownerDocument: viewport.ownerDocument,
101
+ onMove: ({ currentX, currentY }) => {
102
+ const current = axis === "y" ? currentY : currentX;
103
+ const trackSize = axis === "y" ? viewport.clientHeight : viewport.clientWidth;
104
+ applyScroll(
105
+ axis,
106
+ computeScrollFromThumbOffset(
107
+ startOffset + (current - startPoint),
108
+ trackSize,
109
+ axisState.thumbSize,
110
+ axis === "y" ? viewport.scrollHeight : viewport.scrollWidth,
111
+ trackSize
112
+ )
113
+ );
114
+ },
115
+ onEnd: () => {
116
+ setDraggingAxis(null);
117
+ dragSessionRef.current = null;
118
+ }
119
+ });
120
+ },
121
+ [applyScroll]
122
+ );
123
+ const handleTrackMouseDown = useCallback(
124
+ (axis, event) => {
125
+ const target = event.target;
126
+ if (target?.dataset.scrollAreaThumb) {
127
+ startThumbDrag(axis, event);
128
+ return;
129
+ }
130
+ const viewport = viewportRef.current;
131
+ if (!viewport) return;
132
+ const rect = event.currentTarget.getBoundingClientRect();
133
+ const point = axis === "y" ? event.clientY - rect.top : event.clientX - rect.left;
134
+ const axisState = axis === "y" ? stateRef.current.y : stateRef.current.x;
135
+ const trackSize = axis === "y" ? viewport.clientHeight : viewport.clientWidth;
136
+ applyScroll(
137
+ axis,
138
+ computeScrollFromTrackPoint(
139
+ point,
140
+ trackSize,
141
+ axisState.thumbSize,
142
+ axis === "y" ? viewport.scrollHeight : viewport.scrollWidth,
143
+ trackSize
144
+ )
145
+ );
146
+ },
147
+ [applyScroll, startThumbDrag]
148
+ );
149
+ const scrollTo = useCallback(
150
+ (options) => {
151
+ const viewport = viewportRef.current;
152
+ if (!viewport) return;
153
+ const behavior = options.behavior ?? "auto";
154
+ if (typeof viewport.scrollTo === "function") {
155
+ viewport.scrollTo({ top: options.top, left: options.left, behavior });
156
+ } else {
157
+ if (options.top !== void 0) viewport.scrollTop = options.top;
158
+ if (options.left !== void 0) viewport.scrollLeft = options.left;
159
+ }
160
+ handleScroll();
161
+ },
162
+ [handleScroll]
163
+ );
164
+ useImperativeHandle(
165
+ ref,
166
+ () => ({
167
+ scrollTo,
168
+ scrollToTop: (behavior) => scrollTo({ top: 0, behavior }),
169
+ scrollToBottom: (behavior) => scrollTo({ top: viewportRef.current?.scrollHeight ?? 0, behavior }),
170
+ getViewport: () => viewportRef.current,
171
+ getState: () => stateRef.current
172
+ }),
173
+ [scrollTo]
174
+ );
175
+ useEffect(() => {
176
+ syncState();
177
+ return observeScrollAreaSize([viewportRef.current, contentRef.current], syncState);
178
+ }, [syncState, direction]);
179
+ useEffect(() => () => dragSessionRef.current?.dispose(), []);
180
+ const shadowSides = useMemo(
181
+ () => shadow ? getScrollAreaShadowSides(state, direction) : [],
182
+ [shadow, state, direction]
183
+ );
184
+ const renderScrollbar = (axis) => {
185
+ const axisState = axis === "y" ? state.y : state.x;
186
+ if (!shouldRenderScrollAreaScrollbar(scrollbar, direction, axis, axisState)) return null;
187
+ return /* @__PURE__ */ jsx(
188
+ "div",
189
+ {
190
+ className: getScrollAreaScrollbarClasses(axis, scrollbarSize, scrollbar),
191
+ "data-scroll-area-scrollbar": axis,
192
+ "aria-hidden": "true",
193
+ onMouseDown: (event) => handleTrackMouseDown(axis, event),
194
+ children: /* @__PURE__ */ jsx(
195
+ "div",
196
+ {
197
+ className: getScrollAreaThumbClasses(axis, draggingAxis === axis),
198
+ style: getScrollAreaThumbStyle(axis, axisState),
199
+ "data-scroll-area-thumb": axis
200
+ }
201
+ )
202
+ }
203
+ );
204
+ };
205
+ return /* @__PURE__ */ jsxs("div", { ...rest, className: classNames(scrollAreaRootClasses, className), "data-scroll-area": "", children: [
206
+ /* @__PURE__ */ jsx(
207
+ "div",
208
+ {
209
+ ref: viewportRef,
210
+ className: getScrollAreaViewportClasses(direction, viewportClassName),
211
+ style: getScrollAreaBoxStyle({ height, maxHeight, width, maxWidth }),
212
+ tabIndex: 0,
213
+ role: ariaLabel ? "region" : void 0,
214
+ "aria-label": ariaLabel,
215
+ "data-scroll-area-viewport": "",
216
+ onScroll: handleScroll,
217
+ children: /* @__PURE__ */ jsx(
218
+ "div",
219
+ {
220
+ ref: contentRef,
221
+ className: getScrollAreaContentClasses(direction),
222
+ "data-scroll-area-content": "",
223
+ children
224
+ }
225
+ )
226
+ }
227
+ ),
228
+ shadowSides.map((side) => /* @__PURE__ */ jsx(
229
+ "div",
230
+ {
231
+ className: getScrollAreaShadowClasses(side),
232
+ "data-scroll-area-shadow": side,
233
+ "aria-hidden": "true"
234
+ },
235
+ side
236
+ )),
237
+ renderScrollbar("y"),
238
+ renderScrollbar("x")
239
+ ] });
240
+ }
241
+ );
242
+ ScrollArea.displayName = "ScrollArea";
243
+ var ScrollArea_default = ScrollArea;
244
+
245
+ export {
246
+ ScrollArea,
247
+ ScrollArea_default
248
+ };
@@ -3,38 +3,47 @@ import {
3
3
  } from "./chunk-Y5X3G2LD.mjs";
4
4
  import {
5
5
  Input
6
- } from "./chunk-F6WV53BS.mjs";
6
+ } from "./chunk-3LDDXHW2.mjs";
7
7
  import {
8
8
  Empty
9
9
  } from "./chunk-W7BC4I2Y.mjs";
10
10
  import {
11
11
  Textarea
12
- } from "./chunk-UYJJLHVA.mjs";
12
+ } from "./chunk-PMQJ6AYT.mjs";
13
13
  import {
14
14
  Button
15
15
  } from "./chunk-5TE7KLE5.mjs";
16
16
  import {
17
17
  Avatar
18
18
  } from "./chunk-OO562MFD.mjs";
19
+ import {
20
+ useTigerConfig
21
+ } from "./chunk-YSIXURBW.mjs";
19
22
 
20
23
  // src/components/ChatWindow.tsx
21
24
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
22
25
  import {
23
26
  classNames,
24
27
  getChatMessageStatusInfo,
28
+ buildChatMessageStatusInfo,
25
29
  getChatStatusBarClasses,
26
- formatChatTime
30
+ formatChatTime,
31
+ getChatWindowLabels,
32
+ mergeTigerLocale,
33
+ resolveLocaleText
27
34
  } from "@expcat/tigercat-core";
28
35
  import { jsx, jsxs } from "react/jsx-runtime";
29
36
  var ChatWindow = ({
30
37
  messages = [],
31
38
  value,
32
39
  defaultValue = "",
33
- placeholder = "\u8BF7\u8F93\u5165\u6D88\u606F",
40
+ placeholder,
34
41
  disabled = false,
35
42
  maxLength,
36
- emptyText = "\u6682\u65E0\u6D88\u606F",
37
- sendText = "\u53D1\u9001",
43
+ emptyText,
44
+ sendText,
45
+ locale,
46
+ labels: labelsOverride,
38
47
  messageListAriaLabel,
39
48
  inputAriaLabel,
40
49
  sendAriaLabel,
@@ -59,6 +68,19 @@ var ChatWindow = ({
59
68
  className,
60
69
  ...props
61
70
  }) => {
71
+ const config = useTigerConfig();
72
+ const mergedLocale = useMemo(
73
+ () => mergeTigerLocale(config.locale, locale),
74
+ [config.locale, locale]
75
+ );
76
+ const labels = useMemo(
77
+ () => getChatWindowLabels(mergedLocale, labelsOverride),
78
+ [mergedLocale, labelsOverride]
79
+ );
80
+ const statusMap = useMemo(() => buildChatMessageStatusInfo(labels), [labels]);
81
+ const resolvedPlaceholder = resolveLocaleText(labels.placeholder, placeholder);
82
+ const resolvedEmptyText = resolveLocaleText(labels.emptyText, emptyText);
83
+ const resolvedSendText = resolveLocaleText(labels.sendText, sendText);
62
84
  const [innerValue, setInnerValue] = useState(value ?? defaultValue);
63
85
  useEffect(() => {
64
86
  if (value !== void 0) {
@@ -112,7 +134,7 @@ var ChatWindow = ({
112
134
  const renderMessageItem = useCallback(
113
135
  (message, index) => {
114
136
  const isSelf = message.direction === "self";
115
- const statusInfo = message.status ? getChatMessageStatusInfo(message.status) : void 0;
137
+ const statusInfo = message.status ? getChatMessageStatusInfo(message.status, statusMap) : void 0;
116
138
  const timeText = showTime ? formatChatTime(message.time) : "";
117
139
  return /* @__PURE__ */ jsxs(
118
140
  "div",
@@ -163,7 +185,7 @@ var ChatWindow = ({
163
185
  message.id ?? index
164
186
  );
165
187
  },
166
- [renderMessage, showAvatar, showName, showTime]
188
+ [renderMessage, showAvatar, showName, showTime, statusMap]
167
189
  );
168
190
  const messageListRef = useRef(null);
169
191
  useEffect(() => {
@@ -185,7 +207,7 @@ var ChatWindow = ({
185
207
  role: "log",
186
208
  "aria-live": "polite",
187
209
  "aria-relevant": "additions text",
188
- "aria-label": messageListAriaLabel ?? "\u6D88\u606F\u5217\u8868",
210
+ "aria-label": messageListAriaLabel ?? "Message list",
189
211
  children: /* @__PURE__ */ jsx(
190
212
  VirtualList,
191
213
  {
@@ -204,8 +226,8 @@ var ChatWindow = ({
204
226
  role: "log",
205
227
  "aria-live": "polite",
206
228
  "aria-relevant": "additions text",
207
- "aria-label": messageListAriaLabel ?? "\u6D88\u606F\u5217\u8868",
208
- children: messages.length === 0 ? /* @__PURE__ */ jsx("div", { className: "h-full flex items-center justify-center py-8", children: /* @__PURE__ */ jsx(Empty, { description: emptyText }) }) : messages.map(renderMessageItem)
229
+ "aria-label": messageListAriaLabel ?? "Message list",
230
+ children: messages.length === 0 ? /* @__PURE__ */ jsx("div", { className: "h-full flex items-center justify-center py-8", children: /* @__PURE__ */ jsx(Empty, { description: resolvedEmptyText }) }) : messages.map(renderMessageItem)
209
231
  }
210
232
  ),
211
233
  statusText && /* @__PURE__ */ jsx("div", { className: getChatStatusBarClasses(statusVariant), children: statusText }),
@@ -214,10 +236,10 @@ var ChatWindow = ({
214
236
  Input,
215
237
  {
216
238
  value: inputValue,
217
- placeholder,
239
+ placeholder: resolvedPlaceholder,
218
240
  disabled,
219
241
  maxLength,
220
- "aria-label": inputAriaLabel ?? placeholder ?? "\u6D88\u606F\u8F93\u5165",
242
+ "aria-label": inputAriaLabel ?? resolvedPlaceholder,
221
243
  onChange: (event) => handleValueChange(event.currentTarget.value),
222
244
  onKeyDown: handleKeyDown
223
245
  }
@@ -225,16 +247,24 @@ var ChatWindow = ({
225
247
  Textarea,
226
248
  {
227
249
  value: inputValue,
228
- placeholder,
250
+ placeholder: resolvedPlaceholder,
229
251
  disabled,
230
252
  maxLength,
231
253
  rows: inputRows,
232
- "aria-label": inputAriaLabel ?? placeholder ?? "\u6D88\u606F\u8F93\u5165",
254
+ "aria-label": inputAriaLabel ?? resolvedPlaceholder,
233
255
  onChange: (event) => handleValueChange(event.currentTarget.value),
234
256
  onKeyDown: handleKeyDown
235
257
  }
236
258
  ) }),
237
- /* @__PURE__ */ jsx(Button, { disabled: !canSend, onClick: handleSend, "aria-label": sendAriaLabel ?? sendText, children: sendText })
259
+ /* @__PURE__ */ jsx(
260
+ Button,
261
+ {
262
+ disabled: !canSend,
263
+ onClick: handleSend,
264
+ "aria-label": sendAriaLabel ?? resolvedSendText,
265
+ children: resolvedSendText
266
+ }
267
+ )
238
268
  ] })
239
269
  ] });
240
270
  };