@expcat/tigercat-react 0.2.10 → 0.3.0

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 (125) hide show
  1. package/dist/chunk-4IO2M3ZJ.js +110 -0
  2. package/dist/chunk-4MMT4EJJ.mjs +78 -0
  3. package/dist/chunk-67EK62HG.mjs +65 -0
  4. package/dist/chunk-6YKZAWNX.js +258 -0
  5. package/dist/chunk-73DMQ2SR.mjs +206 -0
  6. package/dist/chunk-FAZQT7YP.mjs +255 -0
  7. package/dist/{chunk-HRYBEBZC.js → chunk-GJKT2B56.js} +5 -1
  8. package/dist/{chunk-VXHBQTZS.js → chunk-GY6D4XS3.js} +13 -5
  9. package/dist/chunk-GZPMLPRW.js +107 -0
  10. package/dist/{chunk-7JQ7LURS.mjs → chunk-H36CWHUP.mjs} +9 -4
  11. package/dist/{chunk-5XKYWZZZ.mjs → chunk-HGTF6A46.mjs} +5 -1
  12. package/dist/chunk-HT2BXCEM.js +264 -0
  13. package/dist/chunk-HUZVBDHV.js +81 -0
  14. package/dist/{chunk-6ZC7H22S.mjs → chunk-IAF24RKI.mjs} +1 -1
  15. package/dist/chunk-IYFSM2GA.mjs +141 -0
  16. package/dist/chunk-JAVDNFJD.js +144 -0
  17. package/dist/chunk-JOHKSMJM.mjs +266 -0
  18. package/dist/{chunk-WEGU7O4J.mjs → chunk-KOLLAGRK.mjs} +1 -1
  19. package/dist/{chunk-P273E6XE.js → chunk-MQTHGPHF.js} +37 -21
  20. package/dist/{chunk-IS7YOBR7.mjs → chunk-NDOYQK2R.mjs} +13 -5
  21. package/dist/chunk-OVWCTDAL.js +209 -0
  22. package/dist/{chunk-2DOPHSZP.js → chunk-OWUGXP6K.js} +8 -3
  23. package/dist/{chunk-GIYBVWR4.mjs → chunk-OZLAGTZW.mjs} +38 -22
  24. package/dist/{chunk-OD2NNQD2.js → chunk-PBJ2J2B3.js} +2 -2
  25. package/dist/chunk-PVOQUXIB.mjs +189 -0
  26. package/dist/chunk-Q2GPRAF4.js +66 -0
  27. package/dist/chunk-R67R3TVA.mjs +261 -0
  28. package/dist/{chunk-6PUSRC6S.js → chunk-T3GSXTDU.js} +2 -2
  29. package/dist/chunk-WKGCUR7O.mjs +107 -0
  30. package/dist/chunk-X4F6NSI5.mjs +104 -0
  31. package/dist/chunk-Y6557RWE.mjs +62 -0
  32. package/dist/chunk-YIF5VX7K.mjs +158 -0
  33. package/dist/chunk-Z5DDULTA.js +72 -0
  34. package/dist/chunk-Z6G4HABF.js +272 -0
  35. package/dist/chunk-ZN2BZCTI.js +192 -0
  36. package/dist/chunk-ZPWDDAFE.js +162 -0
  37. package/dist/components/ActivityFeed.d.mts +10 -0
  38. package/dist/components/ActivityFeed.d.ts +10 -0
  39. package/dist/components/ActivityFeed.js +23 -0
  40. package/dist/components/ActivityFeed.mjs +8 -0
  41. package/dist/components/Anchor.d.mts +38 -0
  42. package/dist/components/Anchor.d.ts +38 -0
  43. package/dist/components/Anchor.js +20 -0
  44. package/dist/components/Anchor.mjs +1 -0
  45. package/dist/components/AnchorLink.d.mts +23 -0
  46. package/dist/components/AnchorLink.d.ts +23 -0
  47. package/dist/components/AnchorLink.js +17 -0
  48. package/dist/components/AnchorLink.mjs +2 -0
  49. package/dist/components/AreaChart.js +4 -4
  50. package/dist/components/AreaChart.mjs +2 -2
  51. package/dist/components/BackTop.d.mts +21 -0
  52. package/dist/components/BackTop.d.ts +21 -0
  53. package/dist/components/BackTop.js +16 -0
  54. package/dist/components/BackTop.mjs +1 -0
  55. package/dist/components/BarChart.js +4 -4
  56. package/dist/components/BarChart.mjs +2 -2
  57. package/dist/components/Breadcrumb.d.mts +4 -0
  58. package/dist/components/Breadcrumb.d.ts +4 -0
  59. package/dist/components/Breadcrumb.js +3 -3
  60. package/dist/components/Breadcrumb.mjs +1 -1
  61. package/dist/components/BreadcrumbItem.js +3 -3
  62. package/dist/components/BreadcrumbItem.mjs +2 -2
  63. package/dist/components/Carousel.d.mts +26 -0
  64. package/dist/components/Carousel.d.ts +26 -0
  65. package/dist/components/Carousel.js +10 -0
  66. package/dist/components/Carousel.mjs +1 -0
  67. package/dist/components/ChatWindow.d.mts +12 -0
  68. package/dist/components/ChatWindow.d.ts +12 -0
  69. package/dist/components/ChatWindow.js +20 -0
  70. package/dist/components/ChatWindow.mjs +5 -0
  71. package/dist/components/Collapse.d.mts +29 -0
  72. package/dist/components/Collapse.d.ts +29 -0
  73. package/dist/components/Collapse.js +20 -0
  74. package/dist/components/Collapse.mjs +1 -0
  75. package/dist/components/CollapsePanel.d.mts +24 -0
  76. package/dist/components/CollapsePanel.d.ts +24 -0
  77. package/dist/components/CollapsePanel.js +17 -0
  78. package/dist/components/CollapsePanel.mjs +2 -0
  79. package/dist/components/CommentThread.d.mts +8 -0
  80. package/dist/components/CommentThread.d.ts +8 -0
  81. package/dist/components/CommentThread.js +21 -0
  82. package/dist/components/CommentThread.mjs +6 -0
  83. package/dist/components/DataTableWithToolbar.d.mts +51 -0
  84. package/dist/components/DataTableWithToolbar.d.ts +51 -0
  85. package/dist/components/DataTableWithToolbar.js +24 -0
  86. package/dist/components/DataTableWithToolbar.mjs +9 -0
  87. package/dist/components/Dropdown.js +4 -4
  88. package/dist/components/Dropdown.mjs +2 -2
  89. package/dist/components/DropdownItem.js +4 -4
  90. package/dist/components/DropdownItem.mjs +3 -3
  91. package/dist/components/FormItem.js +2 -2
  92. package/dist/components/FormItem.mjs +1 -1
  93. package/dist/components/FormWizard.d.mts +10 -0
  94. package/dist/components/FormWizard.d.ts +10 -0
  95. package/dist/components/FormWizard.js +19 -0
  96. package/dist/components/FormWizard.mjs +4 -0
  97. package/dist/components/LineChart.js +4 -4
  98. package/dist/components/LineChart.mjs +2 -2
  99. package/dist/components/NotificationCenter.d.mts +8 -0
  100. package/dist/components/NotificationCenter.d.ts +8 -0
  101. package/dist/components/NotificationCenter.js +23 -0
  102. package/dist/components/NotificationCenter.mjs +8 -0
  103. package/dist/components/Pagination.js +3 -3
  104. package/dist/components/Pagination.mjs +1 -1
  105. package/dist/components/ScatterChart.js +4 -4
  106. package/dist/components/ScatterChart.mjs +2 -2
  107. package/dist/components/Table.d.mts +1 -1
  108. package/dist/components/Table.d.ts +1 -1
  109. package/dist/components/Table.js +2 -2
  110. package/dist/components/Table.mjs +1 -1
  111. package/dist/index.d.mts +12 -0
  112. package/dist/index.d.ts +12 -0
  113. package/dist/index.js +221 -153
  114. package/dist/index.mjs +51 -39
  115. package/package.json +2 -2
  116. package/dist/{chunk-42UKIFFQ.js → chunk-4PTI6ZUK.js} +1 -1
  117. package/dist/{chunk-LIJLFLYE.js → chunk-4TWHENPT.js} +1 -1
  118. package/dist/{chunk-OONM7FO7.js → chunk-6E5UKM6O.js} +1 -1
  119. package/dist/{chunk-KBGURVTD.mjs → chunk-AITVDDCE.mjs} +1 -1
  120. package/dist/{chunk-CBALIFPW.mjs → chunk-IL2Y5RCX.mjs} +1 -1
  121. package/dist/{chunk-QI6WAP6Y.js → chunk-L63N3LCG.js} +1 -1
  122. package/dist/{chunk-A2UW5OKX.mjs → chunk-PT4WLSTJ.mjs} +1 -1
  123. package/dist/{chunk-EJLJYOO7.js → chunk-SIB4EHB6.js} +1 -1
  124. package/dist/{chunk-VBSK4TGO.mjs → chunk-WYTHTJN3.mjs} +1 -1
  125. package/dist/{chunk-7IKJBQQV.mjs → chunk-YGOTPK2W.mjs} +1 -1
@@ -0,0 +1,266 @@
1
+ import React, { forwardRef, useState, useRef, useMemo, useCallback, useImperativeHandle, useEffect } from 'react';
2
+ import { classNames, getCarouselContainerClasses, carouselTrackFadeClasses, carouselTrackScrollClasses, getScrollTransform, carouselSlideBaseClasses, getCarouselDotsClasses, clampSlideIndex, getNextSlideIndex, getPrevSlideIndex, isPrevDisabled, isNextDisabled, getCarouselArrowClasses, carouselPrevArrowPath, carouselNextArrowPath, getCarouselDotClasses } from '@expcat/tigercat-core';
3
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
+
5
+ // src/components/Carousel.tsx
6
+ var Carousel = forwardRef(
7
+ ({
8
+ autoplay = false,
9
+ autoplaySpeed = 3e3,
10
+ dots = true,
11
+ dotPosition = "bottom",
12
+ effect = "scroll",
13
+ arrows = false,
14
+ infinite = true,
15
+ speed = 500,
16
+ initialSlide = 0,
17
+ pauseOnHover = true,
18
+ pauseOnFocus = true,
19
+ className,
20
+ style,
21
+ onChange,
22
+ onBeforeChange,
23
+ children
24
+ }, ref) => {
25
+ const [currentIndex, setCurrentIndex] = useState(initialSlide);
26
+ const [isPaused, setIsPaused] = useState(false);
27
+ const autoplayTimerRef = useRef(null);
28
+ const slides = useMemo(() => {
29
+ return React.Children.toArray(children).filter((child) => React.isValidElement(child));
30
+ }, [children]);
31
+ const slideCount = slides.length;
32
+ const containerClasses = useMemo(
33
+ () => classNames(getCarouselContainerClasses(className)),
34
+ [className]
35
+ );
36
+ const trackClasses = useMemo(() => {
37
+ if (effect === "fade") {
38
+ return carouselTrackFadeClasses;
39
+ }
40
+ return carouselTrackScrollClasses;
41
+ }, [effect]);
42
+ const trackStyle = useMemo(() => {
43
+ if (effect === "scroll") {
44
+ return {
45
+ transform: getScrollTransform(currentIndex),
46
+ transitionDuration: `${speed}ms`
47
+ };
48
+ }
49
+ return {};
50
+ }, [effect, currentIndex, speed]);
51
+ const getSlideClasses = useCallback(
52
+ (index) => {
53
+ const isActive = index === currentIndex;
54
+ if (effect === "fade") {
55
+ const positionClass = index === 0 ? "relative" : "absolute inset-0";
56
+ return classNames(
57
+ positionClass,
58
+ "w-full transition-opacity ease-in-out",
59
+ isActive ? "opacity-100 z-10" : "opacity-0 z-0"
60
+ );
61
+ }
62
+ return carouselSlideBaseClasses;
63
+ },
64
+ [effect, currentIndex]
65
+ );
66
+ const getSlideStyle = useCallback(() => {
67
+ return {
68
+ transitionDuration: `${speed}ms`
69
+ };
70
+ }, [speed]);
71
+ const dotsClasses = useMemo(() => {
72
+ return getCarouselDotsClasses(dotPosition);
73
+ }, [dotPosition]);
74
+ const goTo = useCallback(
75
+ (index) => {
76
+ const clampedIndex = clampSlideIndex(index, slideCount);
77
+ if (clampedIndex === currentIndex) return;
78
+ onBeforeChange?.(currentIndex, clampedIndex);
79
+ const prevIndex = currentIndex;
80
+ setCurrentIndex(clampedIndex);
81
+ onChange?.(clampedIndex, prevIndex);
82
+ },
83
+ [currentIndex, slideCount, onBeforeChange, onChange]
84
+ );
85
+ const next = useCallback(() => {
86
+ const nextIdx = getNextSlideIndex(currentIndex, slideCount, infinite);
87
+ if (nextIdx !== currentIndex) {
88
+ goTo(nextIdx);
89
+ }
90
+ }, [currentIndex, slideCount, infinite, goTo]);
91
+ const prev = useCallback(() => {
92
+ const prevIdx = getPrevSlideIndex(currentIndex, slideCount, infinite);
93
+ if (prevIdx !== currentIndex) {
94
+ goTo(prevIdx);
95
+ }
96
+ }, [currentIndex, slideCount, infinite, goTo]);
97
+ useImperativeHandle(
98
+ ref,
99
+ () => ({
100
+ next,
101
+ prev,
102
+ goTo
103
+ }),
104
+ [next, prev, goTo]
105
+ );
106
+ useEffect(() => {
107
+ if (autoplay && !isPaused) {
108
+ if (autoplayTimerRef.current) {
109
+ clearInterval(autoplayTimerRef.current);
110
+ }
111
+ autoplayTimerRef.current = setInterval(() => {
112
+ setCurrentIndex((prevIndex) => {
113
+ const nextIdx = getNextSlideIndex(prevIndex, slideCount, infinite);
114
+ if (nextIdx !== prevIndex) {
115
+ onBeforeChange?.(prevIndex, nextIdx);
116
+ onChange?.(nextIdx, prevIndex);
117
+ }
118
+ return nextIdx;
119
+ });
120
+ }, autoplaySpeed);
121
+ }
122
+ return () => {
123
+ if (autoplayTimerRef.current) {
124
+ clearInterval(autoplayTimerRef.current);
125
+ autoplayTimerRef.current = null;
126
+ }
127
+ };
128
+ }, [autoplay, autoplaySpeed, isPaused, slideCount, infinite, onChange, onBeforeChange]);
129
+ const handleMouseEnter = useCallback(() => {
130
+ if (pauseOnHover && autoplay) {
131
+ setIsPaused(true);
132
+ }
133
+ }, [pauseOnHover, autoplay]);
134
+ const handleMouseLeave = useCallback(() => {
135
+ if (pauseOnHover && autoplay) {
136
+ setIsPaused(false);
137
+ }
138
+ }, [pauseOnHover, autoplay]);
139
+ const handleFocus = useCallback(() => {
140
+ if (pauseOnFocus && autoplay) {
141
+ setIsPaused(true);
142
+ }
143
+ }, [pauseOnFocus, autoplay]);
144
+ const handleBlur = useCallback(() => {
145
+ if (pauseOnFocus && autoplay) {
146
+ setIsPaused(false);
147
+ }
148
+ }, [pauseOnFocus, autoplay]);
149
+ const isPrevArrowDisabled = useMemo(
150
+ () => isPrevDisabled(currentIndex, slideCount, infinite),
151
+ [currentIndex, slideCount, infinite]
152
+ );
153
+ const isNextArrowDisabled = useMemo(
154
+ () => isNextDisabled(currentIndex, slideCount, infinite),
155
+ [currentIndex, slideCount, infinite]
156
+ );
157
+ const renderArrows = () => {
158
+ if (!arrows) return null;
159
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
160
+ /* @__PURE__ */ jsx(
161
+ "button",
162
+ {
163
+ type: "button",
164
+ className: getCarouselArrowClasses("prev", isPrevArrowDisabled),
165
+ onClick: prev,
166
+ disabled: isPrevArrowDisabled,
167
+ "aria-label": "Previous slide",
168
+ children: /* @__PURE__ */ jsx(
169
+ "svg",
170
+ {
171
+ xmlns: "http://www.w3.org/2000/svg",
172
+ viewBox: "0 0 24 24",
173
+ fill: "none",
174
+ stroke: "currentColor",
175
+ strokeWidth: "2",
176
+ strokeLinecap: "round",
177
+ strokeLinejoin: "round",
178
+ className: "w-6 h-6",
179
+ children: /* @__PURE__ */ jsx("path", { d: carouselPrevArrowPath })
180
+ }
181
+ )
182
+ }
183
+ ),
184
+ /* @__PURE__ */ jsx(
185
+ "button",
186
+ {
187
+ type: "button",
188
+ className: getCarouselArrowClasses("next", isNextArrowDisabled),
189
+ onClick: next,
190
+ disabled: isNextArrowDisabled,
191
+ "aria-label": "Next slide",
192
+ children: /* @__PURE__ */ jsx(
193
+ "svg",
194
+ {
195
+ xmlns: "http://www.w3.org/2000/svg",
196
+ viewBox: "0 0 24 24",
197
+ fill: "none",
198
+ stroke: "currentColor",
199
+ strokeWidth: "2",
200
+ strokeLinecap: "round",
201
+ strokeLinejoin: "round",
202
+ className: "w-6 h-6",
203
+ children: /* @__PURE__ */ jsx("path", { d: carouselNextArrowPath })
204
+ }
205
+ )
206
+ }
207
+ )
208
+ ] });
209
+ };
210
+ const renderDots = () => {
211
+ if (!dots || slideCount <= 1) return null;
212
+ return /* @__PURE__ */ jsx("div", { className: dotsClasses, role: "tablist", "aria-label": "Carousel navigation", children: slides.map((_, index) => /* @__PURE__ */ jsx(
213
+ "button",
214
+ {
215
+ type: "button",
216
+ className: getCarouselDotClasses(index === currentIndex),
217
+ onClick: () => goTo(index),
218
+ "aria-label": `Go to slide ${index + 1}`,
219
+ "aria-current": index === currentIndex ? "true" : "false"
220
+ },
221
+ index
222
+ )) });
223
+ };
224
+ const renderSlides = () => {
225
+ const slideElements = slides.map((slide, index) => /* @__PURE__ */ jsx(
226
+ "div",
227
+ {
228
+ className: getSlideClasses(index),
229
+ style: effect === "fade" ? getSlideStyle() : void 0,
230
+ role: "group",
231
+ "aria-roledescription": "slide",
232
+ "aria-label": `Slide ${index + 1} of ${slideCount}`,
233
+ "aria-hidden": index !== currentIndex,
234
+ children: slide
235
+ },
236
+ index
237
+ ));
238
+ if (effect === "fade") {
239
+ return /* @__PURE__ */ jsx("div", { className: classNames(trackClasses, "h-full"), children: slideElements });
240
+ }
241
+ return /* @__PURE__ */ jsx("div", { className: trackClasses, style: trackStyle, children: slideElements });
242
+ };
243
+ return /* @__PURE__ */ jsxs(
244
+ "div",
245
+ {
246
+ className: containerClasses,
247
+ style,
248
+ role: "region",
249
+ "aria-roledescription": "carousel",
250
+ "aria-label": "Image carousel",
251
+ onMouseEnter: handleMouseEnter,
252
+ onMouseLeave: handleMouseLeave,
253
+ onFocus: handleFocus,
254
+ onBlur: handleBlur,
255
+ children: [
256
+ renderSlides(),
257
+ renderArrows(),
258
+ renderDots()
259
+ ]
260
+ }
261
+ );
262
+ }
263
+ );
264
+ Carousel.displayName = "Carousel";
265
+
266
+ export { Carousel };
@@ -1,4 +1,4 @@
1
- import { useBreadcrumbContext } from './chunk-7JQ7LURS.mjs';
1
+ import { useBreadcrumbContext } from './chunk-H36CWHUP.mjs';
2
2
  import { useMemo, useCallback } from 'react';
3
3
  import { getBreadcrumbItemClasses, getBreadcrumbLinkClasses, getBreadcrumbSeparatorClasses, getSeparatorContent } from '@expcat/tigercat-core';
4
4
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
@@ -53,23 +53,33 @@ var FormItem = ({
53
53
  }
54
54
  return width;
55
55
  }, [labelWidth, formContext?.labelWidth]);
56
+ const hasRequiredRule = React.useCallback((maybeRules) => {
57
+ if (!maybeRules) {
58
+ return false;
59
+ }
60
+ const rules2 = Array.isArray(maybeRules) ? maybeRules : [maybeRules];
61
+ return rules2.some((rule) => {
62
+ if (!rule || typeof rule !== "object") {
63
+ return false;
64
+ }
65
+ return !!rule.required;
66
+ });
67
+ }, []);
56
68
  const showRequiredAsterisk = React.useMemo(() => {
57
69
  if (required !== void 0) {
58
70
  return required;
59
71
  }
60
72
  if (rules) {
61
- const ruleArray = Array.isArray(rules) ? rules : [rules];
62
- return ruleArray.some((rule) => rule.required);
73
+ return hasRequiredRule(rules);
63
74
  }
64
75
  if (name && formContext?.rules) {
65
76
  const fieldRules = formContext.rules[name];
66
77
  if (fieldRules) {
67
- const ruleArray = Array.isArray(fieldRules) ? fieldRules : [fieldRules];
68
- return ruleArray.some((rule) => rule.required);
78
+ return hasRequiredRule(fieldRules);
69
79
  }
70
80
  }
71
81
  return false;
72
- }, [required, rules, name, formContext?.rules]);
82
+ }, [required, rules, name, formContext?.rules, hasRequiredRule]);
73
83
  const isRequired = React.useMemo(
74
84
  () => showRequiredAsterisk && (formContext?.showRequiredAsterisk ?? true),
75
85
  [showRequiredAsterisk, formContext?.showRequiredAsterisk]
@@ -154,22 +164,24 @@ var FormItem = ({
154
164
  ]);
155
165
  const formItemClasses = React.useMemo(
156
166
  () => tigercatCore.classNames(
157
- "tiger-form-item",
158
- `tiger-form-item--${actualSize}`,
159
- `tiger-form-item--label-${labelPosition}`,
160
- hasError && "tiger-form-item--error",
161
- formContext?.disabled && "tiger-form-item--disabled",
167
+ tigercatCore.getFormItemClasses({
168
+ size: actualSize,
169
+ labelPosition,
170
+ hasError,
171
+ disabled: formContext?.disabled
172
+ }),
162
173
  className
163
174
  ),
164
175
  [actualSize, labelPosition, hasError, formContext?.disabled, className]
165
176
  );
166
177
  const labelClasses = React.useMemo(
167
- () => tigercatCore.classNames(
168
- "tiger-form-item__label",
169
- `tiger-form-item__label--${labelAlign}`,
170
- isRequired && "tiger-form-item__label--required"
171
- ),
172
- [labelAlign, isRequired]
178
+ () => tigercatCore.getFormItemLabelClasses({
179
+ size: actualSize,
180
+ labelAlign,
181
+ labelPosition,
182
+ isRequired
183
+ }),
184
+ [actualSize, labelAlign, labelPosition, isRequired]
173
185
  );
174
186
  const labelStyles = React.useMemo(() => {
175
187
  if (labelPosition === "top") {
@@ -178,9 +190,13 @@ var FormItem = ({
178
190
  return actualLabelWidth ? { width: actualLabelWidth } : {};
179
191
  }, [labelPosition, actualLabelWidth]);
180
192
  const errorClasses = React.useMemo(
181
- () => tigercatCore.classNames("tiger-form-item__error", hasError && "tiger-form-item__error--show"),
182
- [hasError]
193
+ () => tigercatCore.classNames(tigercatCore.getFormItemErrorClasses(actualSize), hasError && "tiger-form-item__error--show"),
194
+ [actualSize, hasError]
183
195
  );
196
+ const contentClasses = React.useMemo(() => tigercatCore.getFormItemContentClasses(labelPosition), [labelPosition]);
197
+ const fieldClasses = React.useMemo(() => tigercatCore.getFormItemFieldClasses(), []);
198
+ const asteriskClasses = React.useMemo(() => tigercatCore.getFormItemAsteriskClasses(), []);
199
+ const asteriskStyle = React.useMemo(() => tigercatCore.getFormItemAsteriskStyle(), []);
184
200
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: formItemClasses, children: [
185
201
  label && /* @__PURE__ */ jsxRuntime.jsxs(
186
202
  "label",
@@ -190,16 +206,16 @@ var FormItem = ({
190
206
  style: labelStyles,
191
207
  htmlFor: isClonableChild ? effectiveFieldId : void 0,
192
208
  children: [
193
- isRequired && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tiger-form-item__asterisk", children: "*" }),
209
+ isRequired && /* @__PURE__ */ jsxRuntime.jsx("span", { className: asteriskClasses, style: asteriskStyle, children: "*" }),
194
210
  label
195
211
  ]
196
212
  }
197
213
  ),
198
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tiger-form-item__content", children: [
214
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: contentClasses, children: [
199
215
  /* @__PURE__ */ jsxRuntime.jsx(
200
216
  "div",
201
217
  {
202
- className: "tiger-form-item__field",
218
+ className: fieldClasses,
203
219
  role: "group",
204
220
  "aria-labelledby": label ? labelId : void 0,
205
221
  "aria-describedby": describedById,
@@ -96,6 +96,18 @@ var Pagination = ({
96
96
  },
97
97
  [handleQuickJumperSubmit]
98
98
  );
99
+ const normalizedPageSizeOptions = useMemo(() => {
100
+ return pageSizeOptions.map((option) => {
101
+ if (typeof option === "number") {
102
+ return {
103
+ value: option,
104
+ label: `${option} ${labels.itemsPerPageText}`
105
+ };
106
+ }
107
+ const label = option.label ?? `${option.value} ${labels.itemsPerPageText}`;
108
+ return { value: option.value, label };
109
+ });
110
+ }, [pageSizeOptions, labels.itemsPerPageText]);
99
111
  const containerClasses = getPaginationContainerClasses(align, className);
100
112
  const elements = [];
101
113
  if (showTotal) {
@@ -231,11 +243,7 @@ var Pagination = ({
231
243
  value: currentPageSize,
232
244
  onChange: (e) => handlePageSizeChange(parseInt(e.target.value, 10)),
233
245
  "aria-label": labels.itemsPerPageText,
234
- children: pageSizeOptions.map((sizeOption) => /* @__PURE__ */ jsxs("option", { value: sizeOption, children: [
235
- sizeOption,
236
- " ",
237
- labels.itemsPerPageText
238
- ] }, sizeOption))
246
+ children: normalizedPageSizeOptions.map((sizeOption) => /* @__PURE__ */ jsx("option", { value: sizeOption.value, children: sizeOption.label }, sizeOption.value))
239
247
  },
240
248
  "size-changer"
241
249
  )
@@ -0,0 +1,209 @@
1
+ 'use strict';
2
+
3
+ var chunkGJKT2B56_js = require('./chunk-GJKT2B56.js');
4
+ var chunkGY6D4XS3_js = require('./chunk-GY6D4XS3.js');
5
+ var chunkPBJ2J2B3_js = require('./chunk-PBJ2J2B3.js');
6
+ var chunk4TWHENPT_js = require('./chunk-4TWHENPT.js');
7
+ var chunkEQWQXURG_js = require('./chunk-EQWQXURG.js');
8
+ var chunkCIL2AC3F_js = require('./chunk-CIL2AC3F.js');
9
+ var chunkA3DJSVTE_js = require('./chunk-A3DJSVTE.js');
10
+ var react = require('react');
11
+ var tigercatCore = require('@expcat/tigercat-core');
12
+ var jsxRuntime = require('react/jsx-runtime');
13
+
14
+ var resolveFilterLabel = (filter, value) => {
15
+ const option = filter.options.find((item) => item.value === value);
16
+ if (option) return `${filter.label}: ${option.label}`;
17
+ if (value !== null && value !== void 0 && value !== "") {
18
+ return `${filter.label}: ${String(value)}`;
19
+ }
20
+ return filter.placeholder ?? filter.label;
21
+ };
22
+ var DataTableWithToolbar = ({
23
+ toolbar,
24
+ onSearchChange,
25
+ onSearch,
26
+ onFiltersChange,
27
+ onBulkAction,
28
+ pagination = false,
29
+ onPageChange,
30
+ onPageSizeChange,
31
+ className,
32
+ tableClassName,
33
+ ...tableProps
34
+ }) => {
35
+ const [internalSearch, setInternalSearch] = react.useState(toolbar?.defaultSearchValue ?? "");
36
+ const [internalFilters, setInternalFilters] = react.useState(
37
+ () => {
38
+ const initial = {};
39
+ toolbar?.filters?.forEach((filter) => {
40
+ if (filter.value === void 0) {
41
+ initial[filter.key] = filter.defaultValue ?? null;
42
+ }
43
+ });
44
+ return initial;
45
+ }
46
+ );
47
+ react.useEffect(() => {
48
+ if (toolbar?.searchValue !== void 0) {
49
+ setInternalSearch(toolbar.searchValue ?? "");
50
+ }
51
+ }, [toolbar?.searchValue]);
52
+ react.useEffect(() => {
53
+ const filters = toolbar?.filters;
54
+ if (!filters) return;
55
+ setInternalFilters((prev) => {
56
+ const next = { ...prev };
57
+ filters.forEach((filter) => {
58
+ if (filter.value === void 0 && !(filter.key in next)) {
59
+ next[filter.key] = filter.defaultValue ?? null;
60
+ }
61
+ });
62
+ return next;
63
+ });
64
+ }, [toolbar?.filters]);
65
+ const searchValue = toolbar?.searchValue !== void 0 ? toolbar.searchValue : internalSearch;
66
+ const resolvedFilters = react.useMemo(() => {
67
+ const next = {};
68
+ toolbar?.filters?.forEach((filter) => {
69
+ next[filter.key] = filter.value !== void 0 ? filter.value : internalFilters[filter.key] ?? filter.defaultValue ?? null;
70
+ });
71
+ return next;
72
+ }, [toolbar?.filters, internalFilters]);
73
+ const hasSearch = Boolean(
74
+ toolbar && (toolbar.searchPlaceholder || toolbar.searchValue !== void 0 || toolbar.defaultSearchValue !== void 0 || toolbar.showSearchButton || toolbar.onSearchChange || toolbar.onSearch || onSearchChange || onSearch)
75
+ );
76
+ const hasFilters = Boolean(toolbar?.filters && toolbar.filters.length > 0);
77
+ const hasBulkActions = Boolean(toolbar?.bulkActions && toolbar.bulkActions.length > 0);
78
+ const selectedKeys = toolbar?.selectedKeys ?? tableProps.rowSelection?.selectedRowKeys ?? [];
79
+ const selectedCount = toolbar?.selectedCount ?? selectedKeys.length;
80
+ const bulkLabel = toolbar?.bulkActionsLabel ?? "\u5DF2\u9009\u62E9";
81
+ const wrapperClasses = react.useMemo(
82
+ () => tigercatCore.classNames("tiger-data-table-with-toolbar flex flex-col gap-3", className),
83
+ [className]
84
+ );
85
+ const handleSearchChange = (value) => {
86
+ if (toolbar?.searchValue === void 0) {
87
+ setInternalSearch(value);
88
+ }
89
+ onSearchChange?.(value);
90
+ toolbar?.onSearchChange?.(value);
91
+ };
92
+ const handleSearchSubmit = () => {
93
+ onSearch?.(searchValue ?? "");
94
+ toolbar?.onSearch?.(searchValue ?? "");
95
+ };
96
+ const handleFilterSelect = (filter, value) => {
97
+ const nextFilters = {
98
+ ...resolvedFilters,
99
+ [filter.key]: value
100
+ };
101
+ if (filter.value === void 0) {
102
+ setInternalFilters((prev) => ({
103
+ ...prev,
104
+ [filter.key]: value
105
+ }));
106
+ }
107
+ onFiltersChange?.(nextFilters);
108
+ toolbar?.onFiltersChange?.(nextFilters);
109
+ };
110
+ const handleBulkAction = (action) => {
111
+ const keys = selectedKeys ?? [];
112
+ action.onClick?.(keys);
113
+ onBulkAction?.(action, keys);
114
+ toolbar?.onBulkAction?.(action, keys);
115
+ };
116
+ const renderToolbar = () => {
117
+ if (!hasSearch && !hasFilters && !hasBulkActions) return null;
118
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tiger-data-table-toolbar flex flex-wrap items-center gap-2", children: [
119
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [
120
+ hasSearch ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
121
+ /* @__PURE__ */ jsxRuntime.jsx(
122
+ chunkCIL2AC3F_js.Input,
123
+ {
124
+ type: "search",
125
+ size: "sm",
126
+ value: searchValue,
127
+ placeholder: toolbar?.searchPlaceholder ?? "\u641C\u7D22",
128
+ onChange: (event) => handleSearchChange(String(event.currentTarget.value)),
129
+ onKeyDown: (event) => {
130
+ if (event.key === "Enter") {
131
+ handleSearchSubmit();
132
+ }
133
+ }
134
+ }
135
+ ),
136
+ toolbar?.showSearchButton ?? true ? /* @__PURE__ */ jsxRuntime.jsx(
137
+ chunkA3DJSVTE_js.Button,
138
+ {
139
+ size: "sm",
140
+ variant: "primary",
141
+ className: "whitespace-nowrap",
142
+ onClick: handleSearchSubmit,
143
+ disabled: !onSearch && !toolbar?.onSearch,
144
+ children: toolbar?.searchButtonText ?? "\u641C\u7D22"
145
+ }
146
+ ) : null
147
+ ] }) : null,
148
+ hasFilters ? toolbar?.filters?.map((filter) => {
149
+ const currentValue = resolvedFilters[filter.key];
150
+ const triggerLabel = resolveFilterLabel(filter, currentValue);
151
+ const clearable = filter.clearable !== false;
152
+ const clearLabel = filter.clearLabel ?? "\u5168\u90E8";
153
+ const isActive = currentValue !== null && currentValue !== void 0 && currentValue !== "";
154
+ return /* @__PURE__ */ jsxRuntime.jsxs(chunk4TWHENPT_js.Dropdown, { trigger: "click", children: [
155
+ /* @__PURE__ */ jsxRuntime.jsx(
156
+ chunkA3DJSVTE_js.Button,
157
+ {
158
+ size: "sm",
159
+ variant: isActive ? "secondary" : "outline",
160
+ className: "whitespace-nowrap",
161
+ children: triggerLabel
162
+ }
163
+ ),
164
+ /* @__PURE__ */ jsxRuntime.jsxs(chunkEQWQXURG_js.DropdownMenu, { children: [
165
+ clearable ? /* @__PURE__ */ jsxRuntime.jsx(chunkPBJ2J2B3_js.DropdownItem, { onClick: () => handleFilterSelect(filter, null), children: clearLabel }) : null,
166
+ filter.options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
167
+ chunkPBJ2J2B3_js.DropdownItem,
168
+ {
169
+ onClick: () => handleFilterSelect(filter, option.value),
170
+ children: option.label
171
+ },
172
+ String(option.value)
173
+ ))
174
+ ] })
175
+ ] }, filter.key);
176
+ }) : null
177
+ ] }),
178
+ hasBulkActions ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-auto flex items-center gap-2 flex-wrap", children: [
179
+ selectedCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-[var(--tiger-text-muted,#6b7280)]", children: [
180
+ bulkLabel,
181
+ " ",
182
+ selectedCount,
183
+ " \u9879"
184
+ ] }) : null,
185
+ toolbar?.bulkActions?.map((action) => /* @__PURE__ */ jsxRuntime.jsx(
186
+ chunkA3DJSVTE_js.Button,
187
+ {
188
+ size: "sm",
189
+ variant: action.variant ?? "outline",
190
+ disabled: action.disabled || selectedCount === 0,
191
+ onClick: () => handleBulkAction(action),
192
+ children: action.label
193
+ },
194
+ action.key
195
+ ))
196
+ ] }) : null
197
+ ] });
198
+ };
199
+ const showPagination = pagination && typeof pagination === "object";
200
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: wrapperClasses, "data-tiger-data-table-with-toolbar": true, children: [
201
+ renderToolbar(),
202
+ /* @__PURE__ */ jsxRuntime.jsx(chunkGJKT2B56_js.Table, { ...tableProps, pagination: false, className: tableClassName }),
203
+ showPagination ? /* @__PURE__ */ jsxRuntime.jsx(chunkGY6D4XS3_js.Pagination, { ...pagination, onChange: onPageChange, onPageSizeChange }) : null
204
+ ] });
205
+ };
206
+ var DataTableWithToolbar_default = DataTableWithToolbar;
207
+
208
+ exports.DataTableWithToolbar = DataTableWithToolbar;
209
+ exports.DataTableWithToolbar_default = DataTableWithToolbar_default;
@@ -17,15 +17,20 @@ var Breadcrumb = ({
17
17
  separator = "/",
18
18
  className,
19
19
  style,
20
+ extra,
20
21
  children,
21
22
  ...props
22
23
  }) => {
24
+ const hasExtra = Boolean(extra);
23
25
  const containerClasses = React__default.default.useMemo(
24
- () => tigercatCore.classNames(tigercatCore.breadcrumbContainerClasses, className),
25
- [className]
26
+ () => tigercatCore.classNames(tigercatCore.breadcrumbContainerClasses, hasExtra && "w-full", className),
27
+ [className, hasExtra]
26
28
  );
27
29
  const contextValue = React__default.default.useMemo(() => ({ separator }), [separator]);
28
- return /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx("nav", { className: containerClasses, "aria-label": "Breadcrumb", style, ...props, children: /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "flex items-center flex-wrap gap-2", children }) }) });
30
+ return /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsxs("nav", { className: containerClasses, "aria-label": "Breadcrumb", style, ...props, children: [
31
+ /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "flex items-center flex-wrap gap-2", children }),
32
+ hasExtra && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-auto flex items-center", children: extra })
33
+ ] }) });
29
34
  };
30
35
 
31
36
  exports.Breadcrumb = Breadcrumb;