@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,110 @@
1
+ 'use strict';
2
+
3
+ var chunkIQINYCU6_js = require('./chunk-IQINYCU6.js');
4
+ var chunkMKWXJZ3T_js = require('./chunk-MKWXJZ3T.js');
5
+ var chunk6MGEGOYJ_js = require('./chunk-6MGEGOYJ.js');
6
+ var chunk2TS6X5RA_js = require('./chunk-2TS6X5RA.js');
7
+ var chunkYYGTJKP5_js = require('./chunk-YYGTJKP5.js');
8
+ var chunkVO4WDK4K_js = require('./chunk-VO4WDK4K.js');
9
+ var chunkTZ26HQAW_js = require('./chunk-TZ26HQAW.js');
10
+ var react = require('react');
11
+ var tigercatCore = require('@expcat/tigercat-core');
12
+ var jsxRuntime = require('react/jsx-runtime');
13
+
14
+ var renderAction = (item, action, index) => {
15
+ const key = action.key ?? `${item.id}-action-${index}`;
16
+ return /* @__PURE__ */ jsxRuntime.jsx(
17
+ chunkMKWXJZ3T_js.Link,
18
+ {
19
+ size: "sm",
20
+ variant: "primary",
21
+ href: action.href,
22
+ target: action.target,
23
+ disabled: action.disabled,
24
+ onClick: () => action.onClick?.(item, action),
25
+ children: action.label
26
+ },
27
+ key
28
+ );
29
+ };
30
+ var ActivityFeed = ({
31
+ items = [],
32
+ groups,
33
+ groupBy,
34
+ groupOrder,
35
+ loading = false,
36
+ loadingText = "\u52A0\u8F7D\u4E2D...",
37
+ emptyText = "\u6682\u65E0\u52A8\u6001",
38
+ showAvatar = true,
39
+ showTime = true,
40
+ showGroupTitle = true,
41
+ renderItem,
42
+ renderGroupHeader,
43
+ className,
44
+ ...props
45
+ }) => {
46
+ const resolvedGroups = react.useMemo(
47
+ () => tigercatCore.buildActivityGroups(items, groups, groupBy, groupOrder),
48
+ [items, groups, groupBy, groupOrder]
49
+ );
50
+ const wrapperClasses = tigercatCore.classNames(
51
+ "tiger-activity-feed",
52
+ "flex",
53
+ "flex-col",
54
+ "gap-6",
55
+ "w-full",
56
+ className
57
+ );
58
+ const renderDefaultItem = (item, index, group) => {
59
+ if (renderItem) return renderItem(item, index, group);
60
+ const titleText = item.title ?? (typeof item.content === "string" || typeof item.content === "number" ? String(item.content) : "");
61
+ const descriptionText = item.description;
62
+ const timeText = showTime ? tigercatCore.formatActivityTime(item.time) : "";
63
+ const actionNodes = item.actions?.map(
64
+ (action, actionIndex) => renderAction(item, action, actionIndex)
65
+ );
66
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tiger-activity-item", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3 items-start", children: [
67
+ showAvatar && item.user ? /* @__PURE__ */ jsxRuntime.jsx(chunkTZ26HQAW_js.Avatar, { size: "sm", src: item.user.avatar, text: item.user.name, className: "shrink-0" }) : null,
68
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
69
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2 mb-1", children: [
70
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [
71
+ titleText ? /* @__PURE__ */ jsxRuntime.jsx(chunkYYGTJKP5_js.Text, { tag: "div", size: "sm", weight: "medium", className: "truncate", children: titleText }) : null,
72
+ item.status ? /* @__PURE__ */ jsxRuntime.jsx(chunk2TS6X5RA_js.Tag, { variant: item.status.variant ?? "default", size: "sm", className: "shrink-0", children: item.status.label }) : null
73
+ ] }),
74
+ timeText ? /* @__PURE__ */ jsxRuntime.jsx(chunkYYGTJKP5_js.Text, { tag: "div", size: "xs", color: "muted", className: "shrink-0 whitespace-nowrap", children: timeText }) : null
75
+ ] }),
76
+ descriptionText ? /* @__PURE__ */ jsxRuntime.jsx(chunkYYGTJKP5_js.Text, { tag: "div", size: "sm", color: "muted", className: "mb-2 break-words", children: descriptionText }) : null,
77
+ actionNodes?.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: actionNodes }) : null
78
+ ] })
79
+ ] }) });
80
+ };
81
+ if (loading) {
82
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrapperClasses, ...props, "data-tiger-activity-feed": true, children: /* @__PURE__ */ jsxRuntime.jsx(chunkVO4WDK4K_js.Card, { variant: "bordered", size: "sm", className: "tiger-activity-feed-loading", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-4", children: /* @__PURE__ */ jsxRuntime.jsx(chunk6MGEGOYJ_js.Loading, { text: loadingText }) }) }) });
83
+ }
84
+ if (resolvedGroups.length === 0) {
85
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrapperClasses, ...props, "data-tiger-activity-feed": true, children: /* @__PURE__ */ jsxRuntime.jsx(chunkVO4WDK4K_js.Card, { variant: "bordered", size: "sm", className: "tiger-activity-feed-empty", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-6", children: /* @__PURE__ */ jsxRuntime.jsx(chunkYYGTJKP5_js.Text, { tag: "div", size: "sm", color: "muted", children: emptyText }) }) }) });
86
+ }
87
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrapperClasses, ...props, "data-tiger-activity-feed": true, children: resolvedGroups.map((group, groupIndex) => {
88
+ const headerNode = renderGroupHeader?.(group);
89
+ const groupTitle = group.title;
90
+ const timelineItems = tigercatCore.toActivityTimelineItems(group.items);
91
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
92
+ showGroupTitle && groupTitle ? headerNode ?? /* @__PURE__ */ jsxRuntime.jsx(chunkYYGTJKP5_js.Text, { tag: "div", size: "sm", weight: "medium", color: "muted", children: groupTitle }) : null,
93
+ /* @__PURE__ */ jsxRuntime.jsx(
94
+ chunkIQINYCU6_js.Timeline,
95
+ {
96
+ items: timelineItems,
97
+ renderItem: (timelineItem, index) => {
98
+ const activity = timelineItem.activity;
99
+ if (!activity) return null;
100
+ return renderDefaultItem(activity, index, group);
101
+ }
102
+ }
103
+ )
104
+ ] }, group.key ?? groupIndex);
105
+ }) });
106
+ };
107
+ var ActivityFeed_default = ActivityFeed;
108
+
109
+ exports.ActivityFeed = ActivityFeed;
110
+ exports.ActivityFeed_default = ActivityFeed_default;
@@ -0,0 +1,78 @@
1
+ import { useState, useCallback, useEffect, useMemo } from 'react';
2
+ import { getScrollTop, scrollToTop, classNames, backTopButtonClasses, backTopContainerClasses, backTopVisibleClasses, backTopHiddenClasses, backTopIconPath } from '@expcat/tigercat-core';
3
+ import { jsx } from 'react/jsx-runtime';
4
+
5
+ // src/components/BackTop.tsx
6
+ var DefaultIcon = () => /* @__PURE__ */ jsx(
7
+ "svg",
8
+ {
9
+ xmlns: "http://www.w3.org/2000/svg",
10
+ fill: "none",
11
+ viewBox: "0 0 24 24",
12
+ stroke: "currentColor",
13
+ strokeWidth: 2,
14
+ className: "h-5 w-5",
15
+ "aria-hidden": "true",
16
+ children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: backTopIconPath })
17
+ }
18
+ );
19
+ var BackTop = ({
20
+ visibilityHeight = 400,
21
+ target = () => window,
22
+ duration = 450,
23
+ onClick,
24
+ children,
25
+ className,
26
+ "aria-label": ariaLabel = "Back to top",
27
+ ...props
28
+ }) => {
29
+ const [visible, setVisible] = useState(false);
30
+ const handleScroll = useCallback(() => {
31
+ const targetElement = target();
32
+ if (!targetElement) return;
33
+ const scrollTop = getScrollTop(targetElement);
34
+ setVisible(scrollTop >= visibilityHeight);
35
+ }, [target, visibilityHeight]);
36
+ const handleClick = useCallback(
37
+ (event) => {
38
+ const targetElement = target();
39
+ if (targetElement) {
40
+ scrollToTop(targetElement, duration);
41
+ }
42
+ onClick?.(event);
43
+ },
44
+ [target, duration, onClick]
45
+ );
46
+ useEffect(() => {
47
+ const targetElement = target();
48
+ if (!targetElement) return;
49
+ targetElement.addEventListener("scroll", handleScroll, { passive: true });
50
+ handleScroll();
51
+ return () => {
52
+ targetElement.removeEventListener("scroll", handleScroll);
53
+ };
54
+ }, [target, handleScroll]);
55
+ const buttonClasses = useMemo(() => {
56
+ const targetElement = target();
57
+ const positionClasses = !targetElement || targetElement === window ? backTopButtonClasses : backTopContainerClasses;
58
+ return classNames(
59
+ positionClasses,
60
+ visible ? backTopVisibleClasses : backTopHiddenClasses,
61
+ className
62
+ );
63
+ }, [target, visible, className]);
64
+ return /* @__PURE__ */ jsx(
65
+ "button",
66
+ {
67
+ type: "button",
68
+ className: buttonClasses,
69
+ "aria-label": ariaLabel,
70
+ onClick: handleClick,
71
+ ...props,
72
+ children: children || /* @__PURE__ */ jsx(DefaultIcon, {})
73
+ }
74
+ );
75
+ };
76
+ var BackTop_default = BackTop;
77
+
78
+ export { BackTop, BackTop_default };
@@ -0,0 +1,65 @@
1
+ import { useAnchorContext } from './chunk-YIF5VX7K.mjs';
2
+ import React, { useEffect, useMemo } from 'react';
3
+ import { classNames, getAnchorLinkClasses } from '@expcat/tigercat-core';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ var AnchorLink = ({
7
+ href,
8
+ title,
9
+ target,
10
+ className,
11
+ children,
12
+ ...props
13
+ }) => {
14
+ const anchorContext = useAnchorContext();
15
+ useEffect(() => {
16
+ anchorContext?.registerLink(href);
17
+ return () => {
18
+ anchorContext?.unregisterLink(href);
19
+ };
20
+ }, [href, anchorContext]);
21
+ const handleClick = (event) => {
22
+ event.preventDefault();
23
+ anchorContext?.handleLinkClick(href, event);
24
+ };
25
+ const linkClasses = useMemo(() => {
26
+ const isActive = anchorContext?.activeLink === href;
27
+ return classNames(getAnchorLinkClasses(isActive, className));
28
+ }, [anchorContext?.activeLink, href, className]);
29
+ const hasNestedLinks = React.Children.toArray(children).some(
30
+ (child) => React.isValidElement(child) && child.type === AnchorLink
31
+ );
32
+ if (hasNestedLinks) {
33
+ return /* @__PURE__ */ jsxs("div", { className: "anchor-link-wrapper", children: [
34
+ /* @__PURE__ */ jsx(
35
+ "a",
36
+ {
37
+ href,
38
+ target,
39
+ className: linkClasses,
40
+ "data-anchor-href": href,
41
+ onClick: handleClick,
42
+ ...props,
43
+ children: title
44
+ }
45
+ ),
46
+ /* @__PURE__ */ jsx("div", { className: "pl-3 mt-1 space-y-1", children })
47
+ ] });
48
+ }
49
+ const content = children ?? title;
50
+ return /* @__PURE__ */ jsx(
51
+ "a",
52
+ {
53
+ href,
54
+ target,
55
+ className: linkClasses,
56
+ "data-anchor-href": href,
57
+ onClick: handleClick,
58
+ ...props,
59
+ children: content
60
+ }
61
+ );
62
+ };
63
+ var AnchorLink_default = AnchorLink;
64
+
65
+ export { AnchorLink, AnchorLink_default };
@@ -0,0 +1,258 @@
1
+ 'use strict';
2
+
3
+ var chunkHDDBBZQH_js = require('./chunk-HDDBBZQH.js');
4
+ var chunkOZLGNWET_js = require('./chunk-OZLGNWET.js');
5
+ var chunkA3DJSVTE_js = require('./chunk-A3DJSVTE.js');
6
+ var chunk6MGEGOYJ_js = require('./chunk-6MGEGOYJ.js');
7
+ var chunkYYGTJKP5_js = require('./chunk-YYGTJKP5.js');
8
+ var chunkVO4WDK4K_js = require('./chunk-VO4WDK4K.js');
9
+ var react = require('react');
10
+ var tigercatCore = require('@expcat/tigercat-core');
11
+ var jsxRuntime = require('react/jsx-runtime');
12
+
13
+ var getGroupKey = (group, index) => {
14
+ return group.key ?? group.title ?? index;
15
+ };
16
+ var filterItems = (items, filter) => {
17
+ return items.filter((item) => {
18
+ const isRead = Boolean(item.read);
19
+ if (filter === "read") return isRead;
20
+ if (filter === "unread") return !isRead;
21
+ return true;
22
+ });
23
+ };
24
+ var NotificationCenter = ({
25
+ items = [],
26
+ groups,
27
+ groupBy,
28
+ groupOrder,
29
+ activeGroupKey,
30
+ defaultActiveGroupKey,
31
+ readFilter,
32
+ defaultReadFilter = "all",
33
+ loading = false,
34
+ loadingText = "\u52A0\u8F7D\u4E2D...",
35
+ emptyText = "\u6682\u65E0\u901A\u77E5",
36
+ title = "\u901A\u77E5\u4E2D\u5FC3",
37
+ allLabel = "\u5168\u90E8",
38
+ unreadLabel = "\u672A\u8BFB",
39
+ readLabel = "\u5DF2\u8BFB",
40
+ markAllReadText = "\u5168\u90E8\u6807\u8BB0\u5DF2\u8BFB",
41
+ markReadText = "\u6807\u8BB0\u5DF2\u8BFB",
42
+ markUnreadText = "\u6807\u8BB0\u672A\u8BFB",
43
+ manageReadState = false,
44
+ onGroupChange,
45
+ onReadFilterChange,
46
+ onMarkAllRead,
47
+ onItemClick,
48
+ onItemReadChange,
49
+ className,
50
+ ...props
51
+ }) => {
52
+ const resolvedGroups = react.useMemo(
53
+ () => tigercatCore.buildNotificationGroups(items, groups, groupBy, groupOrder),
54
+ [items, groups, groupBy, groupOrder]
55
+ );
56
+ const firstGroupKey = react.useMemo(() => {
57
+ return resolvedGroups.length > 0 ? getGroupKey(resolvedGroups[0], 0) : void 0;
58
+ }, [resolvedGroups]);
59
+ const [internalGroupKey, setInternalGroupKey] = react.useState(
60
+ defaultActiveGroupKey
61
+ );
62
+ const [internalReadFilter, setInternalReadFilter] = react.useState(defaultReadFilter);
63
+ const currentGroupKey = activeGroupKey ?? internalGroupKey ?? firstGroupKey;
64
+ const currentReadFilter = readFilter ?? internalReadFilter;
65
+ react.useEffect(() => {
66
+ if (activeGroupKey !== void 0) return;
67
+ if (resolvedGroups.length === 0) {
68
+ setInternalGroupKey(void 0);
69
+ return;
70
+ }
71
+ const keys = resolvedGroups.map((group, index) => getGroupKey(group, index));
72
+ if (!keys.some((key) => key === currentGroupKey)) {
73
+ setInternalGroupKey(keys[0]);
74
+ }
75
+ }, [activeGroupKey, currentGroupKey, resolvedGroups]);
76
+ const currentGroup = react.useMemo(() => {
77
+ if (resolvedGroups.length === 0) return void 0;
78
+ if (currentGroupKey === void 0) return resolvedGroups[0];
79
+ const index = resolvedGroups.findIndex(
80
+ (group, groupIndex) => getGroupKey(group, groupIndex) === currentGroupKey
81
+ );
82
+ return index >= 0 ? resolvedGroups[index] : resolvedGroups[0];
83
+ }, [currentGroupKey, resolvedGroups]);
84
+ currentGroup?.items ?? [];
85
+ const [readStateOverrides, setReadStateOverrides] = react.useState(
86
+ () => /* @__PURE__ */ new Map()
87
+ );
88
+ react.useEffect(() => {
89
+ if (manageReadState) setReadStateOverrides(/* @__PURE__ */ new Map());
90
+ }, [items, manageReadState]);
91
+ const applyReadOverrides = (list) => {
92
+ if (!manageReadState || readStateOverrides.size === 0) return list;
93
+ return list.map((item) => {
94
+ const override = readStateOverrides.get(item.id);
95
+ return override !== void 0 ? { ...item, read: override } : item;
96
+ });
97
+ };
98
+ const effectiveGroups = react.useMemo(
99
+ () => resolvedGroups.map((group) => ({
100
+ ...group,
101
+ items: applyReadOverrides(group.items)
102
+ })),
103
+ // eslint-disable-next-line react-hooks/exhaustive-deps
104
+ [resolvedGroups, readStateOverrides]
105
+ );
106
+ const effectiveCurrentGroup = react.useMemo(() => {
107
+ if (effectiveGroups.length === 0) return void 0;
108
+ if (currentGroupKey === void 0) return effectiveGroups[0];
109
+ const index = effectiveGroups.findIndex(
110
+ (group, groupIndex) => getGroupKey(group, groupIndex) === currentGroupKey
111
+ );
112
+ return index >= 0 ? effectiveGroups[index] : effectiveGroups[0];
113
+ }, [currentGroupKey, effectiveGroups]);
114
+ const effectiveCurrentGroupItems = effectiveCurrentGroup?.items ?? [];
115
+ const effectiveItems = react.useMemo(() => applyReadOverrides(items), [items, readStateOverrides]);
116
+ const hasUnread = effectiveCurrentGroupItems.some((item) => !item.read);
117
+ const totalUnread = react.useMemo(() => {
118
+ const allItems = effectiveGroups.flatMap((group) => group.items);
119
+ if (allItems.length === 0) return effectiveItems.filter((item) => !item.read).length;
120
+ return allItems.filter((item) => !item.read).length;
121
+ }, [effectiveGroups, effectiveItems]);
122
+ const wrapperClasses = react.useMemo(
123
+ () => tigercatCore.classNames("tiger-notification-center", "w-full", "flex", "flex-col", className),
124
+ [className]
125
+ );
126
+ const handleGroupChange = (key) => {
127
+ if (activeGroupKey === void 0) {
128
+ setInternalGroupKey(key);
129
+ }
130
+ onGroupChange?.(key);
131
+ };
132
+ const handleReadFilterChange = (next) => {
133
+ if (readFilter === void 0) {
134
+ setInternalReadFilter(next);
135
+ }
136
+ onReadFilterChange?.(next);
137
+ };
138
+ const handleMarkAllRead = () => {
139
+ if (manageReadState) {
140
+ setReadStateOverrides((prev) => {
141
+ const next = new Map(prev);
142
+ effectiveCurrentGroupItems.forEach((item) => next.set(item.id, true));
143
+ return next;
144
+ });
145
+ }
146
+ onMarkAllRead?.(currentGroupKey, effectiveCurrentGroupItems);
147
+ };
148
+ const renderItem = (item, index) => {
149
+ const isRead = Boolean(item.read);
150
+ const timeText = item.time ? tigercatCore.formatActivityTime(item.time) : "";
151
+ return /* @__PURE__ */ jsxRuntime.jsxs(
152
+ "div",
153
+ {
154
+ className: tigercatCore.classNames(
155
+ "flex items-start gap-3 w-full py-0.5 transition-colors",
156
+ !isRead && "border-l-2 border-l-[var(--tiger-primary,#2563eb)] -ml-[2px] pl-[calc(0.75rem-2px)]"
157
+ ),
158
+ children: [
159
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
160
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline justify-between gap-2", children: [
161
+ /* @__PURE__ */ jsxRuntime.jsx(chunkYYGTJKP5_js.Text, { tag: "span", size: "sm", weight: isRead ? "normal" : "semibold", children: item.title }),
162
+ timeText ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-[var(--tiger-text-muted,#6b7280)] whitespace-nowrap flex-shrink-0", children: timeText }) : null
163
+ ] }),
164
+ item.description ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-0.5 text-xs text-[var(--tiger-text-muted,#6b7280)] line-clamp-2 leading-relaxed", children: item.description }) : null
165
+ ] }),
166
+ /* @__PURE__ */ jsxRuntime.jsx(
167
+ chunkA3DJSVTE_js.Button,
168
+ {
169
+ size: "sm",
170
+ variant: "ghost",
171
+ onClick: (event) => {
172
+ event.stopPropagation();
173
+ if (manageReadState) {
174
+ setReadStateOverrides((prev) => {
175
+ const next = new Map(prev);
176
+ next.set(item.id, !isRead);
177
+ return next;
178
+ });
179
+ }
180
+ onItemReadChange?.(item, !isRead);
181
+ },
182
+ children: isRead ? markUnreadText : markReadText
183
+ }
184
+ )
185
+ ]
186
+ }
187
+ );
188
+ };
189
+ const renderList = (listItems) => /* @__PURE__ */ jsxRuntime.jsx(
190
+ chunkOZLGNWET_js.List,
191
+ {
192
+ dataSource: listItems,
193
+ split: true,
194
+ bordered: "divided",
195
+ hoverable: true,
196
+ emptyText,
197
+ onItemClick: (item, index) => onItemClick?.(item, index),
198
+ renderItem
199
+ }
200
+ );
201
+ const filterButtons = [
202
+ { key: "all", label: allLabel },
203
+ { key: "unread", label: unreadLabel },
204
+ { key: "read", label: readLabel }
205
+ ];
206
+ const content = loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx(chunk6MGEGOYJ_js.Loading, { text: loadingText }) }) : resolvedGroups.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "-mx-4 -mb-4", children: /* @__PURE__ */ jsxRuntime.jsx(chunkHDDBBZQH_js.Tabs, { type: "line", size: "small", activeKey: currentGroupKey, onChange: handleGroupChange, children: resolvedGroups.map((group, index) => {
207
+ const effectiveGroup = effectiveGroups.find(
208
+ (eg, ei) => getGroupKey(eg, ei) === getGroupKey(group, index)
209
+ );
210
+ const groupItems = effectiveGroup?.items ?? group.items;
211
+ const unreadCount = groupItems.filter((item) => !item.read).length;
212
+ const labelBase = group.title || String(group.key ?? index);
213
+ const label = unreadCount > 0 ? `${labelBase} (${unreadCount})` : labelBase;
214
+ return /* @__PURE__ */ jsxRuntime.jsx(
215
+ chunkHDDBBZQH_js.TabPane,
216
+ {
217
+ tabKey: getGroupKey(group, index),
218
+ label,
219
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-h-[380px] overflow-y-auto", children: renderList(filterItems(groupItems, currentReadFilter)) })
220
+ },
221
+ String(getGroupKey(group, index))
222
+ );
223
+ }) }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "-mx-4 -mb-4 max-h-[380px] overflow-y-auto", children: renderList(filterItems(effectiveItems, currentReadFilter)) });
224
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrapperClasses, ...props, "data-tiger-notification-center": true, children: /* @__PURE__ */ jsxRuntime.jsx(
225
+ chunkVO4WDK4K_js.Card,
226
+ {
227
+ variant: "bordered",
228
+ className: "w-full",
229
+ header: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
230
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
231
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5", children: [
232
+ /* @__PURE__ */ jsxRuntime.jsx(chunkYYGTJKP5_js.Text, { tag: "div", size: "base", weight: "bold", children: title }),
233
+ totalUnread > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex items-center justify-center min-w-[20px] h-5 px-1.5 text-xs font-semibold rounded-full bg-[var(--tiger-primary,#2563eb)] text-white", children: totalUnread }) : null
234
+ ] }),
235
+ /* @__PURE__ */ jsxRuntime.jsx(chunkA3DJSVTE_js.Button, { size: "sm", variant: "ghost", disabled: !hasUnread, onClick: handleMarkAllRead, children: markAllReadText })
236
+ ] }),
237
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "inline-flex rounded-md border border-[var(--tiger-border,#e5e7eb)] overflow-hidden self-start", children: filterButtons.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
238
+ "button",
239
+ {
240
+ className: tigercatCore.classNames(
241
+ "px-3 py-1 text-xs font-medium transition-colors",
242
+ "border-r border-[var(--tiger-border,#e5e7eb)] last:border-r-0",
243
+ currentReadFilter === option.key ? "bg-[var(--tiger-primary,#2563eb)] text-white" : "bg-[var(--tiger-surface,#ffffff)] text-[var(--tiger-text-muted,#6b7280)] hover:bg-[var(--tiger-surface-muted,#f9fafb)]"
244
+ ),
245
+ onClick: () => handleReadFilterChange(option.key),
246
+ children: option.label
247
+ },
248
+ option.key
249
+ )) })
250
+ ] }),
251
+ children: content
252
+ }
253
+ ) });
254
+ };
255
+ var NotificationCenter_default = NotificationCenter;
256
+
257
+ exports.NotificationCenter = NotificationCenter;
258
+ exports.NotificationCenter_default = NotificationCenter_default;