@taskon/widget-react 0.0.1-beta.5 → 0.0.1-beta.7

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 (65) hide show
  1. package/README.md +61 -47
  2. package/dist/CommunityTaskList.css +9 -1
  3. package/dist/EligibilityInfo.css +48 -75
  4. package/dist/LeaderboardWidget.css +73 -71
  5. package/dist/PageBuilder.css +5 -0
  6. package/dist/Quest.css +18 -14
  7. package/dist/TaskOnProvider.css +289 -0
  8. package/dist/ThemeProvider.css +227 -0
  9. package/dist/UserCenterWidget.css +6 -6
  10. package/dist/UserCenterWidget2.css +1388 -1621
  11. package/dist/{dynamic-import-helper.css → WidgetShell.css} +0 -227
  12. package/dist/chunks/{CommunityTaskList-CrMvOB8w.js → CommunityTaskList-D0uVD8wD.js} +393 -208
  13. package/dist/chunks/{EligibilityInfo-Beww12QX.js → EligibilityInfo-Cf6hx9-a.js} +459 -679
  14. package/dist/chunks/{LeaderboardWidget-DwuSpVl0.js → LeaderboardWidget-DyoiiNS6.js} +274 -252
  15. package/dist/chunks/{PageBuilder-DsX6Tv0N.js → PageBuilder-DoAFPm6-.js} +5 -5
  16. package/dist/chunks/{Quest-CuD2LElS.js → Quest-ySZlYd4u.js} +74 -57
  17. package/dist/chunks/TaskOnProvider-CxtFIs3n.js +2072 -0
  18. package/dist/chunks/{dynamic-import-helper-WmIF58Sb.js → ThemeProvider-CulHkqqY.js} +1282 -555
  19. package/dist/chunks/UserCenterWidget-BJsc_GSZ.js +3246 -0
  20. package/dist/chunks/{UserCenterWidget-CvU6K4AC.js → UserCenterWidget-STq8kpV4.js} +1174 -1386
  21. package/dist/chunks/WidgetShell-8xn-Jivw.js +659 -0
  22. package/dist/chunks/communitytask-es-CBNnS4o2.js +521 -0
  23. package/dist/chunks/communitytask-ja-GRf9cbdx.js +521 -0
  24. package/dist/chunks/communitytask-ko-Bf24PQKI.js +521 -0
  25. package/dist/chunks/{communitytask-ru-DhySaZL8.js → communitytask-ru-CZm2CPoV.js} +211 -1
  26. package/dist/chunks/leaderboardwidget-es-vKjrjQaz.js +146 -0
  27. package/dist/chunks/leaderboardwidget-ja-Q6u0HxKG.js +146 -0
  28. package/dist/chunks/leaderboardwidget-ko-CG6SWgxf.js +146 -0
  29. package/dist/chunks/leaderboardwidget-ru-DCcHcJGz.js +146 -0
  30. package/dist/chunks/{quest-es-D-b5xcme.js → quest-es-Dyyy0zaw.js} +8 -93
  31. package/dist/chunks/{quest-ja-Dxd2vqBF.js → quest-ja-Depog33y.js} +8 -93
  32. package/dist/chunks/{quest-ko-CSmRWgK_.js → quest-ko-BMu3uRQJ.js} +8 -93
  33. package/dist/chunks/{quest-ru-CkEKv1_F.js → quest-ru-xne814Rw.js} +8 -93
  34. package/dist/chunks/useIsMobile-D6Ybur-6.js +30 -0
  35. package/dist/chunks/useToast-BGJhd3BX.js +93 -0
  36. package/dist/chunks/usercenter-es-Dz3Wp2vV.js +512 -0
  37. package/dist/chunks/usercenter-ja-CKE4DJC6.js +512 -0
  38. package/dist/chunks/usercenter-ko-Dtpkn2qb.js +512 -0
  39. package/dist/chunks/usercenter-ru-DnBGee45.js +512 -0
  40. package/dist/community-task.d.ts +0 -390
  41. package/dist/community-task.js +2 -7
  42. package/dist/core.d.ts +38 -20
  43. package/dist/core.js +9 -10
  44. package/dist/index.d.ts +86 -709
  45. package/dist/index.js +22 -28
  46. package/dist/leaderboard.d.ts +0 -498
  47. package/dist/leaderboard.js +2 -16
  48. package/dist/page-builder.js +1 -1
  49. package/dist/quest.d.ts +0 -971
  50. package/dist/quest.js +2 -7
  51. package/dist/user-center.d.ts +0 -1610
  52. package/dist/user-center.js +2 -494
  53. package/package.json +2 -2
  54. package/dist/chunks/TaskOnProvider-xUeP2Nro.js +0 -1243
  55. package/dist/chunks/ThemeProvider-Bt4UZ33y.js +0 -1334
  56. package/dist/chunks/UserCenterWidget-CB0hnj-L.js +0 -3230
  57. package/dist/chunks/communitytask-es-1zawvXEX.js +0 -311
  58. package/dist/chunks/communitytask-ja-CmW6nP-L.js +0 -311
  59. package/dist/chunks/communitytask-ko-BD0hzQSi.js +0 -311
  60. package/dist/chunks/createLocaleLoader-BameiEhU.js +0 -65
  61. package/dist/chunks/leaderboardwidget-ja-Bj6gz6y1.js +0 -119
  62. package/dist/chunks/leaderboardwidget-ko-f1cLO9ic.js +0 -119
  63. package/dist/chunks/useToast-CaRkylKe.js +0 -304
  64. package/dist/chunks/usercenter-ja-B2465c1O.js +0 -326
  65. package/dist/chunks/usercenter-ko-xAEYxqLg.js +0 -326
@@ -1,70 +1,322 @@
1
- import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
1
  import * as React from "react";
3
- import { forwardRef, useState, useMemo, useCallback, useEffect } from "react";
4
- import { r 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, s as createContext2, t as useTaskOnPortalContainer, d as useTaskOnContext, T as ThemeProvider } from "./ThemeProvider-Bt4UZ33y.js";
5
- import { createWidgetApi, parseWidgetConfig } from "@taskon/core";
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
2
+ import { createContext, useContext, useMemo, useState, useRef, useEffect } from "react";
3
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
4
+ import * as ReactDOM from "react-dom";
5
+ import ReactDOM__default from "react-dom";
6
+ import '../ThemeProvider.css';const ThemeContext = createContext(null);
7
+ const ThemePortalContainerContext = createContext(void 0);
8
+ function useTaskOnTheme() {
9
+ const theme = useContext(ThemeContext);
10
+ if (!theme) {
11
+ throw new Error("useTaskOnTheme must be used within a ThemeProvider");
12
+ }
13
+ return theme;
14
+ }
15
+ function useTaskOnPortalContainer() {
16
+ const container = useContext(ThemePortalContainerContext);
17
+ if (container !== void 0) {
18
+ return container;
19
+ }
20
+ if (typeof document !== "undefined") {
21
+ return document.body;
22
+ }
23
+ return null;
24
+ }
25
+ const TaskOnContext = createContext(null);
26
+ function useTaskOnContext() {
27
+ const context = useContext(TaskOnContext);
28
+ if (!context) {
29
+ throw new Error("useTaskOnContext must be used within a TaskOnProvider");
30
+ }
31
+ return context;
32
+ }
33
+ function useTaskOnAuth() {
34
+ const context = useTaskOnContext();
35
+ return useMemo(
36
+ () => ({
37
+ // User state
38
+ userId: context.userId,
39
+ isLoggedIn: context.isLoggedIn,
40
+ isInitializing: context.isInitializing,
41
+ isSessionReady: context.isSessionReady,
42
+ // Unified login
43
+ login: context.login,
44
+ // Logout
45
+ logout: context.logout,
46
+ // Request login (triggers config.onRequestLogin)
47
+ requestLogin: context.requestLogin
48
+ }),
49
+ [
50
+ context.userId,
51
+ context.isLoggedIn,
52
+ context.isInitializing,
53
+ context.isSessionReady,
54
+ context.login,
55
+ context.logout,
56
+ context.requestLogin
57
+ ]
58
+ );
59
+ }
60
+ function isSupportedLocale(locale) {
61
+ return locale === "en" || locale === "ko" || locale === "ja" || locale === "ru" || locale === "es";
62
+ }
63
+ function warnUnsupportedLocale(locale, widgetId) {
64
+ if (process.env.NODE_ENV !== "production" && !isSupportedLocale(locale)) {
65
+ console.warn(
66
+ `[widget-react] Locale "${locale}" is not fully supported in ${widgetId}. Falling back to English. Supported locales: en, ko, ja, ru, es`
67
+ );
68
+ }
69
+ }
70
+ const localeCache = /* @__PURE__ */ new Map();
71
+ const DEFAULT_LOCALE = "en";
72
+ function useWidgetLocale(options) {
73
+ const { widgetId, defaultMessages, loadMessages } = options;
74
+ const { locale } = useTaskOnContext();
75
+ const getInitialState = () => {
76
+ if (locale === DEFAULT_LOCALE) {
77
+ return { messages: defaultMessages, isLoading: false };
78
+ }
79
+ const cacheKey = `${widgetId}-${locale}`;
80
+ if (localeCache.has(cacheKey)) {
81
+ return { messages: localeCache.get(cacheKey), isLoading: false };
82
+ }
83
+ return { messages: defaultMessages, isLoading: true };
84
+ };
85
+ const [state, setState] = useState(getInitialState);
86
+ const loadMessagesRef = useRef(loadMessages);
87
+ loadMessagesRef.current = loadMessages;
88
+ const defaultMessagesRef = useRef(defaultMessages);
89
+ defaultMessagesRef.current = defaultMessages;
90
+ useEffect(() => {
91
+ if (locale === DEFAULT_LOCALE) {
92
+ setState({ messages: defaultMessagesRef.current, isLoading: false });
93
+ return;
94
+ }
95
+ warnUnsupportedLocale(locale, widgetId);
96
+ const cacheKey = `${widgetId}-${locale}`;
97
+ if (localeCache.has(cacheKey)) {
98
+ setState({ messages: localeCache.get(cacheKey), isLoading: false });
99
+ return;
100
+ }
101
+ let isMounted = true;
102
+ setState((prev) => ({ ...prev, isLoading: true }));
103
+ loadMessagesRef.current(locale).then((module) => {
104
+ if (isMounted) {
105
+ const loadedMessages = module.default;
106
+ localeCache.set(cacheKey, loadedMessages);
107
+ setState({ messages: loadedMessages, isLoading: false });
108
+ }
109
+ }).catch((error) => {
110
+ console.warn(
111
+ `[widget-react] Failed to load locale "${locale}" for ${widgetId}, falling back to English:`,
112
+ error
113
+ );
114
+ if (isMounted) {
115
+ setState({ messages: defaultMessagesRef.current, isLoading: false });
116
+ }
117
+ });
118
+ return () => {
119
+ isMounted = false;
32
120
  };
121
+ }, [locale, widgetId]);
122
+ return state;
123
+ }
124
+ function clearLocaleCache() {
125
+ localeCache.clear();
126
+ }
127
+ async function preloadWidgetLocale(widgetId, locale, loadMessages) {
128
+ if (locale === DEFAULT_LOCALE) return;
129
+ const cacheKey = `${widgetId}-${locale}`;
130
+ if (localeCache.has(cacheKey)) return;
131
+ try {
132
+ const module = await loadMessages(locale);
133
+ localeCache.set(cacheKey, module.default);
134
+ } catch (error) {
135
+ console.warn(
136
+ `[widget-react] Failed to preload locale "${locale}" for ${widgetId}:`,
137
+ error
138
+ );
139
+ }
140
+ }
141
+ function interpolate(template, params) {
142
+ if (!params) {
143
+ return template;
144
+ }
145
+ return template.replace(/\{(\w+)\}/g, (match, key) => {
146
+ const value = params[key];
147
+ if (value === void 0) {
148
+ return match;
149
+ }
150
+ return String(value);
151
+ });
152
+ }
153
+ function createT(messages) {
154
+ return (key, params) => {
155
+ const template = messages[key];
156
+ if (typeof template !== "string") {
157
+ if (process.env.NODE_ENV !== "production") {
158
+ console.warn(`[widget-react] Missing translation key: ${String(key)}`);
159
+ }
160
+ return String(key);
161
+ }
162
+ return interpolate(template, params);
33
163
  };
164
+ }
165
+ function createTFunction(messages) {
166
+ return (key, params) => {
167
+ const template = messages[key];
168
+ if (typeof template !== "string") {
169
+ if (process.env.NODE_ENV !== "production") {
170
+ console.warn(`[widget-react] Missing translation key: ${String(key)}`);
171
+ }
172
+ return String(key);
173
+ }
174
+ return interpolate(template, params);
175
+ };
176
+ }
177
+ function useTranslation(options) {
178
+ const { messages, isLoading } = useWidgetLocale(options);
179
+ const t = useMemo(() => createTFunction(messages), [messages]);
34
180
  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)
181
+ t,
182
+ messages,
183
+ isLoading
184
+ };
185
+ }
186
+ function createLocaleLoader(defaultMessages, imports) {
187
+ return (locale) => {
188
+ if (locale === "en") {
189
+ return Promise.resolve({ default: defaultMessages });
190
+ }
191
+ const importFn = imports[locale];
192
+ if (importFn) {
193
+ return importFn();
194
+ }
195
+ return Promise.resolve({ default: defaultMessages });
196
+ };
197
+ }
198
+ function composeEventHandlers(originalEventHandler, ourEventHandler, { checkForDefaultPrevented = true } = {}) {
199
+ return function handleEvent(event) {
200
+ originalEventHandler == null ? void 0 : originalEventHandler(event);
201
+ if (checkForDefaultPrevented === false || !event.defaultPrevented) {
202
+ return ourEventHandler == null ? void 0 : ourEventHandler(event);
203
+ }
204
+ };
205
+ }
206
+ function setRef(ref, value) {
207
+ if (typeof ref === "function") {
208
+ return ref(value);
209
+ } else if (ref !== null && ref !== void 0) {
210
+ ref.current = value;
211
+ }
212
+ }
213
+ function composeRefs(...refs) {
214
+ return (node) => {
215
+ let hasCleanup = false;
216
+ const cleanups = refs.map((ref) => {
217
+ const cleanup = setRef(ref, node);
218
+ if (!hasCleanup && typeof cleanup == "function") {
219
+ hasCleanup = true;
220
+ }
221
+ return cleanup;
222
+ });
223
+ if (hasCleanup) {
224
+ return () => {
225
+ for (let i = 0; i < cleanups.length; i++) {
226
+ const cleanup = cleanups[i];
227
+ if (typeof cleanup == "function") {
228
+ cleanup();
229
+ } else {
230
+ setRef(refs[i], null);
231
+ }
232
+ }
233
+ };
49
234
  }
50
235
  };
51
236
  }
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;
237
+ function useComposedRefs(...refs) {
238
+ return React.useCallback(composeRefs(...refs), refs);
239
+ }
240
+ function createContext2(rootComponentName, defaultContext) {
241
+ const Context = React.createContext(defaultContext);
242
+ const Provider = (props) => {
243
+ const { children, ...context } = props;
244
+ const value = React.useMemo(() => context, Object.values(context));
245
+ return /* @__PURE__ */ jsx(Context.Provider, { value, children });
246
+ };
247
+ Provider.displayName = rootComponentName + "Provider";
248
+ function useContext2(consumerName) {
249
+ const context = React.useContext(Context);
250
+ if (context) return context;
251
+ if (defaultContext !== void 0) return defaultContext;
252
+ throw new Error(`\`${consumerName}\` must be used within \`${rootComponentName}\``);
253
+ }
254
+ return [Provider, useContext2];
255
+ }
256
+ function createContextScope(scopeName, createContextScopeDeps = []) {
257
+ let defaultContexts = [];
258
+ function createContext3(rootComponentName, defaultContext) {
259
+ const BaseContext = React.createContext(defaultContext);
260
+ const index = defaultContexts.length;
261
+ defaultContexts = [...defaultContexts, defaultContext];
262
+ const Provider = (props) => {
263
+ var _a;
264
+ const { scope, children, ...context } = props;
265
+ const Context = ((_a = scope == null ? void 0 : scope[scopeName]) == null ? void 0 : _a[index]) || BaseContext;
266
+ const value = React.useMemo(() => context, Object.values(context));
267
+ return /* @__PURE__ */ jsx(Context.Provider, { value, children });
268
+ };
269
+ Provider.displayName = rootComponentName + "Provider";
270
+ function useContext2(consumerName, scope) {
271
+ var _a;
272
+ const Context = ((_a = scope == null ? void 0 : scope[scopeName]) == null ? void 0 : _a[index]) || BaseContext;
273
+ const context = React.useContext(Context);
274
+ if (context) return context;
275
+ if (defaultContext !== void 0) return defaultContext;
276
+ throw new Error(`\`${consumerName}\` must be used within \`${rootComponentName}\``);
277
+ }
278
+ return [Provider, useContext2];
279
+ }
280
+ const createScope = () => {
281
+ const scopeContexts = defaultContexts.map((defaultContext) => {
282
+ return React.createContext(defaultContext);
283
+ });
284
+ return function useScope(scope) {
285
+ const contexts = (scope == null ? void 0 : scope[scopeName]) || scopeContexts;
286
+ return React.useMemo(
287
+ () => ({ [`__scope${scopeName}`]: { ...scope, [scopeName]: contexts } }),
288
+ [scope, contexts]
289
+ );
290
+ };
291
+ };
292
+ createScope.scopeName = scopeName;
293
+ return [createContext3, composeContextScopes(createScope, ...createContextScopeDeps)];
56
294
  }
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);
295
+ function composeContextScopes(...scopes) {
296
+ const baseScope = scopes[0];
297
+ if (scopes.length === 1) return baseScope;
298
+ const createScope = () => {
299
+ const scopeHooks = scopes.map((createScope2) => ({
300
+ useScope: createScope2(),
301
+ scopeName: createScope2.scopeName
302
+ }));
303
+ return function useComposedScopes(overrideScopes) {
304
+ const nextScopes = scopeHooks.reduce((nextScopes2, { useScope, scopeName }) => {
305
+ const scopeProps = useScope(overrideScopes);
306
+ const currentScope = scopeProps[`__scope${scopeName}`];
307
+ return { ...nextScopes2, ...currentScope };
308
+ }, {});
309
+ return React.useMemo(() => ({ [`__scope${baseScope.scopeName}`]: nextScopes }), [nextScopes]);
310
+ };
311
+ };
312
+ createScope.scopeName = baseScope.scopeName;
313
+ return createScope;
59
314
  }
60
315
  // @__NO_SIDE_EFFECTS__
61
316
  function createSlot(ownerName) {
62
317
  const SlotClone = /* @__PURE__ */ createSlotClone(ownerName);
63
318
  const Slot2 = React.forwardRef((props, forwardedRef) => {
64
- let { children, ...slotProps } = props;
65
- if (isLazyComponent(children) && typeof use === "function") {
66
- children = use(children._payload);
67
- }
319
+ const { children, ...slotProps } = props;
68
320
  const childrenArray = React.Children.toArray(children);
69
321
  const slottable = childrenArray.find(isSlottable);
70
322
  if (slottable) {
@@ -84,16 +336,12 @@ function createSlot(ownerName) {
84
336
  Slot2.displayName = `${ownerName}.Slot`;
85
337
  return Slot2;
86
338
  }
87
- var Slot$1 = /* @__PURE__ */ createSlot("Slot");
88
339
  // @__NO_SIDE_EFFECTS__
89
340
  function createSlotClone(ownerName) {
90
341
  const SlotClone = React.forwardRef((props, forwardedRef) => {
91
- let { children, ...slotProps } = props;
92
- if (isLazyComponent(children) && typeof use === "function") {
93
- children = use(children._payload);
94
- }
342
+ const { children, ...slotProps } = props;
95
343
  if (React.isValidElement(children)) {
96
- const childrenRef = getElementRef(children);
344
+ const childrenRef = getElementRef$1(children);
97
345
  const props2 = mergeProps(slotProps, children.props);
98
346
  if (children.type !== React.Fragment) {
99
347
  props2.ref = forwardedRef ? composeRefs(forwardedRef, childrenRef) : childrenRef;
@@ -133,7 +381,7 @@ function mergeProps(slotProps, childProps) {
133
381
  }
134
382
  return { ...slotProps, ...overrideProps };
135
383
  }
136
- function getElementRef(element) {
384
+ function getElementRef$1(element) {
137
385
  var _a, _b;
138
386
  let getter = (_a = Object.getOwnPropertyDescriptor(element.props, "ref")) == null ? void 0 : _a.get;
139
387
  let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
@@ -147,149 +395,467 @@ function getElementRef(element) {
147
395
  }
148
396
  return element.props.ref || element.ref;
149
397
  }
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"
398
+ var NODES = [
399
+ "a",
400
+ "button",
401
+ "div",
402
+ "form",
403
+ "h2",
404
+ "h3",
405
+ "img",
406
+ "input",
407
+ "label",
408
+ "li",
409
+ "nav",
410
+ "ol",
411
+ "p",
412
+ "select",
413
+ "span",
414
+ "svg",
415
+ "ul"
416
+ ];
417
+ var Primitive = NODES.reduce((primitive, node) => {
418
+ const Slot2 = /* @__PURE__ */ createSlot(`Primitive.${node}`);
419
+ const Node2 = React.forwardRef((props, forwardedRef) => {
420
+ const { asChild, ...primitiveProps } = props;
421
+ const Comp = asChild ? Slot2 : node;
422
+ if (typeof window !== "undefined") {
423
+ window[Symbol.for("radix-ui")] = true;
424
+ }
425
+ return /* @__PURE__ */ jsx(Comp, { ...primitiveProps, ref: forwardedRef });
426
+ });
427
+ Node2.displayName = `Primitive.${node}`;
428
+ return { ...primitive, [node]: Node2 };
429
+ }, {});
430
+ function dispatchDiscreteCustomEvent(target, event) {
431
+ if (target) ReactDOM.flushSync(() => target.dispatchEvent(event));
432
+ }
433
+ function useCallbackRef$1(callback) {
434
+ const callbackRef = React.useRef(callback);
435
+ React.useEffect(() => {
436
+ callbackRef.current = callback;
437
+ });
438
+ return React.useMemo(() => (...args) => {
439
+ var _a;
440
+ return (_a = callbackRef.current) == null ? void 0 : _a.call(callbackRef, ...args);
441
+ }, []);
442
+ }
443
+ function useEscapeKeydown(onEscapeKeyDownProp, ownerDocument = globalThis == null ? void 0 : globalThis.document) {
444
+ const onEscapeKeyDown = useCallbackRef$1(onEscapeKeyDownProp);
445
+ React.useEffect(() => {
446
+ const handleKeyDown = (event) => {
447
+ if (event.key === "Escape") {
448
+ onEscapeKeyDown(event);
207
449
  }
208
450
  };
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)"
451
+ ownerDocument.addEventListener("keydown", handleKeyDown, { capture: true });
452
+ return () => ownerDocument.removeEventListener("keydown", handleKeyDown, { capture: true });
453
+ }, [onEscapeKeyDown, ownerDocument]);
454
+ }
455
+ var DISMISSABLE_LAYER_NAME = "DismissableLayer";
456
+ var CONTEXT_UPDATE = "dismissableLayer.update";
457
+ var POINTER_DOWN_OUTSIDE = "dismissableLayer.pointerDownOutside";
458
+ var FOCUS_OUTSIDE = "dismissableLayer.focusOutside";
459
+ var originalBodyPointerEvents;
460
+ var DismissableLayerContext = React.createContext({
461
+ layers: /* @__PURE__ */ new Set(),
462
+ layersWithOutsidePointerEventsDisabled: /* @__PURE__ */ new Set(),
463
+ branches: /* @__PURE__ */ new Set()
464
+ });
465
+ var DismissableLayer = React.forwardRef(
466
+ (props, forwardedRef) => {
467
+ const {
468
+ disableOutsidePointerEvents = false,
469
+ onEscapeKeyDown,
470
+ onPointerDownOutside,
471
+ onFocusOutside,
472
+ onInteractOutside,
473
+ onDismiss,
474
+ ...layerProps
475
+ } = props;
476
+ const context = React.useContext(DismissableLayerContext);
477
+ const [node, setNode] = React.useState(null);
478
+ const ownerDocument = (node == null ? void 0 : node.ownerDocument) ?? (globalThis == null ? void 0 : globalThis.document);
479
+ const [, force] = React.useState({});
480
+ const composedRefs = useComposedRefs(forwardedRef, (node2) => setNode(node2));
481
+ const layers = Array.from(context.layers);
482
+ const [highestLayerWithOutsidePointerEventsDisabled] = [...context.layersWithOutsidePointerEventsDisabled].slice(-1);
483
+ const highestLayerWithOutsidePointerEventsDisabledIndex = layers.indexOf(highestLayerWithOutsidePointerEventsDisabled);
484
+ const index = node ? layers.indexOf(node) : -1;
485
+ const isBodyPointerEventsDisabled = context.layersWithOutsidePointerEventsDisabled.size > 0;
486
+ const isPointerEventsEnabled = index >= highestLayerWithOutsidePointerEventsDisabledIndex;
487
+ const pointerDownOutside = usePointerDownOutside((event) => {
488
+ const target = event.target;
489
+ const isPointerDownOnBranch = [...context.branches].some((branch) => branch.contains(target));
490
+ if (!isPointerEventsEnabled || isPointerDownOnBranch) return;
491
+ onPointerDownOutside == null ? void 0 : onPointerDownOutside(event);
492
+ onInteractOutside == null ? void 0 : onInteractOutside(event);
493
+ if (!event.defaultPrevented) onDismiss == null ? void 0 : onDismiss();
494
+ }, ownerDocument);
495
+ const focusOutside = useFocusOutside((event) => {
496
+ const target = event.target;
497
+ const isFocusInBranch = [...context.branches].some((branch) => branch.contains(target));
498
+ if (isFocusInBranch) return;
499
+ onFocusOutside == null ? void 0 : onFocusOutside(event);
500
+ onInteractOutside == null ? void 0 : onInteractOutside(event);
501
+ if (!event.defaultPrevented) onDismiss == null ? void 0 : onDismiss();
502
+ }, ownerDocument);
503
+ useEscapeKeydown((event) => {
504
+ const isHighestLayer = index === context.layers.size - 1;
505
+ if (!isHighestLayer) return;
506
+ onEscapeKeyDown == null ? void 0 : onEscapeKeyDown(event);
507
+ if (!event.defaultPrevented && onDismiss) {
508
+ event.preventDefault();
509
+ onDismiss();
510
+ }
511
+ }, ownerDocument);
512
+ React.useEffect(() => {
513
+ if (!node) return;
514
+ if (disableOutsidePointerEvents) {
515
+ if (context.layersWithOutsidePointerEventsDisabled.size === 0) {
516
+ originalBodyPointerEvents = ownerDocument.body.style.pointerEvents;
517
+ ownerDocument.body.style.pointerEvents = "none";
518
+ }
519
+ context.layersWithOutsidePointerEventsDisabled.add(node);
520
+ }
521
+ context.layers.add(node);
522
+ dispatchUpdate();
523
+ return () => {
524
+ if (disableOutsidePointerEvents && context.layersWithOutsidePointerEventsDisabled.size === 1) {
525
+ ownerDocument.body.style.pointerEvents = originalBodyPointerEvents;
526
+ }
527
+ };
528
+ }, [node, ownerDocument, disableOutsidePointerEvents, context]);
529
+ React.useEffect(() => {
530
+ return () => {
531
+ if (!node) return;
532
+ context.layers.delete(node);
533
+ context.layersWithOutsidePointerEventsDisabled.delete(node);
534
+ dispatchUpdate();
535
+ };
536
+ }, [node, context]);
537
+ React.useEffect(() => {
538
+ const handleUpdate = () => force({});
539
+ document.addEventListener(CONTEXT_UPDATE, handleUpdate);
540
+ return () => document.removeEventListener(CONTEXT_UPDATE, handleUpdate);
541
+ }, []);
542
+ return /* @__PURE__ */ jsx(
543
+ Primitive.div,
544
+ {
545
+ ...layerProps,
546
+ ref: composedRefs,
547
+ style: {
548
+ pointerEvents: isBodyPointerEventsDisabled ? isPointerEventsEnabled ? "auto" : "none" : void 0,
549
+ ...props.style
550
+ },
551
+ onFocusCapture: composeEventHandlers(props.onFocusCapture, focusOutside.onFocusCapture),
552
+ onBlurCapture: composeEventHandlers(props.onBlurCapture, focusOutside.onBlurCapture),
553
+ onPointerDownCapture: composeEventHandlers(
554
+ props.onPointerDownCapture,
555
+ pointerDownOutside.onPointerDownCapture
556
+ )
557
+ }
558
+ );
559
+ }
560
+ );
561
+ DismissableLayer.displayName = DISMISSABLE_LAYER_NAME;
562
+ var BRANCH_NAME = "DismissableLayerBranch";
563
+ var DismissableLayerBranch = React.forwardRef((props, forwardedRef) => {
564
+ const context = React.useContext(DismissableLayerContext);
565
+ const ref = React.useRef(null);
566
+ const composedRefs = useComposedRefs(forwardedRef, ref);
567
+ React.useEffect(() => {
568
+ const node = ref.current;
569
+ if (node) {
570
+ context.branches.add(node);
571
+ return () => {
572
+ context.branches.delete(node);
573
+ };
574
+ }
575
+ }, [context.branches]);
576
+ return /* @__PURE__ */ jsx(Primitive.div, { ...props, ref: composedRefs });
577
+ });
578
+ DismissableLayerBranch.displayName = BRANCH_NAME;
579
+ function usePointerDownOutside(onPointerDownOutside, ownerDocument = globalThis == null ? void 0 : globalThis.document) {
580
+ const handlePointerDownOutside = useCallbackRef$1(onPointerDownOutside);
581
+ const isPointerInsideReactTreeRef = React.useRef(false);
582
+ const handleClickRef = React.useRef(() => {
583
+ });
584
+ React.useEffect(() => {
585
+ const handlePointerDown = (event) => {
586
+ if (event.target && !isPointerInsideReactTreeRef.current) {
587
+ let handleAndDispatchPointerDownOutsideEvent2 = function() {
588
+ handleAndDispatchCustomEvent(
589
+ POINTER_DOWN_OUTSIDE,
590
+ handlePointerDownOutside,
591
+ eventDetail,
592
+ { discrete: true }
593
+ );
594
+ };
595
+ const eventDetail = { originalEvent: event };
596
+ if (event.pointerType === "touch") {
597
+ ownerDocument.removeEventListener("click", handleClickRef.current);
598
+ handleClickRef.current = handleAndDispatchPointerDownOutsideEvent2;
599
+ ownerDocument.addEventListener("click", handleClickRef.current, { once: true });
600
+ } else {
601
+ handleAndDispatchPointerDownOutsideEvent2();
602
+ }
603
+ } else {
604
+ ownerDocument.removeEventListener("click", handleClickRef.current);
230
605
  }
606
+ isPointerInsideReactTreeRef.current = false;
231
607
  };
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"
608
+ const timerId = window.setTimeout(() => {
609
+ ownerDocument.addEventListener("pointerdown", handlePointerDown);
610
+ }, 0);
611
+ return () => {
612
+ window.clearTimeout(timerId);
613
+ ownerDocument.removeEventListener("pointerdown", handlePointerDown);
614
+ ownerDocument.removeEventListener("click", handleClickRef.current);
238
615
  };
239
- const mergedStyle = {
240
- ...baseStyles,
241
- ...sizeStyles[size],
242
- ...variantStyles[variant]
616
+ }, [ownerDocument, handlePointerDownOutside]);
617
+ return {
618
+ // ensures we check React component tree (not just DOM tree)
619
+ onPointerDownCapture: () => isPointerInsideReactTreeRef.current = true
620
+ };
621
+ }
622
+ function useFocusOutside(onFocusOutside, ownerDocument = globalThis == null ? void 0 : globalThis.document) {
623
+ const handleFocusOutside = useCallbackRef$1(onFocusOutside);
624
+ const isFocusInsideReactTreeRef = React.useRef(false);
625
+ React.useEffect(() => {
626
+ const handleFocus = (event) => {
627
+ if (event.target && !isFocusInsideReactTreeRef.current) {
628
+ const eventDetail = { originalEvent: event };
629
+ handleAndDispatchCustomEvent(FOCUS_OUTSIDE, handleFocusOutside, eventDetail, {
630
+ discrete: false
631
+ });
632
+ }
243
633
  };
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
- }
634
+ ownerDocument.addEventListener("focusin", handleFocus);
635
+ return () => ownerDocument.removeEventListener("focusin", handleFocus);
636
+ }, [ownerDocument, handleFocusOutside]);
637
+ return {
638
+ onFocusCapture: () => isFocusInsideReactTreeRef.current = true,
639
+ onBlurCapture: () => isFocusInsideReactTreeRef.current = false
640
+ };
641
+ }
642
+ function dispatchUpdate() {
643
+ const event = new CustomEvent(CONTEXT_UPDATE);
644
+ document.dispatchEvent(event);
645
+ }
646
+ function handleAndDispatchCustomEvent(name, handler, detail, { discrete }) {
647
+ const target = detail.originalEvent.target;
648
+ const event = new CustomEvent(name, { bubbles: false, cancelable: true, detail });
649
+ if (handler) target.addEventListener(name, handler, { once: true });
650
+ if (discrete) {
651
+ dispatchDiscreteCustomEvent(target, event);
652
+ } else {
653
+ target.dispatchEvent(event);
654
+ }
655
+ }
656
+ var Root$1 = DismissableLayer;
657
+ var Branch = DismissableLayerBranch;
658
+ var useLayoutEffect2 = (globalThis == null ? void 0 : globalThis.document) ? React.useLayoutEffect : () => {
659
+ };
660
+ var PORTAL_NAME$1 = "Portal";
661
+ var Portal$1 = React.forwardRef((props, forwardedRef) => {
662
+ var _a;
663
+ const { container: containerProp, ...portalProps } = props;
664
+ const [mounted, setMounted] = React.useState(false);
665
+ useLayoutEffect2(() => setMounted(true), []);
666
+ const container = containerProp || mounted && ((_a = globalThis == null ? void 0 : globalThis.document) == null ? void 0 : _a.body);
667
+ return container ? ReactDOM__default.createPortal(/* @__PURE__ */ jsx(Primitive.div, { ...portalProps, ref: forwardedRef }), container) : null;
668
+ });
669
+ Portal$1.displayName = PORTAL_NAME$1;
670
+ function useStateMachine(initialState, machine) {
671
+ return React.useReducer((state, event) => {
672
+ const nextState = machine[state][event];
673
+ return nextState ?? state;
674
+ }, initialState);
675
+ }
676
+ var Presence = (props) => {
677
+ const { present, children } = props;
678
+ const presence = usePresence(present);
679
+ const child = typeof children === "function" ? children({ present: presence.isPresent }) : React.Children.only(children);
680
+ const ref = useComposedRefs(presence.ref, getElementRef(child));
681
+ const forceMount = typeof children === "function";
682
+ return forceMount || presence.isPresent ? React.cloneElement(child, { ref }) : null;
683
+ };
684
+ Presence.displayName = "Presence";
685
+ function usePresence(present) {
686
+ const [node, setNode] = React.useState();
687
+ const stylesRef = React.useRef(null);
688
+ const prevPresentRef = React.useRef(present);
689
+ const prevAnimationNameRef = React.useRef("none");
690
+ const initialState = present ? "mounted" : "unmounted";
691
+ const [state, send] = useStateMachine(initialState, {
692
+ mounted: {
693
+ UNMOUNT: "unmounted",
694
+ ANIMATION_OUT: "unmountSuspended"
695
+ },
696
+ unmountSuspended: {
697
+ MOUNT: "mounted",
698
+ ANIMATION_END: "unmounted"
699
+ },
700
+ unmounted: {
701
+ MOUNT: "mounted"
702
+ }
703
+ });
704
+ React.useEffect(() => {
705
+ const currentAnimationName = getAnimationName(stylesRef.current);
706
+ prevAnimationNameRef.current = state === "mounted" ? currentAnimationName : "none";
707
+ }, [state]);
708
+ useLayoutEffect2(() => {
709
+ const styles = stylesRef.current;
710
+ const wasPresent = prevPresentRef.current;
711
+ const hasPresentChanged = wasPresent !== present;
712
+ if (hasPresentChanged) {
713
+ const prevAnimationName = prevAnimationNameRef.current;
714
+ const currentAnimationName = getAnimationName(styles);
715
+ if (present) {
716
+ send("MOUNT");
717
+ } else if (currentAnimationName === "none" || (styles == null ? void 0 : styles.display) === "none") {
718
+ send("UNMOUNT");
719
+ } else {
720
+ const isAnimating = prevAnimationName !== currentAnimationName;
721
+ if (wasPresent && isAnimating) {
722
+ send("ANIMATION_OUT");
723
+ } else {
724
+ send("UNMOUNT");
259
725
  }
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
- }
726
+ }
727
+ prevPresentRef.current = present;
728
+ }
729
+ }, [present, send]);
730
+ useLayoutEffect2(() => {
731
+ if (node) {
732
+ let timeoutId;
733
+ const ownerWindow = node.ownerDocument.defaultView ?? window;
734
+ const handleAnimationEnd = (event) => {
735
+ const currentAnimationName = getAnimationName(stylesRef.current);
736
+ const isCurrentAnimation = currentAnimationName.includes(CSS.escape(event.animationName));
737
+ if (event.target === node && isCurrentAnimation) {
738
+ send("ANIMATION_END");
739
+ if (!prevPresentRef.current) {
740
+ const currentFillMode = node.style.animationFillMode;
741
+ node.style.animationFillMode = "forwards";
742
+ timeoutId = ownerWindow.setTimeout(() => {
743
+ if (node.style.animationFillMode === "forwards") {
744
+ node.style.animationFillMode = currentFillMode;
745
+ }
746
+ });
271
747
  }
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
748
  }
288
- )
289
- ] });
749
+ };
750
+ const handleAnimationStart = (event) => {
751
+ if (event.target === node) {
752
+ prevAnimationNameRef.current = getAnimationName(stylesRef.current);
753
+ }
754
+ };
755
+ node.addEventListener("animationstart", handleAnimationStart);
756
+ node.addEventListener("animationcancel", handleAnimationEnd);
757
+ node.addEventListener("animationend", handleAnimationEnd);
758
+ return () => {
759
+ ownerWindow.clearTimeout(timeoutId);
760
+ node.removeEventListener("animationstart", handleAnimationStart);
761
+ node.removeEventListener("animationcancel", handleAnimationEnd);
762
+ node.removeEventListener("animationend", handleAnimationEnd);
763
+ };
764
+ } else {
765
+ send("ANIMATION_END");
766
+ }
767
+ }, [node, send]);
768
+ return {
769
+ isPresent: ["mounted", "unmountSuspended"].includes(state),
770
+ ref: React.useCallback((node2) => {
771
+ stylesRef.current = node2 ? getComputedStyle(node2) : null;
772
+ setNode(node2);
773
+ }, [])
774
+ };
775
+ }
776
+ function getAnimationName(styles) {
777
+ return (styles == null ? void 0 : styles.animationName) || "none";
778
+ }
779
+ function getElementRef(element) {
780
+ var _a, _b;
781
+ let getter = (_a = Object.getOwnPropertyDescriptor(element.props, "ref")) == null ? void 0 : _a.get;
782
+ let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
783
+ if (mayWarn) {
784
+ return element.ref;
290
785
  }
291
- );
292
- Button.displayName = "Button";
786
+ getter = (_b = Object.getOwnPropertyDescriptor(element, "ref")) == null ? void 0 : _b.get;
787
+ mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning;
788
+ if (mayWarn) {
789
+ return element.props.ref;
790
+ }
791
+ return element.props.ref || element.ref;
792
+ }
793
+ var useInsertionEffect = React[" useInsertionEffect ".trim().toString()] || useLayoutEffect2;
794
+ function useControllableState({
795
+ prop,
796
+ defaultProp,
797
+ onChange = () => {
798
+ },
799
+ caller
800
+ }) {
801
+ const [uncontrolledProp, setUncontrolledProp, onChangeRef] = useUncontrolledState({
802
+ defaultProp,
803
+ onChange
804
+ });
805
+ const isControlled = prop !== void 0;
806
+ const value = isControlled ? prop : uncontrolledProp;
807
+ {
808
+ const isControlledRef = React.useRef(prop !== void 0);
809
+ React.useEffect(() => {
810
+ const wasControlled = isControlledRef.current;
811
+ if (wasControlled !== isControlled) {
812
+ const from = wasControlled ? "controlled" : "uncontrolled";
813
+ const to = isControlled ? "controlled" : "uncontrolled";
814
+ console.warn(
815
+ `${caller} is changing from ${from} to ${to}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`
816
+ );
817
+ }
818
+ isControlledRef.current = isControlled;
819
+ }, [isControlled, caller]);
820
+ }
821
+ const setValue = React.useCallback(
822
+ (nextValue) => {
823
+ var _a;
824
+ if (isControlled) {
825
+ const value2 = isFunction(nextValue) ? nextValue(prop) : nextValue;
826
+ if (value2 !== prop) {
827
+ (_a = onChangeRef.current) == null ? void 0 : _a.call(onChangeRef, value2);
828
+ }
829
+ } else {
830
+ setUncontrolledProp(nextValue);
831
+ }
832
+ },
833
+ [isControlled, prop, setUncontrolledProp, onChangeRef]
834
+ );
835
+ return [value, setValue];
836
+ }
837
+ function useUncontrolledState({
838
+ defaultProp,
839
+ onChange
840
+ }) {
841
+ const [value, setValue] = React.useState(defaultProp);
842
+ const prevValueRef = React.useRef(value);
843
+ const onChangeRef = React.useRef(onChange);
844
+ useInsertionEffect(() => {
845
+ onChangeRef.current = onChange;
846
+ }, [onChange]);
847
+ React.useEffect(() => {
848
+ var _a;
849
+ if (prevValueRef.current !== value) {
850
+ (_a = onChangeRef.current) == null ? void 0 : _a.call(onChangeRef, value);
851
+ prevValueRef.current = value;
852
+ }
853
+ }, [value, prevValueRef]);
854
+ return [value, setValue, onChangeRef];
855
+ }
856
+ function isFunction(value) {
857
+ return typeof value === "function";
858
+ }
293
859
  var useReactId = React[" useId ".trim().toString()] || (() => void 0);
294
860
  var count$1 = 0;
295
861
  function useId(deterministicId) {
@@ -1383,7 +1949,7 @@ var DialogOverlay = React.forwardRef(
1383
1949
  }
1384
1950
  );
1385
1951
  DialogOverlay.displayName = OVERLAY_NAME;
1386
- var Slot = createSlot$1("DialogOverlay.RemoveScroll");
1952
+ var Slot = /* @__PURE__ */ createSlot("DialogOverlay.RemoveScroll");
1387
1953
  var DialogOverlayImpl = React.forwardRef(
1388
1954
  (props, forwardedRef) => {
1389
1955
  const { __scopeDialog, ...overlayProps } = props;
@@ -1699,386 +2265,547 @@ function Dialog({
1699
2265
  )
1700
2266
  ] }) });
1701
2267
  }
1702
- const defaultPaginationMessages = {
1703
- previous: "Previous",
1704
- next: "Next",
1705
- page: "Page",
1706
- of: "of",
1707
- showing: "Showing {start}-{end} of {total}"
2268
+ const lightDefaultTokens = {
2269
+ // Primary colors
2270
+ colorPrimary: "#CBFF01",
2271
+ colorPrimaryHover: "#daff2a",
2272
+ colorPrimaryActive: "#a5d900",
2273
+ colorPrimaryBg: "#fdffcd",
2274
+ // Secondary color
2275
+ colorSecondary: "#00FFA3",
2276
+ // Status colors
2277
+ colorSuccess: "#1FCBAF",
2278
+ colorWarning: "#FFB800",
2279
+ colorError: "#FF4D4D",
2280
+ // Background colors (V2)
2281
+ colorBgCanvas: "#FFFFFF",
2282
+ colorBgSurface: "#fafafb",
2283
+ colorBgSurfaceSubtle: "rgba(26, 29, 31, 0.04)",
2284
+ colorBgSurfaceStrong: "rgba(26, 29, 31, 0.06)",
2285
+ colorBgFloating: "#f4f4f4",
2286
+ colorBgMask: "rgba(26, 29, 31, 0.45)",
2287
+ colorBgInset: "#eaebeb",
2288
+ colorSuccessBg: "#1fcbaf1a",
2289
+ colorWarningBg: "#ffb8001a",
2290
+ colorErrorBg: "#ff4d4d1a",
2291
+ colorSecondaryBg: "#00ffa31a",
2292
+ // Text colors
2293
+ colorText: "#1A1D1F",
2294
+ colorTextSecondary: "rgba(26, 29, 31, 0.72)",
2295
+ colorTextTertiary: "rgba(26, 29, 31, 0.6)",
2296
+ colorTextDisabled: "rgba(26, 29, 31, 0.4)",
2297
+ colorLink: "#58AFFF",
2298
+ colorTextOnPrimary: "#000000",
2299
+ // Border colors
2300
+ colorBorder: "rgba(26, 29, 31, 0.1)",
2301
+ colorBorderSecondary: "rgba(26, 29, 31, 0.06)",
2302
+ // Border radius
2303
+ borderRadius: 8,
2304
+ borderRadiusSm: 4,
2305
+ borderRadiusLg: 12,
2306
+ // Font
2307
+ fontSize: 14,
2308
+ fontSizeSm: 12,
2309
+ fontSizeLg: 16,
2310
+ fontSizeXl: 18,
2311
+ fontSizeXxl: 22,
2312
+ fontSizeXxxl: 24,
2313
+ // Spacing
2314
+ spacing: 8,
2315
+ spacingXs: 4,
2316
+ spacingSm: 8,
2317
+ spacingMd: 16,
2318
+ spacingLg: 24,
2319
+ spacingXl: 32
1708
2320
  };
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) {
2321
+ const darkDefaultTokens = {
2322
+ // Primary colors
2323
+ colorPrimary: "#CBFF01",
2324
+ colorPrimaryHover: "#daff2a",
2325
+ colorPrimaryActive: "#a5d900",
2326
+ colorPrimaryBg: "#1e2600",
2327
+ // Secondary color
2328
+ colorSecondary: "#00FFA3",
2329
+ // Status colors
2330
+ colorSuccess: "#1FCBAF",
2331
+ colorWarning: "#FFB800",
2332
+ colorError: "#FF4D4D",
2333
+ // Background colors (V2)
2334
+ colorBgCanvas: "#1A1D1F",
2335
+ colorBgSurface: "#282b2c",
2336
+ colorBgSurfaceSubtle: "rgba(255, 255, 255, 0.04)",
2337
+ colorBgSurfaceStrong: "rgba(255, 255, 255, 0.12)",
2338
+ colorBgFloating: "#313435",
2339
+ colorBgMask: "rgba(26, 29, 31, 0.6)",
2340
+ colorBgInset: "#3a3d3e",
2341
+ colorSuccessBg: "#1fcbaf26",
2342
+ colorWarningBg: "#ffb80026",
2343
+ colorErrorBg: "#ff4d4d26",
2344
+ colorSecondaryBg: "#00ffa326",
2345
+ // Text colors
2346
+ colorText: "#FFFFFF",
2347
+ colorTextSecondary: "rgba(255, 255, 255, 0.72)",
2348
+ colorTextTertiary: "rgba(255, 255, 255, 0.6)",
2349
+ colorTextDisabled: "rgba(255, 255, 255, 0.4)",
2350
+ colorLink: "#58AFFF",
2351
+ colorTextOnPrimary: "#000000",
2352
+ // Border colors
2353
+ colorBorder: "rgba(255, 255, 255, 0.1)",
2354
+ colorBorderSecondary: "rgba(255, 255, 255, 0.06)",
2355
+ // Border radius
2356
+ borderRadius: 8,
2357
+ borderRadiusSm: 4,
2358
+ borderRadiusLg: 12,
2359
+ // Font
2360
+ fontSize: 14,
2361
+ fontSizeSm: 12,
2362
+ fontSizeLg: 16,
2363
+ fontSizeXl: 18,
2364
+ fontSizeXxl: 22,
2365
+ fontSizeXxxl: 24,
2366
+ // Spacing
2367
+ spacing: 8,
2368
+ spacingXs: 4,
2369
+ spacingSm: 8,
2370
+ spacingMd: 16,
2371
+ spacingLg: 24,
2372
+ spacingXl: 32
2373
+ };
2374
+ const hueStep = 2;
2375
+ const saturationStep = 0.16;
2376
+ const saturationStep2 = 0.05;
2377
+ const brightnessStep1 = 0.05;
2378
+ const brightnessStep2 = 0.15;
2379
+ const lightColorCount = 5;
2380
+ const darkColorCount = 4;
2381
+ function hexToRgb(hex) {
2382
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
2383
+ if (!result || !result[1] || !result[2] || !result[3]) {
1755
2384
  return null;
1756
2385
  }
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;
2386
+ return {
2387
+ r: parseInt(result[1], 16),
2388
+ g: parseInt(result[2], 16),
2389
+ b: parseInt(result[3], 16)
1824
2390
  };
1825
- const getAlignClassName = (align) => {
1826
- if (!align || align === "left") return "";
1827
- return `taskon-table__header--${align}`;
2391
+ }
2392
+ function rgbToHex(rgb) {
2393
+ const toHex = (n) => {
2394
+ const hex = Math.round(Math.max(0, Math.min(255, n))).toString(16);
2395
+ return hex.length === 1 ? "0" + hex : hex;
1828
2396
  };
1829
- const getCellAlignClassName = (align) => {
1830
- if (!align || align === "left") return "";
1831
- return `taskon-table__cell--${align}`;
2397
+ return "#" + toHex(rgb.r) + toHex(rgb.g) + toHex(rgb.b);
2398
+ }
2399
+ function rgbToHsv(rgb) {
2400
+ const r = rgb.r / 255;
2401
+ const g = rgb.g / 255;
2402
+ const b = rgb.b / 255;
2403
+ const max = Math.max(r, g, b);
2404
+ const min = Math.min(r, g, b);
2405
+ const delta = max - min;
2406
+ let h = 0;
2407
+ const v = max;
2408
+ const s = max === 0 ? 0 : delta / max;
2409
+ if (delta !== 0) {
2410
+ if (max === r) {
2411
+ h = ((g - b) / delta + (g < b ? 6 : 0)) * 60;
2412
+ } else if (max === g) {
2413
+ h = ((b - r) / delta + 2) * 60;
2414
+ } else {
2415
+ h = ((r - g) / delta + 4) * 60;
2416
+ }
2417
+ }
2418
+ return { h, s, v };
2419
+ }
2420
+ function hsvToRgb(hsv) {
2421
+ const h = hsv.h / 60;
2422
+ const s = hsv.s;
2423
+ const v = hsv.v;
2424
+ const i = Math.floor(h) % 6;
2425
+ const f = h - Math.floor(h);
2426
+ const p = v * (1 - s);
2427
+ const q = v * (1 - f * s);
2428
+ const t = v * (1 - (1 - f) * s);
2429
+ let r = 0, g = 0, b = 0;
2430
+ switch (i) {
2431
+ case 0:
2432
+ r = v;
2433
+ g = t;
2434
+ b = p;
2435
+ break;
2436
+ case 1:
2437
+ r = q;
2438
+ g = v;
2439
+ b = p;
2440
+ break;
2441
+ case 2:
2442
+ r = p;
2443
+ g = v;
2444
+ b = t;
2445
+ break;
2446
+ case 3:
2447
+ r = p;
2448
+ g = q;
2449
+ b = v;
2450
+ break;
2451
+ case 4:
2452
+ r = t;
2453
+ g = p;
2454
+ b = v;
2455
+ break;
2456
+ case 5:
2457
+ r = v;
2458
+ g = p;
2459
+ b = q;
2460
+ break;
2461
+ }
2462
+ return {
2463
+ r: Math.round(r * 255),
2464
+ g: Math.round(g * 255),
2465
+ b: Math.round(b * 255)
1832
2466
  };
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
- }
2467
+ }
2468
+ function getHue(hsv, i, isLight) {
2469
+ let hue;
2470
+ if (hsv.h >= 60 && hsv.h <= 240) {
2471
+ hue = isLight ? hsv.h - hueStep * i : hsv.h + hueStep * i;
2472
+ } else {
2473
+ hue = isLight ? hsv.h + hueStep * i : hsv.h - hueStep * i;
2474
+ }
2475
+ if (hue < 0) {
2476
+ hue += 360;
2477
+ } else if (hue >= 360) {
2478
+ hue -= 360;
2479
+ }
2480
+ return hue;
2481
+ }
2482
+ function getSaturation(hsv, i, isLight) {
2483
+ if (hsv.s === 0) {
2484
+ return hsv.s;
2485
+ }
2486
+ let saturation;
2487
+ if (isLight) {
2488
+ saturation = hsv.s - saturationStep * i;
2489
+ } else {
2490
+ saturation = hsv.s + saturationStep2 * i;
2491
+ }
2492
+ if (saturation < 0.06) {
2493
+ saturation = 0.06;
2494
+ }
2495
+ if (saturation > 1) {
2496
+ saturation = 1;
2497
+ }
2498
+ return saturation;
2499
+ }
2500
+ function getValue(hsv, i, isLight) {
2501
+ let value;
2502
+ if (isLight) {
2503
+ value = hsv.v + brightnessStep1 * i;
2504
+ } else {
2505
+ value = hsv.v - brightnessStep2 * i;
2506
+ }
2507
+ if (value < 0) {
2508
+ value = 0;
2509
+ }
2510
+ if (value > 1) {
2511
+ value = 1;
2512
+ }
2513
+ return value;
2514
+ }
2515
+ function generatePalette(primaryColor) {
2516
+ const rgb = hexToRgb(primaryColor);
2517
+ if (!rgb) {
2518
+ return Array(10).fill(primaryColor);
2519
+ }
2520
+ const hsv = rgbToHsv(rgb);
2521
+ const palette = [];
2522
+ for (let i = lightColorCount; i > 0; i--) {
2523
+ const newHsv = {
2524
+ h: getHue(hsv, i, true),
2525
+ s: getSaturation(hsv, i, true),
2526
+ v: getValue(hsv, i, true)
2527
+ };
2528
+ palette.push(rgbToHex(hsvToRgb(newHsv)));
2529
+ }
2530
+ palette.push(primaryColor);
2531
+ for (let i = 1; i <= darkColorCount; i++) {
2532
+ const newHsv = {
2533
+ h: getHue(hsv, i, false),
2534
+ s: getSaturation(hsv, i, false),
2535
+ v: getValue(hsv, i, false)
1871
2536
  };
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);
2537
+ palette.push(rgbToHex(hsvToRgb(newHsv)));
2538
+ }
2539
+ return palette;
2540
+ }
2541
+ function mixColors(color1, color2, weight) {
2542
+ const rgb1 = hexToRgb(color1);
2543
+ const rgb2 = hexToRgb(color2);
2544
+ if (!rgb1 || !rgb2) return color1;
2545
+ return rgbToHex({
2546
+ r: rgb1.r + (rgb2.r - rgb1.r) * weight,
2547
+ g: rgb1.g + (rgb2.g - rgb1.g) * weight,
2548
+ b: rgb1.b + (rgb2.b - rgb1.b) * weight
1883
2549
  });
1884
- const renderBody = () => {
1885
- if (!data || data.length === 0) {
1886
- if (loading) {
1887
- return renderLoading();
1888
- }
1889
- return renderEmpty();
2550
+ }
2551
+ function withAlpha(color, alpha) {
2552
+ const rgb = hexToRgb(color);
2553
+ if (!rgb) return color;
2554
+ return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha})`;
2555
+ }
2556
+ function deriveTokens(seed, mode) {
2557
+ const derived = {};
2558
+ const isLight = mode === "light";
2559
+ if (seed.colorPrimary) {
2560
+ const palette = generatePalette(seed.colorPrimary);
2561
+ derived.colorPrimary = seed.colorPrimary;
2562
+ if (isLight) {
2563
+ derived.colorPrimaryHover = palette[4];
2564
+ derived.colorPrimaryActive = palette[6];
2565
+ derived.colorPrimaryBg = palette[0];
2566
+ } else {
2567
+ derived.colorPrimaryHover = palette[4];
2568
+ derived.colorPrimaryActive = palette[6];
2569
+ derived.colorPrimaryBg = mixColors(seed.colorPrimary, "#000000", 0.85);
1890
2570
  }
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]);
2571
+ }
2572
+ if (seed.colorSecondary) derived.colorSecondary = seed.colorSecondary;
2573
+ if (seed.colorSuccess) derived.colorSuccess = seed.colorSuccess;
2574
+ if (seed.colorWarning) derived.colorWarning = seed.colorWarning;
2575
+ if (seed.colorError) derived.colorError = seed.colorError;
2576
+ if (seed.colorLink) derived.colorLink = seed.colorLink;
2577
+ if (seed.colorText) derived.colorText = seed.colorText;
2578
+ if (seed.colorTextOnPrimary) {
2579
+ derived.colorTextOnPrimary = seed.colorTextOnPrimary;
2580
+ }
2581
+ if (seed.colorText) {
2582
+ derived.colorTextSecondary = withAlpha(seed.colorText, 0.72);
2583
+ derived.colorTextTertiary = withAlpha(seed.colorText, 0.6);
2584
+ derived.colorTextDisabled = withAlpha(seed.colorText, 0.4);
2585
+ derived.colorBorder = withAlpha(seed.colorText, 0.1);
2586
+ derived.colorBorderSecondary = withAlpha(seed.colorText, 0.06);
2587
+ }
2588
+ if (seed.colorBgBase) {
2589
+ derived.colorBgCanvas = seed.colorBgBase;
2590
+ if (seed.colorText) {
2591
+ derived.colorBgSurface = mixColors(
2592
+ seed.colorBgBase,
2593
+ seed.colorText,
2594
+ 0.06
2595
+ );
2596
+ derived.colorBgSurfaceSubtle = withAlpha(seed.colorText, 0.04);
2597
+ derived.colorBgSurfaceStrong = withAlpha(seed.colorText, 0.12);
2598
+ derived.colorBgFloating = mixColors(
2599
+ seed.colorBgBase,
2600
+ seed.colorText,
2601
+ 0.1
2602
+ );
2603
+ derived.colorBgInset = mixColors(
2604
+ seed.colorBgBase,
2605
+ seed.colorText,
2606
+ 0.14
2607
+ );
2608
+ derived.colorBgMask = isLight ? withAlpha(seed.colorText, 0.45) : withAlpha(seed.colorBgBase, 0.6);
2609
+ } else {
2610
+ derived.colorBgSurface = seed.colorBgBase;
2611
+ derived.colorBgFloating = seed.colorBgBase;
2612
+ derived.colorBgInset = seed.colorBgBase;
2613
+ }
2614
+ }
2615
+ if (seed.colorSecondary) {
2616
+ derived.colorSecondaryBg = withAlpha(seed.colorSecondary, 0.15);
2617
+ }
2618
+ if (seed.colorSuccess) {
2619
+ derived.colorSuccessBg = withAlpha(seed.colorSuccess, 0.15);
2620
+ }
2621
+ if (seed.colorWarning) {
2622
+ derived.colorWarningBg = withAlpha(seed.colorWarning, 0.15);
2623
+ }
2624
+ if (seed.colorError) {
2625
+ derived.colorErrorBg = withAlpha(seed.colorError, 0.15);
2626
+ }
2627
+ if (seed.borderRadius !== void 0) {
2628
+ derived.borderRadius = seed.borderRadius;
2629
+ derived.borderRadiusSm = Math.max(0, seed.borderRadius - 4);
2630
+ derived.borderRadiusLg = seed.borderRadius + 4;
2631
+ }
2632
+ if (seed.fontSize !== void 0) {
2633
+ derived.fontSize = seed.fontSize;
2634
+ derived.fontSizeSm = seed.fontSize - 2;
2635
+ derived.fontSizeLg = seed.fontSize + 2;
2636
+ derived.fontSizeXl = seed.fontSize + 4;
2637
+ derived.fontSizeXxl = seed.fontSize + 8;
2638
+ derived.fontSizeXxxl = seed.fontSize + 10;
2639
+ }
2640
+ if (seed.spacingBaseStep !== void 0 || seed.spacingChangeUnit !== void 0) {
2641
+ const base = Math.max(1, Number(seed.spacingBaseStep) || 1);
2642
+ const unit = Math.max(1, Number(seed.spacingChangeUnit) || 1);
2643
+ const spacingXs = base;
2644
+ const spacingSm = base + unit;
2645
+ const spacingMd = base + unit * 3;
2646
+ const spacingLg = base + unit * 5;
2647
+ const spacingXl = base + unit * 7;
2648
+ derived.spacing = spacingSm;
2649
+ derived.spacingXs = spacingXs;
2650
+ derived.spacingSm = spacingSm;
2651
+ derived.spacingMd = spacingMd;
2652
+ derived.spacingLg = spacingLg;
2653
+ derived.spacingXl = spacingXl;
2654
+ }
2655
+ return derived;
2656
+ }
2657
+ function mergeTokens(defaults, derived, override) {
1954
2658
  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
2659
+ ...defaults,
2660
+ ...derived,
2661
+ ...override
1969
2662
  };
1970
2663
  }
1971
- function useWidgetConfig(widgetId) {
1972
- const { client } = useTaskOnContext();
1973
- const [config, setConfig] = useState(null);
1974
- const [isLoading, setIsLoading] = useState(false);
1975
- const [error, setError] = useState(null);
1976
- useEffect(() => {
1977
- if (!widgetId || !client) {
1978
- setConfig(null);
1979
- setIsLoading(false);
1980
- setError(null);
1981
- return;
2664
+ function getSystemThemeMode() {
2665
+ if (typeof window === "undefined") {
2666
+ return "light";
2667
+ }
2668
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
2669
+ }
2670
+ const defaultTheme = {
2671
+ mode: "dark",
2672
+ compact: false,
2673
+ tokens: darkDefaultTokens
2674
+ };
2675
+ function toKebabCase(str) {
2676
+ return str.replace(/([A-Z])/g, "-$1").toLowerCase();
2677
+ }
2678
+ function tokensToCssVariables(tokens) {
2679
+ const cssVars = {};
2680
+ for (const [key, value] of Object.entries(tokens)) {
2681
+ const cssVarName = `--taskon-${toKebabCase(key)}`;
2682
+ if (typeof value === "number") {
2683
+ cssVars[cssVarName] = `${value}px`;
2684
+ } else {
2685
+ cssVars[cssVarName] = value;
1982
2686
  }
1983
- let cancelled = false;
1984
- setIsLoading(true);
1985
- setError(null);
1986
- const api = createWidgetApi(client);
1987
- api.getWidgetInfo(widgetId).then((info) => {
1988
- if (!cancelled) {
1989
- setConfig(parseWidgetConfig(info));
1990
- }
1991
- }).catch((err) => {
1992
- if (!cancelled) {
1993
- console.warn("[TaskOn] Failed to load widget config:", err);
1994
- setError(
1995
- err instanceof Error ? err.message : "Failed to load widget config"
1996
- );
1997
- }
1998
- }).finally(() => {
1999
- if (!cancelled) {
2000
- setIsLoading(false);
2001
- }
2002
- });
2003
- return () => {
2004
- cancelled = true;
2005
- };
2006
- }, [widgetId, client]);
2007
- return { config, isLoading, error };
2008
- }
2009
- function useResolvedWidgetConfig(widgetId) {
2010
- const { config, isLoading, error } = useWidgetConfig(widgetId);
2011
- const cloudTheme = useMemo(() => {
2012
- if (!(config == null ? void 0 : config.theme)) return void 0;
2013
- return cloudThemeToReactTheme(config.theme);
2014
- }, [config == null ? void 0 : config.theme]);
2687
+ }
2688
+ return cssVars;
2689
+ }
2690
+ function resolveTheme(config, systemMode) {
2691
+ if (!config) {
2692
+ return defaultTheme;
2693
+ }
2694
+ let resolvedMode;
2695
+ if (config.mode === "auto") {
2696
+ resolvedMode = systemMode;
2697
+ } else if (config.mode) {
2698
+ resolvedMode = config.mode;
2699
+ } else {
2700
+ resolvedMode = "dark";
2701
+ }
2702
+ const defaultTokens = resolvedMode === "light" ? lightDefaultTokens : darkDefaultTokens;
2703
+ const modeConfig = resolvedMode === "light" ? config.light : config.dark;
2704
+ const mergedSeed = {
2705
+ ...config.seed,
2706
+ ...modeConfig == null ? void 0 : modeConfig.seed
2707
+ };
2708
+ const derivedTokens = deriveTokens(mergedSeed, resolvedMode);
2709
+ const mergedMap = {
2710
+ ...config.map,
2711
+ ...modeConfig == null ? void 0 : modeConfig.map
2712
+ };
2713
+ const finalTokens = mergeTokens(defaultTokens, derivedTokens, mergedMap);
2015
2714
  return {
2016
- functionConfig: (config == null ? void 0 : config.functionConfig) ?? null,
2017
- cloudTheme,
2018
- isConfigLoading: isLoading,
2019
- configError: error
2715
+ mode: resolvedMode,
2716
+ compact: config.compact ?? false,
2717
+ tokens: finalTokens
2020
2718
  };
2021
2719
  }
2022
- function WidgetShell({
2023
- widgetId,
2024
- isConfigLoading,
2025
- cloudTheme,
2026
- themeMode,
2027
- className,
2028
- errorMessage,
2720
+ function ThemeProvider({
2721
+ theme: themeConfig,
2029
2722
  children
2030
2723
  }) {
2031
- const resolvedCloudTheme = useMemo(() => {
2032
- if (!cloudTheme) return void 0;
2033
- if (!themeMode) return cloudTheme;
2034
- return {
2035
- ...cloudTheme,
2036
- mode: themeMode
2724
+ const [portalContainer, setPortalContainer] = useState(
2725
+ null
2726
+ );
2727
+ const [systemMode, setSystemMode] = useState(
2728
+ () => getSystemThemeMode()
2729
+ );
2730
+ const effectiveMode = themeConfig == null ? void 0 : themeConfig.mode;
2731
+ useEffect(() => {
2732
+ if (effectiveMode !== "auto") {
2733
+ return;
2734
+ }
2735
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
2736
+ const handler = (e) => {
2737
+ setSystemMode(e.matches ? "dark" : "light");
2037
2738
  };
2038
- }, [cloudTheme, themeMode]);
2039
- if (widgetId && isConfigLoading) {
2040
- return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsxs("div", { className: `${className}-loading`, children: [
2041
- /* @__PURE__ */ jsx("div", { className: `${className}-loading-spinner` }),
2042
- /* @__PURE__ */ jsx("span", { children: "Loading config..." })
2043
- ] }) });
2044
- }
2045
- if (errorMessage) {
2046
- return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsx("div", { className: `${className}-error`, children: /* @__PURE__ */ jsx("span", { className: `${className}-error-message`, children: errorMessage }) }) });
2047
- }
2048
- if (resolvedCloudTheme) {
2049
- return /* @__PURE__ */ jsx(ThemeProvider, { theme: resolvedCloudTheme, children });
2050
- }
2051
- return /* @__PURE__ */ jsx(Fragment, { children });
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
- };
2739
+ mediaQuery.addEventListener("change", handler);
2740
+ return () => mediaQuery.removeEventListener("change", handler);
2741
+ }, [effectiveMode]);
2742
+ const resolvedTheme = useMemo(
2743
+ () => resolveTheme(themeConfig, systemMode),
2744
+ [themeConfig, systemMode]
2745
+ );
2746
+ const cssVariables = useMemo(
2747
+ () => tokensToCssVariables(resolvedTheme.tokens),
2748
+ [resolvedTheme.tokens]
2749
+ );
2750
+ return /* @__PURE__ */ jsx(ThemeContext.Provider, { value: resolvedTheme, children: /* @__PURE__ */ jsx(ThemePortalContainerContext.Provider, { value: portalContainer, children: /* @__PURE__ */ jsxs(
2751
+ "div",
2752
+ {
2753
+ style: cssVariables,
2754
+ "data-taskon-theme": resolvedTheme.mode,
2755
+ children: [
2756
+ /* @__PURE__ */ jsx(
2757
+ "div",
2758
+ {
2759
+ ref: setPortalContainer,
2760
+ "aria-hidden": "true",
2761
+ style: {
2762
+ position: "absolute",
2763
+ top: 0,
2764
+ left: 0,
2765
+ width: 0,
2766
+ height: 0
2767
+ }
2768
+ }
2769
+ ),
2770
+ children
2771
+ ]
2772
+ }
2773
+ ) }) });
2774
+ }
2069
2775
  export {
2070
- Button as B,
2776
+ useFocusGuards as A,
2777
+ Branch as B,
2778
+ DismissableLayer as C,
2071
2779
  Dialog as D,
2780
+ useTaskOnPortalContainer as E,
2072
2781
  FocusScope as F,
2073
- Pagination as P,
2074
- ReactRemoveScroll as R,
2075
- Table as T,
2076
- WidgetShell as W,
2077
- __variableDynamicImportRuntimeHelper as _,
2078
- useResolvedWidgetConfig as a,
2079
- useId as b,
2080
- cloudThemeToReactTheme as c,
2081
- useFocusGuards as d,
2082
- hideOthers as h,
2083
- usePagination as u
2782
+ Primitive as P,
2783
+ Root$1 as R,
2784
+ ThemeProvider as T,
2785
+ useTaskOnTheme as a,
2786
+ useWidgetLocale as b,
2787
+ useTranslation as c,
2788
+ clearLocaleCache as d,
2789
+ createLocaleLoader as e,
2790
+ createT as f,
2791
+ isSupportedLocale as g,
2792
+ useTaskOnContext as h,
2793
+ interpolate as i,
2794
+ composeRefs as j,
2795
+ createContextScope as k,
2796
+ useComposedRefs as l,
2797
+ createSlot as m,
2798
+ useControllableState as n,
2799
+ Presence as o,
2800
+ preloadWidgetLocale as p,
2801
+ composeEventHandlers as q,
2802
+ useCallbackRef$1 as r,
2803
+ Portal$1 as s,
2804
+ dispatchDiscreteCustomEvent as t,
2805
+ useTaskOnAuth as u,
2806
+ useLayoutEffect2 as v,
2807
+ TaskOnContext as w,
2808
+ useId as x,
2809
+ hideOthers as y,
2810
+ ReactRemoveScroll as z
2084
2811
  };