@windrun-huaiin/third-ui 29.2.1 → 30.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/dist/fuma/mdx/cheet-table.d.ts +13 -0
  2. package/dist/fuma/mdx/cheet-table.js +295 -0
  3. package/dist/fuma/mdx/cheet-table.mjs +293 -0
  4. package/dist/fuma/mdx/index.d.ts +1 -0
  5. package/dist/fuma/mdx/index.js +2 -0
  6. package/dist/fuma/mdx/index.mjs +1 -0
  7. package/dist/fuma/server/features/widgets.js +2 -0
  8. package/dist/fuma/server/features/widgets.mjs +2 -0
  9. package/dist/lib/fuma-schema-check-util.d.ts +1 -1
  10. package/dist/main/alert-dialog/confirm-dialog.js +1 -1
  11. package/dist/main/alert-dialog/confirm-dialog.mjs +2 -2
  12. package/dist/main/alert-dialog/dialog-loading-action.js +5 -2
  13. package/dist/main/alert-dialog/dialog-loading-action.mjs +5 -2
  14. package/dist/main/alert-dialog/dialog-styles.d.ts +4 -2
  15. package/dist/main/alert-dialog/dialog-styles.js +8 -4
  16. package/dist/main/alert-dialog/dialog-styles.mjs +7 -5
  17. package/dist/main/alert-dialog/high-priority-confirm-dialog.js +5 -5
  18. package/dist/main/alert-dialog/high-priority-confirm-dialog.mjs +6 -6
  19. package/dist/main/alert-dialog/info-dialog.js +1 -1
  20. package/dist/main/alert-dialog/info-dialog.mjs +2 -2
  21. package/dist/main/alert-dialog/undoable-confirm-dialog.js +2 -2
  22. package/dist/main/alert-dialog/undoable-confirm-dialog.mjs +3 -3
  23. package/dist/main/anime/anime-beam-frame.d.ts +3 -0
  24. package/dist/main/anime/anime-beam-frame.js +63 -0
  25. package/dist/main/anime/anime-beam-frame.mjs +61 -0
  26. package/dist/main/anime/anime-spiral-loading.d.ts +10 -0
  27. package/dist/main/anime/anime-spiral-loading.js +77 -0
  28. package/dist/main/anime/anime-spiral-loading.mjs +75 -0
  29. package/dist/main/anime/index.d.ts +2 -0
  30. package/dist/main/anime/index.js +10 -0
  31. package/dist/main/anime/index.mjs +3 -0
  32. package/dist/main/beam-frame/animate.d.ts +3 -0
  33. package/dist/main/beam-frame/animate.js +63 -0
  34. package/dist/main/beam-frame/animate.mjs +61 -0
  35. package/dist/main/beam-frame/beam-frame.d.ts +4 -0
  36. package/dist/main/beam-frame/beam-frame.js +262 -0
  37. package/dist/main/beam-frame/beam-frame.mjs +258 -0
  38. package/dist/main/beam-frame/index.d.ts +4 -0
  39. package/dist/main/beam-frame/index.js +11 -0
  40. package/dist/main/beam-frame/index.mjs +3 -0
  41. package/dist/main/beam-frame/motion.d.ts +3 -0
  42. package/dist/main/beam-frame/motion.js +61 -0
  43. package/dist/main/beam-frame/motion.mjs +59 -0
  44. package/dist/main/beam-frame/share-config.d.ts +54 -0
  45. package/dist/main/beam-frame/share-config.js +161 -0
  46. package/dist/main/beam-frame/share-config.mjs +152 -0
  47. package/dist/main/beam-frame-config.d.ts +54 -0
  48. package/dist/main/beam-frame-config.js +161 -0
  49. package/dist/main/beam-frame-config.mjs +152 -0
  50. package/dist/main/calendar/random-date-range-dialog.js +177 -51
  51. package/dist/main/calendar/random-date-range-dialog.mjs +178 -52
  52. package/dist/main/cta.js +17 -1
  53. package/dist/main/cta.mjs +18 -2
  54. package/dist/main/delayed-img.d.ts +1 -1
  55. package/dist/main/delayed-img.js +8 -5
  56. package/dist/main/delayed-img.mjs +8 -5
  57. package/dist/main/info-tooltip.js +70 -9
  58. package/dist/main/info-tooltip.mjs +70 -9
  59. package/dist/main/loading-frame/index.d.ts +1 -0
  60. package/dist/main/loading.d.ts +2 -1
  61. package/dist/main/loading.js +64 -26
  62. package/dist/main/loading.mjs +64 -26
  63. package/dist/main/motion/index.d.ts +1 -0
  64. package/dist/main/motion/index.js +9 -0
  65. package/dist/main/motion/index.mjs +2 -0
  66. package/dist/main/motion/motion-beam-frame.d.ts +3 -0
  67. package/dist/main/motion/motion-beam-frame.js +61 -0
  68. package/dist/main/motion/motion-beam-frame.mjs +59 -0
  69. package/dist/main/snake-loading-frame.d.ts +7 -3
  70. package/dist/main/snake-loading-frame.js +44 -252
  71. package/dist/main/snake-loading-frame.mjs +46 -254
  72. package/package.json +16 -5
  73. package/src/fuma/mdx/cheet-table.tsx +650 -0
  74. package/src/fuma/mdx/index.ts +1 -0
  75. package/src/fuma/server/features/widgets.tsx +2 -0
  76. package/src/main/alert-dialog/confirm-dialog.tsx +2 -1
  77. package/src/main/alert-dialog/dialog-loading-action.tsx +7 -5
  78. package/src/main/alert-dialog/dialog-styles.ts +13 -3
  79. package/src/main/alert-dialog/high-priority-confirm-dialog.tsx +26 -23
  80. package/src/main/alert-dialog/info-dialog.tsx +2 -1
  81. package/src/main/alert-dialog/undoable-confirm-dialog.tsx +18 -17
  82. package/src/main/anime/anime-beam-frame.tsx +128 -0
  83. package/src/main/anime/anime-spiral-loading.tsx +123 -0
  84. package/src/main/anime/index.ts +9 -0
  85. package/src/main/beam-frame-config.tsx +341 -0
  86. package/src/main/calendar/random-date-range-dialog.tsx +225 -69
  87. package/src/main/cta.tsx +50 -21
  88. package/src/main/delayed-img.tsx +9 -4
  89. package/src/main/info-tooltip.tsx +116 -20
  90. package/src/main/loading-frame/index.ts +4 -0
  91. package/src/main/loading.tsx +75 -24
  92. package/src/main/motion/index.ts +8 -0
  93. package/src/main/motion/motion-beam-frame.tsx +137 -0
  94. package/src/main/snake-loading-frame.tsx +95 -496
  95. package/src/styles/cta.css +21 -4
  96. package/src/styles/third-ui.css +0 -20
@@ -9,6 +9,7 @@ import '@windrun-huaiin/base-ui/lib';
9
9
  import '@windrun-huaiin/lib/utils';
10
10
  import { ZiaFolder, ZiaFile } from '../../mdx/zia-file.mjs';
11
11
  import { SunoEmbed } from '../../mdx/suno-embed.mjs';
12
+ import { CheetTable } from '../../mdx/cheet-table.mjs';
12
13
 
13
14
  const ImageGrid = lazy(() => import('../../heavy/image-grid.mjs').then((mod) => ({ default: mod.ImageGrid })));
14
15
  const ImageZoom = lazy(() => import('../../heavy/image-zoom.mjs').then((mod) => ({ default: mod.ImageZoom })));
@@ -20,6 +21,7 @@ function createWidgetMdxComponents(cdnBaseUrl, imageFallbackSrc) {
20
21
  ZiaFile,
21
22
  ZiaFolder,
22
23
  SunoEmbed,
24
+ CheetTable,
23
25
  ImageGrid: (props) => (jsx(ImageGrid, Object.assign({}, props, { cdnBaseUrl: cdnBaseUrl }))),
24
26
  ImageZoom: (props) => (jsx(ImageZoom, Object.assign({}, props, { fallbackSrc: imageFallbackSrc }))),
25
27
  };
@@ -1,5 +1,5 @@
1
1
  import { z, ZodObject } from 'zod';
2
- export declare const createDateSchema: () => z.ZodPipe<z.ZodTransform<any, any>, z.ZodString>;
2
+ export declare const createDateSchema: () => z.ZodPreprocess<z.ZodString>;
3
3
  export declare const createCommonDocsSchema: () => ZodObject<any>;
4
4
  export declare const createCommonMetaSchema: () => ZodObject<any>;
5
5
  export declare const remarkInstallOptions: {
@@ -37,7 +37,7 @@ function ConfirmDialog({ open, onOpenChange, type = 'normal', title, description
37
37
  const handleClose = () => {
38
38
  onOpenChange(false);
39
39
  };
40
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ui.AlertDialog, { open: open, onOpenChange: onOpenChange, children: jsxRuntime.jsxs(ui.AlertDialogContent, { className: utils.cn(dialogStyles.dialogContentClass, typeClass.content), overlayClassName: dialogStyles.dialogThemedOverlayClass, onOverlayClick: handleClose, children: [jsxRuntime.jsxs("div", { className: dialogStyles.dialogHeaderClass, children: [jsxRuntime.jsx(ui.AlertDialogTitle, { asChild: true, children: jsxRuntime.jsxs("div", { className: dialogStyles.dialogTitleClass, children: [jsxRuntime.jsx("span", { className: utils.cn('inline-flex size-9 shrink-0 items-center justify-center rounded-full ring-1', typeClass.iconWrap), children: jsxRuntime.jsx(Icon, { className: utils.cn('size-5', typeClass.icon) }) }), jsxRuntime.jsx("span", { className: "min-w-0 truncate", children: title })] }) }), jsxRuntime.jsx("button", { type: "button", className: dialogStyles.closeButtonClass, onClick: handleClose, "aria-label": "Close", children: jsxRuntime.jsx(icons.XIcon, { className: "size-4" }) })] }), jsxRuntime.jsx(ui.AlertDialogDescription, { className: dialogStyles.dialogDescriptionClass, children: description }), jsxRuntime.jsxs("div", { className: dialogStyles.dialogFooterClass, children: [jsxRuntime.jsx(ui.AlertDialogCancel, { className: cancelButtonClass, onClick: handleCancel, children: cancelText }), jsxRuntime.jsx(ui.AlertDialogAction, { className: confirmButtonClass, onClick: () => {
40
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ui.AlertDialog, { open: open, onOpenChange: onOpenChange, children: jsxRuntime.jsxs(ui.AlertDialogContent, { className: utils.cn(dialogStyles.dialogContentClass, typeClass.content), overlayClassName: dialogStyles.dialogThemedOverlayClass, onOverlayClick: handleClose, children: [jsxRuntime.jsxs("div", { className: dialogStyles.dialogHeaderClass, children: [jsxRuntime.jsx(ui.AlertDialogTitle, { asChild: true, children: jsxRuntime.jsxs("div", { className: dialogStyles.dialogTitleClass, children: [jsxRuntime.jsx("span", { className: utils.cn('inline-flex size-9 shrink-0 items-center justify-center rounded-full ring-1', typeClass.iconWrap), children: jsxRuntime.jsx(Icon, { className: utils.cn('size-5', typeClass.icon) }) }), jsxRuntime.jsx("span", { className: dialogStyles.dialogTitleTextClass, children: title })] }) }), jsxRuntime.jsx("button", { type: "button", className: dialogStyles.closeButtonClass, onClick: handleClose, "aria-label": "Close", children: jsxRuntime.jsx(icons.XIcon, { className: "size-4" }) })] }), jsxRuntime.jsx(ui.AlertDialogDescription, { className: dialogStyles.dialogDescriptionClass, children: description }), jsxRuntime.jsxs("div", { className: dialogStyles.dialogFooterClass, children: [jsxRuntime.jsx(ui.AlertDialogCancel, { className: cancelButtonClass, onClick: handleCancel, children: cancelText }), jsxRuntime.jsx(ui.AlertDialogAction, { className: confirmButtonClass, onClick: () => {
41
41
  void runDialogAction('confirm', onConfirm);
42
42
  }, children: confirmText })] })] }) }), dialogLoading] }));
43
43
  }
@@ -4,7 +4,7 @@ import { CircleAlertIcon, CircleQuestionMarkIcon, XIcon } from '@windrun-huaiin/
4
4
  import { themeBgColor, themeIconColor } from '@windrun-huaiin/base-ui/lib';
5
5
  import { AlertDialog, AlertDialogContent, AlertDialogTitle, AlertDialogDescription, AlertDialogCancel, AlertDialogAction } from '@windrun-huaiin/base-ui/ui';
6
6
  import { cn } from '@windrun-huaiin/lib/utils';
7
- import { dangerButtonClass, primaryButtonClass, secondaryButtonClass, dialogThemedOverlayClass, dialogHeaderClass, dialogTitleClass, closeButtonClass, dialogDescriptionClass, dialogFooterClass, dialogContentClass } from './dialog-styles.mjs';
7
+ import { dangerButtonClass, primaryButtonClass, secondaryButtonClass, dialogThemedOverlayClass, dialogHeaderClass, dialogTitleClass, dialogTitleTextClass, closeButtonClass, dialogDescriptionClass, dialogFooterClass, dialogContentClass } from './dialog-styles.mjs';
8
8
  import { useDialogLoadingAction } from './dialog-loading-action.mjs';
9
9
 
10
10
  const confirmTypeClassMap = {
@@ -35,7 +35,7 @@ function ConfirmDialog({ open, onOpenChange, type = 'normal', title, description
35
35
  const handleClose = () => {
36
36
  onOpenChange(false);
37
37
  };
38
- return (jsxs(Fragment, { children: [jsx(AlertDialog, { open: open, onOpenChange: onOpenChange, children: jsxs(AlertDialogContent, { className: cn(dialogContentClass, typeClass.content), overlayClassName: dialogThemedOverlayClass, onOverlayClick: handleClose, children: [jsxs("div", { className: dialogHeaderClass, children: [jsx(AlertDialogTitle, { asChild: true, children: jsxs("div", { className: dialogTitleClass, children: [jsx("span", { className: cn('inline-flex size-9 shrink-0 items-center justify-center rounded-full ring-1', typeClass.iconWrap), children: jsx(Icon, { className: cn('size-5', typeClass.icon) }) }), jsx("span", { className: "min-w-0 truncate", children: title })] }) }), jsx("button", { type: "button", className: closeButtonClass, onClick: handleClose, "aria-label": "Close", children: jsx(XIcon, { className: "size-4" }) })] }), jsx(AlertDialogDescription, { className: dialogDescriptionClass, children: description }), jsxs("div", { className: dialogFooterClass, children: [jsx(AlertDialogCancel, { className: cancelButtonClass, onClick: handleCancel, children: cancelText }), jsx(AlertDialogAction, { className: confirmButtonClass, onClick: () => {
38
+ return (jsxs(Fragment, { children: [jsx(AlertDialog, { open: open, onOpenChange: onOpenChange, children: jsxs(AlertDialogContent, { className: cn(dialogContentClass, typeClass.content), overlayClassName: dialogThemedOverlayClass, onOverlayClick: handleClose, children: [jsxs("div", { className: dialogHeaderClass, children: [jsx(AlertDialogTitle, { asChild: true, children: jsxs("div", { className: dialogTitleClass, children: [jsx("span", { className: cn('inline-flex size-9 shrink-0 items-center justify-center rounded-full ring-1', typeClass.iconWrap), children: jsx(Icon, { className: cn('size-5', typeClass.icon) }) }), jsx("span", { className: dialogTitleTextClass, children: title })] }) }), jsx("button", { type: "button", className: closeButtonClass, onClick: handleClose, "aria-label": "Close", children: jsx(XIcon, { className: "size-4" }) })] }), jsx(AlertDialogDescription, { className: dialogDescriptionClass, children: description }), jsxs("div", { className: dialogFooterClass, children: [jsx(AlertDialogCancel, { className: cancelButtonClass, onClick: handleCancel, children: cancelText }), jsx(AlertDialogAction, { className: confirmButtonClass, onClick: () => {
39
39
  void runDialogAction('confirm', onConfirm);
40
40
  }, children: confirmText })] })] }) }), dialogLoading] }));
41
41
  }
@@ -6,6 +6,7 @@ var jsxRuntime = require('react/jsx-runtime');
6
6
  var React = require('react');
7
7
  var reactDom = require('react-dom');
8
8
  var loading = require('../loading.js');
9
+ var dialogStyles = require('./dialog-styles.js');
9
10
 
10
11
  function useDialogLoadingAction({ loadingActions, loadingFullPage = false, onOpenChange, }) {
11
12
  const [mounted, setMounted] = React.useState(false);
@@ -14,15 +15,17 @@ function useDialogLoadingAction({ loadingActions, loadingFullPage = false, onOpe
14
15
  setMounted(true);
15
16
  }, []);
16
17
  const runDialogAction = React.useCallback((action, handler) => tslib.__awaiter(this, void 0, void 0, function* () {
17
- onOpenChange(false);
18
18
  if (!handler) {
19
+ onOpenChange(false);
19
20
  return;
20
21
  }
21
22
  if (!(loadingActions === null || loadingActions === void 0 ? void 0 : loadingActions.includes(action))) {
23
+ onOpenChange(false);
22
24
  yield handler();
23
25
  return;
24
26
  }
25
27
  setLoading(true);
28
+ onOpenChange(false);
26
29
  try {
27
30
  yield handler();
28
31
  }
@@ -31,7 +34,7 @@ function useDialogLoadingAction({ loadingActions, loadingFullPage = false, onOpe
31
34
  }
32
35
  }), [loadingActions, onOpenChange]);
33
36
  const dialogLoading = mounted && loading$1
34
- ? reactDom.createPortal(loadingFullPage ? (jsxRuntime.jsx("div", { className: "fixed inset-0 z-10000", children: jsxRuntime.jsx(loading.Loading, { className: "h-full w-full" }) })) : (jsxRuntime.jsx("div", { className: "pointer-events-none fixed inset-0 z-10000 flex items-center justify-center p-4", children: jsxRuntime.jsx("div", { className: "pointer-events-auto overflow-hidden rounded-[28px] bg-neutral-50/58 shadow-[0_18px_56px_rgba(15,23,42,0.14)] backdrop-blur-md dark:bg-neutral-900/58 dark:shadow-[0_18px_56px_rgba(0,0,0,0.34)]", children: jsxRuntime.jsx(loading.Loading, { compact: true, label: "Loading", className: "min-h-[250px] w-[min(22rem,calc(100vw-2rem))] bg-transparent", labelClassName: "text-foreground" }) }) })), document.body)
37
+ ? reactDom.createPortal(loadingFullPage ? (jsxRuntime.jsx("div", { className: "fixed inset-0 z-10000", children: jsxRuntime.jsx(loading.Loading, { className: "h-full w-full" }) })) : (jsxRuntime.jsx("div", { className: "fixed inset-0 z-10000", children: jsxRuntime.jsx("div", { className: dialogStyles.dialogLoadingContentClass, children: jsxRuntime.jsx(loading.Loading, { compact: true, label: "Loading", className: "min-h-[220px] w-fit max-w-full rounded-none bg-transparent px-0 py-0 dark:bg-transparent", labelClassName: "text-foreground" }) }) })), document.body)
35
38
  : null;
36
39
  return {
37
40
  dialogLoading,
@@ -4,6 +4,7 @@ import { jsx } from 'react/jsx-runtime';
4
4
  import React__default from 'react';
5
5
  import { createPortal } from 'react-dom';
6
6
  import { Loading } from '../loading.mjs';
7
+ import { dialogLoadingContentClass } from './dialog-styles.mjs';
7
8
 
8
9
  function useDialogLoadingAction({ loadingActions, loadingFullPage = false, onOpenChange, }) {
9
10
  const [mounted, setMounted] = React__default.useState(false);
@@ -12,15 +13,17 @@ function useDialogLoadingAction({ loadingActions, loadingFullPage = false, onOpe
12
13
  setMounted(true);
13
14
  }, []);
14
15
  const runDialogAction = React__default.useCallback((action, handler) => __awaiter(this, void 0, void 0, function* () {
15
- onOpenChange(false);
16
16
  if (!handler) {
17
+ onOpenChange(false);
17
18
  return;
18
19
  }
19
20
  if (!(loadingActions === null || loadingActions === void 0 ? void 0 : loadingActions.includes(action))) {
21
+ onOpenChange(false);
20
22
  yield handler();
21
23
  return;
22
24
  }
23
25
  setLoading(true);
26
+ onOpenChange(false);
24
27
  try {
25
28
  yield handler();
26
29
  }
@@ -29,7 +32,7 @@ function useDialogLoadingAction({ loadingActions, loadingFullPage = false, onOpe
29
32
  }
30
33
  }), [loadingActions, onOpenChange]);
31
34
  const dialogLoading = mounted && loading
32
- ? createPortal(loadingFullPage ? (jsx("div", { className: "fixed inset-0 z-10000", children: jsx(Loading, { className: "h-full w-full" }) })) : (jsx("div", { className: "pointer-events-none fixed inset-0 z-10000 flex items-center justify-center p-4", children: jsx("div", { className: "pointer-events-auto overflow-hidden rounded-[28px] bg-neutral-50/58 shadow-[0_18px_56px_rgba(15,23,42,0.14)] backdrop-blur-md dark:bg-neutral-900/58 dark:shadow-[0_18px_56px_rgba(0,0,0,0.34)]", children: jsx(Loading, { compact: true, label: "Loading", className: "min-h-[250px] w-[min(22rem,calc(100vw-2rem))] bg-transparent", labelClassName: "text-foreground" }) }) })), document.body)
35
+ ? createPortal(loadingFullPage ? (jsx("div", { className: "fixed inset-0 z-10000", children: jsx(Loading, { className: "h-full w-full" }) })) : (jsx("div", { className: "fixed inset-0 z-10000", children: jsx("div", { className: dialogLoadingContentClass, children: jsx(Loading, { compact: true, label: "Loading", className: "min-h-[220px] w-fit max-w-full rounded-none bg-transparent px-0 py-0 dark:bg-transparent", labelClassName: "text-foreground" }) }) })), document.body)
33
36
  : null;
34
37
  return {
35
38
  dialogLoading,
@@ -1,9 +1,11 @@
1
1
  export declare const dialogSurfaceClass: string;
2
2
  export declare const dialogThemedOverlayClass: string;
3
3
  export declare const dialogContentClass: string;
4
+ export declare const dialogLoadingContentClass: string;
4
5
  export declare const dialogHeaderClass = "flex items-start justify-between gap-4";
5
- export declare const dialogTitleClass = "flex min-w-0 items-center gap-2 text-lg font-bold leading-tight text-neutral-950 dark:text-neutral-50";
6
- export declare const dialogDescriptionClass = "mt-3 text-sm font-medium leading-relaxed text-neutral-600 dark:text-neutral-300";
6
+ export declare const dialogTitleClass = "flex min-w-0 flex-1 items-center gap-2 text-lg font-bold leading-tight text-neutral-950 dark:text-neutral-50";
7
+ export declare const dialogTitleTextClass = "min-w-0 flex-1 line-clamp-2 break-words";
8
+ export declare const dialogDescriptionClass = "mt-3 break-words text-sm font-medium leading-relaxed text-neutral-600 dark:text-neutral-300";
7
9
  export declare const dialogFooterClass = "mt-6 flex flex-col-reverse gap-2 sm:flex-row sm:justify-end";
8
10
  export declare const closeButtonClass = "inline-flex size-8 shrink-0 items-center justify-center rounded-full text-neutral-400 transition hover:bg-neutral-100 hover:text-neutral-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-400 dark:hover:bg-neutral-800 dark:hover:text-neutral-200";
9
11
  export declare const secondaryButtonClass = "inline-flex min-h-10 items-center justify-center rounded-full border border-neutral-300 bg-white px-5 py-2 text-sm font-semibold text-neutral-700 transition hover:bg-neutral-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-400 disabled:pointer-events-none disabled:opacity-60 dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-200 dark:hover:bg-neutral-800";
@@ -4,12 +4,14 @@
4
4
  var lib = require('@windrun-huaiin/base-ui/lib');
5
5
  var utils = require('@windrun-huaiin/lib/utils');
6
6
 
7
- const dialogSurfaceClass = utils.cn('w-[calc(100vw-2rem)] max-w-md rounded-2xl border bg-white p-5 text-neutral-950 shadow-2xl outline-none dark:bg-neutral-950 dark:text-neutral-50', 'border-neutral-200 dark:border-neutral-800');
7
+ const dialogSurfaceClass = utils.cn('min-h-[240px] w-[calc(100vw-2rem)] max-w-md rounded-2xl border bg-white p-5 text-neutral-950 shadow-2xl outline-none dark:bg-neutral-950 dark:text-neutral-50', 'border-neutral-200 dark:border-neutral-800');
8
8
  const dialogThemedOverlayClass = utils.cn(lib.themeMainBgColor, 'opacity-90 backdrop-blur-[2px] dark:opacity-85');
9
9
  const dialogContentClass = utils.cn('fixed left-1/2 top-1/2 z-50 -translate-x-1/2 -translate-y-1/2', dialogSurfaceClass);
10
+ const dialogLoadingContentClass = utils.cn('fixed left-1/2 top-1/2 z-10000 -translate-x-1/2 -translate-y-1/2', dialogSurfaceClass, 'flex items-center justify-center overflow-hidden animate-in fade-in-0 zoom-in-95 duration-150');
10
11
  const dialogHeaderClass = 'flex items-start justify-between gap-4';
11
- const dialogTitleClass = 'flex min-w-0 items-center gap-2 text-lg font-bold leading-tight text-neutral-950 dark:text-neutral-50';
12
- const dialogDescriptionClass = 'mt-3 text-sm font-medium leading-relaxed text-neutral-600 dark:text-neutral-300';
12
+ const dialogTitleClass = 'flex min-w-0 flex-1 items-center gap-2 text-lg font-bold leading-tight text-neutral-950 dark:text-neutral-50';
13
+ const dialogTitleTextClass = 'min-w-0 flex-1 line-clamp-2 break-words';
14
+ const dialogDescriptionClass = 'mt-3 break-words text-sm font-medium leading-relaxed text-neutral-600 dark:text-neutral-300';
13
15
  const dialogFooterClass = 'mt-6 flex flex-col-reverse gap-2 sm:flex-row sm:justify-end';
14
16
  const closeButtonClass = 'inline-flex size-8 shrink-0 items-center justify-center rounded-full text-neutral-400 transition hover:bg-neutral-100 hover:text-neutral-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-400 dark:hover:bg-neutral-800 dark:hover:text-neutral-200';
15
17
  const secondaryButtonClass = 'inline-flex min-h-10 items-center justify-center rounded-full border border-neutral-300 bg-white px-5 py-2 text-sm font-semibold text-neutral-700 transition hover:bg-neutral-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-400 disabled:pointer-events-none disabled:opacity-60 dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-200 dark:hover:bg-neutral-800';
@@ -17,7 +19,7 @@ const primaryButtonClass = utils.cn('inline-flex min-h-10 items-center justify-c
17
19
  const subtlePrimaryButtonClass = utils.cn('inline-flex min-h-10 items-center justify-center rounded-full border px-5 py-2 text-sm font-bold transition hover:brightness-95 focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-60', lib.themeBgColor, lib.themeBorderColor, lib.themeIconColor, lib.themeRingColor);
18
20
  const dangerButtonClass = 'inline-flex min-h-10 items-center justify-center rounded-full bg-red-600 px-5 py-2 text-sm font-bold text-white shadow-sm transition hover:bg-red-700 hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-red-500 disabled:pointer-events-none disabled:opacity-60 dark:bg-red-600 dark:hover:bg-red-500';
19
21
  const highPriorityTitleClass = utils.cn('flex min-w-0 items-center gap-2 text-lg font-bold leading-tight', lib.themeIconColor);
20
- const highPrioritySurfaceClass = utils.cn(dialogSurfaceClass, 'backdrop-blur-md ring-4 animate-in zoom-in-95 duration-300', lib.themeBorderColor, lib.themeRingColor);
22
+ const highPrioritySurfaceClass = utils.cn(dialogSurfaceClass, 'flex flex-col', 'backdrop-blur-md ring-4 animate-in zoom-in-95 duration-300', lib.themeBorderColor, lib.themeRingColor);
21
23
 
22
24
  exports.closeButtonClass = closeButtonClass;
23
25
  exports.dangerButtonClass = dangerButtonClass;
@@ -25,9 +27,11 @@ exports.dialogContentClass = dialogContentClass;
25
27
  exports.dialogDescriptionClass = dialogDescriptionClass;
26
28
  exports.dialogFooterClass = dialogFooterClass;
27
29
  exports.dialogHeaderClass = dialogHeaderClass;
30
+ exports.dialogLoadingContentClass = dialogLoadingContentClass;
28
31
  exports.dialogSurfaceClass = dialogSurfaceClass;
29
32
  exports.dialogThemedOverlayClass = dialogThemedOverlayClass;
30
33
  exports.dialogTitleClass = dialogTitleClass;
34
+ exports.dialogTitleTextClass = dialogTitleTextClass;
31
35
  exports.highPrioritySurfaceClass = highPrioritySurfaceClass;
32
36
  exports.highPriorityTitleClass = highPriorityTitleClass;
33
37
  exports.primaryButtonClass = primaryButtonClass;
@@ -2,12 +2,14 @@
2
2
  import { themeMainBgColor, themeButtonGradientClass, themeButtonGradientHoverClass, themeRingColor, themeBgColor, themeBorderColor, themeIconColor } from '@windrun-huaiin/base-ui/lib';
3
3
  import { cn } from '@windrun-huaiin/lib/utils';
4
4
 
5
- const dialogSurfaceClass = cn('w-[calc(100vw-2rem)] max-w-md rounded-2xl border bg-white p-5 text-neutral-950 shadow-2xl outline-none dark:bg-neutral-950 dark:text-neutral-50', 'border-neutral-200 dark:border-neutral-800');
5
+ const dialogSurfaceClass = cn('min-h-[240px] w-[calc(100vw-2rem)] max-w-md rounded-2xl border bg-white p-5 text-neutral-950 shadow-2xl outline-none dark:bg-neutral-950 dark:text-neutral-50', 'border-neutral-200 dark:border-neutral-800');
6
6
  const dialogThemedOverlayClass = cn(themeMainBgColor, 'opacity-90 backdrop-blur-[2px] dark:opacity-85');
7
7
  const dialogContentClass = cn('fixed left-1/2 top-1/2 z-50 -translate-x-1/2 -translate-y-1/2', dialogSurfaceClass);
8
+ const dialogLoadingContentClass = cn('fixed left-1/2 top-1/2 z-10000 -translate-x-1/2 -translate-y-1/2', dialogSurfaceClass, 'flex items-center justify-center overflow-hidden animate-in fade-in-0 zoom-in-95 duration-150');
8
9
  const dialogHeaderClass = 'flex items-start justify-between gap-4';
9
- const dialogTitleClass = 'flex min-w-0 items-center gap-2 text-lg font-bold leading-tight text-neutral-950 dark:text-neutral-50';
10
- const dialogDescriptionClass = 'mt-3 text-sm font-medium leading-relaxed text-neutral-600 dark:text-neutral-300';
10
+ const dialogTitleClass = 'flex min-w-0 flex-1 items-center gap-2 text-lg font-bold leading-tight text-neutral-950 dark:text-neutral-50';
11
+ const dialogTitleTextClass = 'min-w-0 flex-1 line-clamp-2 break-words';
12
+ const dialogDescriptionClass = 'mt-3 break-words text-sm font-medium leading-relaxed text-neutral-600 dark:text-neutral-300';
11
13
  const dialogFooterClass = 'mt-6 flex flex-col-reverse gap-2 sm:flex-row sm:justify-end';
12
14
  const closeButtonClass = 'inline-flex size-8 shrink-0 items-center justify-center rounded-full text-neutral-400 transition hover:bg-neutral-100 hover:text-neutral-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-400 dark:hover:bg-neutral-800 dark:hover:text-neutral-200';
13
15
  const secondaryButtonClass = 'inline-flex min-h-10 items-center justify-center rounded-full border border-neutral-300 bg-white px-5 py-2 text-sm font-semibold text-neutral-700 transition hover:bg-neutral-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-400 disabled:pointer-events-none disabled:opacity-60 dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-200 dark:hover:bg-neutral-800';
@@ -15,6 +17,6 @@ const primaryButtonClass = cn('inline-flex min-h-10 items-center justify-center
15
17
  const subtlePrimaryButtonClass = cn('inline-flex min-h-10 items-center justify-center rounded-full border px-5 py-2 text-sm font-bold transition hover:brightness-95 focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-60', themeBgColor, themeBorderColor, themeIconColor, themeRingColor);
16
18
  const dangerButtonClass = 'inline-flex min-h-10 items-center justify-center rounded-full bg-red-600 px-5 py-2 text-sm font-bold text-white shadow-sm transition hover:bg-red-700 hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-red-500 disabled:pointer-events-none disabled:opacity-60 dark:bg-red-600 dark:hover:bg-red-500';
17
19
  const highPriorityTitleClass = cn('flex min-w-0 items-center gap-2 text-lg font-bold leading-tight', themeIconColor);
18
- const highPrioritySurfaceClass = cn(dialogSurfaceClass, 'backdrop-blur-md ring-4 animate-in zoom-in-95 duration-300', themeBorderColor, themeRingColor);
20
+ const highPrioritySurfaceClass = cn(dialogSurfaceClass, 'flex flex-col', 'backdrop-blur-md ring-4 animate-in zoom-in-95 duration-300', themeBorderColor, themeRingColor);
19
21
 
20
- export { closeButtonClass, dangerButtonClass, dialogContentClass, dialogDescriptionClass, dialogFooterClass, dialogHeaderClass, dialogSurfaceClass, dialogThemedOverlayClass, dialogTitleClass, highPrioritySurfaceClass, highPriorityTitleClass, primaryButtonClass, secondaryButtonClass, subtlePrimaryButtonClass };
22
+ export { closeButtonClass, dangerButtonClass, dialogContentClass, dialogDescriptionClass, dialogFooterClass, dialogHeaderClass, dialogLoadingContentClass, dialogSurfaceClass, dialogThemedOverlayClass, dialogTitleClass, dialogTitleTextClass, highPrioritySurfaceClass, highPriorityTitleClass, primaryButtonClass, secondaryButtonClass, subtlePrimaryButtonClass };
@@ -22,11 +22,11 @@ function HighPriorityConfirmDialog({ open, onOpenChange, onCancel, onConfirm, ti
22
22
  const handleClose = () => {
23
23
  onOpenChange(false);
24
24
  };
25
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [open && reactDom.createPortal(jsxRuntime.jsx("div", { className: "fixed inset-0 z-10000 flex items-center justify-center bg-black/60 backdrop-blur-sm animate-in fade-in duration-300", children: jsxRuntime.jsxs("div", { className: utils.cn(dialogStyles.highPrioritySurfaceClass, "scale-100"), role: "dialog", "aria-modal": "true", onClick: (e) => e.stopPropagation(), children: [jsxRuntime.jsxs("div", { className: dialogStyles.dialogHeaderClass, children: [jsxRuntime.jsxs("h3", { className: dialogStyles.highPriorityTitleClass, children: [jsxRuntime.jsx("span", { className: utils.cn('inline-flex size-9 shrink-0 items-center justify-center rounded-full ring-1', lib.themeBgColor, lib.themeBorderColor), children: jsxRuntime.jsx(icons.FAQSIcon, { className: utils.cn('size-5', lib.themeIconColor) }) }), jsxRuntime.jsx("span", { className: "min-w-0 truncate", children: title })] }), jsxRuntime.jsx("button", { type: "button", className: dialogStyles.closeButtonClass, onClick: handleClose, "aria-label": "Close", children: jsxRuntime.jsx(icons.XIcon, { className: "size-4" }) })] }), jsxRuntime.jsx("div", { className: dialogStyles.dialogDescriptionClass, children: description }), jsxRuntime.jsxs("div", { className: dialogStyles.dialogFooterClass, children: [jsxRuntime.jsx("button", { type: "button", onClick: () => {
26
- void runDialogAction('cancel', onCancel);
27
- }, className: dialogStyles.secondaryButtonClass, children: cancelText }), jsxRuntime.jsx("button", { type: "button", onClick: () => {
28
- void runDialogAction('confirm', onConfirm);
29
- }, className: utils.cn(dialogStyles.primaryButtonClass, "hover:scale-105 active:scale-95"), children: confirmText })] })] }) }), document.body), dialogLoading] }));
25
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [open && reactDom.createPortal(jsxRuntime.jsx("div", { className: "fixed inset-0 z-10000 flex items-center justify-center bg-black/60 backdrop-blur-sm animate-in fade-in duration-300", children: jsxRuntime.jsxs("div", { className: utils.cn(dialogStyles.highPrioritySurfaceClass, "scale-100"), role: "dialog", "aria-modal": "true", onClick: (e) => e.stopPropagation(), children: [jsxRuntime.jsxs("div", { className: dialogStyles.dialogHeaderClass, children: [jsxRuntime.jsxs("h3", { className: dialogStyles.highPriorityTitleClass, children: [jsxRuntime.jsx("span", { className: utils.cn('inline-flex size-9 shrink-0 items-center justify-center rounded-full ring-1', lib.themeBgColor, lib.themeBorderColor), children: jsxRuntime.jsx(icons.FAQSIcon, { className: utils.cn('size-5', lib.themeIconColor) }) }), jsxRuntime.jsx("span", { className: dialogStyles.dialogTitleTextClass, children: title })] }), jsxRuntime.jsx("button", { type: "button", className: dialogStyles.closeButtonClass, onClick: handleClose, "aria-label": "Close", children: jsxRuntime.jsx(icons.XIcon, { className: "size-4" }) })] }), jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1 flex-col", children: [jsxRuntime.jsx("div", { className: dialogStyles.dialogDescriptionClass, children: description }), jsxRuntime.jsxs("div", { className: utils.cn(dialogStyles.dialogFooterClass, 'mt-auto'), children: [jsxRuntime.jsx("button", { type: "button", onClick: () => {
26
+ void runDialogAction('cancel', onCancel);
27
+ }, className: dialogStyles.secondaryButtonClass, children: cancelText }), jsxRuntime.jsx("button", { type: "button", onClick: () => {
28
+ void runDialogAction('confirm', onConfirm);
29
+ }, className: utils.cn(dialogStyles.primaryButtonClass, "hover:scale-105 active:scale-95"), children: confirmText })] })] })] }) }), document.body), dialogLoading] }));
30
30
  }
31
31
 
32
32
  exports.HighPriorityConfirmDialog = HighPriorityConfirmDialog;
@@ -4,7 +4,7 @@ import { useState, useEffect } from 'react';
4
4
  import { createPortal } from 'react-dom';
5
5
  import { FAQSIcon, XIcon } from '@windrun-huaiin/base-ui/icons';
6
6
  import { cn } from '@windrun-huaiin/lib/utils';
7
- import { dialogHeaderClass, highPriorityTitleClass, closeButtonClass, dialogDescriptionClass, dialogFooterClass, secondaryButtonClass, primaryButtonClass, highPrioritySurfaceClass } from './dialog-styles.mjs';
7
+ import { dialogHeaderClass, highPriorityTitleClass, dialogTitleTextClass, closeButtonClass, dialogDescriptionClass, secondaryButtonClass, primaryButtonClass, dialogFooterClass, highPrioritySurfaceClass } from './dialog-styles.mjs';
8
8
  import { themeIconColor, themeBgColor, themeBorderColor } from '@windrun-huaiin/base-ui/lib';
9
9
  import { useDialogLoadingAction } from './dialog-loading-action.mjs';
10
10
 
@@ -20,11 +20,11 @@ function HighPriorityConfirmDialog({ open, onOpenChange, onCancel, onConfirm, ti
20
20
  const handleClose = () => {
21
21
  onOpenChange(false);
22
22
  };
23
- return (jsxs(Fragment, { children: [open && createPortal(jsx("div", { className: "fixed inset-0 z-10000 flex items-center justify-center bg-black/60 backdrop-blur-sm animate-in fade-in duration-300", children: jsxs("div", { className: cn(highPrioritySurfaceClass, "scale-100"), role: "dialog", "aria-modal": "true", onClick: (e) => e.stopPropagation(), children: [jsxs("div", { className: dialogHeaderClass, children: [jsxs("h3", { className: highPriorityTitleClass, children: [jsx("span", { className: cn('inline-flex size-9 shrink-0 items-center justify-center rounded-full ring-1', themeBgColor, themeBorderColor), children: jsx(FAQSIcon, { className: cn('size-5', themeIconColor) }) }), jsx("span", { className: "min-w-0 truncate", children: title })] }), jsx("button", { type: "button", className: closeButtonClass, onClick: handleClose, "aria-label": "Close", children: jsx(XIcon, { className: "size-4" }) })] }), jsx("div", { className: dialogDescriptionClass, children: description }), jsxs("div", { className: dialogFooterClass, children: [jsx("button", { type: "button", onClick: () => {
24
- void runDialogAction('cancel', onCancel);
25
- }, className: secondaryButtonClass, children: cancelText }), jsx("button", { type: "button", onClick: () => {
26
- void runDialogAction('confirm', onConfirm);
27
- }, className: cn(primaryButtonClass, "hover:scale-105 active:scale-95"), children: confirmText })] })] }) }), document.body), dialogLoading] }));
23
+ return (jsxs(Fragment, { children: [open && createPortal(jsx("div", { className: "fixed inset-0 z-10000 flex items-center justify-center bg-black/60 backdrop-blur-sm animate-in fade-in duration-300", children: jsxs("div", { className: cn(highPrioritySurfaceClass, "scale-100"), role: "dialog", "aria-modal": "true", onClick: (e) => e.stopPropagation(), children: [jsxs("div", { className: dialogHeaderClass, children: [jsxs("h3", { className: highPriorityTitleClass, children: [jsx("span", { className: cn('inline-flex size-9 shrink-0 items-center justify-center rounded-full ring-1', themeBgColor, themeBorderColor), children: jsx(FAQSIcon, { className: cn('size-5', themeIconColor) }) }), jsx("span", { className: dialogTitleTextClass, children: title })] }), jsx("button", { type: "button", className: closeButtonClass, onClick: handleClose, "aria-label": "Close", children: jsx(XIcon, { className: "size-4" }) })] }), jsxs("div", { className: "flex min-h-0 flex-1 flex-col", children: [jsx("div", { className: dialogDescriptionClass, children: description }), jsxs("div", { className: cn(dialogFooterClass, 'mt-auto'), children: [jsx("button", { type: "button", onClick: () => {
24
+ void runDialogAction('cancel', onCancel);
25
+ }, className: secondaryButtonClass, children: cancelText }), jsx("button", { type: "button", onClick: () => {
26
+ void runDialogAction('confirm', onConfirm);
27
+ }, className: cn(primaryButtonClass, "hover:scale-105 active:scale-95"), children: confirmText })] })] })] }) }), document.body), dialogLoading] }));
28
28
  }
29
29
 
30
30
  export { HighPriorityConfirmDialog };
@@ -43,7 +43,7 @@ function InfoDialog({ open, onOpenChange, type = 'info', title, description, con
43
43
  const Icon = typeClass.Icon;
44
44
  const handleClose = () => onOpenChange(false);
45
45
  const { dialogLoading, runDialogAction } = dialogLoadingAction.useDialogLoadingAction({ loadingActions, loadingFullPage, onOpenChange });
46
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ui.AlertDialog, { open: open, onOpenChange: onOpenChange, children: jsxRuntime.jsxs(ui.AlertDialogContent, { className: utils.cn(dialogStyles.dialogContentClass, typeClass.content), overlayClassName: dialogStyles.dialogThemedOverlayClass, onOverlayClick: handleClose, children: [jsxRuntime.jsxs("div", { className: dialogStyles.dialogHeaderClass, children: [jsxRuntime.jsx(ui.AlertDialogTitle, { asChild: true, children: jsxRuntime.jsxs("div", { className: dialogStyles.dialogTitleClass, children: [jsxRuntime.jsx("span", { className: utils.cn('inline-flex size-9 shrink-0 items-center justify-center rounded-full ring-1', typeClass.iconWrap), children: jsxRuntime.jsx(Icon, { className: utils.cn('size-5', typeClass.icon) }) }), jsxRuntime.jsx("span", { className: "min-w-0 truncate", children: title })] }) }), jsxRuntime.jsx("button", { type: "button", className: dialogStyles.closeButtonClass, onClick: handleClose, "aria-label": "Close", children: jsxRuntime.jsx(icons.XIcon, { className: "size-4" }) })] }), jsxRuntime.jsx(ui.AlertDialogDescription, { className: dialogStyles.dialogDescriptionClass, children: description }), jsxRuntime.jsx("div", { className: dialogStyles.dialogFooterClass, children: jsxRuntime.jsx(ui.AlertDialogAction, { className: utils.cn('inline-flex min-h-10 items-center justify-center rounded-full px-5 py-2 text-sm font-bold transition focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-60', typeClass.action), onClick: () => {
46
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ui.AlertDialog, { open: open, onOpenChange: onOpenChange, children: jsxRuntime.jsxs(ui.AlertDialogContent, { className: utils.cn(dialogStyles.dialogContentClass, typeClass.content), overlayClassName: dialogStyles.dialogThemedOverlayClass, onOverlayClick: handleClose, children: [jsxRuntime.jsxs("div", { className: dialogStyles.dialogHeaderClass, children: [jsxRuntime.jsx(ui.AlertDialogTitle, { asChild: true, children: jsxRuntime.jsxs("div", { className: dialogStyles.dialogTitleClass, children: [jsxRuntime.jsx("span", { className: utils.cn('inline-flex size-9 shrink-0 items-center justify-center rounded-full ring-1', typeClass.iconWrap), children: jsxRuntime.jsx(Icon, { className: utils.cn('size-5', typeClass.icon) }) }), jsxRuntime.jsx("span", { className: dialogStyles.dialogTitleTextClass, children: title })] }) }), jsxRuntime.jsx("button", { type: "button", className: dialogStyles.closeButtonClass, onClick: handleClose, "aria-label": "Close", children: jsxRuntime.jsx(icons.XIcon, { className: "size-4" }) })] }), jsxRuntime.jsx(ui.AlertDialogDescription, { className: dialogStyles.dialogDescriptionClass, children: description }), jsxRuntime.jsx("div", { className: dialogStyles.dialogFooterClass, children: jsxRuntime.jsx(ui.AlertDialogAction, { className: utils.cn('inline-flex min-h-10 items-center justify-center rounded-full px-5 py-2 text-sm font-bold transition focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-60', typeClass.action), onClick: () => {
47
47
  void runDialogAction('confirm', onConfirm);
48
48
  }, children: confirmText }) })] }) }), dialogLoading] }));
49
49
  }
@@ -3,7 +3,7 @@ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
3
  import { BadgeXIcon, BadgeCheckIcon, BadgeAlertIcon, BadgeInfoIcon, XIcon } from '@windrun-huaiin/base-ui/icons';
4
4
  import { AlertDialog, AlertDialogContent, AlertDialogTitle, AlertDialogDescription, AlertDialogAction } from '@windrun-huaiin/base-ui/ui';
5
5
  import { cn } from '@windrun-huaiin/lib/utils';
6
- import { dialogThemedOverlayClass, dialogHeaderClass, dialogTitleClass, closeButtonClass, dialogDescriptionClass, dialogFooterClass, dialogContentClass } from './dialog-styles.mjs';
6
+ import { dialogThemedOverlayClass, dialogHeaderClass, dialogTitleClass, dialogTitleTextClass, closeButtonClass, dialogDescriptionClass, dialogFooterClass, dialogContentClass } from './dialog-styles.mjs';
7
7
  import { useDialogLoadingAction } from './dialog-loading-action.mjs';
8
8
 
9
9
  const infoTypeClassMap = {
@@ -41,7 +41,7 @@ function InfoDialog({ open, onOpenChange, type = 'info', title, description, con
41
41
  const Icon = typeClass.Icon;
42
42
  const handleClose = () => onOpenChange(false);
43
43
  const { dialogLoading, runDialogAction } = useDialogLoadingAction({ loadingActions, loadingFullPage, onOpenChange });
44
- return (jsxs(Fragment, { children: [jsx(AlertDialog, { open: open, onOpenChange: onOpenChange, children: jsxs(AlertDialogContent, { className: cn(dialogContentClass, typeClass.content), overlayClassName: dialogThemedOverlayClass, onOverlayClick: handleClose, children: [jsxs("div", { className: dialogHeaderClass, children: [jsx(AlertDialogTitle, { asChild: true, children: jsxs("div", { className: dialogTitleClass, children: [jsx("span", { className: cn('inline-flex size-9 shrink-0 items-center justify-center rounded-full ring-1', typeClass.iconWrap), children: jsx(Icon, { className: cn('size-5', typeClass.icon) }) }), jsx("span", { className: "min-w-0 truncate", children: title })] }) }), jsx("button", { type: "button", className: closeButtonClass, onClick: handleClose, "aria-label": "Close", children: jsx(XIcon, { className: "size-4" }) })] }), jsx(AlertDialogDescription, { className: dialogDescriptionClass, children: description }), jsx("div", { className: dialogFooterClass, children: jsx(AlertDialogAction, { className: cn('inline-flex min-h-10 items-center justify-center rounded-full px-5 py-2 text-sm font-bold transition focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-60', typeClass.action), onClick: () => {
44
+ return (jsxs(Fragment, { children: [jsx(AlertDialog, { open: open, onOpenChange: onOpenChange, children: jsxs(AlertDialogContent, { className: cn(dialogContentClass, typeClass.content), overlayClassName: dialogThemedOverlayClass, onOverlayClick: handleClose, children: [jsxs("div", { className: dialogHeaderClass, children: [jsx(AlertDialogTitle, { asChild: true, children: jsxs("div", { className: dialogTitleClass, children: [jsx("span", { className: cn('inline-flex size-9 shrink-0 items-center justify-center rounded-full ring-1', typeClass.iconWrap), children: jsx(Icon, { className: cn('size-5', typeClass.icon) }) }), jsx("span", { className: dialogTitleTextClass, children: title })] }) }), jsx("button", { type: "button", className: closeButtonClass, onClick: handleClose, "aria-label": "Close", children: jsx(XIcon, { className: "size-4" }) })] }), jsx(AlertDialogDescription, { className: dialogDescriptionClass, children: description }), jsx("div", { className: dialogFooterClass, children: jsx(AlertDialogAction, { className: cn('inline-flex min-h-10 items-center justify-center rounded-full px-5 py-2 text-sm font-bold transition focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-60', typeClass.action), onClick: () => {
45
45
  void runDialogAction('confirm', onConfirm);
46
46
  }, children: confirmText }) })] }) }), dialogLoading] }));
47
47
  }
@@ -86,9 +86,9 @@ function UndoableConfirmDialog({ open, onOpenChange, title, description, pending
86
86
  return;
87
87
  }
88
88
  onOpenChange(nextOpen);
89
- }, children: jsxRuntime.jsxs(ui.AlertDialogContent, { className: utils.cn(dialogStyles.dialogContentClass, 'border-red-300 dark:border-red-700'), overlayClassName: dialogStyles.dialogThemedOverlayClass, onOverlayClick: pending ? undefined : handleClose, children: [jsxRuntime.jsxs("div", { className: dialogStyles.dialogHeaderClass, children: [jsxRuntime.jsx(ui.AlertDialogTitle, { asChild: true, children: jsxRuntime.jsxs("div", { className: dialogStyles.dialogTitleClass, children: [jsxRuntime.jsx("span", { className: "inline-flex size-9 shrink-0 items-center justify-center rounded-full bg-red-100 text-red-600 ring-1 ring-red-200 dark:bg-red-950 dark:text-red-300 dark:ring-red-900", children: pending ? jsxRuntime.jsx(icons.Trash2Icon, { className: "size-5" }) : jsxRuntime.jsx(icons.CircleAlertIcon, { className: "size-5" }) }), jsxRuntime.jsx("span", { className: "min-w-0 truncate", children: displayTitle })] }) }), jsxRuntime.jsx("button", { type: "button", className: dialogStyles.closeButtonClass, onClick: handleClose, "aria-label": "Close", disabled: confirming, children: jsxRuntime.jsx(icons.XIcon, { className: "size-4" }) })] }), jsxRuntime.jsx(ui.AlertDialogDescription, { className: utils.cn(dialogStyles.dialogDescriptionClass, 'min-h-[44px]'), children: jsxRuntime.jsx("span", { children: displayDescription }) }), jsxRuntime.jsx("div", { className: "flex h-12 items-center justify-center py-1", children: jsxRuntime.jsxs("div", { className: "flex items-baseline justify-center gap-2", children: [jsxRuntime.jsx("span", { className: utils.cn('text-4xl font-black leading-none tabular-nums', pending && 'animate-bounce', lib.themeIconColor), children: pending ? remainingSeconds : safeCountdownSeconds }), jsxRuntime.jsx("span", { className: utils.cn('text-sm font-bold', lib.themeIconColor), children: "s" })] }) }), jsxRuntime.jsx("div", { className: utils.cn(dialogStyles.dialogFooterClass, 'min-h-[88px] sm:min-h-10 sm:items-center'), children: pending ? (jsxRuntime.jsxs("button", { type: "button", onClick: () => {
89
+ }, children: jsxRuntime.jsxs(ui.AlertDialogContent, { className: utils.cn(dialogStyles.dialogContentClass, 'border-red-300 dark:border-red-700'), overlayClassName: dialogStyles.dialogThemedOverlayClass, onOverlayClick: pending ? undefined : handleClose, children: [jsxRuntime.jsxs("div", { className: dialogStyles.dialogHeaderClass, children: [jsxRuntime.jsx(ui.AlertDialogTitle, { asChild: true, children: jsxRuntime.jsxs("div", { className: dialogStyles.dialogTitleClass, children: [jsxRuntime.jsx("span", { className: "inline-flex size-9 shrink-0 items-center justify-center rounded-full bg-red-100 text-red-600 ring-1 ring-red-200 dark:bg-red-950 dark:text-red-300 dark:ring-red-900", children: pending ? jsxRuntime.jsx(icons.Trash2Icon, { className: "size-5" }) : jsxRuntime.jsx(icons.CircleAlertIcon, { className: "size-5" }) }), jsxRuntime.jsx("span", { className: dialogStyles.dialogTitleTextClass, children: displayTitle })] }) }), jsxRuntime.jsx("button", { type: "button", className: dialogStyles.closeButtonClass, onClick: handleClose, "aria-label": "Close", disabled: confirming, children: jsxRuntime.jsx(icons.XIcon, { className: "size-4" }) })] }), jsxRuntime.jsx(ui.AlertDialogDescription, { className: utils.cn(dialogStyles.dialogDescriptionClass, 'min-h-[44px]'), children: jsxRuntime.jsx("span", { children: displayDescription }) }), jsxRuntime.jsx("div", { className: "flex h-12 items-center justify-center py-1", children: jsxRuntime.jsxs("div", { className: "flex items-baseline justify-center gap-2", children: [jsxRuntime.jsx("span", { className: utils.cn('text-4xl font-black leading-none tabular-nums', pending && 'animate-bounce', lib.themeIconColor), children: pending ? remainingSeconds : safeCountdownSeconds }), jsxRuntime.jsx("span", { className: utils.cn('text-sm font-bold', lib.themeIconColor), children: "s" })] }) }), jsxRuntime.jsx("div", { className: utils.cn(dialogStyles.dialogFooterClass, 'min-h-[88px] sm:min-h-10 sm:items-center'), children: pending ? (jsxRuntime.jsxs("button", { type: "button", onClick: () => {
90
90
  void handleUndo();
91
- }, className: dialogStyles.secondaryButtonClass, disabled: confirming, children: [jsxRuntime.jsx(icons.Undo2Icon, { className: "mr-1.5 size-4" }), undoText] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("button", { type: "button", onClick: handleCancel, className: cancelButtonClass, children: cancelText }), jsxRuntime.jsx("button", { type: "button", onClick: startCountdown, className: confirmButtonClass, children: confirmText })] })) })] }) }), dialogLoading] }));
91
+ }, className: utils.cn(dialogStyles.secondaryButtonClass, 'w-full sm:w-auto'), disabled: confirming, children: [jsxRuntime.jsx(icons.Undo2Icon, { className: "mr-1.5 size-4" }), undoText] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("button", { type: "button", onClick: handleCancel, className: utils.cn(cancelButtonClass, 'w-full sm:w-auto'), children: cancelText }), jsxRuntime.jsx("button", { type: "button", onClick: startCountdown, className: utils.cn(confirmButtonClass, 'w-full sm:w-auto'), children: confirmText })] })) })] }) }), dialogLoading] }));
92
92
  }
93
93
 
94
94
  exports.UndoableConfirmDialog = UndoableConfirmDialog;
@@ -6,7 +6,7 @@ import { Trash2Icon, CircleAlertIcon, XIcon, Undo2Icon } from '@windrun-huaiin/b
6
6
  import { themeIconColor } from '@windrun-huaiin/base-ui/lib';
7
7
  import { AlertDialog, AlertDialogContent, AlertDialogTitle, AlertDialogDescription } from '@windrun-huaiin/base-ui/ui';
8
8
  import { cn } from '@windrun-huaiin/lib/utils';
9
- import { dialogThemedOverlayClass, dialogHeaderClass, dialogTitleClass, closeButtonClass, dialogDescriptionClass, secondaryButtonClass, dangerButtonClass, dialogFooterClass, dialogContentClass } from './dialog-styles.mjs';
9
+ import { dialogThemedOverlayClass, dialogHeaderClass, dialogTitleClass, dialogTitleTextClass, closeButtonClass, dialogDescriptionClass, secondaryButtonClass, dangerButtonClass, dialogFooterClass, dialogContentClass } from './dialog-styles.mjs';
10
10
  import { useDialogLoadingAction } from './dialog-loading-action.mjs';
11
11
 
12
12
  function UndoableConfirmDialog({ open, onOpenChange, title, description, pendingTitle, pendingDescription, cancelText = 'Cancel', confirmText = 'Delete', undoText = 'Undo', emphasis = 'confirm', countdownSeconds = 5, loadingActions, loadingFullPage, onCancel, onConfirm, onUndo, }) {
@@ -84,9 +84,9 @@ function UndoableConfirmDialog({ open, onOpenChange, title, description, pending
84
84
  return;
85
85
  }
86
86
  onOpenChange(nextOpen);
87
- }, children: jsxs(AlertDialogContent, { className: cn(dialogContentClass, 'border-red-300 dark:border-red-700'), overlayClassName: dialogThemedOverlayClass, onOverlayClick: pending ? undefined : handleClose, children: [jsxs("div", { className: dialogHeaderClass, children: [jsx(AlertDialogTitle, { asChild: true, children: jsxs("div", { className: dialogTitleClass, children: [jsx("span", { className: "inline-flex size-9 shrink-0 items-center justify-center rounded-full bg-red-100 text-red-600 ring-1 ring-red-200 dark:bg-red-950 dark:text-red-300 dark:ring-red-900", children: pending ? jsx(Trash2Icon, { className: "size-5" }) : jsx(CircleAlertIcon, { className: "size-5" }) }), jsx("span", { className: "min-w-0 truncate", children: displayTitle })] }) }), jsx("button", { type: "button", className: closeButtonClass, onClick: handleClose, "aria-label": "Close", disabled: confirming, children: jsx(XIcon, { className: "size-4" }) })] }), jsx(AlertDialogDescription, { className: cn(dialogDescriptionClass, 'min-h-[44px]'), children: jsx("span", { children: displayDescription }) }), jsx("div", { className: "flex h-12 items-center justify-center py-1", children: jsxs("div", { className: "flex items-baseline justify-center gap-2", children: [jsx("span", { className: cn('text-4xl font-black leading-none tabular-nums', pending && 'animate-bounce', themeIconColor), children: pending ? remainingSeconds : safeCountdownSeconds }), jsx("span", { className: cn('text-sm font-bold', themeIconColor), children: "s" })] }) }), jsx("div", { className: cn(dialogFooterClass, 'min-h-[88px] sm:min-h-10 sm:items-center'), children: pending ? (jsxs("button", { type: "button", onClick: () => {
87
+ }, children: jsxs(AlertDialogContent, { className: cn(dialogContentClass, 'border-red-300 dark:border-red-700'), overlayClassName: dialogThemedOverlayClass, onOverlayClick: pending ? undefined : handleClose, children: [jsxs("div", { className: dialogHeaderClass, children: [jsx(AlertDialogTitle, { asChild: true, children: jsxs("div", { className: dialogTitleClass, children: [jsx("span", { className: "inline-flex size-9 shrink-0 items-center justify-center rounded-full bg-red-100 text-red-600 ring-1 ring-red-200 dark:bg-red-950 dark:text-red-300 dark:ring-red-900", children: pending ? jsx(Trash2Icon, { className: "size-5" }) : jsx(CircleAlertIcon, { className: "size-5" }) }), jsx("span", { className: dialogTitleTextClass, children: displayTitle })] }) }), jsx("button", { type: "button", className: closeButtonClass, onClick: handleClose, "aria-label": "Close", disabled: confirming, children: jsx(XIcon, { className: "size-4" }) })] }), jsx(AlertDialogDescription, { className: cn(dialogDescriptionClass, 'min-h-[44px]'), children: jsx("span", { children: displayDescription }) }), jsx("div", { className: "flex h-12 items-center justify-center py-1", children: jsxs("div", { className: "flex items-baseline justify-center gap-2", children: [jsx("span", { className: cn('text-4xl font-black leading-none tabular-nums', pending && 'animate-bounce', themeIconColor), children: pending ? remainingSeconds : safeCountdownSeconds }), jsx("span", { className: cn('text-sm font-bold', themeIconColor), children: "s" })] }) }), jsx("div", { className: cn(dialogFooterClass, 'min-h-[88px] sm:min-h-10 sm:items-center'), children: pending ? (jsxs("button", { type: "button", onClick: () => {
88
88
  void handleUndo();
89
- }, className: secondaryButtonClass, disabled: confirming, children: [jsx(Undo2Icon, { className: "mr-1.5 size-4" }), undoText] })) : (jsxs(Fragment, { children: [jsx("button", { type: "button", onClick: handleCancel, className: cancelButtonClass, children: cancelText }), jsx("button", { type: "button", onClick: startCountdown, className: confirmButtonClass, children: confirmText })] })) })] }) }), dialogLoading] }));
89
+ }, className: cn(secondaryButtonClass, 'w-full sm:w-auto'), disabled: confirming, children: [jsx(Undo2Icon, { className: "mr-1.5 size-4" }), undoText] })) : (jsxs(Fragment, { children: [jsx("button", { type: "button", onClick: handleCancel, className: cn(cancelButtonClass, 'w-full sm:w-auto'), children: cancelText }), jsx("button", { type: "button", onClick: startCountdown, className: cn(confirmButtonClass, 'w-full sm:w-auto'), children: confirmText })] })) })] }) }), dialogLoading] }));
90
90
  }
91
91
 
92
92
  export { UndoableConfirmDialog };
@@ -0,0 +1,3 @@
1
+ import { type BeamFrameProps } from '../beam-frame-config';
2
+ export type { BeamFrameProps, BeamFrameTone } from '../beam-frame-config';
3
+ export declare function AnimeBeamFrame(props: BeamFrameProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,63 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var React = require('react');
6
+ var animejs = require('animejs');
7
+ var react = require('motion/react');
8
+ var beamFrameConfig = require('../beam-frame-config.js');
9
+
10
+ function AnimeBeamLayer({ isRunning, duration, radius, size, }) {
11
+ const aroundBeamRef = React.useRef(null);
12
+ const animationRef = React.useRef(null);
13
+ const hasStartedRef = React.useRef(false);
14
+ const auraGradientId = React.useId().replace(/:/g, '');
15
+ const softGlowFilterId = React.useId().replace(/:/g, '');
16
+ React.useEffect(() => {
17
+ var _a;
18
+ const node = aroundBeamRef.current;
19
+ if (!node) {
20
+ return undefined;
21
+ }
22
+ if (isRunning) {
23
+ hasStartedRef.current = true;
24
+ }
25
+ node.style.opacity = isRunning || hasStartedRef.current ? 'var(--beam-frame-beam-opacity)' : '0';
26
+ if (!isRunning) {
27
+ (_a = animationRef.current) === null || _a === void 0 ? void 0 : _a.pause();
28
+ return undefined;
29
+ }
30
+ if (animationRef.current) {
31
+ animationRef.current.speed = beamFrameConfig.BASE_DURATION_SECONDS / duration;
32
+ animationRef.current.play();
33
+ return undefined;
34
+ }
35
+ animationRef.current = animejs.waapi.animate(node, {
36
+ strokeDashoffset: [0, -1],
37
+ loop: true,
38
+ duration: beamFrameConfig.BASE_DURATION_SECONDS * 1000,
39
+ ease: 'linear',
40
+ });
41
+ animationRef.current.speed = beamFrameConfig.BASE_DURATION_SECONDS / duration;
42
+ return undefined;
43
+ }, [duration, isRunning]);
44
+ React.useEffect(() => {
45
+ return () => {
46
+ var _a;
47
+ (_a = animationRef.current) === null || _a === void 0 ? void 0 : _a.revert();
48
+ animationRef.current = null;
49
+ };
50
+ }, []);
51
+ return (jsxRuntime.jsx(beamFrameConfig.BeamSvgLayer, { beamRef: aroundBeamRef, auraGradientId: auraGradientId, softGlowFilterId: softGlowFilterId, radius: radius, size: size }));
52
+ }
53
+ function AnimeBeamFrame(props) {
54
+ const { children, active = false, interactive = true, tone = 'theme', duration = beamFrameConfig.BASE_DURATION_SECONDS, radius, className, } = props;
55
+ const prefersReducedMotion = react.useReducedMotion();
56
+ const { isRunning, interactionProps } = beamFrameConfig.useInteractiveRunning(active, interactive);
57
+ const shouldRun = isRunning && !prefersReducedMotion;
58
+ const normalizedDuration = beamFrameConfig.normalizeDuration(duration);
59
+ const { ref, size } = beamFrameConfig.useMeasuredFrameSize();
60
+ return (jsxRuntime.jsx(beamFrameConfig.BeamFrameShell, { active: active, interactive: interactive, tone: tone, duration: normalizedDuration, radius: radius, className: className, isRunning: shouldRun, interactionProps: interactionProps, rootRef: ref, renderBeam: () => (jsxRuntime.jsx(AnimeBeamLayer, { isRunning: shouldRun, duration: normalizedDuration, radius: radius, size: size })), children: children }));
61
+ }
62
+
63
+ exports.AnimeBeamFrame = AnimeBeamFrame;
@@ -0,0 +1,61 @@
1
+ "use client";
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import { useRef, useId, useEffect } from 'react';
4
+ import { waapi } from 'animejs';
5
+ import { useReducedMotion } from 'motion/react';
6
+ import { BASE_DURATION_SECONDS, useInteractiveRunning, useMeasuredFrameSize, BeamFrameShell, normalizeDuration, BeamSvgLayer } from '../beam-frame-config.mjs';
7
+
8
+ function AnimeBeamLayer({ isRunning, duration, radius, size, }) {
9
+ const aroundBeamRef = useRef(null);
10
+ const animationRef = useRef(null);
11
+ const hasStartedRef = useRef(false);
12
+ const auraGradientId = useId().replace(/:/g, '');
13
+ const softGlowFilterId = useId().replace(/:/g, '');
14
+ useEffect(() => {
15
+ var _a;
16
+ const node = aroundBeamRef.current;
17
+ if (!node) {
18
+ return undefined;
19
+ }
20
+ if (isRunning) {
21
+ hasStartedRef.current = true;
22
+ }
23
+ node.style.opacity = isRunning || hasStartedRef.current ? 'var(--beam-frame-beam-opacity)' : '0';
24
+ if (!isRunning) {
25
+ (_a = animationRef.current) === null || _a === void 0 ? void 0 : _a.pause();
26
+ return undefined;
27
+ }
28
+ if (animationRef.current) {
29
+ animationRef.current.speed = BASE_DURATION_SECONDS / duration;
30
+ animationRef.current.play();
31
+ return undefined;
32
+ }
33
+ animationRef.current = waapi.animate(node, {
34
+ strokeDashoffset: [0, -1],
35
+ loop: true,
36
+ duration: BASE_DURATION_SECONDS * 1000,
37
+ ease: 'linear',
38
+ });
39
+ animationRef.current.speed = BASE_DURATION_SECONDS / duration;
40
+ return undefined;
41
+ }, [duration, isRunning]);
42
+ useEffect(() => {
43
+ return () => {
44
+ var _a;
45
+ (_a = animationRef.current) === null || _a === void 0 ? void 0 : _a.revert();
46
+ animationRef.current = null;
47
+ };
48
+ }, []);
49
+ return (jsx(BeamSvgLayer, { beamRef: aroundBeamRef, auraGradientId: auraGradientId, softGlowFilterId: softGlowFilterId, radius: radius, size: size }));
50
+ }
51
+ function AnimeBeamFrame(props) {
52
+ const { children, active = false, interactive = true, tone = 'theme', duration = BASE_DURATION_SECONDS, radius, className, } = props;
53
+ const prefersReducedMotion = useReducedMotion();
54
+ const { isRunning, interactionProps } = useInteractiveRunning(active, interactive);
55
+ const shouldRun = isRunning && !prefersReducedMotion;
56
+ const normalizedDuration = normalizeDuration(duration);
57
+ const { ref, size } = useMeasuredFrameSize();
58
+ return (jsx(BeamFrameShell, { active: active, interactive: interactive, tone: tone, duration: normalizedDuration, radius: radius, className: className, isRunning: shouldRun, interactionProps: interactionProps, rootRef: ref, renderBeam: () => (jsx(AnimeBeamLayer, { isRunning: shouldRun, duration: normalizedDuration, radius: radius, size: size })), children: children }));
59
+ }
60
+
61
+ export { AnimeBeamFrame };
@@ -0,0 +1,10 @@
1
+ export interface AnimeSpiralLoadingProps {
2
+ className?: string;
3
+ dotCount?: number;
4
+ duration?: number;
5
+ distanceRem?: number;
6
+ dotSizeEm?: number;
7
+ fontSize?: number;
8
+ paused?: boolean;
9
+ }
10
+ export declare function AnimeSpiralLoading({ className, dotCount, duration, distanceRem, dotSizeEm, fontSize, paused, }: AnimeSpiralLoadingProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,77 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var React = require('react');
6
+ var animejs = require('animejs');
7
+ var utils = require('@windrun-huaiin/lib/utils');
8
+
9
+ const DEFAULT_DOT_COUNT = 2024;
10
+ const DEFAULT_DURATION = 10000;
11
+ const DEFAULT_DISTANCE_REM = 20;
12
+ const DEFAULT_DOT_SIZE_EM = 1;
13
+ const DEFAULT_FONT_SIZE = 20;
14
+ function AnimeSpiralLoading({ className, dotCount = DEFAULT_DOT_COUNT, duration = DEFAULT_DURATION, distanceRem = DEFAULT_DISTANCE_REM, dotSizeEm = DEFAULT_DOT_SIZE_EM, fontSize = DEFAULT_FONT_SIZE, paused = false, }) {
15
+ const rootRef = React.useRef(null);
16
+ const timelineRef = React.useRef(null);
17
+ const pausedRef = React.useRef(paused);
18
+ const safeDotCount = Math.max(1, Math.floor(dotCount));
19
+ const safeDuration = Math.max(1, duration);
20
+ const angle = React.useMemo(() => (index) => animejs.utils.mapRange(index, 0, safeDotCount, 0, Math.PI * 100), [safeDotCount]);
21
+ const dots = React.useMemo(() => Array.from({ length: safeDotCount }, (_, index) => {
22
+ const hue = animejs.utils.round((360 / safeDotCount) * index, 0);
23
+ return {
24
+ id: index,
25
+ background: `hsl(${hue}, 60%, 60%)`,
26
+ };
27
+ }), [safeDotCount]);
28
+ pausedRef.current = paused;
29
+ React.useEffect(() => {
30
+ var _a;
31
+ const root = rootRef.current;
32
+ if (!root) {
33
+ return undefined;
34
+ }
35
+ const dotNodes = Array.from(root.querySelectorAll('[data-anime-spiral-dot]'));
36
+ (_a = timelineRef.current) === null || _a === void 0 ? void 0 : _a.revert();
37
+ timelineRef.current = animejs.createTimeline()
38
+ .add(dotNodes, {
39
+ x: (_target, i) => `${Math.sin(angle(i)) * distanceRem}rem`,
40
+ y: (_target, i) => `${Math.cos(angle(i)) * distanceRem}rem`,
41
+ scale: [0, 0.4, 0.2, 0.9, 0],
42
+ playbackEase: 'inOutSine',
43
+ loop: true,
44
+ duration: safeDuration,
45
+ }, animejs.stagger([0, safeDuration]))
46
+ .init()
47
+ .seek(safeDuration);
48
+ if (pausedRef.current) {
49
+ timelineRef.current.pause();
50
+ }
51
+ return () => {
52
+ var _a;
53
+ (_a = timelineRef.current) === null || _a === void 0 ? void 0 : _a.revert();
54
+ timelineRef.current = null;
55
+ };
56
+ }, [angle, distanceRem, safeDuration, dots]);
57
+ React.useEffect(() => {
58
+ const timeline = timelineRef.current;
59
+ if (!timeline) {
60
+ return;
61
+ }
62
+ if (paused) {
63
+ timeline.pause();
64
+ }
65
+ else {
66
+ timeline.play();
67
+ }
68
+ }, [paused]);
69
+ return (jsxRuntime.jsx("div", { ref: rootRef, className: utils.cn('relative h-dvh w-full overflow-hidden', className), style: { fontSize }, "aria-hidden": "true", children: dots.map(dot => (jsxRuntime.jsx("div", { "data-anime-spiral-dot": "", className: "absolute left-1/2 top-1/2 rounded-full", style: {
70
+ width: `${dotSizeEm}em`,
71
+ height: `${dotSizeEm}em`,
72
+ margin: `${dotSizeEm / -2}em 0 0 ${dotSizeEm / -2}em`,
73
+ backgroundColor: dot.background,
74
+ } }, dot.id))) }));
75
+ }
76
+
77
+ exports.AnimeSpiralLoading = AnimeSpiralLoading;