@expcat/tigercat-react 2.0.0-rc.2 → 2.0.4

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 (80) hide show
  1. package/dist/{chunk-JTFNGXOC.mjs → chunk-2ENQZECC.mjs} +53 -31
  2. package/dist/{chunk-O5RAMCBV.mjs → chunk-2JYJPNW3.mjs} +1 -1
  3. package/dist/{chunk-POP3TS4Q.mjs → chunk-2WGEHH5A.mjs} +57 -29
  4. package/dist/{chunk-K7MYQISG.mjs → chunk-54HN5BXW.mjs} +10 -4
  5. package/dist/chunk-5CKMYMTS.mjs +292 -0
  6. package/dist/{chunk-Y7K27DVV.mjs → chunk-6H5Y7Y6E.mjs} +42 -28
  7. package/dist/chunk-6MGQAJ62.mjs +203 -0
  8. package/dist/{chunk-TO2URY7X.mjs → chunk-7AFRHC7P.mjs} +90 -61
  9. package/dist/{chunk-MGQWVJHX.mjs → chunk-ALSOPYM5.mjs} +69 -62
  10. package/dist/{chunk-N6JNLJIN.mjs → chunk-BOGOQ44C.mjs} +6 -2
  11. package/dist/{chunk-Q327ESD2.mjs → chunk-BUXHI6UK.mjs} +17 -38
  12. package/dist/{chunk-TORX7SG4.mjs → chunk-CC7IOSNI.mjs} +10 -4
  13. package/dist/{chunk-OVE2ZUJJ.mjs → chunk-D33BIMGK.mjs} +1 -1
  14. package/dist/{chunk-PYDWF4ED.mjs → chunk-D3KP72UC.mjs} +34 -9
  15. package/dist/{chunk-ZEP7I6WB.mjs → chunk-DPWRXXXW.mjs} +16 -8
  16. package/dist/{chunk-44CQTGAN.mjs → chunk-E7OTDBI6.mjs} +2 -2
  17. package/dist/{chunk-DJ4PSDQS.mjs → chunk-FYINJRYN.mjs} +2 -2
  18. package/dist/{chunk-KFPQ6DIH.mjs → chunk-GV4F6X3C.mjs} +29 -25
  19. package/dist/chunk-HKAZXG74.mjs +308 -0
  20. package/dist/{chunk-QWUDJC6K.mjs → chunk-HOYBHB7B.mjs} +38 -17
  21. package/dist/{chunk-IZYFETUS.mjs → chunk-HS6KUPTI.mjs} +2 -2
  22. package/dist/{chunk-EKESN747.mjs → chunk-HSBN5MLS.mjs} +1 -1
  23. package/dist/{chunk-AJJJ6HWC.mjs → chunk-K4GIKSZE.mjs} +1 -1
  24. package/dist/{chunk-2UOGBS3C.mjs → chunk-KP6DEYWB.mjs} +27 -6
  25. package/dist/{chunk-PAN256RW.mjs → chunk-KVCI2346.mjs} +59 -55
  26. package/dist/{chunk-3O2WHF3U.mjs → chunk-NCHUEGUW.mjs} +2 -2
  27. package/dist/{chunk-VD55SSP7.mjs → chunk-PD6Q36OO.mjs} +14 -6
  28. package/dist/{chunk-5RVLBNLI.mjs → chunk-RJPNBYK5.mjs} +4 -4
  29. package/dist/{chunk-HXD7KMRP.mjs → chunk-UCBW5RJN.mjs} +31 -2
  30. package/dist/{chunk-5IHOOP5A.mjs → chunk-UD4DTVJZ.mjs} +64 -79
  31. package/dist/{chunk-A6JNS35U.mjs → chunk-UT5BV2VO.mjs} +2 -2
  32. package/dist/{chunk-K6GJMKJR.mjs → chunk-V6P7ZK6O.mjs} +3 -3
  33. package/dist/{chunk-4XGO3OSE.mjs → chunk-XE4YFBOZ.mjs} +12 -17
  34. package/dist/{chunk-YI7NQWUV.mjs → chunk-YI6YWH66.mjs} +14 -30
  35. package/dist/{chunk-SHCBCM2W.mjs → chunk-YIB6ZXZF.mjs} +142 -105
  36. package/dist/{chunk-SZBYEGKU.mjs → chunk-ZCGIZOMT.mjs} +1 -1
  37. package/dist/{chunk-S7IB6YST.mjs → chunk-ZG56T75O.mjs} +25 -40
  38. package/dist/{chunk-44BPUG24.mjs → chunk-ZH5ZBLAN.mjs} +38 -16
  39. package/dist/components/ActivityFeed.mjs +3 -3
  40. package/dist/components/AreaChart.mjs +1 -1
  41. package/dist/components/AutoComplete.mjs +2 -1
  42. package/dist/components/BarChart.mjs +1 -1
  43. package/dist/components/Cascader.mjs +2 -1
  44. package/dist/components/ColorPicker.mjs +2 -1
  45. package/dist/components/CommentThread.mjs +1 -1
  46. package/dist/components/CropUpload.mjs +4 -4
  47. package/dist/components/DataExport.mjs +3 -3
  48. package/dist/components/DataTableWithToolbar.mjs +6 -6
  49. package/dist/components/DatePicker.mjs +2 -1
  50. package/dist/components/Drawer.mjs +2 -2
  51. package/dist/components/Dropdown.mjs +2 -2
  52. package/dist/components/FormItem.mjs +2 -1
  53. package/dist/components/Image.mjs +5 -5
  54. package/dist/components/ImageCropper.mjs +1 -1
  55. package/dist/components/ImageGroup.mjs +3 -3
  56. package/dist/components/ImagePreview.mjs +2 -2
  57. package/dist/components/LineChart.mjs +1 -1
  58. package/dist/components/Loading.mjs +2 -2
  59. package/dist/components/Mentions.mjs +2 -1
  60. package/dist/components/Menu.mjs +2 -2
  61. package/dist/components/Modal.mjs +2 -2
  62. package/dist/components/NotificationCenter.mjs +3 -3
  63. package/dist/components/Popconfirm.mjs +3 -3
  64. package/dist/components/Popover.mjs +3 -3
  65. package/dist/components/ScatterChart.mjs +1 -1
  66. package/dist/components/Select.mjs +2 -1
  67. package/dist/components/Spotlight.mjs +2 -2
  68. package/dist/components/Table.mjs +3 -2
  69. package/dist/components/TimePicker.mjs +2 -1
  70. package/dist/components/Tooltip.mjs +3 -3
  71. package/dist/components/Tour.mjs +2 -2
  72. package/dist/components/TreeSelect.mjs +2 -1
  73. package/dist/components/Upload.mjs +1 -1
  74. package/dist/components/VirtualTable.mjs +1 -1
  75. package/dist/index.d.mts +1 -1
  76. package/dist/index.mjs +4 -2
  77. package/package.json +2 -2
  78. package/dist/chunk-KVARQQAG.mjs +0 -181
  79. package/dist/chunk-SEWNVIHH.mjs +0 -153
  80. package/dist/chunk-XIVU7TWX.mjs +0 -305
@@ -1,3 +1,7 @@
1
+ import {
2
+ renderOverlayPortal,
3
+ useAnchoredOverlay
4
+ } from "./chunk-HKAZXG74.mjs";
1
5
  import {
2
6
  useTigerConfig
3
7
  } from "./chunk-YSIXURBW.mjs";
@@ -89,6 +93,20 @@ var AutoComplete = (props) => {
89
93
  const [activeIndex, setActiveIndex] = useState(-1);
90
94
  const containerRef = useRef(null);
91
95
  const inputRef = useRef(null);
96
+ const dropdownRef = useRef(null);
97
+ const overlay = useAnchoredOverlay({
98
+ enabled: isOpen,
99
+ referenceRef: inputRef,
100
+ floatingRef: dropdownRef,
101
+ containerRef,
102
+ placement: "bottom-start",
103
+ offset: 4,
104
+ matchReferenceWidth: true,
105
+ dismissOnOutside: true,
106
+ dismissOnEscape: true,
107
+ restoreFocusOnDismiss: true,
108
+ onDismiss: closeDropdown
109
+ });
92
110
  useEffect(() => {
93
111
  if (searchValue !== void 0) {
94
112
  return;
@@ -191,17 +209,41 @@ var AutoComplete = (props) => {
191
209
  break;
192
210
  }
193
211
  }
194
- useEffect(() => {
195
- if (!isOpen) return;
196
- function handleClickOutside(e) {
197
- if (containerRef.current && !containerRef.current.contains(e.target)) {
198
- closeDropdown();
199
- }
200
- }
201
- document.addEventListener("click", handleClickOutside);
202
- return () => document.removeEventListener("click", handleClickOutside);
203
- }, [isOpen]);
204
212
  const containerClasses = classNames(autoCompleteBaseClasses, className);
213
+ const dropdown = isOpen && (filteredOptions.length > 0 || inputValue) ? /* @__PURE__ */ jsx(
214
+ "div",
215
+ {
216
+ ref: dropdownRef,
217
+ ...filteredOptions.length > 0 ? getPickerListboxAria({ id: listboxId }) : {},
218
+ className: classNames(
219
+ autoCompleteDropdownClasses,
220
+ filteredOptions.length === 0 && autoCompleteEmptyStateClasses,
221
+ overlay.floatingClasses
222
+ ),
223
+ style: overlay.floatingStyles,
224
+ "data-positioned": overlay.positioned,
225
+ children: filteredOptions.length > 0 ? filteredOptions.map((option, index) => /* @__PURE__ */ jsx(
226
+ "div",
227
+ {
228
+ id: getPickerOptionId(listboxId, index),
229
+ ...getPickerOptionAria({
230
+ selected: String(option.value) === String(value),
231
+ disabled: !!option.disabled
232
+ }),
233
+ className: getAutoCompleteOptionClasses(
234
+ String(option.value) === String(value),
235
+ !!option.disabled,
236
+ size
237
+ ),
238
+ onMouseDown: (event) => event.preventDefault(),
239
+ onClick: () => handleSelect(option),
240
+ onMouseEnter: () => setActiveIndex(index),
241
+ children: option.label
242
+ },
243
+ String(option.value)
244
+ )) : resolvedNotFoundText
245
+ }
246
+ ) : null;
205
247
  return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: containerClasses, ...divProps, children: [
206
248
  /* @__PURE__ */ jsx(
207
249
  "input",
@@ -239,27 +281,7 @@ var AutoComplete = (props) => {
239
281
  )
240
282
  }
241
283
  ),
242
- isOpen && filteredOptions.length > 0 && /* @__PURE__ */ jsx("div", { ...getPickerListboxAria({ id: listboxId }), className: autoCompleteDropdownClasses, children: filteredOptions.map((option, index) => /* @__PURE__ */ jsx(
243
- "div",
244
- {
245
- id: getPickerOptionId(listboxId, index),
246
- ...getPickerOptionAria({
247
- selected: String(option.value) === String(value),
248
- disabled: !!option.disabled
249
- }),
250
- className: getAutoCompleteOptionClasses(
251
- String(option.value) === String(value),
252
- !!option.disabled,
253
- size
254
- ),
255
- onMouseDown: (e) => e.preventDefault(),
256
- onClick: () => handleSelect(option),
257
- onMouseEnter: () => setActiveIndex(index),
258
- children: option.label
259
- },
260
- String(option.value)
261
- )) }),
262
- isOpen && inputValue && filteredOptions.length === 0 && /* @__PURE__ */ jsx("div", { className: classNames(autoCompleteDropdownClasses, autoCompleteEmptyStateClasses), children: resolvedNotFoundText })
284
+ renderOverlayPortal(dropdown, overlay.target)
263
285
  ] });
264
286
  };
265
287
 
@@ -6,7 +6,7 @@ import {
6
6
  useBodyScrollLock,
7
7
  useEscapeKey,
8
8
  useFocusTrap
9
- } from "./chunk-SEWNVIHH.mjs";
9
+ } from "./chunk-HKAZXG74.mjs";
10
10
  import {
11
11
  useTigerConfig
12
12
  } from "./chunk-YSIXURBW.mjs";
@@ -10,7 +10,7 @@ import {
10
10
  } from "./chunk-5TE7KLE5.mjs";
11
11
  import {
12
12
  Loading
13
- } from "./chunk-AJJJ6HWC.mjs";
13
+ } from "./chunk-K4GIKSZE.mjs";
14
14
  import {
15
15
  Text
16
16
  } from "./chunk-HLS4CHWX.mjs";
@@ -25,6 +25,34 @@ import {
25
25
  buildNotificationGroups,
26
26
  formatActivityTime
27
27
  } from "@expcat/tigercat-core";
28
+
29
+ // ../core/src/internal/notification-center-styles.ts
30
+ var notificationCenterItemClasses = "tiger-motion-aware group relative flex items-start gap-3.5 w-full p-3.5 rounded-[var(--tiger-radius-lg,0.75rem)] hover:bg-[var(--tiger-surface-muted,#f9fafb)] [transition:var(--tiger-transition-base,all_200ms_cubic-bezier(0.4,0,0.2,1))]";
31
+ var notificationCenterUnreadItemClasses = "bg-[var(--tiger-outline-bg-hover,#eff6ff)] border-l-[3px] border-l-[var(--tiger-primary,#2563eb)] -ml-[3px] pl-[calc(0.875rem-3px)]";
32
+ var notificationCenterReadItemClasses = "border-l-[3px] border-l-transparent -ml-[3px] pl-[calc(0.875rem-3px)]";
33
+ var notificationCenterReadTitleClasses = "text-[var(--tiger-text-secondary,#4b5563)]";
34
+ var notificationCenterUnreadTitleClasses = "text-[var(--tiger-text,#111827)]";
35
+ var notificationCenterUnreadDotClasses = "tiger-motion-aware w-1.5 h-1.5 rounded-full bg-[var(--tiger-primary,#2563eb)] shrink-0 shadow-sm animate-pulse";
36
+ var notificationCenterTimeClasses = "text-[11px] text-[var(--tiger-text-muted,#6b7280)] font-medium whitespace-nowrap flex-shrink-0 self-center";
37
+ var notificationCenterReadDescriptionClasses = "text-[var(--tiger-text-muted,#6b7280)]";
38
+ var notificationCenterUnreadDescriptionClasses = "text-[var(--tiger-text-secondary,#4b5563)]";
39
+ var notificationCenterItemActionClasses = "tiger-motion-aware opacity-0 group-hover:opacity-100 focus:opacity-100 rounded-full px-2.5 py-1 text-[11px] font-semibold bg-[var(--tiger-surface-muted,#f3f4f6)] hover:bg-[var(--tiger-fill-hover,#e5e7eb)] text-[var(--tiger-text-secondary,#374151)] border-0 flex-shrink-0 self-center [transition:var(--tiger-transition-base,all_200ms_cubic-bezier(0.4,0,0.2,1))]";
40
+ var notificationCenterEmptyIconWrapperClasses = "p-3.5 bg-[var(--tiger-surface-muted,#f9fafb)] rounded-full mb-3 shadow-inner";
41
+ var notificationCenterEmptyIconClasses = "tiger-motion-aware w-8 h-8 text-[var(--tiger-text-muted,#9ca3af)] animate-pulse";
42
+ var notificationCenterEmptyTextClasses = "font-semibold text-[var(--tiger-text-muted,#6b7280)]";
43
+ var notificationCenterLoadingClasses = "text-[var(--tiger-primary,#2563eb)] font-medium";
44
+ var notificationCenterCardClasses = "tiger-motion-aware w-full rounded-[var(--tiger-radius-xl,1rem)] border border-[var(--tiger-border,#e5e7eb)] bg-[var(--tiger-surface,#ffffff)] shadow-[var(--tiger-shadow-glass,0_8px_30px_rgb(0_0_0_/_0.04))] [transition:var(--tiger-transition-base,all_200ms_cubic-bezier(0.4,0,0.2,1))] overflow-hidden";
45
+ var notificationCenterTitleClasses = "text-[var(--tiger-text,#111827)]";
46
+ var notificationCenterUnreadBadgeClasses = "tiger-motion-aware inline-flex items-center justify-center min-w-[20px] h-5 px-1.5 text-[11px] font-bold rounded-full bg-[var(--tiger-primary,#2563eb)] text-white shadow-sm animate-pulse";
47
+ var notificationCenterMarkAllBaseClasses = "tiger-motion-aware text-xs font-semibold transition-colors";
48
+ var notificationCenterMarkAllEnabledClasses = "text-[var(--tiger-primary,#2563eb)] hover:text-[var(--tiger-primary-hover,#1d4ed8)]";
49
+ var notificationCenterMarkAllDisabledClasses = "text-[var(--tiger-text-muted,#9ca3af)]";
50
+ var notificationCenterFilterGroupClasses = "inline-flex items-center gap-0.5 p-0.5 rounded-[var(--tiger-radius-md,0.5rem)] bg-[var(--tiger-surface-muted,#f3f4f6)] self-start";
51
+ var notificationCenterFilterButtonClasses = "tiger-motion-aware px-3.5 py-1 text-xs font-semibold rounded-[var(--tiger-radius-sm,0.375rem)] [transition:var(--tiger-transition-base,all_200ms_cubic-bezier(0.4,0,0.2,1))]";
52
+ var notificationCenterFilterActiveClasses = "bg-[var(--tiger-surface,#ffffff)] text-[var(--tiger-text,#111827)] shadow-sm";
53
+ var notificationCenterFilterIdleClasses = "text-[var(--tiger-text-muted,#6b7280)] hover:text-[var(--tiger-text,#111827)]";
54
+
55
+ // src/components/NotificationCenter.tsx
28
56
  import { jsx, jsxs } from "react/jsx-runtime";
29
57
  var getGroupKey = (group, index) => {
30
58
  return group.key ?? group.title ?? index;
@@ -193,8 +221,8 @@ var NotificationCenter = ({
193
221
  "div",
194
222
  {
195
223
  className: classNames(
196
- "group relative flex items-start gap-3.5 w-full p-3.5 rounded-xl transition-all duration-300 hover:bg-gray-50/60 dark:hover:bg-gray-800/30",
197
- !isRead ? "bg-blue-50/20 dark:bg-blue-950/5 hover:bg-blue-50/40 dark:hover:bg-blue-950/10 border-l-[3px] border-l-blue-500/80 -ml-[3px] pl-[calc(0.875rem-3px)]" : "border-l-[3px] border-l-transparent -ml-[3px] pl-[calc(0.875rem-3px)]"
224
+ notificationCenterItemClasses,
225
+ isRead ? notificationCenterReadItemClasses : notificationCenterUnreadItemClasses
198
226
  ),
199
227
  children: [
200
228
  /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
@@ -206,20 +234,20 @@ var NotificationCenter = ({
206
234
  tag: "span",
207
235
  size: "sm",
208
236
  weight: isRead ? "normal" : "semibold",
209
- className: isRead ? "text-gray-600 dark:text-gray-400" : "text-gray-900 dark:text-gray-100",
237
+ className: isRead ? notificationCenterReadTitleClasses : notificationCenterUnreadTitleClasses,
210
238
  children: item.title
211
239
  }
212
240
  ),
213
- !isRead && /* @__PURE__ */ jsx("span", { className: "w-1.5 h-1.5 rounded-full bg-blue-500 dark:bg-blue-400 shrink-0 shadow-sm shadow-blue-500/40 animate-pulse" })
241
+ !isRead && /* @__PURE__ */ jsx("span", { className: notificationCenterUnreadDotClasses })
214
242
  ] }),
215
- timeText ? /* @__PURE__ */ jsx("span", { className: "text-[11px] text-gray-400 dark:text-gray-500 font-medium whitespace-nowrap flex-shrink-0 self-center", children: timeText }) : null
243
+ timeText ? /* @__PURE__ */ jsx("span", { className: notificationCenterTimeClasses, children: timeText }) : null
216
244
  ] }),
217
245
  item.description ? /* @__PURE__ */ jsx(
218
246
  "div",
219
247
  {
220
248
  className: classNames(
221
249
  "mt-1 text-xs leading-relaxed line-clamp-2",
222
- isRead ? "text-gray-500 dark:text-gray-400" : "text-gray-600 dark:text-gray-300"
250
+ isRead ? notificationCenterReadDescriptionClasses : notificationCenterUnreadDescriptionClasses
223
251
  ),
224
252
  children: item.description
225
253
  }
@@ -230,7 +258,7 @@ var NotificationCenter = ({
230
258
  {
231
259
  size: "sm",
232
260
  variant: "ghost",
233
- className: "opacity-0 group-hover:opacity-100 focus:opacity-100 rounded-full px-2.5 py-1 text-[11px] font-semibold transition-all duration-200 bg-gray-100 hover:bg-gray-200 dark:bg-gray-800 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300 border-0 flex-shrink-0 self-center",
261
+ className: notificationCenterItemActionClasses,
234
262
  onClick: (event) => {
235
263
  event.stopPropagation();
236
264
  if (manageReadState) {
@@ -252,10 +280,10 @@ var NotificationCenter = ({
252
280
  const renderList = (listItems) => {
253
281
  if (listItems.length === 0) {
254
282
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center py-14 px-4 text-center", children: [
255
- /* @__PURE__ */ jsx("div", { className: "p-3.5 bg-gray-50 dark:bg-gray-900 rounded-full mb-3 shadow-inner", children: /* @__PURE__ */ jsx(
283
+ /* @__PURE__ */ jsx("div", { className: notificationCenterEmptyIconWrapperClasses, children: /* @__PURE__ */ jsx(
256
284
  "svg",
257
285
  {
258
- className: "w-8 h-8 text-gray-400 dark:text-gray-600 animate-pulse",
286
+ className: notificationCenterEmptyIconClasses,
259
287
  fill: "none",
260
288
  viewBox: "0 0 24 24",
261
289
  stroke: "currentColor",
@@ -270,16 +298,7 @@ var NotificationCenter = ({
270
298
  )
271
299
  }
272
300
  ) }),
273
- /* @__PURE__ */ jsx(
274
- Text,
275
- {
276
- tag: "div",
277
- size: "sm",
278
- color: "muted",
279
- className: "font-semibold text-gray-400 dark:text-gray-500",
280
- children: emptyText
281
- }
282
- )
301
+ /* @__PURE__ */ jsx(Text, { tag: "div", size: "sm", color: "muted", className: notificationCenterEmptyTextClasses, children: emptyText })
283
302
  ] });
284
303
  }
285
304
  return /* @__PURE__ */ jsx(
@@ -295,7 +314,16 @@ var NotificationCenter = ({
295
314
  }
296
315
  );
297
316
  };
298
- const content = loading ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-16", children: /* @__PURE__ */ jsx(Loading, { text: loadingText, className: "text-blue-500 dark:text-blue-400 font-medium" }) }) : resolvedGroups.length > 0 ? /* @__PURE__ */ jsx("div", { className: "-mx-4 -mb-4", children: /* @__PURE__ */ jsx(Tabs, { type: "line", size: "small", activeKey: currentGroupKey, onActiveKeyChange: handleGroupChange, children: groupTabData.map((tab) => /* @__PURE__ */ jsx(TabPane, { tabKey: tab.key, label: tab.label, children: /* @__PURE__ */ jsx("div", { className: "max-h-[380px] overflow-y-auto", children: renderList(tab.filteredItems) }) }, String(tab.key))) }) }) : /* @__PURE__ */ jsx("div", { className: "-mx-4 -mb-4 max-h-[380px] overflow-y-auto", children: renderList(filteredFlatItems) });
317
+ const content = loading ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-16", children: /* @__PURE__ */ jsx(Loading, { text: loadingText, className: notificationCenterLoadingClasses }) }) : resolvedGroups.length > 0 ? /* @__PURE__ */ jsx("div", { className: "-mx-4 -mb-4", children: /* @__PURE__ */ jsx(
318
+ Tabs,
319
+ {
320
+ type: "line",
321
+ size: "small",
322
+ activeKey: currentGroupKey,
323
+ onActiveKeyChange: handleGroupChange,
324
+ children: groupTabData.map((tab) => /* @__PURE__ */ jsx(TabPane, { tabKey: tab.key, label: tab.label, children: /* @__PURE__ */ jsx("div", { className: "max-h-[380px] overflow-y-auto", children: renderList(tab.filteredItems) }) }, String(tab.key)))
325
+ }
326
+ ) }) : /* @__PURE__ */ jsx("div", { className: "-mx-4 -mb-4 max-h-[380px] overflow-y-auto", children: renderList(filteredFlatItems) });
299
327
  return /* @__PURE__ */ jsx(
300
328
  "div",
301
329
  {
@@ -308,7 +336,7 @@ var NotificationCenter = ({
308
336
  Card,
309
337
  {
310
338
  variant: "bordered",
311
- className: "w-full rounded-2xl border border-gray-100/80 dark:border-gray-800/80 bg-white/95 dark:bg-gray-950/90 backdrop-blur-md shadow-[0_8px_30px_rgb(0,0,0,0.04)] dark:shadow-[0_8px_30px_rgb(0,0,0,0.2)] transition-all duration-300 overflow-hidden",
339
+ className: notificationCenterCardClasses,
312
340
  header: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
313
341
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
314
342
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5", children: [
@@ -318,11 +346,11 @@ var NotificationCenter = ({
318
346
  tag: "div",
319
347
  size: "base",
320
348
  weight: "bold",
321
- className: "text-gray-900 dark:text-gray-100",
349
+ className: notificationCenterTitleClasses,
322
350
  children: title
323
351
  }
324
352
  ),
325
- totalUnread > 0 ? /* @__PURE__ */ jsx("span", { className: "inline-flex items-center justify-center min-w-[20px] h-5 px-1.5 text-[11px] font-bold rounded-full bg-gradient-to-r from-blue-500 to-indigo-600 text-white shadow-sm shadow-blue-500/20 animate-pulse", children: totalUnread }) : null
353
+ totalUnread > 0 ? /* @__PURE__ */ jsx("span", { className: notificationCenterUnreadBadgeClasses, children: totalUnread }) : null
326
354
  ] }),
327
355
  /* @__PURE__ */ jsx(
328
356
  Button,
@@ -332,19 +360,19 @@ var NotificationCenter = ({
332
360
  disabled: !hasUnread,
333
361
  onClick: handleMarkAllRead,
334
362
  className: classNames(
335
- "text-xs font-semibold transition-colors duration-200",
336
- hasUnread ? "text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300" : "text-gray-400 dark:text-gray-600"
363
+ notificationCenterMarkAllBaseClasses,
364
+ hasUnread ? notificationCenterMarkAllEnabledClasses : notificationCenterMarkAllDisabledClasses
337
365
  ),
338
366
  children: markAllReadText
339
367
  }
340
368
  )
341
369
  ] }),
342
- /* @__PURE__ */ jsx("div", { className: "inline-flex items-center gap-0.5 p-0.5 rounded-lg bg-gray-100/80 dark:bg-gray-800/60 self-start", children: filterButtons.map((option) => /* @__PURE__ */ jsx(
370
+ /* @__PURE__ */ jsx("div", { className: notificationCenterFilterGroupClasses, children: filterButtons.map((option) => /* @__PURE__ */ jsx(
343
371
  "button",
344
372
  {
345
373
  className: classNames(
346
- "px-3.5 py-1 text-xs font-semibold rounded-md transition-all duration-200",
347
- currentReadFilter === option.key ? "bg-white dark:bg-gray-700 text-gray-900 dark:text-white shadow-sm scale-102" : "text-gray-500 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white"
374
+ notificationCenterFilterButtonClasses,
375
+ currentReadFilter === option.key ? notificationCenterFilterActiveClasses : notificationCenterFilterIdleClasses
348
376
  ),
349
377
  onClick: () => handleReadFilterChange(option.key),
350
378
  children: option.label
@@ -6,7 +6,7 @@ import {
6
6
  useBodyScrollLock,
7
7
  useEscapeKey,
8
8
  useFocusTrap
9
- } from "./chunk-SEWNVIHH.mjs";
9
+ } from "./chunk-HKAZXG74.mjs";
10
10
  import {
11
11
  useTigerConfig
12
12
  } from "./chunk-YSIXURBW.mjs";
@@ -166,6 +166,7 @@ var Modal = ({
166
166
  const reactId = useId();
167
167
  const modalId = useMemo(() => `tiger-modal-${reactId}`, [reactId]);
168
168
  const titleId = `${modalId}-title`;
169
+ const overlayHostId = `${modalId}-overlay-host`;
169
170
  const {
170
171
  ["aria-labelledby"]: _ariaLabelledby,
171
172
  role: _role,
@@ -174,6 +175,7 @@ var Modal = ({
174
175
  } = rest;
175
176
  const ariaLabelledby = rest["aria-labelledby"] ?? (title || titleContent ? titleId : void 0);
176
177
  const dialogRef = useRef(null);
178
+ const rootRef = useRef(null);
177
179
  const closeButtonRef = useRef(null);
178
180
  const previousActiveElementRef = useRef(null);
179
181
  const touchStartRef = useRef(null);
@@ -188,9 +190,9 @@ var Modal = ({
188
190
  }
189
191
  restoreFocus(previousActiveElementRef.current);
190
192
  }, [open]);
191
- useEscapeKey({ enabled: open, onEscape: handleClose });
193
+ useEscapeKey({ enabled: open, onEscape: handleClose, layerRef: rootRef });
192
194
  useBodyScrollLock({ enabled: open });
193
- useFocusTrap({ enabled: open, containerRef: dialogRef });
195
+ useFocusTrap({ enabled: open, containerRef: rootRef });
194
196
  const resetTouchGesture = useCallback(() => {
195
197
  touchStartRef.current = null;
196
198
  touchCurrentRef.current = null;
@@ -263,10 +265,12 @@ var Modal = ({
263
265
  const modalContent = /* @__PURE__ */ jsxs(
264
266
  "div",
265
267
  {
268
+ ref: rootRef,
266
269
  className: classNames(modalWrapperClasses, !open && "pointer-events-none"),
267
270
  style: { zIndex },
268
271
  hidden: !open,
269
272
  "aria-hidden": !open ? "true" : void 0,
273
+ "data-tiger-overlay-layer": "",
270
274
  "data-tiger-modal-root": "",
271
275
  children: [
272
276
  mask && /* @__PURE__ */ jsx(
@@ -290,6 +294,7 @@ var Modal = ({
290
294
  role: "dialog",
291
295
  "aria-modal": "true",
292
296
  "aria-labelledby": ariaLabelledby,
297
+ "aria-owns": overlayHostId,
293
298
  tabIndex: -1,
294
299
  ref: dialogRef,
295
300
  onTouchStart: handleTouchStart,
@@ -327,7 +332,8 @@ var Modal = ({
327
332
  ] }) : null
328
333
  ]
329
334
  }
330
- ) })
335
+ ) }),
336
+ /* @__PURE__ */ jsx("div", { id: overlayHostId, className: "contents", "data-tiger-overlay-host": "" })
331
337
  ]
332
338
  }
333
339
  );
@@ -0,0 +1,292 @@
1
+ import {
2
+ Timeline
3
+ } from "./chunk-QB5472NM.mjs";
4
+ import {
5
+ Link
6
+ } from "./chunk-XZVQ3PJS.mjs";
7
+ import {
8
+ Loading
9
+ } from "./chunk-K4GIKSZE.mjs";
10
+ import {
11
+ Tag
12
+ } from "./chunk-7EXOY7GD.mjs";
13
+ import {
14
+ Text
15
+ } from "./chunk-HLS4CHWX.mjs";
16
+ import {
17
+ Card
18
+ } from "./chunk-IXV5YBCZ.mjs";
19
+ import {
20
+ Avatar
21
+ } from "./chunk-OO562MFD.mjs";
22
+
23
+ // src/components/ActivityFeed.tsx
24
+ import { useMemo } from "react";
25
+ import {
26
+ classNames,
27
+ buildActivityGroups,
28
+ formatActivityTime,
29
+ toActivityTimelineItems,
30
+ activityItemClasses,
31
+ activityItemLayoutClasses,
32
+ activityItemBodyClasses,
33
+ activityItemHeaderClasses,
34
+ activityItemTitleGroupClasses,
35
+ activityItemDescriptionClasses,
36
+ activityItemActionsClasses
37
+ } from "@expcat/tigercat-core";
38
+
39
+ // ../core/src/internal/activity-feed-styles.ts
40
+ var activityFeedActionClasses = "tiger-motion-aware inline-flex items-center px-2.5 py-1 rounded-[var(--tiger-radius-md,0.5rem)] text-xs font-semibold text-[var(--tiger-primary,#2563eb)] hover:bg-[var(--tiger-outline-bg-hover,#eff6ff)] [transition:var(--tiger-transition-base,all_200ms_cubic-bezier(0.4,0,0.2,1))]";
41
+ var activityFeedItemSurfaceClasses = "tiger-motion-aware p-4 rounded-[var(--tiger-radius-xl,1rem)] border border-[var(--tiger-border,#e5e7eb)] bg-[var(--tiger-surface,#ffffff)] shadow-[var(--tiger-shadow-sm,0_1px_2px_rgb(0_0_0_/_0.05))] [transition:var(--tiger-transition-base,all_200ms_cubic-bezier(0.4,0,0.2,1))] hover:shadow-[var(--tiger-shadow-glass-strong,0_4px_6px_-1px_rgb(0_0_0_/_0.1))] hover:-translate-y-0.5 w-full";
42
+ var activityFeedAvatarClasses = "tiger-motion-aware shrink-0 ring-2 ring-[var(--tiger-surface,#ffffff)] shadow-[var(--tiger-shadow-sm,0_1px_2px_rgb(0_0_0_/_0.05))] [transition:var(--tiger-transition-base,all_200ms_cubic-bezier(0.4,0,0.2,1))] hover:scale-105";
43
+ var activityFeedTitleClasses = "tiger-motion-aware text-[var(--tiger-text,#111827)] hover:text-[var(--tiger-primary,#2563eb)] transition-colors cursor-pointer truncate";
44
+ var activityFeedTimeClasses = "shrink-0 whitespace-nowrap font-medium text-[var(--tiger-text-muted,#6b7280)]";
45
+ var activityFeedDescriptionClasses = "text-[var(--tiger-text-secondary,#4b5563)] leading-relaxed pl-0.5 mt-1";
46
+ var activityFeedStateCardClasses = "bg-[var(--tiger-surface,#ffffff)] border-[var(--tiger-border,#e5e7eb)] rounded-[var(--tiger-radius-xl,1rem)] shadow-[var(--tiger-shadow-sm,0_1px_2px_rgb(0_0_0_/_0.05))] overflow-hidden";
47
+ var activityFeedLoadingClasses = "text-[var(--tiger-primary,#2563eb)] font-medium";
48
+ var activityFeedEmptyIconClasses = "tiger-motion-aware w-12 h-12 text-[var(--tiger-text-muted,#9ca3af)] mb-3 animate-pulse";
49
+ var activityFeedGroupMarkerClasses = "w-1.5 h-3.5 bg-[var(--tiger-primary,#2563eb)] rounded-full shadow-sm";
50
+ var activityFeedGroupTitleClasses = "text-[var(--tiger-text,#111827)] uppercase tracking-wider";
51
+ var activityFeedDotBaseClasses = "w-3 h-3 rounded-full border-2 border-[var(--tiger-surface,#ffffff)] shadow-sm relative z-10";
52
+ var activityFeedDotPulseBaseClasses = "tiger-motion-aware absolute inline-flex h-full w-full rounded-full animate-ping opacity-75";
53
+ var dotVariantClasses = {
54
+ success: "bg-[var(--tiger-success,#16a34a)]",
55
+ warning: "bg-[var(--tiger-warning,#d97706)]",
56
+ error: "bg-[var(--tiger-error,#dc2626)]",
57
+ danger: "bg-[var(--tiger-error,#dc2626)]",
58
+ primary: "bg-[var(--tiger-primary,#2563eb)]",
59
+ info: "bg-[var(--tiger-primary,#2563eb)]"
60
+ };
61
+ var dotPulseVariantClasses = {
62
+ success: "bg-[var(--tiger-success,#16a34a)]/30",
63
+ warning: "bg-[var(--tiger-warning,#d97706)]/30",
64
+ error: "bg-[var(--tiger-error,#dc2626)]/30",
65
+ danger: "bg-[var(--tiger-error,#dc2626)]/30",
66
+ primary: "bg-[var(--tiger-primary,#2563eb)]/30",
67
+ info: "bg-[var(--tiger-primary,#2563eb)]/30"
68
+ };
69
+ var getActivityFeedDotClasses = (variant) => ({
70
+ dot: dotVariantClasses[variant ?? ""] ?? "bg-[var(--tiger-border,#d1d5db)]",
71
+ pulse: dotPulseVariantClasses[variant ?? ""] ?? ""
72
+ });
73
+
74
+ // src/components/ActivityFeed.tsx
75
+ import { jsx, jsxs } from "react/jsx-runtime";
76
+ var renderAction = (item, action, index) => {
77
+ const key = action.key ?? `${item.id}-action-${index}`;
78
+ return /* @__PURE__ */ jsx(
79
+ Link,
80
+ {
81
+ size: "sm",
82
+ variant: "primary",
83
+ underline: false,
84
+ href: action.href,
85
+ target: action.target,
86
+ disabled: action.disabled,
87
+ className: activityFeedActionClasses,
88
+ onClick: () => action.onClick?.(item, action),
89
+ children: action.label
90
+ },
91
+ key
92
+ );
93
+ };
94
+ var ActivityFeed = ({
95
+ items = [],
96
+ groups,
97
+ groupBy,
98
+ groupOrder,
99
+ loading = false,
100
+ loadingText = "\u52A0\u8F7D\u4E2D...",
101
+ emptyText = "\u6682\u65E0\u52A8\u6001",
102
+ showAvatar = true,
103
+ showTime = true,
104
+ showGroupTitle = true,
105
+ renderItem,
106
+ renderGroupHeader,
107
+ className,
108
+ ...props
109
+ }) => {
110
+ const resolvedGroups = useMemo(
111
+ () => buildActivityGroups(items, groups, groupBy, groupOrder),
112
+ [items, groups, groupBy, groupOrder]
113
+ );
114
+ const wrapperClasses = classNames(
115
+ "tiger-activity-feed",
116
+ "flex",
117
+ "flex-col",
118
+ "gap-6",
119
+ "w-full",
120
+ className
121
+ );
122
+ const renderDefaultItem = (item, index, group) => {
123
+ if (renderItem) return renderItem(item, index, group);
124
+ const titleText = item.title ?? (typeof item.content === "string" || typeof item.content === "number" ? String(item.content) : "");
125
+ const descriptionText = item.description;
126
+ const timeText = showTime ? formatActivityTime(item.time) : "";
127
+ const actionNodes = item.actions?.map(
128
+ (action, actionIndex) => renderAction(item, action, actionIndex)
129
+ );
130
+ return /* @__PURE__ */ jsx("div", { className: classNames(activityItemClasses, activityFeedItemSurfaceClasses), children: /* @__PURE__ */ jsxs("div", { className: activityItemLayoutClasses, children: [
131
+ showAvatar && item.user ? /* @__PURE__ */ jsx(
132
+ Avatar,
133
+ {
134
+ size: "sm",
135
+ src: item.user.avatar,
136
+ text: item.user.name,
137
+ className: activityFeedAvatarClasses
138
+ }
139
+ ) : null,
140
+ /* @__PURE__ */ jsxs("div", { className: activityItemBodyClasses, children: [
141
+ /* @__PURE__ */ jsxs("div", { className: activityItemHeaderClasses, children: [
142
+ /* @__PURE__ */ jsxs("div", { className: activityItemTitleGroupClasses, children: [
143
+ titleText ? /* @__PURE__ */ jsx(Text, { tag: "div", size: "sm", weight: "semibold", className: activityFeedTitleClasses, children: titleText }) : null,
144
+ item.status ? /* @__PURE__ */ jsx(
145
+ Tag,
146
+ {
147
+ variant: item.status.variant ?? "default",
148
+ size: "sm",
149
+ className: "shrink-0 rounded-full px-2 py-0.5 text-[10px] font-semibold tracking-wide uppercase border border-current bg-current/10 shadow-sm",
150
+ children: item.status.label
151
+ }
152
+ ) : null
153
+ ] }),
154
+ timeText ? /* @__PURE__ */ jsx(Text, { tag: "div", size: "xs", color: "muted", className: activityFeedTimeClasses, children: timeText }) : null
155
+ ] }),
156
+ descriptionText ? /* @__PURE__ */ jsx(
157
+ Text,
158
+ {
159
+ tag: "div",
160
+ size: "sm",
161
+ color: "muted",
162
+ className: classNames(
163
+ activityItemDescriptionClasses,
164
+ activityFeedDescriptionClasses
165
+ ),
166
+ children: descriptionText
167
+ }
168
+ ) : null,
169
+ actionNodes?.length ? /* @__PURE__ */ jsx("div", { className: classNames(activityItemActionsClasses, "mt-2.5"), children: actionNodes }) : null
170
+ ] })
171
+ ] }) });
172
+ };
173
+ if (loading) {
174
+ return /* @__PURE__ */ jsx(
175
+ "div",
176
+ {
177
+ className: wrapperClasses,
178
+ role: "feed",
179
+ "aria-label": "\u52A8\u6001",
180
+ "aria-busy": true,
181
+ ...props,
182
+ "data-tiger-activity-feed": true,
183
+ children: /* @__PURE__ */ jsx(
184
+ Card,
185
+ {
186
+ variant: "bordered",
187
+ size: "sm",
188
+ className: classNames("tiger-activity-feed-loading", activityFeedStateCardClasses),
189
+ children: /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsx(Loading, { text: loadingText, className: activityFeedLoadingClasses }) })
190
+ }
191
+ )
192
+ }
193
+ );
194
+ }
195
+ if (resolvedGroups.length === 0) {
196
+ return /* @__PURE__ */ jsx(
197
+ "div",
198
+ {
199
+ className: wrapperClasses,
200
+ role: "feed",
201
+ "aria-label": "\u52A8\u6001",
202
+ ...props,
203
+ "data-tiger-activity-feed": true,
204
+ children: /* @__PURE__ */ jsx(
205
+ Card,
206
+ {
207
+ variant: "bordered",
208
+ size: "sm",
209
+ className: classNames("tiger-activity-feed-empty", activityFeedStateCardClasses),
210
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center py-12 px-4", children: [
211
+ /* @__PURE__ */ jsx(
212
+ "svg",
213
+ {
214
+ className: activityFeedEmptyIconClasses,
215
+ fill: "none",
216
+ viewBox: "0 0 24 24",
217
+ stroke: "currentColor",
218
+ strokeWidth: "1.5",
219
+ children: /* @__PURE__ */ jsx(
220
+ "path",
221
+ {
222
+ strokeLinecap: "round",
223
+ strokeLinejoin: "round",
224
+ d: "M12 7.5h1.5m-1.5 3h1.5m-7.5 3h10.5m-10.5 3h10.5m-13.5-9h16.5M3 5.25h18M3 18.75h18"
225
+ }
226
+ )
227
+ }
228
+ ),
229
+ /* @__PURE__ */ jsx(Text, { tag: "div", size: "sm", color: "muted", className: "font-medium", children: emptyText })
230
+ ] })
231
+ }
232
+ )
233
+ }
234
+ );
235
+ }
236
+ return /* @__PURE__ */ jsx(
237
+ "div",
238
+ {
239
+ className: wrapperClasses,
240
+ role: "feed",
241
+ "aria-label": "\u52A8\u6001",
242
+ ...props,
243
+ "data-tiger-activity-feed": true,
244
+ children: resolvedGroups.map((group, groupIndex) => {
245
+ const headerNode = renderGroupHeader?.(group);
246
+ const groupTitle = group.title;
247
+ const timelineItems = toActivityTimelineItems(group.items);
248
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
249
+ showGroupTitle && groupTitle ? headerNode ?? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-2", children: [
250
+ /* @__PURE__ */ jsx("span", { className: activityFeedGroupMarkerClasses }),
251
+ /* @__PURE__ */ jsx(
252
+ Text,
253
+ {
254
+ tag: "span",
255
+ size: "sm",
256
+ weight: "bold",
257
+ className: activityFeedGroupTitleClasses,
258
+ children: groupTitle
259
+ }
260
+ )
261
+ ] }) : null,
262
+ /* @__PURE__ */ jsx(
263
+ Timeline,
264
+ {
265
+ items: timelineItems,
266
+ renderDot: (timelineItem) => {
267
+ const activity = timelineItem.activity;
268
+ const statusVariant = activity?.status?.variant ?? "default";
269
+ const dotClasses = getActivityFeedDotClasses(statusVariant);
270
+ return /* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center w-4 h-4", children: [
271
+ dotClasses.pulse ? /* @__PURE__ */ jsx("span", { className: `${activityFeedDotPulseBaseClasses} ${dotClasses.pulse}` }) : null,
272
+ /* @__PURE__ */ jsx("span", { className: `${activityFeedDotBaseClasses} ${dotClasses.dot}` })
273
+ ] });
274
+ },
275
+ renderItem: (timelineItem, index) => {
276
+ const activity = timelineItem.activity;
277
+ if (!activity) return null;
278
+ return renderDefaultItem(activity, index, group);
279
+ }
280
+ }
281
+ )
282
+ ] }, group.key ?? groupIndex);
283
+ })
284
+ }
285
+ );
286
+ };
287
+ var ActivityFeed_default = ActivityFeed;
288
+
289
+ export {
290
+ ActivityFeed,
291
+ ActivityFeed_default
292
+ };