@taskon/widget-react 0.0.1-beta.2 → 0.0.1-beta.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 (44) hide show
  1. package/README.md +56 -17
  2. package/dist/CommunityTaskList.css +1593 -1741
  3. package/dist/EligibilityInfo.css +1275 -582
  4. package/dist/LeaderboardWidget.css +355 -152
  5. package/dist/PageBuilder.css +0 -2
  6. package/dist/Quest.css +1140 -903
  7. package/dist/TaskOnProvider.css +50 -31
  8. package/dist/UserCenterWidget.css +108 -237
  9. package/dist/UserCenterWidget2.css +2016 -711
  10. package/dist/chunks/{CommunityTaskList-BlH1Wdd5.js → CommunityTaskList-C9Gv8KOF.js} +962 -827
  11. package/dist/chunks/{EligibilityInfo-C7GZ2G5u.js → EligibilityInfo-D-Fuy9GE.js} +1137 -449
  12. package/dist/chunks/{LeaderboardWidget-CmYfDeHV.js → LeaderboardWidget-BV2D2q1N.js} +15 -10
  13. package/dist/chunks/{PageBuilder-Bw0zSkFh.js → PageBuilder-DQoU4Mwf.js} +5 -5
  14. package/dist/chunks/{Quest-DKFZ-pPU.js → Quest-B5NyVr3o.js} +516 -325
  15. package/dist/chunks/{TaskOnProvider-BD6Vp2x8.js → TaskOnProvider-93UxARFo.js} +2 -207
  16. package/dist/chunks/{ThemeProvider-wnSXrNQb.js → ThemeProvider-CPI_roeh.js} +249 -57
  17. package/dist/chunks/{UserCenterWidget-Cw6h_5hT.js → UserCenterWidget-BRtigY_S.js} +206 -1002
  18. package/dist/chunks/UserCenterWidget-cADBSVg7.js +8358 -0
  19. package/dist/chunks/{WidgetShell-D_5OjvNZ.js → dynamic-import-helper-DwXlQC0S.js} +607 -40
  20. package/dist/chunks/useToast-CaRkylKe.js +304 -0
  21. package/dist/chunks/{usercenter-ja-uu-XfVF9.js → usercenter-ja-B2465c1O.js} +4 -10
  22. package/dist/chunks/{usercenter-ko-DYgUOVzd.js → usercenter-ko-xAEYxqLg.js} +4 -10
  23. package/dist/community-task.d.ts +34 -3
  24. package/dist/community-task.js +1 -1
  25. package/dist/core.d.ts +40 -3
  26. package/dist/core.js +9 -10
  27. package/dist/dynamic-import-helper.css +596 -289
  28. package/dist/index.d.ts +207 -10
  29. package/dist/index.js +21 -19
  30. package/dist/leaderboard.d.ts +8 -1
  31. package/dist/leaderboard.js +2 -2
  32. package/dist/page-builder.js +1 -1
  33. package/dist/quest.d.ts +8 -2
  34. package/dist/quest.js +1 -1
  35. package/dist/user-center.d.ts +20 -136
  36. package/dist/user-center.js +19 -236
  37. package/package.json +10 -2
  38. package/dist/TipPopover.css +0 -210
  39. package/dist/WidgetShell.css +0 -182
  40. package/dist/chunks/TipPopover-BrW8jo71.js +0 -2926
  41. package/dist/chunks/UserCenterWidget-BE329iS7.js +0 -3546
  42. package/dist/chunks/dynamic-import-helper-DxEFwm31.js +0 -537
  43. package/dist/chunks/useToast-B-wyO5zL.js +0 -93
  44. package/dist/chunks/useWidgetLocale-JDelxtt8.js +0 -74
@@ -1,9 +1,296 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
- import { useState, useEffect, useMemo } from "react";
4
- import { e as useLayoutEffect2, h as useCallbackRef$1, g as useComposedRefs, P as Primitive, i as useControllableState, f as createContextScope, k as Presence, l as Portal$1, j as composeEventHandlers, m as createSlot, D as DismissableLayer, o as createContext2, b as useTaskOnContext, T as ThemeProvider } from "./ThemeProvider-wnSXrNQb.js";
3
+ import { forwardRef, useState, useMemo, useCallback, useEffect } from "react";
4
+ import { q as composeRefs, o as useLayoutEffect2, l as useCallbackRef$1, f as useComposedRefs, P as Primitive, h as useControllableState, e as createContextScope, j as Presence, m as Portal$1, k as composeEventHandlers, g as createSlot$1, D as DismissableLayer, r as createContext2, s as useTaskOnPortalContainer, d as useTaskOnContext, T as ThemeProvider } from "./ThemeProvider-CPI_roeh.js";
5
5
  import { createWidgetApi, parseWidgetConfig } from "@taskon/core";
6
- import '../WidgetShell.css';var useReactId = React[" useId ".trim().toString()] || (() => void 0);
6
+ import '../dynamic-import-helper.css';function cloudThemeToReactTheme(cloud) {
7
+ const isDual = cloud.colorMode.type === "dual";
8
+ const modeStrategy = isDual ? cloud.colorMode.dualVariant : "auto";
9
+ let mode;
10
+ if (cloud.colorMode.type === "dual") {
11
+ mode = cloud.colorMode.dualVariant === "auto" ? "auto" : "light";
12
+ } else {
13
+ mode = cloud.colorMode.type;
14
+ }
15
+ const mapColorToSeed = (color) => ({
16
+ colorPrimary: color.primaryColor,
17
+ colorSecondary: color.secondaryColor,
18
+ colorSuccess: color.successColor,
19
+ colorWarning: color.warningColor,
20
+ colorError: color.errorColor,
21
+ colorLink: color.linkColor,
22
+ colorTextOnPrimary: color.textInPrimaryButton,
23
+ colorText: color.textColor,
24
+ colorBgBase: color.backgroundColor
25
+ });
26
+ const mapSpacingToSeed = () => {
27
+ const base = Math.max(1, Number(cloud.spacing.sizeBaseStep) || 1);
28
+ const unit = Math.max(1, Number(cloud.spacing.sizeChangeUnit) || 1);
29
+ return {
30
+ spacingBaseStep: base,
31
+ spacingChangeUnit: unit
32
+ };
33
+ };
34
+ return {
35
+ mode,
36
+ modeStrategy,
37
+ // Global seed (shape and spacing values applied regardless of mode)
38
+ seed: {
39
+ borderRadius: cloud.shape.borderRadius,
40
+ fontSize: cloud.shape.fontSize,
41
+ ...mapSpacingToSeed()
42
+ },
43
+ // Per-mode color overrides
44
+ light: {
45
+ seed: mapColorToSeed(cloud.light)
46
+ },
47
+ dark: {
48
+ seed: mapColorToSeed(cloud.dark)
49
+ }
50
+ };
51
+ }
52
+ var REACT_LAZY_TYPE = Symbol.for("react.lazy");
53
+ var use = React[" use ".trim().toString()];
54
+ function isPromiseLike(value) {
55
+ return typeof value === "object" && value !== null && "then" in value;
56
+ }
57
+ function isLazyComponent(element) {
58
+ return element != null && typeof element === "object" && "$$typeof" in element && element.$$typeof === REACT_LAZY_TYPE && "_payload" in element && isPromiseLike(element._payload);
59
+ }
60
+ // @__NO_SIDE_EFFECTS__
61
+ function createSlot(ownerName) {
62
+ const SlotClone = /* @__PURE__ */ createSlotClone(ownerName);
63
+ const Slot2 = React.forwardRef((props, forwardedRef) => {
64
+ let { children, ...slotProps } = props;
65
+ if (isLazyComponent(children) && typeof use === "function") {
66
+ children = use(children._payload);
67
+ }
68
+ const childrenArray = React.Children.toArray(children);
69
+ const slottable = childrenArray.find(isSlottable);
70
+ if (slottable) {
71
+ const newElement = slottable.props.children;
72
+ const newChildren = childrenArray.map((child) => {
73
+ if (child === slottable) {
74
+ if (React.Children.count(newElement) > 1) return React.Children.only(null);
75
+ return React.isValidElement(newElement) ? newElement.props.children : null;
76
+ } else {
77
+ return child;
78
+ }
79
+ });
80
+ return /* @__PURE__ */ jsx(SlotClone, { ...slotProps, ref: forwardedRef, children: React.isValidElement(newElement) ? React.cloneElement(newElement, void 0, newChildren) : null });
81
+ }
82
+ return /* @__PURE__ */ jsx(SlotClone, { ...slotProps, ref: forwardedRef, children });
83
+ });
84
+ Slot2.displayName = `${ownerName}.Slot`;
85
+ return Slot2;
86
+ }
87
+ var Slot$1 = /* @__PURE__ */ createSlot("Slot");
88
+ // @__NO_SIDE_EFFECTS__
89
+ function createSlotClone(ownerName) {
90
+ const SlotClone = React.forwardRef((props, forwardedRef) => {
91
+ let { children, ...slotProps } = props;
92
+ if (isLazyComponent(children) && typeof use === "function") {
93
+ children = use(children._payload);
94
+ }
95
+ if (React.isValidElement(children)) {
96
+ const childrenRef = getElementRef(children);
97
+ const props2 = mergeProps(slotProps, children.props);
98
+ if (children.type !== React.Fragment) {
99
+ props2.ref = forwardedRef ? composeRefs(forwardedRef, childrenRef) : childrenRef;
100
+ }
101
+ return React.cloneElement(children, props2);
102
+ }
103
+ return React.Children.count(children) > 1 ? React.Children.only(null) : null;
104
+ });
105
+ SlotClone.displayName = `${ownerName}.SlotClone`;
106
+ return SlotClone;
107
+ }
108
+ var SLOTTABLE_IDENTIFIER = Symbol("radix.slottable");
109
+ function isSlottable(child) {
110
+ return React.isValidElement(child) && typeof child.type === "function" && "__radixId" in child.type && child.type.__radixId === SLOTTABLE_IDENTIFIER;
111
+ }
112
+ function mergeProps(slotProps, childProps) {
113
+ const overrideProps = { ...childProps };
114
+ for (const propName in childProps) {
115
+ const slotPropValue = slotProps[propName];
116
+ const childPropValue = childProps[propName];
117
+ const isHandler = /^on[A-Z]/.test(propName);
118
+ if (isHandler) {
119
+ if (slotPropValue && childPropValue) {
120
+ overrideProps[propName] = (...args) => {
121
+ const result = childPropValue(...args);
122
+ slotPropValue(...args);
123
+ return result;
124
+ };
125
+ } else if (slotPropValue) {
126
+ overrideProps[propName] = slotPropValue;
127
+ }
128
+ } else if (propName === "style") {
129
+ overrideProps[propName] = { ...slotPropValue, ...childPropValue };
130
+ } else if (propName === "className") {
131
+ overrideProps[propName] = [slotPropValue, childPropValue].filter(Boolean).join(" ");
132
+ }
133
+ }
134
+ return { ...slotProps, ...overrideProps };
135
+ }
136
+ function getElementRef(element) {
137
+ var _a, _b;
138
+ let getter = (_a = Object.getOwnPropertyDescriptor(element.props, "ref")) == null ? void 0 : _a.get;
139
+ let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
140
+ if (mayWarn) {
141
+ return element.ref;
142
+ }
143
+ getter = (_b = Object.getOwnPropertyDescriptor(element, "ref")) == null ? void 0 : _b.get;
144
+ mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
145
+ if (mayWarn) {
146
+ return element.props.ref;
147
+ }
148
+ return element.props.ref || element.ref;
149
+ }
150
+ const Button = forwardRef(
151
+ ({
152
+ size = "medium",
153
+ variant = "primary",
154
+ loading = false,
155
+ iconPosition,
156
+ leftIcon,
157
+ rightIcon,
158
+ asChild = false,
159
+ disabled,
160
+ className = "",
161
+ style,
162
+ children,
163
+ ...props
164
+ }, ref) => {
165
+ const Comp = asChild ? Slot$1 : "button";
166
+ const actualIconPosition = iconPosition || (leftIcon ? "left" : rightIcon ? "right" : void 0);
167
+ const isIconOnly = actualIconPosition === "only" || !children && (leftIcon || rightIcon);
168
+ const baseStyles = {
169
+ display: "inline-flex",
170
+ alignItems: "center",
171
+ justifyContent: "center",
172
+ gap: "var(--taskon-spacing-xs)",
173
+ fontFamily: "inherit",
174
+ fontWeight: 500,
175
+ lineHeight: 1.5,
176
+ border: "none",
177
+ outline: "none",
178
+ cursor: disabled || loading ? "not-allowed" : "pointer",
179
+ transition: "all 0.2s ease-in-out",
180
+ position: "relative",
181
+ userSelect: "none",
182
+ whiteSpace: "nowrap",
183
+ opacity: disabled ? 0.5 : 1,
184
+ ...style
185
+ };
186
+ const sizeStyles = {
187
+ small: {
188
+ fontSize: "var(--taskon-font-size-sm)",
189
+ padding: isIconOnly ? "var(--taskon-spacing-xs)" : "var(--taskon-spacing-xs) var(--taskon-spacing-sm)",
190
+ borderRadius: "var(--taskon-border-radius-sm)",
191
+ minWidth: isIconOnly ? "24px" : "64px",
192
+ height: "24px"
193
+ },
194
+ medium: {
195
+ fontSize: "var(--taskon-font-size)",
196
+ padding: isIconOnly ? "var(--taskon-spacing-xs)" : "var(--taskon-spacing-xs) var(--taskon-spacing-md)",
197
+ borderRadius: "var(--taskon-border-radius)",
198
+ minWidth: isIconOnly ? "32px" : "80px",
199
+ height: "32px"
200
+ },
201
+ large: {
202
+ fontSize: "var(--taskon-font-size-lg)",
203
+ padding: isIconOnly ? "var(--taskon-spacing-sm)" : "var(--taskon-spacing-sm) var(--taskon-spacing-lg)",
204
+ borderRadius: "var(--taskon-border-radius)",
205
+ minWidth: isIconOnly ? "40px" : "96px",
206
+ height: "40px"
207
+ }
208
+ };
209
+ const variantStyles = {
210
+ primary: {
211
+ backgroundColor: "var(--taskon-color-primary)",
212
+ color: "var(--taskon-color-text-on-primary)"
213
+ },
214
+ secondary: {
215
+ backgroundColor: "var(--taskon-color-secondary)",
216
+ color: "var(--taskon-color-text-on-primary)"
217
+ },
218
+ outline: {
219
+ backgroundColor: "transparent",
220
+ color: "var(--taskon-color-text)",
221
+ border: "1px solid var(--taskon-color-border)"
222
+ },
223
+ ghost: {
224
+ backgroundColor: "transparent",
225
+ color: "var(--taskon-color-text)"
226
+ },
227
+ danger: {
228
+ backgroundColor: "var(--taskon-color-error)",
229
+ color: "var(--taskon-color-text-on-primary)"
230
+ }
231
+ };
232
+ const hoverStyles = {
233
+ primary: "hover:bg-[var(--taskon-color-primary-hover)] active:bg-[var(--taskon-color-primary-active)]",
234
+ secondary: "hover:opacity-90 active:opacity-80",
235
+ outline: "hover:bg-[var(--taskon-color-bg-surface-strong)] active:bg-[var(--taskon-color-bg-surface-strong)]",
236
+ ghost: "hover:bg-[var(--taskon-color-bg-surface-strong)] active:bg-[var(--taskon-color-bg-surface-strong)]",
237
+ danger: "hover:opacity-90 active:opacity-80"
238
+ };
239
+ const mergedStyle = {
240
+ ...baseStyles,
241
+ ...sizeStyles[size],
242
+ ...variantStyles[variant]
243
+ };
244
+ const mergedClassName = `${className} ${hoverStyles[variant]}`.trim();
245
+ const renderLoadingIndicator = () => {
246
+ if (!loading) return null;
247
+ return /* @__PURE__ */ jsx(
248
+ "span",
249
+ {
250
+ style: {
251
+ display: "inline-block",
252
+ width: "1em",
253
+ height: "1em",
254
+ border: "2px solid currentColor",
255
+ borderTopColor: "transparent",
256
+ borderRadius: "50%",
257
+ animation: "taskon-button-spin 0.6s linear infinite"
258
+ }
259
+ }
260
+ );
261
+ };
262
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
263
+ /* @__PURE__ */ jsx("style", { children: `
264
+ @keyframes taskon-button-spin {
265
+ from {
266
+ transform: rotate(0deg);
267
+ }
268
+ to {
269
+ transform: rotate(360deg);
270
+ }
271
+ }
272
+ ` }),
273
+ /* @__PURE__ */ jsxs(
274
+ Comp,
275
+ {
276
+ ref,
277
+ disabled: disabled || loading,
278
+ className: mergedClassName,
279
+ style: mergedStyle,
280
+ ...props,
281
+ children: [
282
+ loading && renderLoadingIndicator(),
283
+ !loading && leftIcon && actualIconPosition === "left" && /* @__PURE__ */ jsx("span", { style: { display: "inline-flex" }, children: leftIcon }),
284
+ !isIconOnly && children,
285
+ !loading && rightIcon && actualIconPosition === "right" && /* @__PURE__ */ jsx("span", { style: { display: "inline-flex" }, children: rightIcon })
286
+ ]
287
+ }
288
+ )
289
+ ] });
290
+ }
291
+ );
292
+ Button.displayName = "Button";
293
+ var useReactId = React[" useId ".trim().toString()] || (() => void 0);
7
294
  var count$1 = 0;
8
295
  function useId(deterministicId) {
9
296
  const [id, setId] = React.useState(useReactId());
@@ -1096,7 +1383,7 @@ var DialogOverlay = React.forwardRef(
1096
1383
  }
1097
1384
  );
1098
1385
  DialogOverlay.displayName = OVERLAY_NAME;
1099
- var Slot = createSlot("DialogOverlay.RemoveScroll");
1386
+ var Slot = createSlot$1("DialogOverlay.RemoveScroll");
1100
1387
  var DialogOverlayImpl = React.forwardRef(
1101
1388
  (props, forwardedRef) => {
1102
1389
  const { __scopeDialog, ...overlayProps } = props;
@@ -1356,8 +1643,10 @@ function Dialog({
1356
1643
  contentClassName,
1357
1644
  overlayClassName,
1358
1645
  rightSlot,
1359
- maxWidth
1646
+ maxWidth,
1647
+ bodyPadding = true
1360
1648
  }) {
1649
+ const portalContainer = useTaskOnPortalContainer();
1361
1650
  const contentStyle = maxWidth ? { maxWidth: typeof maxWidth === "number" ? `${maxWidth}px` : maxWidth } : {};
1362
1651
  const handleInteractOutside = (event) => {
1363
1652
  if (!closeOnOverlayClick) {
@@ -1369,7 +1658,7 @@ function Dialog({
1369
1658
  event.preventDefault();
1370
1659
  }
1371
1660
  };
1372
- return /* @__PURE__ */ jsx(Root, { open, onOpenChange, children: /* @__PURE__ */ jsxs(Portal, { children: [
1661
+ return /* @__PURE__ */ jsx(Root, { open, onOpenChange, children: /* @__PURE__ */ jsxs(Portal, { container: portalContainer ?? void 0, children: [
1373
1662
  /* @__PURE__ */ jsx(
1374
1663
  Overlay,
1375
1664
  {
@@ -1398,12 +1687,287 @@ function Dialog({
1398
1687
  }
1399
1688
  )
1400
1689
  ] }),
1401
- /* @__PURE__ */ jsx("div", { className: "taskon-dialog-body", children })
1690
+ /* @__PURE__ */ jsx(
1691
+ "div",
1692
+ {
1693
+ className: `taskon-dialog-body${bodyPadding ? "" : " taskon-dialog-body--no-padding"}`,
1694
+ children
1695
+ }
1696
+ )
1402
1697
  ]
1403
1698
  }
1404
1699
  )
1405
1700
  ] }) });
1406
1701
  }
1702
+ const defaultPaginationMessages = {
1703
+ previous: "Previous",
1704
+ next: "Next",
1705
+ page: "Page",
1706
+ of: "of",
1707
+ showing: "Showing {start}-{end} of {total}"
1708
+ };
1709
+ function ChevronLeftIcon() {
1710
+ return /* @__PURE__ */ jsx(
1711
+ "svg",
1712
+ {
1713
+ className: "taskon-pagination-icon",
1714
+ viewBox: "0 0 24 24",
1715
+ fill: "none",
1716
+ stroke: "currentColor",
1717
+ strokeWidth: "2",
1718
+ strokeLinecap: "round",
1719
+ strokeLinejoin: "round",
1720
+ children: /* @__PURE__ */ jsx("polyline", { points: "15 18 9 12 15 6" })
1721
+ }
1722
+ );
1723
+ }
1724
+ function ChevronRightIcon() {
1725
+ return /* @__PURE__ */ jsx(
1726
+ "svg",
1727
+ {
1728
+ className: "taskon-pagination-icon",
1729
+ viewBox: "0 0 24 24",
1730
+ fill: "none",
1731
+ stroke: "currentColor",
1732
+ strokeWidth: "2",
1733
+ strokeLinecap: "round",
1734
+ strokeLinejoin: "round",
1735
+ children: /* @__PURE__ */ jsx("polyline", { points: "9 18 15 12 9 6" })
1736
+ }
1737
+ );
1738
+ }
1739
+ function Pagination({
1740
+ page,
1741
+ totalPages,
1742
+ hasPrevious,
1743
+ hasNext,
1744
+ onPrevious,
1745
+ onNext,
1746
+ messages = defaultPaginationMessages,
1747
+ className = "",
1748
+ showRange,
1749
+ showArrows = true,
1750
+ showButtonText = false,
1751
+ // 默认不显示按钮文字,只显示箭头图标
1752
+ size = "medium"
1753
+ }) {
1754
+ if (totalPages <= 1) {
1755
+ return null;
1756
+ }
1757
+ const rangeText = showRange && messages.showing ? messages.showing.replace("{start}", String(showRange.start)).replace("{end}", String(showRange.end)).replace("{total}", String(showRange.total)) : null;
1758
+ return /* @__PURE__ */ jsxs("div", { className: `taskon-pagination taskon-pagination--${size} ${className}`, children: [
1759
+ rangeText && /* @__PURE__ */ jsx("span", { className: "taskon-pagination-range", children: rangeText }),
1760
+ /* @__PURE__ */ jsxs("div", { className: "taskon-pagination-controls", children: [
1761
+ /* @__PURE__ */ jsx(
1762
+ Button,
1763
+ {
1764
+ variant: "ghost",
1765
+ size,
1766
+ disabled: !hasPrevious,
1767
+ onClick: onPrevious,
1768
+ "aria-label": messages.previous,
1769
+ leftIcon: showArrows ? /* @__PURE__ */ jsx(ChevronLeftIcon, {}) : void 0,
1770
+ className: "taskon-pagination-btn taskon-pagination-btn--prev",
1771
+ children: showButtonText && messages.previous
1772
+ }
1773
+ ),
1774
+ /* @__PURE__ */ jsxs("span", { className: "taskon-pagination-info", children: [
1775
+ /* @__PURE__ */ jsx("span", { className: "taskon-pagination-info-current", children: page + 1 }),
1776
+ /* @__PURE__ */ jsx("span", { className: "taskon-pagination-info-separator", children: " / " }),
1777
+ /* @__PURE__ */ jsx("span", { className: "taskon-pagination-info-total", children: totalPages })
1778
+ ] }),
1779
+ /* @__PURE__ */ jsx(
1780
+ Button,
1781
+ {
1782
+ variant: "ghost",
1783
+ size,
1784
+ disabled: !hasNext,
1785
+ onClick: onNext,
1786
+ "aria-label": messages.next,
1787
+ rightIcon: showArrows ? /* @__PURE__ */ jsx(ChevronRightIcon, {}) : void 0,
1788
+ className: "taskon-pagination-btn taskon-pagination-btn--next",
1789
+ children: showButtonText && messages.next
1790
+ }
1791
+ )
1792
+ ] })
1793
+ ] });
1794
+ }
1795
+ function Table({
1796
+ columns,
1797
+ data,
1798
+ rowConfig,
1799
+ loading = false,
1800
+ loadingText = "Loading...",
1801
+ empty,
1802
+ striped = false,
1803
+ compact = false,
1804
+ borderless = false,
1805
+ className = "",
1806
+ style
1807
+ }) {
1808
+ const tableClassName = [
1809
+ "taskon-table",
1810
+ striped && "taskon-table--striped",
1811
+ compact && "taskon-table--compact",
1812
+ borderless && "taskon-table--borderless"
1813
+ ].filter(Boolean).join(" ");
1814
+ const getRowKey = (rowConfig == null ? void 0 : rowConfig.getRowKey) || ((_, index) => index);
1815
+ const getColumnStyle = (column) => {
1816
+ const style2 = {};
1817
+ if (column.width) {
1818
+ style2.width = typeof column.width === "number" ? `${column.width}px` : column.width;
1819
+ }
1820
+ if (column.minWidth) {
1821
+ style2.minWidth = typeof column.minWidth === "number" ? `${column.minWidth}px` : column.minWidth;
1822
+ }
1823
+ return style2;
1824
+ };
1825
+ const getAlignClassName = (align) => {
1826
+ if (!align || align === "left") return "";
1827
+ return `taskon-table__header--${align}`;
1828
+ };
1829
+ const getCellAlignClassName = (align) => {
1830
+ if (!align || align === "left") return "";
1831
+ return `taskon-table__cell--${align}`;
1832
+ };
1833
+ const renderHeader = () => /* @__PURE__ */ jsx("thead", { className: "taskon-table__head", children: /* @__PURE__ */ jsx("tr", { children: columns.map((column) => /* @__PURE__ */ jsx(
1834
+ "th",
1835
+ {
1836
+ className: `taskon-table__header ${getAlignClassName(column.align)} ${column.headerClassName || ""}`,
1837
+ style: getColumnStyle(column),
1838
+ children: column.title
1839
+ },
1840
+ column.key
1841
+ )) }) });
1842
+ const renderLoading = () => /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsxs("td", { colSpan: columns.length, className: "taskon-table__loading", children: [
1843
+ /* @__PURE__ */ jsx("div", { className: "taskon-table__loading-spinner" }),
1844
+ /* @__PURE__ */ jsx("div", { style: { marginTop: 8 }, children: loadingText })
1845
+ ] }) });
1846
+ const renderEmpty = () => /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: columns.length, className: "taskon-table__empty", children: /* @__PURE__ */ jsxs("div", { className: "taskon-table__empty-content", children: [
1847
+ (empty == null ? void 0 : empty.icon) && /* @__PURE__ */ jsx("div", { className: "taskon-table__empty-icon", children: empty.icon }),
1848
+ (empty == null ? void 0 : empty.title) && /* @__PURE__ */ jsx("p", { className: "taskon-table__empty-title", children: empty.title }),
1849
+ (empty == null ? void 0 : empty.description) && /* @__PURE__ */ jsx("p", { className: "taskon-table__empty-desc", children: empty.description }),
1850
+ !(empty == null ? void 0 : empty.title) && !(empty == null ? void 0 : empty.description) && /* @__PURE__ */ jsx("p", { className: "taskon-table__empty-title", children: "No data" })
1851
+ ] }) }) });
1852
+ const renderRows = () => data.map((row, rowIndex) => {
1853
+ var _a, _b, _c;
1854
+ const rowKey = getRowKey(row, rowIndex);
1855
+ const isHighlighted = ((_a = rowConfig == null ? void 0 : rowConfig.isHighlighted) == null ? void 0 : _a.call(rowConfig, row, rowIndex)) || false;
1856
+ const isDisabled = ((_b = rowConfig == null ? void 0 : rowConfig.isDisabled) == null ? void 0 : _b.call(rowConfig, row, rowIndex)) || false;
1857
+ const isClickable = !!(rowConfig == null ? void 0 : rowConfig.onRowClick);
1858
+ const customRowClassName = ((_c = rowConfig == null ? void 0 : rowConfig.rowClassName) == null ? void 0 : _c.call(rowConfig, row, rowIndex)) || "";
1859
+ const rowClassName = [
1860
+ "taskon-table__row",
1861
+ isHighlighted && "taskon-table__row--highlighted",
1862
+ isDisabled && "taskon-table__row--disabled",
1863
+ isClickable && "taskon-table__row--clickable",
1864
+ customRowClassName
1865
+ ].filter(Boolean).join(" ");
1866
+ const handleRowClick = () => {
1867
+ var _a2;
1868
+ if (isClickable && !isDisabled) {
1869
+ (_a2 = rowConfig == null ? void 0 : rowConfig.onRowClick) == null ? void 0 : _a2.call(rowConfig, row, rowIndex);
1870
+ }
1871
+ };
1872
+ return /* @__PURE__ */ jsx("tr", { className: rowClassName, onClick: handleRowClick, children: columns.map((column) => {
1873
+ const value = row[column.key];
1874
+ const cellContent = column.render ? column.render(value, row, rowIndex) : value;
1875
+ const cellClassName = [
1876
+ "taskon-table__cell",
1877
+ getCellAlignClassName(column.align),
1878
+ column.ellipsis && "taskon-table__cell--ellipsis",
1879
+ column.cellClassName
1880
+ ].filter(Boolean).join(" ");
1881
+ return /* @__PURE__ */ jsx("td", { className: cellClassName, style: getColumnStyle(column), children: cellContent }, column.key);
1882
+ }) }, rowKey);
1883
+ });
1884
+ const renderBody = () => {
1885
+ if (!data || data.length === 0) {
1886
+ if (loading) {
1887
+ return renderLoading();
1888
+ }
1889
+ return renderEmpty();
1890
+ }
1891
+ return renderRows();
1892
+ };
1893
+ return /* @__PURE__ */ jsxs("div", { className: `taskon-table-container ${className}`, style, children: [
1894
+ /* @__PURE__ */ jsxs("table", { className: tableClassName, children: [
1895
+ renderHeader(),
1896
+ /* @__PURE__ */ jsx("tbody", { className: "taskon-table__body", children: renderBody() })
1897
+ ] }),
1898
+ loading && data && data.length > 0 && /* @__PURE__ */ jsx("div", { className: "taskon-table__loading-overlay", children: /* @__PURE__ */ jsx("div", { className: "taskon-table__loading-spinner" }) })
1899
+ ] });
1900
+ }
1901
+ function usePagination(options) {
1902
+ const { total, pageSize, initialPage = 0, mode = "pagination" } = options;
1903
+ const [page, setPage] = useState(initialPage);
1904
+ const totalPages = useMemo(() => {
1905
+ return Math.max(1, Math.ceil(total / pageSize));
1906
+ }, [total, pageSize]);
1907
+ const safePage = useMemo(() => {
1908
+ return Math.min(page, totalPages - 1);
1909
+ }, [page, totalPages]);
1910
+ if (safePage !== page) {
1911
+ setPage(safePage);
1912
+ }
1913
+ const hasPrevious = safePage > 0;
1914
+ const hasNext = safePage < totalPages - 1;
1915
+ const goToPage = useCallback(
1916
+ (targetPage) => {
1917
+ const validPage = Math.max(0, Math.min(targetPage, totalPages - 1));
1918
+ setPage(validPage);
1919
+ },
1920
+ [totalPages]
1921
+ );
1922
+ const goToPrevious = useCallback(() => {
1923
+ if (hasPrevious) {
1924
+ setPage((p) => p - 1);
1925
+ }
1926
+ }, [hasPrevious]);
1927
+ const goToNext = useCallback(() => {
1928
+ if (hasNext) {
1929
+ setPage((p) => p + 1);
1930
+ }
1931
+ }, [hasNext]);
1932
+ const reset = useCallback(() => {
1933
+ setPage(0);
1934
+ }, []);
1935
+ const startIndex = safePage * pageSize + 1;
1936
+ const endIndex = Math.min((safePage + 1) * pageSize, total);
1937
+ const hasMore = useMemo(() => {
1938
+ if (mode === "infinite") {
1939
+ return safePage < totalPages - 1;
1940
+ }
1941
+ return hasNext;
1942
+ }, [mode, safePage, totalPages, hasNext]);
1943
+ const loadedCount = useMemo(() => {
1944
+ if (mode === "infinite") {
1945
+ return Math.min((safePage + 1) * pageSize, total);
1946
+ }
1947
+ return endIndex - startIndex + 1;
1948
+ }, [mode, safePage, pageSize, total, startIndex, endIndex]);
1949
+ const loadMore = useCallback(() => {
1950
+ if (mode === "infinite" && hasMore) {
1951
+ setPage((p) => p + 1);
1952
+ }
1953
+ }, [mode, hasMore]);
1954
+ return {
1955
+ page: safePage,
1956
+ totalPages,
1957
+ hasPrevious,
1958
+ hasNext,
1959
+ goToPage,
1960
+ goToPrevious,
1961
+ goToNext,
1962
+ reset,
1963
+ startIndex,
1964
+ endIndex,
1965
+ // Infinite 模式专用
1966
+ loadMore,
1967
+ hasMore,
1968
+ loadedCount
1969
+ };
1970
+ }
1407
1971
  function useWidgetConfig(widgetId) {
1408
1972
  const { client } = useTaskOnContext();
1409
1973
  const [config, setConfig] = useState(null);
@@ -1442,34 +2006,6 @@ function useWidgetConfig(widgetId) {
1442
2006
  }, [widgetId, client]);
1443
2007
  return { config, isLoading, error };
1444
2008
  }
1445
- function cloudThemeToReactTheme(cloud) {
1446
- let mode;
1447
- if (cloud.colorMode.type === "dual") {
1448
- mode = "auto";
1449
- } else {
1450
- mode = cloud.colorMode.type;
1451
- }
1452
- const mapColorToSeed = (color) => ({
1453
- colorPrimary: color.primaryColor,
1454
- colorSecondary: color.secondaryColor,
1455
- colorSuccess: color.successColor,
1456
- colorWarning: color.warningColor,
1457
- colorError: color.errorColor,
1458
- borderRadius: cloud.shape.borderRadius,
1459
- fontSize: cloud.shape.fontSize
1460
- });
1461
- return {
1462
- mode,
1463
- // Global seed (shape values applied regardless of mode)
1464
- seed: {
1465
- borderRadius: cloud.shape.borderRadius,
1466
- fontSize: cloud.shape.fontSize
1467
- },
1468
- // Per-mode color overrides
1469
- light: { seed: mapColorToSeed(cloud.light) },
1470
- dark: { seed: mapColorToSeed(cloud.dark) }
1471
- };
1472
- }
1473
2009
  function useResolvedWidgetConfig(widgetId) {
1474
2010
  const { config, isLoading, error } = useWidgetConfig(widgetId);
1475
2011
  const cloudTheme = useMemo(() => {
@@ -1487,10 +2023,19 @@ function WidgetShell({
1487
2023
  widgetId,
1488
2024
  isConfigLoading,
1489
2025
  cloudTheme,
2026
+ themeMode,
1490
2027
  className,
1491
2028
  errorMessage,
1492
2029
  children
1493
2030
  }) {
2031
+ const resolvedCloudTheme = useMemo(() => {
2032
+ if (!cloudTheme) return void 0;
2033
+ if (!themeMode) return cloudTheme;
2034
+ return {
2035
+ ...cloudTheme,
2036
+ mode: themeMode
2037
+ };
2038
+ }, [cloudTheme, themeMode]);
1494
2039
  if (widgetId && isConfigLoading) {
1495
2040
  return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsxs("div", { className: `${className}-loading`, children: [
1496
2041
  /* @__PURE__ */ jsx("div", { className: `${className}-loading-spinner` }),
@@ -1500,18 +2045,40 @@ function WidgetShell({
1500
2045
  if (errorMessage) {
1501
2046
  return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsx("div", { className: `${className}-error`, children: /* @__PURE__ */ jsx("span", { className: `${className}-error-message`, children: errorMessage }) }) });
1502
2047
  }
1503
- if (cloudTheme) {
1504
- return /* @__PURE__ */ jsx(ThemeProvider, { theme: cloudTheme, children });
2048
+ if (resolvedCloudTheme) {
2049
+ return /* @__PURE__ */ jsx(ThemeProvider, { theme: resolvedCloudTheme, children });
1505
2050
  }
1506
2051
  return /* @__PURE__ */ jsx(Fragment, { children });
1507
2052
  }
2053
+ const __variableDynamicImportRuntimeHelper = (glob, path, segs) => {
2054
+ const v = glob[path];
2055
+ if (v) {
2056
+ return typeof v === "function" ? v() : Promise.resolve(v);
2057
+ }
2058
+ return new Promise((_, reject) => {
2059
+ (typeof queueMicrotask === "function" ? queueMicrotask : setTimeout)(
2060
+ reject.bind(
2061
+ null,
2062
+ new Error(
2063
+ "Unknown variable dynamic import: " + path + (path.split("/").length !== segs ? ". Note that variables only represent file names one level deep." : "")
2064
+ )
2065
+ )
2066
+ );
2067
+ });
2068
+ };
1508
2069
  export {
2070
+ Button as B,
1509
2071
  Dialog as D,
1510
2072
  FocusScope as F,
2073
+ Pagination as P,
1511
2074
  ReactRemoveScroll as R,
2075
+ Table as T,
1512
2076
  WidgetShell as W,
1513
- useId as a,
1514
- useFocusGuards as b,
2077
+ __variableDynamicImportRuntimeHelper as _,
2078
+ useResolvedWidgetConfig as a,
2079
+ useId as b,
2080
+ cloudThemeToReactTheme as c,
2081
+ useFocusGuards as d,
1515
2082
  hideOthers as h,
1516
- useResolvedWidgetConfig as u
2083
+ usePagination as u
1517
2084
  };