@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,206 @@
1
+ import { Table } from './chunk-HGTF6A46.mjs';
2
+ import { Pagination } from './chunk-NDOYQK2R.mjs';
3
+ import { DropdownItem } from './chunk-IAF24RKI.mjs';
4
+ import { Dropdown } from './chunk-YGOTPK2W.mjs';
5
+ import { DropdownMenu } from './chunk-SIVJX7VU.mjs';
6
+ import { Input } from './chunk-6ZTCBQJ7.mjs';
7
+ import { Button } from './chunk-STEIWBMF.mjs';
8
+ import { useState, useEffect, useMemo } from 'react';
9
+ import { classNames } from '@expcat/tigercat-core';
10
+ import { jsxs, jsx } from 'react/jsx-runtime';
11
+
12
+ var resolveFilterLabel = (filter, value) => {
13
+ const option = filter.options.find((item) => item.value === value);
14
+ if (option) return `${filter.label}: ${option.label}`;
15
+ if (value !== null && value !== void 0 && value !== "") {
16
+ return `${filter.label}: ${String(value)}`;
17
+ }
18
+ return filter.placeholder ?? filter.label;
19
+ };
20
+ var DataTableWithToolbar = ({
21
+ toolbar,
22
+ onSearchChange,
23
+ onSearch,
24
+ onFiltersChange,
25
+ onBulkAction,
26
+ pagination = false,
27
+ onPageChange,
28
+ onPageSizeChange,
29
+ className,
30
+ tableClassName,
31
+ ...tableProps
32
+ }) => {
33
+ const [internalSearch, setInternalSearch] = useState(toolbar?.defaultSearchValue ?? "");
34
+ const [internalFilters, setInternalFilters] = useState(
35
+ () => {
36
+ const initial = {};
37
+ toolbar?.filters?.forEach((filter) => {
38
+ if (filter.value === void 0) {
39
+ initial[filter.key] = filter.defaultValue ?? null;
40
+ }
41
+ });
42
+ return initial;
43
+ }
44
+ );
45
+ useEffect(() => {
46
+ if (toolbar?.searchValue !== void 0) {
47
+ setInternalSearch(toolbar.searchValue ?? "");
48
+ }
49
+ }, [toolbar?.searchValue]);
50
+ useEffect(() => {
51
+ const filters = toolbar?.filters;
52
+ if (!filters) return;
53
+ setInternalFilters((prev) => {
54
+ const next = { ...prev };
55
+ filters.forEach((filter) => {
56
+ if (filter.value === void 0 && !(filter.key in next)) {
57
+ next[filter.key] = filter.defaultValue ?? null;
58
+ }
59
+ });
60
+ return next;
61
+ });
62
+ }, [toolbar?.filters]);
63
+ const searchValue = toolbar?.searchValue !== void 0 ? toolbar.searchValue : internalSearch;
64
+ const resolvedFilters = useMemo(() => {
65
+ const next = {};
66
+ toolbar?.filters?.forEach((filter) => {
67
+ next[filter.key] = filter.value !== void 0 ? filter.value : internalFilters[filter.key] ?? filter.defaultValue ?? null;
68
+ });
69
+ return next;
70
+ }, [toolbar?.filters, internalFilters]);
71
+ const hasSearch = Boolean(
72
+ toolbar && (toolbar.searchPlaceholder || toolbar.searchValue !== void 0 || toolbar.defaultSearchValue !== void 0 || toolbar.showSearchButton || toolbar.onSearchChange || toolbar.onSearch || onSearchChange || onSearch)
73
+ );
74
+ const hasFilters = Boolean(toolbar?.filters && toolbar.filters.length > 0);
75
+ const hasBulkActions = Boolean(toolbar?.bulkActions && toolbar.bulkActions.length > 0);
76
+ const selectedKeys = toolbar?.selectedKeys ?? tableProps.rowSelection?.selectedRowKeys ?? [];
77
+ const selectedCount = toolbar?.selectedCount ?? selectedKeys.length;
78
+ const bulkLabel = toolbar?.bulkActionsLabel ?? "\u5DF2\u9009\u62E9";
79
+ const wrapperClasses = useMemo(
80
+ () => classNames("tiger-data-table-with-toolbar flex flex-col gap-3", className),
81
+ [className]
82
+ );
83
+ const handleSearchChange = (value) => {
84
+ if (toolbar?.searchValue === void 0) {
85
+ setInternalSearch(value);
86
+ }
87
+ onSearchChange?.(value);
88
+ toolbar?.onSearchChange?.(value);
89
+ };
90
+ const handleSearchSubmit = () => {
91
+ onSearch?.(searchValue ?? "");
92
+ toolbar?.onSearch?.(searchValue ?? "");
93
+ };
94
+ const handleFilterSelect = (filter, value) => {
95
+ const nextFilters = {
96
+ ...resolvedFilters,
97
+ [filter.key]: value
98
+ };
99
+ if (filter.value === void 0) {
100
+ setInternalFilters((prev) => ({
101
+ ...prev,
102
+ [filter.key]: value
103
+ }));
104
+ }
105
+ onFiltersChange?.(nextFilters);
106
+ toolbar?.onFiltersChange?.(nextFilters);
107
+ };
108
+ const handleBulkAction = (action) => {
109
+ const keys = selectedKeys ?? [];
110
+ action.onClick?.(keys);
111
+ onBulkAction?.(action, keys);
112
+ toolbar?.onBulkAction?.(action, keys);
113
+ };
114
+ const renderToolbar = () => {
115
+ if (!hasSearch && !hasFilters && !hasBulkActions) return null;
116
+ return /* @__PURE__ */ jsxs("div", { className: "tiger-data-table-toolbar flex flex-wrap items-center gap-2", children: [
117
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [
118
+ hasSearch ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
119
+ /* @__PURE__ */ jsx(
120
+ Input,
121
+ {
122
+ type: "search",
123
+ size: "sm",
124
+ value: searchValue,
125
+ placeholder: toolbar?.searchPlaceholder ?? "\u641C\u7D22",
126
+ onChange: (event) => handleSearchChange(String(event.currentTarget.value)),
127
+ onKeyDown: (event) => {
128
+ if (event.key === "Enter") {
129
+ handleSearchSubmit();
130
+ }
131
+ }
132
+ }
133
+ ),
134
+ toolbar?.showSearchButton ?? true ? /* @__PURE__ */ jsx(
135
+ Button,
136
+ {
137
+ size: "sm",
138
+ variant: "primary",
139
+ className: "whitespace-nowrap",
140
+ onClick: handleSearchSubmit,
141
+ disabled: !onSearch && !toolbar?.onSearch,
142
+ children: toolbar?.searchButtonText ?? "\u641C\u7D22"
143
+ }
144
+ ) : null
145
+ ] }) : null,
146
+ hasFilters ? toolbar?.filters?.map((filter) => {
147
+ const currentValue = resolvedFilters[filter.key];
148
+ const triggerLabel = resolveFilterLabel(filter, currentValue);
149
+ const clearable = filter.clearable !== false;
150
+ const clearLabel = filter.clearLabel ?? "\u5168\u90E8";
151
+ const isActive = currentValue !== null && currentValue !== void 0 && currentValue !== "";
152
+ return /* @__PURE__ */ jsxs(Dropdown, { trigger: "click", children: [
153
+ /* @__PURE__ */ jsx(
154
+ Button,
155
+ {
156
+ size: "sm",
157
+ variant: isActive ? "secondary" : "outline",
158
+ className: "whitespace-nowrap",
159
+ children: triggerLabel
160
+ }
161
+ ),
162
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
163
+ clearable ? /* @__PURE__ */ jsx(DropdownItem, { onClick: () => handleFilterSelect(filter, null), children: clearLabel }) : null,
164
+ filter.options.map((option) => /* @__PURE__ */ jsx(
165
+ DropdownItem,
166
+ {
167
+ onClick: () => handleFilterSelect(filter, option.value),
168
+ children: option.label
169
+ },
170
+ String(option.value)
171
+ ))
172
+ ] })
173
+ ] }, filter.key);
174
+ }) : null
175
+ ] }),
176
+ hasBulkActions ? /* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center gap-2 flex-wrap", children: [
177
+ selectedCount > 0 ? /* @__PURE__ */ jsxs("span", { className: "text-sm text-[var(--tiger-text-muted,#6b7280)]", children: [
178
+ bulkLabel,
179
+ " ",
180
+ selectedCount,
181
+ " \u9879"
182
+ ] }) : null,
183
+ toolbar?.bulkActions?.map((action) => /* @__PURE__ */ jsx(
184
+ Button,
185
+ {
186
+ size: "sm",
187
+ variant: action.variant ?? "outline",
188
+ disabled: action.disabled || selectedCount === 0,
189
+ onClick: () => handleBulkAction(action),
190
+ children: action.label
191
+ },
192
+ action.key
193
+ ))
194
+ ] }) : null
195
+ ] });
196
+ };
197
+ const showPagination = pagination && typeof pagination === "object";
198
+ return /* @__PURE__ */ jsxs("div", { className: wrapperClasses, "data-tiger-data-table-with-toolbar": true, children: [
199
+ renderToolbar(),
200
+ /* @__PURE__ */ jsx(Table, { ...tableProps, pagination: false, className: tableClassName }),
201
+ showPagination ? /* @__PURE__ */ jsx(Pagination, { ...pagination, onChange: onPageChange, onPageSizeChange }) : null
202
+ ] });
203
+ };
204
+ var DataTableWithToolbar_default = DataTableWithToolbar;
205
+
206
+ export { DataTableWithToolbar, DataTableWithToolbar_default };
@@ -0,0 +1,255 @@
1
+ import { Tabs, TabPane } from './chunk-C52ZCGYG.mjs';
2
+ import { List } from './chunk-BAPR7UUR.mjs';
3
+ import { Button } from './chunk-STEIWBMF.mjs';
4
+ import { Loading } from './chunk-PUDU34R4.mjs';
5
+ import { Text } from './chunk-6YDIBMCM.mjs';
6
+ import { Card } from './chunk-VD3IK5XT.mjs';
7
+ import { useMemo, useState, useEffect } from 'react';
8
+ import { buildNotificationGroups, classNames, formatActivityTime } from '@expcat/tigercat-core';
9
+ import { jsx, jsxs } from 'react/jsx-runtime';
10
+
11
+ var getGroupKey = (group, index) => {
12
+ return group.key ?? group.title ?? index;
13
+ };
14
+ var filterItems = (items, filter) => {
15
+ return items.filter((item) => {
16
+ const isRead = Boolean(item.read);
17
+ if (filter === "read") return isRead;
18
+ if (filter === "unread") return !isRead;
19
+ return true;
20
+ });
21
+ };
22
+ var NotificationCenter = ({
23
+ items = [],
24
+ groups,
25
+ groupBy,
26
+ groupOrder,
27
+ activeGroupKey,
28
+ defaultActiveGroupKey,
29
+ readFilter,
30
+ defaultReadFilter = "all",
31
+ loading = false,
32
+ loadingText = "\u52A0\u8F7D\u4E2D...",
33
+ emptyText = "\u6682\u65E0\u901A\u77E5",
34
+ title = "\u901A\u77E5\u4E2D\u5FC3",
35
+ allLabel = "\u5168\u90E8",
36
+ unreadLabel = "\u672A\u8BFB",
37
+ readLabel = "\u5DF2\u8BFB",
38
+ markAllReadText = "\u5168\u90E8\u6807\u8BB0\u5DF2\u8BFB",
39
+ markReadText = "\u6807\u8BB0\u5DF2\u8BFB",
40
+ markUnreadText = "\u6807\u8BB0\u672A\u8BFB",
41
+ manageReadState = false,
42
+ onGroupChange,
43
+ onReadFilterChange,
44
+ onMarkAllRead,
45
+ onItemClick,
46
+ onItemReadChange,
47
+ className,
48
+ ...props
49
+ }) => {
50
+ const resolvedGroups = useMemo(
51
+ () => buildNotificationGroups(items, groups, groupBy, groupOrder),
52
+ [items, groups, groupBy, groupOrder]
53
+ );
54
+ const firstGroupKey = useMemo(() => {
55
+ return resolvedGroups.length > 0 ? getGroupKey(resolvedGroups[0], 0) : void 0;
56
+ }, [resolvedGroups]);
57
+ const [internalGroupKey, setInternalGroupKey] = useState(
58
+ defaultActiveGroupKey
59
+ );
60
+ const [internalReadFilter, setInternalReadFilter] = useState(defaultReadFilter);
61
+ const currentGroupKey = activeGroupKey ?? internalGroupKey ?? firstGroupKey;
62
+ const currentReadFilter = readFilter ?? internalReadFilter;
63
+ useEffect(() => {
64
+ if (activeGroupKey !== void 0) return;
65
+ if (resolvedGroups.length === 0) {
66
+ setInternalGroupKey(void 0);
67
+ return;
68
+ }
69
+ const keys = resolvedGroups.map((group, index) => getGroupKey(group, index));
70
+ if (!keys.some((key) => key === currentGroupKey)) {
71
+ setInternalGroupKey(keys[0]);
72
+ }
73
+ }, [activeGroupKey, currentGroupKey, resolvedGroups]);
74
+ const currentGroup = useMemo(() => {
75
+ if (resolvedGroups.length === 0) return void 0;
76
+ if (currentGroupKey === void 0) return resolvedGroups[0];
77
+ const index = resolvedGroups.findIndex(
78
+ (group, groupIndex) => getGroupKey(group, groupIndex) === currentGroupKey
79
+ );
80
+ return index >= 0 ? resolvedGroups[index] : resolvedGroups[0];
81
+ }, [currentGroupKey, resolvedGroups]);
82
+ currentGroup?.items ?? [];
83
+ const [readStateOverrides, setReadStateOverrides] = useState(
84
+ () => /* @__PURE__ */ new Map()
85
+ );
86
+ useEffect(() => {
87
+ if (manageReadState) setReadStateOverrides(/* @__PURE__ */ new Map());
88
+ }, [items, manageReadState]);
89
+ const applyReadOverrides = (list) => {
90
+ if (!manageReadState || readStateOverrides.size === 0) return list;
91
+ return list.map((item) => {
92
+ const override = readStateOverrides.get(item.id);
93
+ return override !== void 0 ? { ...item, read: override } : item;
94
+ });
95
+ };
96
+ const effectiveGroups = useMemo(
97
+ () => resolvedGroups.map((group) => ({
98
+ ...group,
99
+ items: applyReadOverrides(group.items)
100
+ })),
101
+ // eslint-disable-next-line react-hooks/exhaustive-deps
102
+ [resolvedGroups, readStateOverrides]
103
+ );
104
+ const effectiveCurrentGroup = useMemo(() => {
105
+ if (effectiveGroups.length === 0) return void 0;
106
+ if (currentGroupKey === void 0) return effectiveGroups[0];
107
+ const index = effectiveGroups.findIndex(
108
+ (group, groupIndex) => getGroupKey(group, groupIndex) === currentGroupKey
109
+ );
110
+ return index >= 0 ? effectiveGroups[index] : effectiveGroups[0];
111
+ }, [currentGroupKey, effectiveGroups]);
112
+ const effectiveCurrentGroupItems = effectiveCurrentGroup?.items ?? [];
113
+ const effectiveItems = useMemo(() => applyReadOverrides(items), [items, readStateOverrides]);
114
+ const hasUnread = effectiveCurrentGroupItems.some((item) => !item.read);
115
+ const totalUnread = useMemo(() => {
116
+ const allItems = effectiveGroups.flatMap((group) => group.items);
117
+ if (allItems.length === 0) return effectiveItems.filter((item) => !item.read).length;
118
+ return allItems.filter((item) => !item.read).length;
119
+ }, [effectiveGroups, effectiveItems]);
120
+ const wrapperClasses = useMemo(
121
+ () => classNames("tiger-notification-center", "w-full", "flex", "flex-col", className),
122
+ [className]
123
+ );
124
+ const handleGroupChange = (key) => {
125
+ if (activeGroupKey === void 0) {
126
+ setInternalGroupKey(key);
127
+ }
128
+ onGroupChange?.(key);
129
+ };
130
+ const handleReadFilterChange = (next) => {
131
+ if (readFilter === void 0) {
132
+ setInternalReadFilter(next);
133
+ }
134
+ onReadFilterChange?.(next);
135
+ };
136
+ const handleMarkAllRead = () => {
137
+ if (manageReadState) {
138
+ setReadStateOverrides((prev) => {
139
+ const next = new Map(prev);
140
+ effectiveCurrentGroupItems.forEach((item) => next.set(item.id, true));
141
+ return next;
142
+ });
143
+ }
144
+ onMarkAllRead?.(currentGroupKey, effectiveCurrentGroupItems);
145
+ };
146
+ const renderItem = (item, index) => {
147
+ const isRead = Boolean(item.read);
148
+ const timeText = item.time ? formatActivityTime(item.time) : "";
149
+ return /* @__PURE__ */ jsxs(
150
+ "div",
151
+ {
152
+ className: classNames(
153
+ "flex items-start gap-3 w-full py-0.5 transition-colors",
154
+ !isRead && "border-l-2 border-l-[var(--tiger-primary,#2563eb)] -ml-[2px] pl-[calc(0.75rem-2px)]"
155
+ ),
156
+ children: [
157
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
158
+ /* @__PURE__ */ jsxs("div", { className: "flex items-baseline justify-between gap-2", children: [
159
+ /* @__PURE__ */ jsx(Text, { tag: "span", size: "sm", weight: isRead ? "normal" : "semibold", children: item.title }),
160
+ timeText ? /* @__PURE__ */ jsx("span", { className: "text-xs text-[var(--tiger-text-muted,#6b7280)] whitespace-nowrap flex-shrink-0", children: timeText }) : null
161
+ ] }),
162
+ item.description ? /* @__PURE__ */ jsx("div", { className: "mt-0.5 text-xs text-[var(--tiger-text-muted,#6b7280)] line-clamp-2 leading-relaxed", children: item.description }) : null
163
+ ] }),
164
+ /* @__PURE__ */ jsx(
165
+ Button,
166
+ {
167
+ size: "sm",
168
+ variant: "ghost",
169
+ onClick: (event) => {
170
+ event.stopPropagation();
171
+ if (manageReadState) {
172
+ setReadStateOverrides((prev) => {
173
+ const next = new Map(prev);
174
+ next.set(item.id, !isRead);
175
+ return next;
176
+ });
177
+ }
178
+ onItemReadChange?.(item, !isRead);
179
+ },
180
+ children: isRead ? markUnreadText : markReadText
181
+ }
182
+ )
183
+ ]
184
+ }
185
+ );
186
+ };
187
+ const renderList = (listItems) => /* @__PURE__ */ jsx(
188
+ List,
189
+ {
190
+ dataSource: listItems,
191
+ split: true,
192
+ bordered: "divided",
193
+ hoverable: true,
194
+ emptyText,
195
+ onItemClick: (item, index) => onItemClick?.(item, index),
196
+ renderItem
197
+ }
198
+ );
199
+ const filterButtons = [
200
+ { key: "all", label: allLabel },
201
+ { key: "unread", label: unreadLabel },
202
+ { key: "read", label: readLabel }
203
+ ];
204
+ const content = loading ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsx(Loading, { text: loadingText }) }) : resolvedGroups.length > 0 ? /* @__PURE__ */ jsx("div", { className: "-mx-4 -mb-4", children: /* @__PURE__ */ jsx(Tabs, { type: "line", size: "small", activeKey: currentGroupKey, onChange: handleGroupChange, children: resolvedGroups.map((group, index) => {
205
+ const effectiveGroup = effectiveGroups.find(
206
+ (eg, ei) => getGroupKey(eg, ei) === getGroupKey(group, index)
207
+ );
208
+ const groupItems = effectiveGroup?.items ?? group.items;
209
+ const unreadCount = groupItems.filter((item) => !item.read).length;
210
+ const labelBase = group.title || String(group.key ?? index);
211
+ const label = unreadCount > 0 ? `${labelBase} (${unreadCount})` : labelBase;
212
+ return /* @__PURE__ */ jsx(
213
+ TabPane,
214
+ {
215
+ tabKey: getGroupKey(group, index),
216
+ label,
217
+ children: /* @__PURE__ */ jsx("div", { className: "max-h-[380px] overflow-y-auto", children: renderList(filterItems(groupItems, currentReadFilter)) })
218
+ },
219
+ String(getGroupKey(group, index))
220
+ );
221
+ }) }) }) : /* @__PURE__ */ jsx("div", { className: "-mx-4 -mb-4 max-h-[380px] overflow-y-auto", children: renderList(filterItems(effectiveItems, currentReadFilter)) });
222
+ return /* @__PURE__ */ jsx("div", { className: wrapperClasses, ...props, "data-tiger-notification-center": true, children: /* @__PURE__ */ jsx(
223
+ Card,
224
+ {
225
+ variant: "bordered",
226
+ className: "w-full",
227
+ header: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
228
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
229
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5", children: [
230
+ /* @__PURE__ */ jsx(Text, { tag: "div", size: "base", weight: "bold", children: title }),
231
+ totalUnread > 0 ? /* @__PURE__ */ 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
232
+ ] }),
233
+ /* @__PURE__ */ jsx(Button, { size: "sm", variant: "ghost", disabled: !hasUnread, onClick: handleMarkAllRead, children: markAllReadText })
234
+ ] }),
235
+ /* @__PURE__ */ jsx("div", { className: "inline-flex rounded-md border border-[var(--tiger-border,#e5e7eb)] overflow-hidden self-start", children: filterButtons.map((option) => /* @__PURE__ */ jsx(
236
+ "button",
237
+ {
238
+ className: classNames(
239
+ "px-3 py-1 text-xs font-medium transition-colors",
240
+ "border-r border-[var(--tiger-border,#e5e7eb)] last:border-r-0",
241
+ 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)]"
242
+ ),
243
+ onClick: () => handleReadFilterChange(option.key),
244
+ children: option.label
245
+ },
246
+ option.key
247
+ )) })
248
+ ] }),
249
+ children: content
250
+ }
251
+ ) });
252
+ };
253
+ var NotificationCenter_default = NotificationCenter;
254
+
255
+ export { NotificationCenter, NotificationCenter_default };
@@ -89,6 +89,7 @@ function Table({
89
89
  rowClassName,
90
90
  stickyHeader = false,
91
91
  maxHeight,
92
+ tableLayout = "auto",
92
93
  onChange,
93
94
  onRowClick,
94
95
  onSelectionChange,
@@ -657,7 +658,10 @@ function Table({
657
658
  /* @__PURE__ */ jsxRuntime.jsxs(
658
659
  "table",
659
660
  {
660
- className: tigercatCore.tableBaseClasses,
661
+ className: tigercatCore.classNames(
662
+ tigercatCore.tableBaseClasses,
663
+ tableLayout === "fixed" ? "table-fixed" : "table-auto"
664
+ ),
661
665
  ...props,
662
666
  style: fixedColumnsInfo.hasFixedColumns && fixedColumnsInfo.minTableWidth ? {
663
667
  ...props.style,
@@ -98,6 +98,18 @@ var Pagination = ({
98
98
  },
99
99
  [handleQuickJumperSubmit]
100
100
  );
101
+ const normalizedPageSizeOptions = react.useMemo(() => {
102
+ return pageSizeOptions.map((option) => {
103
+ if (typeof option === "number") {
104
+ return {
105
+ value: option,
106
+ label: `${option} ${labels.itemsPerPageText}`
107
+ };
108
+ }
109
+ const label = option.label ?? `${option.value} ${labels.itemsPerPageText}`;
110
+ return { value: option.value, label };
111
+ });
112
+ }, [pageSizeOptions, labels.itemsPerPageText]);
101
113
  const containerClasses = tigercatCore.getPaginationContainerClasses(align, className);
102
114
  const elements = [];
103
115
  if (showTotal) {
@@ -233,11 +245,7 @@ var Pagination = ({
233
245
  value: currentPageSize,
234
246
  onChange: (e) => handlePageSizeChange(parseInt(e.target.value, 10)),
235
247
  "aria-label": labels.itemsPerPageText,
236
- children: pageSizeOptions.map((sizeOption) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: sizeOption, children: [
237
- sizeOption,
238
- " ",
239
- labels.itemsPerPageText
240
- ] }, sizeOption))
248
+ children: normalizedPageSizeOptions.map((sizeOption) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: sizeOption.value, children: sizeOption.label }, sizeOption.value))
241
249
  },
242
250
  "size-changer"
243
251
  )
@@ -0,0 +1,107 @@
1
+ 'use strict';
2
+
3
+ var chunkQ2GPRAF4_js = require('./chunk-Q2GPRAF4.js');
4
+ var react = require('react');
5
+ var tigercatCore = require('@expcat/tigercat-core');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+
8
+ var CollapsePanel = ({
9
+ panelKey,
10
+ header,
11
+ disabled = false,
12
+ showArrow = true,
13
+ className,
14
+ style,
15
+ extra,
16
+ children
17
+ }) => {
18
+ const collapseContext = chunkQ2GPRAF4_js.useCollapseContext();
19
+ if (!collapseContext) {
20
+ throw new Error("CollapsePanel must be used within a Collapse component");
21
+ }
22
+ const isActive = react.useMemo(() => {
23
+ return tigercatCore.isPanelActive(panelKey, collapseContext.activeKeys);
24
+ }, [panelKey, collapseContext.activeKeys]);
25
+ const panelClasses = react.useMemo(() => {
26
+ return tigercatCore.classNames(tigercatCore.getCollapsePanelClasses(collapseContext.ghost, className));
27
+ }, [collapseContext.ghost, className]);
28
+ const headerClasses = react.useMemo(() => {
29
+ return tigercatCore.getCollapsePanelHeaderClasses(isActive, disabled);
30
+ }, [isActive, disabled]);
31
+ const iconClasses = react.useMemo(() => {
32
+ return tigercatCore.getCollapseIconClasses(isActive, collapseContext.expandIconPosition);
33
+ }, [isActive, collapseContext.expandIconPosition]);
34
+ const handleClick = react.useCallback(() => {
35
+ if (!disabled) {
36
+ collapseContext.handlePanelClick(panelKey);
37
+ }
38
+ }, [disabled, collapseContext, panelKey]);
39
+ const handleKeyDown = react.useCallback(
40
+ (event) => {
41
+ if (disabled) {
42
+ return;
43
+ }
44
+ if (event.key === "Enter" || event.key === " ") {
45
+ event.preventDefault();
46
+ collapseContext.handlePanelClick(panelKey);
47
+ }
48
+ },
49
+ [disabled, collapseContext, panelKey]
50
+ );
51
+ const arrowIcon = /* @__PURE__ */ jsxRuntime.jsx(
52
+ "svg",
53
+ {
54
+ className: iconClasses,
55
+ width: "16",
56
+ height: "16",
57
+ viewBox: "0 0 16 16",
58
+ fill: "none",
59
+ xmlns: "http://www.w3.org/2000/svg",
60
+ children: /* @__PURE__ */ jsxRuntime.jsx(
61
+ "path",
62
+ {
63
+ d: "M6 12L10 8L6 4",
64
+ stroke: "currentColor",
65
+ strokeWidth: "2",
66
+ strokeLinecap: "round",
67
+ strokeLinejoin: "round"
68
+ }
69
+ )
70
+ }
71
+ );
72
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: panelClasses, style, children: [
73
+ /* @__PURE__ */ jsxRuntime.jsxs(
74
+ "div",
75
+ {
76
+ className: headerClasses,
77
+ role: "button",
78
+ tabIndex: disabled ? -1 : 0,
79
+ "aria-expanded": isActive,
80
+ "aria-disabled": disabled,
81
+ onClick: handleClick,
82
+ onKeyDown: handleKeyDown,
83
+ children: [
84
+ showArrow && collapseContext.expandIconPosition === "start" && arrowIcon,
85
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: tigercatCore.collapseHeaderTextClasses, children: header }),
86
+ extra && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto", children: extra }),
87
+ showArrow && collapseContext.expandIconPosition === "end" && arrowIcon
88
+ ]
89
+ }
90
+ ),
91
+ /* @__PURE__ */ jsxRuntime.jsx(
92
+ "div",
93
+ {
94
+ className: tigercatCore.collapsePanelContentWrapperClasses,
95
+ style: {
96
+ maxHeight: isActive ? "none" : "0",
97
+ opacity: isActive ? "1" : "0"
98
+ },
99
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: tigercatCore.collapsePanelContentBaseClasses, children })
100
+ }
101
+ )
102
+ ] });
103
+ };
104
+ var CollapsePanel_default = CollapsePanel;
105
+
106
+ exports.CollapsePanel = CollapsePanel;
107
+ exports.CollapsePanel_default = CollapsePanel_default;
@@ -1,6 +1,6 @@
1
1
  import React, { createContext, useContext } from 'react';
2
2
  import { classNames, breadcrumbContainerClasses } from '@expcat/tigercat-core';
3
- import { jsx } from 'react/jsx-runtime';
3
+ import { jsx, jsxs } from 'react/jsx-runtime';
4
4
 
5
5
  // src/components/Breadcrumb.tsx
6
6
  var BreadcrumbContext = createContext(null);
@@ -11,15 +11,20 @@ var Breadcrumb = ({
11
11
  separator = "/",
12
12
  className,
13
13
  style,
14
+ extra,
14
15
  children,
15
16
  ...props
16
17
  }) => {
18
+ const hasExtra = Boolean(extra);
17
19
  const containerClasses = React.useMemo(
18
- () => classNames(breadcrumbContainerClasses, className),
19
- [className]
20
+ () => classNames(breadcrumbContainerClasses, hasExtra && "w-full", className),
21
+ [className, hasExtra]
20
22
  );
21
23
  const contextValue = React.useMemo(() => ({ separator }), [separator]);
22
- return /* @__PURE__ */ jsx(BreadcrumbContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx("nav", { className: containerClasses, "aria-label": "Breadcrumb", style, ...props, children: /* @__PURE__ */ jsx("ol", { className: "flex items-center flex-wrap gap-2", children }) }) });
24
+ return /* @__PURE__ */ jsx(BreadcrumbContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs("nav", { className: containerClasses, "aria-label": "Breadcrumb", style, ...props, children: [
25
+ /* @__PURE__ */ jsx("ol", { className: "flex items-center flex-wrap gap-2", children }),
26
+ hasExtra && /* @__PURE__ */ jsx("div", { className: "ml-auto flex items-center", children: extra })
27
+ ] }) });
23
28
  };
24
29
 
25
30
  export { Breadcrumb, useBreadcrumbContext };
@@ -87,6 +87,7 @@ function Table({
87
87
  rowClassName,
88
88
  stickyHeader = false,
89
89
  maxHeight,
90
+ tableLayout = "auto",
90
91
  onChange,
91
92
  onRowClick,
92
93
  onSelectionChange,
@@ -655,7 +656,10 @@ function Table({
655
656
  /* @__PURE__ */ jsxs(
656
657
  "table",
657
658
  {
658
- className: tableBaseClasses,
659
+ className: classNames(
660
+ tableBaseClasses,
661
+ tableLayout === "fixed" ? "table-fixed" : "table-auto"
662
+ ),
659
663
  ...props,
660
664
  style: fixedColumnsInfo.hasFixedColumns && fixedColumnsInfo.minTableWidth ? {
661
665
  ...props.style,