@windrun-huaiin/third-ui 29.2.1 → 30.1.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 (121) hide show
  1. package/dist/fuma/fuma-page-genarator.d.ts +2 -6
  2. package/dist/fuma/fuma-page-genarator.js +3 -2
  3. package/dist/fuma/fuma-page-genarator.mjs +3 -2
  4. package/dist/fuma/mdx/cheet-table.d.ts +13 -0
  5. package/dist/fuma/mdx/cheet-table.js +295 -0
  6. package/dist/fuma/mdx/cheet-table.mjs +293 -0
  7. package/dist/fuma/mdx/index.d.ts +1 -0
  8. package/dist/fuma/mdx/index.js +2 -0
  9. package/dist/fuma/mdx/index.mjs +1 -0
  10. package/dist/fuma/server/features/widgets.js +2 -0
  11. package/dist/fuma/server/features/widgets.mjs +2 -0
  12. package/dist/lib/fuma-schema-check-util.d.ts +1 -1
  13. package/dist/main/404-page.d.ts +12 -0
  14. package/dist/main/404-page.js +66 -0
  15. package/dist/main/404-page.mjs +64 -0
  16. package/dist/main/alert-dialog/confirm-dialog.js +1 -1
  17. package/dist/main/alert-dialog/confirm-dialog.mjs +2 -2
  18. package/dist/main/alert-dialog/dialog-loading-action.js +5 -2
  19. package/dist/main/alert-dialog/dialog-loading-action.mjs +5 -2
  20. package/dist/main/alert-dialog/dialog-styles.d.ts +4 -2
  21. package/dist/main/alert-dialog/dialog-styles.js +8 -4
  22. package/dist/main/alert-dialog/dialog-styles.mjs +7 -5
  23. package/dist/main/alert-dialog/high-priority-confirm-dialog.js +5 -5
  24. package/dist/main/alert-dialog/high-priority-confirm-dialog.mjs +6 -6
  25. package/dist/main/alert-dialog/info-dialog.js +1 -1
  26. package/dist/main/alert-dialog/info-dialog.mjs +2 -2
  27. package/dist/main/alert-dialog/undoable-confirm-dialog.js +2 -2
  28. package/dist/main/alert-dialog/undoable-confirm-dialog.mjs +3 -3
  29. package/dist/main/anime/anime-404-page.d.ts +14 -0
  30. package/dist/main/anime/anime-404-page.js +197 -0
  31. package/dist/main/anime/anime-404-page.mjs +195 -0
  32. package/dist/main/anime/anime-beam-frame.d.ts +3 -0
  33. package/dist/main/anime/anime-beam-frame.js +63 -0
  34. package/dist/main/anime/anime-beam-frame.mjs +61 -0
  35. package/dist/main/anime/anime-not-found-page.d.ts +7 -0
  36. package/dist/main/anime/anime-not-found-page.js +142 -0
  37. package/dist/main/anime/anime-not-found-page.mjs +140 -0
  38. package/dist/main/anime/anime-spiral-loading.d.ts +10 -0
  39. package/dist/main/anime/anime-spiral-loading.js +77 -0
  40. package/dist/main/anime/anime-spiral-loading.mjs +75 -0
  41. package/dist/main/anime/index.d.ts +3 -0
  42. package/dist/main/anime/index.js +12 -0
  43. package/dist/main/anime/index.mjs +4 -0
  44. package/dist/main/beam-frame/animate.d.ts +3 -0
  45. package/dist/main/beam-frame/animate.js +63 -0
  46. package/dist/main/beam-frame/animate.mjs +61 -0
  47. package/dist/main/beam-frame/beam-frame.d.ts +4 -0
  48. package/dist/main/beam-frame/beam-frame.js +262 -0
  49. package/dist/main/beam-frame/beam-frame.mjs +258 -0
  50. package/dist/main/beam-frame/index.d.ts +4 -0
  51. package/dist/main/beam-frame/index.js +11 -0
  52. package/dist/main/beam-frame/index.mjs +3 -0
  53. package/dist/main/beam-frame/motion.d.ts +3 -0
  54. package/dist/main/beam-frame/motion.js +61 -0
  55. package/dist/main/beam-frame/motion.mjs +59 -0
  56. package/dist/main/beam-frame/share-config.d.ts +54 -0
  57. package/dist/main/beam-frame/share-config.js +161 -0
  58. package/dist/main/beam-frame/share-config.mjs +152 -0
  59. package/dist/main/beam-frame-config.d.ts +54 -0
  60. package/dist/main/beam-frame-config.js +161 -0
  61. package/dist/main/beam-frame-config.mjs +152 -0
  62. package/dist/main/calendar/random-date-range-dialog.js +177 -51
  63. package/dist/main/calendar/random-date-range-dialog.mjs +178 -52
  64. package/dist/main/cta.js +17 -1
  65. package/dist/main/cta.mjs +18 -2
  66. package/dist/main/delayed-img.d.ts +1 -1
  67. package/dist/main/delayed-img.js +8 -5
  68. package/dist/main/delayed-img.mjs +8 -5
  69. package/dist/main/index.d.ts +1 -0
  70. package/dist/main/index.js +2 -0
  71. package/dist/main/index.mjs +1 -0
  72. package/dist/main/info-tooltip.js +70 -9
  73. package/dist/main/info-tooltip.mjs +70 -9
  74. package/dist/main/loading-frame/index.d.ts +1 -0
  75. package/dist/main/loading.d.ts +2 -1
  76. package/dist/main/loading.js +64 -26
  77. package/dist/main/loading.mjs +64 -26
  78. package/dist/main/motion/creative-left-panel.d.ts +7 -0
  79. package/dist/main/motion/creative-left-panel.js +11 -0
  80. package/dist/main/motion/creative-left-panel.mjs +9 -0
  81. package/dist/main/motion/creative-right-panel.d.ts +7 -0
  82. package/dist/main/motion/creative-right-panel.js +11 -0
  83. package/dist/main/motion/creative-right-panel.mjs +9 -0
  84. package/dist/main/motion/index.d.ts +1 -0
  85. package/dist/main/motion/index.js +9 -0
  86. package/dist/main/motion/index.mjs +2 -0
  87. package/dist/main/motion/motion-beam-frame.d.ts +3 -0
  88. package/dist/main/motion/motion-beam-frame.js +61 -0
  89. package/dist/main/motion/motion-beam-frame.mjs +59 -0
  90. package/dist/main/snake-loading-frame.d.ts +7 -3
  91. package/dist/main/snake-loading-frame.js +45 -252
  92. package/dist/main/snake-loading-frame.mjs +47 -254
  93. package/package.json +16 -5
  94. package/src/fuma/fuma-page-genarator.tsx +2 -22
  95. package/src/fuma/mdx/cheet-table.tsx +650 -0
  96. package/src/fuma/mdx/index.ts +1 -0
  97. package/src/fuma/server/features/widgets.tsx +2 -0
  98. package/src/main/404-page.tsx +162 -0
  99. package/src/main/alert-dialog/confirm-dialog.tsx +2 -1
  100. package/src/main/alert-dialog/dialog-loading-action.tsx +7 -5
  101. package/src/main/alert-dialog/dialog-styles.ts +13 -3
  102. package/src/main/alert-dialog/high-priority-confirm-dialog.tsx +26 -23
  103. package/src/main/alert-dialog/info-dialog.tsx +2 -1
  104. package/src/main/alert-dialog/undoable-confirm-dialog.tsx +18 -17
  105. package/src/main/anime/anime-404-page.tsx +344 -0
  106. package/src/main/anime/anime-beam-frame.tsx +128 -0
  107. package/src/main/anime/anime-spiral-loading.tsx +123 -0
  108. package/src/main/anime/index.ts +10 -0
  109. package/src/main/beam-frame-config.tsx +341 -0
  110. package/src/main/calendar/random-date-range-dialog.tsx +225 -69
  111. package/src/main/cta.tsx +50 -21
  112. package/src/main/delayed-img.tsx +9 -4
  113. package/src/main/index.ts +1 -0
  114. package/src/main/info-tooltip.tsx +116 -20
  115. package/src/main/loading-frame/index.ts +4 -0
  116. package/src/main/loading.tsx +75 -24
  117. package/src/main/motion/index.ts +8 -0
  118. package/src/main/motion/motion-beam-frame.tsx +137 -0
  119. package/src/main/snake-loading-frame.tsx +95 -496
  120. package/src/styles/cta.css +21 -4
  121. package/src/styles/third-ui.css +0 -20
@@ -3,21 +3,69 @@
3
3
 
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var React = require('react');
6
+ var reactDom = require('react-dom');
6
7
  var icons = require('@windrun-huaiin/base-ui/icons');
7
8
  var lib = require('@windrun-huaiin/base-ui/lib');
8
9
  var utils = require('@windrun-huaiin/lib/utils');
9
10
 
11
+ const TOOLTIP_MARGIN = 12;
12
+ const TOOLTIP_GAP = 8;
13
+ const TOOLTIP_MAX_WIDTH = 288;
14
+ function clamp(value, min, max) {
15
+ return Math.min(Math.max(value, min), max);
16
+ }
17
+ function getTooltipPosition(target, align, desktopSide) {
18
+ const rect = target.getBoundingClientRect();
19
+ const viewportWidth = window.innerWidth;
20
+ const viewportHeight = window.innerHeight;
21
+ const maxWidth = Math.min(TOOLTIP_MAX_WIDTH, Math.max(160, viewportWidth - TOOLTIP_MARGIN * 2));
22
+ const useInlineSide = desktopSide === 'right' && viewportWidth >= 768;
23
+ if (useInlineSide) {
24
+ const rightSpace = viewportWidth - rect.right - TOOLTIP_GAP - TOOLTIP_MARGIN;
25
+ const leftSpace = rect.left - TOOLTIP_GAP - TOOLTIP_MARGIN;
26
+ const placeRight = rightSpace >= Math.min(220, maxWidth) || rightSpace >= leftSpace;
27
+ const preferredLeft = placeRight
28
+ ? rect.right + TOOLTIP_GAP
29
+ : rect.left - maxWidth - TOOLTIP_GAP;
30
+ return {
31
+ left: clamp(preferredLeft, TOOLTIP_MARGIN, viewportWidth - maxWidth - TOOLTIP_MARGIN),
32
+ top: clamp(rect.top + rect.height / 2, TOOLTIP_MARGIN + 40, viewportHeight - TOOLTIP_MARGIN - 40),
33
+ maxWidth,
34
+ side: 'inline',
35
+ };
36
+ }
37
+ const preferredLeft = align === 'start'
38
+ ? rect.left
39
+ : rect.right - maxWidth;
40
+ return {
41
+ left: clamp(preferredLeft, TOOLTIP_MARGIN, viewportWidth - maxWidth - TOOLTIP_MARGIN),
42
+ top: Math.min(rect.bottom + TOOLTIP_GAP, viewportHeight - TOOLTIP_MARGIN),
43
+ maxWidth,
44
+ side: 'bottom',
45
+ };
46
+ }
10
47
  function InfoTooltip({ content, className, align = 'end', desktopSide = 'right', }) {
11
48
  const normalizedContent = content.trim();
12
49
  const containerRef = React.useRef(null);
50
+ const tooltipRef = React.useRef(null);
13
51
  const [open, setOpen] = React.useState(false);
52
+ const [position, setPosition] = React.useState(null);
53
+ const updatePosition = () => {
54
+ if (!containerRef.current) {
55
+ return;
56
+ }
57
+ setPosition(getTooltipPosition(containerRef.current, align, desktopSide));
58
+ };
14
59
  React.useEffect(() => {
15
60
  function handlePointerDown(event) {
61
+ var _a;
16
62
  if (!containerRef.current) {
17
63
  return;
18
64
  }
19
65
  const target = event.target;
20
- if (target instanceof Node && !containerRef.current.contains(target)) {
66
+ if (target instanceof Node &&
67
+ !containerRef.current.contains(target) &&
68
+ !((_a = tooltipRef.current) === null || _a === void 0 ? void 0 : _a.contains(target))) {
21
69
  setOpen(false);
22
70
  }
23
71
  }
@@ -28,21 +76,34 @@ function InfoTooltip({ content, className, align = 'end', desktopSide = 'right',
28
76
  document.removeEventListener('touchstart', handlePointerDown);
29
77
  };
30
78
  }, []);
79
+ React.useEffect(() => {
80
+ if (!open) {
81
+ setPosition(null);
82
+ return;
83
+ }
84
+ updatePosition();
85
+ window.addEventListener('resize', updatePosition);
86
+ window.addEventListener('scroll', updatePosition, true);
87
+ return () => {
88
+ window.removeEventListener('resize', updatePosition);
89
+ window.removeEventListener('scroll', updatePosition, true);
90
+ };
91
+ }, [align, desktopSide, open]);
31
92
  if (!normalizedContent) {
32
93
  return null;
33
94
  }
34
- return (jsxRuntime.jsxs("span", { ref: containerRef, className: utils.cn('relative inline-flex h-5 w-5 shrink-0 align-middle', className), onMouseLeave: () => setOpen(false), children: [jsxRuntime.jsx("button", { type: "button", onMouseEnter: () => setOpen(true), onPointerDown: (event) => {
95
+ return (jsxRuntime.jsxs("span", { ref: containerRef, className: utils.cn('inline-flex h-5 w-5 shrink-0 align-middle', className), onMouseLeave: () => setOpen(false), children: [jsxRuntime.jsx("button", { type: "button", onMouseEnter: () => setOpen(true), onPointerDown: (event) => {
35
96
  event.stopPropagation();
36
97
  }, onClick: (event) => {
37
98
  event.stopPropagation();
38
99
  setOpen((value) => !value);
39
- }, className: utils.cn('inline-flex h-5 w-5 items-center justify-center rounded-full text-slate-400 transition', 'hover:bg-black/5 hover:dark:bg-white/5', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-1 dark:focus-visible:ring-offset-slate-950', 'hover:text-slate-700 dark:hover:text-white focus-visible:text-slate-700 dark:focus-visible:text-white', lib.themeIconColor, lib.themeRingColor), "aria-label": normalizedContent, "aria-expanded": open, children: jsxRuntime.jsx(icons.CircleQuestionMarkIcon, { className: "h-4 w-4" }) }), jsxRuntime.jsx("span", { className: utils.cn('pointer-events-none absolute top-full z-50 mt-2 w-[min(18rem,calc(100vw-2rem))] rounded-2xl border bg-white/95 px-3 py-2 text-xs leading-5 text-slate-600 shadow-xl backdrop-blur-sm dark:bg-slate-950/95 dark:text-slate-300', align === 'start' ? 'left-0 right-auto' : 'right-0 left-auto', desktopSide === 'right'
40
- ? align === 'start'
41
- ? 'sm:left-0 sm:right-auto md:left-full md:right-auto md:top-1/2 md:mt-0 md:ml-2 md:-translate-y-1/2'
42
- : 'sm:right-0 sm:left-auto md:left-full md:right-auto md:top-1/2 md:mt-0 md:ml-2 md:-translate-y-1/2'
43
- : align === 'start'
44
- ? 'md:left-0 md:right-auto md:top-full md:mt-2 md:ml-0 md:translate-y-0'
45
- : 'md:right-0 md:left-auto md:top-full md:mt-2 md:ml-0 md:translate-y-0', open ? 'block' : 'hidden', lib.themeBorderColor), role: "tooltip", children: normalizedContent })] }));
100
+ }, className: utils.cn('inline-flex h-5 w-5 items-center justify-center rounded-full text-slate-400 transition', 'hover:bg-black/5 hover:dark:bg-white/5', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-1 dark:focus-visible:ring-offset-slate-950', 'hover:text-slate-700 dark:hover:text-white focus-visible:text-slate-700 dark:focus-visible:text-white', lib.themeIconColor, lib.themeRingColor), "aria-label": normalizedContent, "aria-expanded": open, children: jsxRuntime.jsx(icons.CircleQuestionMarkIcon, { className: "h-4 w-4" }) }), open && position
101
+ ? reactDom.createPortal(jsxRuntime.jsx("span", { ref: tooltipRef, className: utils.cn('pointer-events-none fixed z-50 max-h-[calc(100vh-1.5rem)] overflow-y-auto rounded-2xl border bg-white/95 px-3 py-2 text-xs leading-5 text-slate-600 shadow-xl backdrop-blur-sm dark:bg-slate-950/95 dark:text-slate-300', position.side === 'inline' && '-translate-y-1/2', lib.themeBorderColor), style: {
102
+ left: position.left,
103
+ top: position.top,
104
+ width: position.maxWidth,
105
+ }, role: "tooltip", children: normalizedContent }), document.body)
106
+ : null] }));
46
107
  }
47
108
 
48
109
  exports.InfoTooltip = InfoTooltip;
@@ -1,21 +1,69 @@
1
1
  "use client";
2
2
  import { jsxs, jsx } from 'react/jsx-runtime';
3
3
  import { useRef, useState, useEffect } from 'react';
4
+ import { createPortal } from 'react-dom';
4
5
  import { CircleQuestionMarkIcon } from '@windrun-huaiin/base-ui/icons';
5
6
  import { themeIconColor, themeRingColor, themeBorderColor } from '@windrun-huaiin/base-ui/lib';
6
7
  import { cn } from '@windrun-huaiin/lib/utils';
7
8
 
9
+ const TOOLTIP_MARGIN = 12;
10
+ const TOOLTIP_GAP = 8;
11
+ const TOOLTIP_MAX_WIDTH = 288;
12
+ function clamp(value, min, max) {
13
+ return Math.min(Math.max(value, min), max);
14
+ }
15
+ function getTooltipPosition(target, align, desktopSide) {
16
+ const rect = target.getBoundingClientRect();
17
+ const viewportWidth = window.innerWidth;
18
+ const viewportHeight = window.innerHeight;
19
+ const maxWidth = Math.min(TOOLTIP_MAX_WIDTH, Math.max(160, viewportWidth - TOOLTIP_MARGIN * 2));
20
+ const useInlineSide = desktopSide === 'right' && viewportWidth >= 768;
21
+ if (useInlineSide) {
22
+ const rightSpace = viewportWidth - rect.right - TOOLTIP_GAP - TOOLTIP_MARGIN;
23
+ const leftSpace = rect.left - TOOLTIP_GAP - TOOLTIP_MARGIN;
24
+ const placeRight = rightSpace >= Math.min(220, maxWidth) || rightSpace >= leftSpace;
25
+ const preferredLeft = placeRight
26
+ ? rect.right + TOOLTIP_GAP
27
+ : rect.left - maxWidth - TOOLTIP_GAP;
28
+ return {
29
+ left: clamp(preferredLeft, TOOLTIP_MARGIN, viewportWidth - maxWidth - TOOLTIP_MARGIN),
30
+ top: clamp(rect.top + rect.height / 2, TOOLTIP_MARGIN + 40, viewportHeight - TOOLTIP_MARGIN - 40),
31
+ maxWidth,
32
+ side: 'inline',
33
+ };
34
+ }
35
+ const preferredLeft = align === 'start'
36
+ ? rect.left
37
+ : rect.right - maxWidth;
38
+ return {
39
+ left: clamp(preferredLeft, TOOLTIP_MARGIN, viewportWidth - maxWidth - TOOLTIP_MARGIN),
40
+ top: Math.min(rect.bottom + TOOLTIP_GAP, viewportHeight - TOOLTIP_MARGIN),
41
+ maxWidth,
42
+ side: 'bottom',
43
+ };
44
+ }
8
45
  function InfoTooltip({ content, className, align = 'end', desktopSide = 'right', }) {
9
46
  const normalizedContent = content.trim();
10
47
  const containerRef = useRef(null);
48
+ const tooltipRef = useRef(null);
11
49
  const [open, setOpen] = useState(false);
50
+ const [position, setPosition] = useState(null);
51
+ const updatePosition = () => {
52
+ if (!containerRef.current) {
53
+ return;
54
+ }
55
+ setPosition(getTooltipPosition(containerRef.current, align, desktopSide));
56
+ };
12
57
  useEffect(() => {
13
58
  function handlePointerDown(event) {
59
+ var _a;
14
60
  if (!containerRef.current) {
15
61
  return;
16
62
  }
17
63
  const target = event.target;
18
- if (target instanceof Node && !containerRef.current.contains(target)) {
64
+ if (target instanceof Node &&
65
+ !containerRef.current.contains(target) &&
66
+ !((_a = tooltipRef.current) === null || _a === void 0 ? void 0 : _a.contains(target))) {
19
67
  setOpen(false);
20
68
  }
21
69
  }
@@ -26,21 +74,34 @@ function InfoTooltip({ content, className, align = 'end', desktopSide = 'right',
26
74
  document.removeEventListener('touchstart', handlePointerDown);
27
75
  };
28
76
  }, []);
77
+ useEffect(() => {
78
+ if (!open) {
79
+ setPosition(null);
80
+ return;
81
+ }
82
+ updatePosition();
83
+ window.addEventListener('resize', updatePosition);
84
+ window.addEventListener('scroll', updatePosition, true);
85
+ return () => {
86
+ window.removeEventListener('resize', updatePosition);
87
+ window.removeEventListener('scroll', updatePosition, true);
88
+ };
89
+ }, [align, desktopSide, open]);
29
90
  if (!normalizedContent) {
30
91
  return null;
31
92
  }
32
- return (jsxs("span", { ref: containerRef, className: cn('relative inline-flex h-5 w-5 shrink-0 align-middle', className), onMouseLeave: () => setOpen(false), children: [jsx("button", { type: "button", onMouseEnter: () => setOpen(true), onPointerDown: (event) => {
93
+ return (jsxs("span", { ref: containerRef, className: cn('inline-flex h-5 w-5 shrink-0 align-middle', className), onMouseLeave: () => setOpen(false), children: [jsx("button", { type: "button", onMouseEnter: () => setOpen(true), onPointerDown: (event) => {
33
94
  event.stopPropagation();
34
95
  }, onClick: (event) => {
35
96
  event.stopPropagation();
36
97
  setOpen((value) => !value);
37
- }, className: cn('inline-flex h-5 w-5 items-center justify-center rounded-full text-slate-400 transition', 'hover:bg-black/5 hover:dark:bg-white/5', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-1 dark:focus-visible:ring-offset-slate-950', 'hover:text-slate-700 dark:hover:text-white focus-visible:text-slate-700 dark:focus-visible:text-white', themeIconColor, themeRingColor), "aria-label": normalizedContent, "aria-expanded": open, children: jsx(CircleQuestionMarkIcon, { className: "h-4 w-4" }) }), jsx("span", { className: cn('pointer-events-none absolute top-full z-50 mt-2 w-[min(18rem,calc(100vw-2rem))] rounded-2xl border bg-white/95 px-3 py-2 text-xs leading-5 text-slate-600 shadow-xl backdrop-blur-sm dark:bg-slate-950/95 dark:text-slate-300', align === 'start' ? 'left-0 right-auto' : 'right-0 left-auto', desktopSide === 'right'
38
- ? align === 'start'
39
- ? 'sm:left-0 sm:right-auto md:left-full md:right-auto md:top-1/2 md:mt-0 md:ml-2 md:-translate-y-1/2'
40
- : 'sm:right-0 sm:left-auto md:left-full md:right-auto md:top-1/2 md:mt-0 md:ml-2 md:-translate-y-1/2'
41
- : align === 'start'
42
- ? 'md:left-0 md:right-auto md:top-full md:mt-2 md:ml-0 md:translate-y-0'
43
- : 'md:right-0 md:left-auto md:top-full md:mt-2 md:ml-0 md:translate-y-0', open ? 'block' : 'hidden', themeBorderColor), role: "tooltip", children: normalizedContent })] }));
98
+ }, className: cn('inline-flex h-5 w-5 items-center justify-center rounded-full text-slate-400 transition', 'hover:bg-black/5 hover:dark:bg-white/5', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-1 dark:focus-visible:ring-offset-slate-950', 'hover:text-slate-700 dark:hover:text-white focus-visible:text-slate-700 dark:focus-visible:text-white', themeIconColor, themeRingColor), "aria-label": normalizedContent, "aria-expanded": open, children: jsx(CircleQuestionMarkIcon, { className: "h-4 w-4" }) }), open && position
99
+ ? createPortal(jsx("span", { ref: tooltipRef, className: cn('pointer-events-none fixed z-50 max-h-[calc(100vh-1.5rem)] overflow-y-auto rounded-2xl border bg-white/95 px-3 py-2 text-xs leading-5 text-slate-600 shadow-xl backdrop-blur-sm dark:bg-slate-950/95 dark:text-slate-300', position.side === 'inline' && '-translate-y-1/2', themeBorderColor), style: {
100
+ left: position.left,
101
+ top: position.top,
102
+ width: position.maxWidth,
103
+ }, role: "tooltip", children: normalizedContent }), document.body)
104
+ : null] }));
44
105
  }
45
106
 
46
107
  export { InfoTooltip };
@@ -1 +1,2 @@
1
1
  export { SnakeLoadingFrame, SnakeLoadingPreview } from '../snake-loading-frame';
2
+ export type { SnakeLoadingFrameProps, SnakeLoadingPreviewProps, } from '../snake-loading-frame';
@@ -5,6 +5,7 @@ interface LoadingProps {
5
5
  className?: string;
6
6
  label?: string;
7
7
  labelClassName?: string;
8
+ paused?: boolean;
8
9
  }
9
- export declare function Loading({ themeColor, compact, className, label, labelClassName, }?: LoadingProps): import("react/jsx-runtime").JSX.Element;
10
+ export declare function Loading({ themeColor, compact, className, label, labelClassName, paused, }?: LoadingProps): import("react/jsx-runtime").JSX.Element;
10
11
  export {};
@@ -2,8 +2,10 @@
2
2
  'use strict';
3
3
 
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
+ var React = require('react');
5
6
  var utils = require('@windrun-huaiin/lib/utils');
6
7
  var lib = require('@windrun-huaiin/base-ui/lib');
8
+ var animejs = require('animejs');
7
9
 
8
10
  const NUM_ROWS = 15;
9
11
  const NUM_COLS = 15;
@@ -53,36 +55,77 @@ function createLoadingPalette(baseHex) {
53
55
  shiftColor(baseHex, { r: -24, g: -14, b: 6 }),
54
56
  ];
55
57
  }
56
- function Loading({ themeColor = lib.themeSvgIconColor, compact = false, className, label = 'Loading...', labelClassName, } = {}) {
57
- const colors = createLoadingPalette(themeColor);
58
- const dots = [];
58
+ function Loading({ themeColor = lib.themeSvgIconColor, compact = false, className, label = 'Loading...', labelClassName, paused = false, } = {}) {
59
+ const gridRef = React.useRef(null);
60
+ const animationRef = React.useRef(null);
61
+ const pausedRef = React.useRef(paused);
62
+ const colors = React.useMemo(() => createLoadingPalette(themeColor), [themeColor]);
59
63
  const centerX = (NUM_COLS - 1) / 2;
60
64
  const centerY = (NUM_ROWS - 1) / 2;
61
- for (let i = 0; i < NUM_ROWS; i++) {
62
- for (let j = 0; j < NUM_COLS; j++) {
63
- // Calculate distance from the center of the grid
64
- const distance = Math.sqrt(Math.pow(i - centerY, 2) + Math.pow(j - centerX, 2));
65
- dots.push({
66
- id: `${i}-${j}`,
67
- row: i,
68
- col: j,
69
- // Animation delay based on distance, creating a ripple effect
70
- delay: distance * STAGGER_DELAY_FACTOR,
71
- // Color selection based on distance rings
72
- color: colors[Math.floor(distance) % colors.length],
73
- });
65
+ const dots = React.useMemo(() => {
66
+ const nextDots = [];
67
+ for (let i = 0; i < NUM_ROWS; i++) {
68
+ for (let j = 0; j < NUM_COLS; j++) {
69
+ const distance = Math.sqrt(Math.pow(i - centerY, 2) + Math.pow(j - centerX, 2));
70
+ nextDots.push({
71
+ id: `${i}-${j}`,
72
+ row: i,
73
+ col: j,
74
+ delay: distance * STAGGER_DELAY_FACTOR,
75
+ color: colors[Math.floor(distance) % colors.length],
76
+ });
77
+ }
74
78
  }
75
- }
79
+ return nextDots;
80
+ }, [centerX, centerY, colors]);
76
81
  // Calculate the total width and height of the dot container
77
82
  const containerWidth = (NUM_COLS - 1) * SPACING + DOT_SIZE;
78
83
  const containerHeight = (NUM_ROWS - 1) * SPACING + DOT_SIZE;
79
- return (jsxRuntime.jsx("div", { className: utils.cn('flex flex-col items-center justify-center bg-neutral-100 dark:bg-neutral-900', compact ? 'min-h-[250px] rounded-[28px] px-4 py-2' : 'min-h-screen', className), children: jsxRuntime.jsxs("div", { style: {
84
+ pausedRef.current = paused;
85
+ React.useEffect(() => {
86
+ var _a;
87
+ const grid = gridRef.current;
88
+ if (!grid) {
89
+ return undefined;
90
+ }
91
+ const dotNodes = Array.from(grid.querySelectorAll('[data-loading-dot]'));
92
+ (_a = animationRef.current) === null || _a === void 0 ? void 0 : _a.revert();
93
+ animationRef.current = animejs.animate(dotNodes, {
94
+ opacity: [0, 1, 0.7, 0],
95
+ scale: [0.2, 1.2, 0.8, 0.2],
96
+ duration: ANIMATION_DURATION * 1000,
97
+ delay: (target) => { var _a; return Number((_a = target === null || target === void 0 ? void 0 : target.dataset.loadingDelay) !== null && _a !== void 0 ? _a : 0) * 1000; },
98
+ ease: 'inOutSine',
99
+ loop: true,
100
+ });
101
+ if (pausedRef.current) {
102
+ animationRef.current.pause();
103
+ }
104
+ return () => {
105
+ var _a;
106
+ (_a = animationRef.current) === null || _a === void 0 ? void 0 : _a.revert();
107
+ animationRef.current = null;
108
+ };
109
+ }, [dots]);
110
+ React.useEffect(() => {
111
+ const animation = animationRef.current;
112
+ if (!animation) {
113
+ return;
114
+ }
115
+ if (paused) {
116
+ animation.pause();
117
+ }
118
+ else {
119
+ animation.play();
120
+ }
121
+ }, [paused]);
122
+ return (jsxRuntime.jsx("div", { className: utils.cn('flex flex-col items-center justify-center bg-neutral-100 dark:bg-neutral-900', compact ? 'min-h-[250px] rounded-[28px] px-4 py-2' : 'min-h-screen', className), children: jsxRuntime.jsxs("div", { ref: gridRef, style: {
80
123
  width: containerWidth,
81
124
  height: containerHeight,
82
125
  position: 'relative',
83
126
  borderRadius: '50%', // Make the container circular
84
127
  overflow: 'hidden', // Clip dots outside the circle
85
- }, children: [dots.map(dot => (jsxRuntime.jsx("div", { style: {
128
+ }, children: [dots.map(dot => (jsxRuntime.jsx("div", { "data-loading-dot": "", "data-loading-delay": dot.delay, style: {
86
129
  position: 'absolute',
87
130
  left: dot.col * SPACING,
88
131
  top: dot.row * SPACING,
@@ -90,13 +133,8 @@ function Loading({ themeColor = lib.themeSvgIconColor, compact = false, classNam
90
133
  height: DOT_SIZE,
91
134
  backgroundColor: dot.color,
92
135
  borderRadius: '50%',
93
- animationName: 'loading-dot-pulse',
94
- animationDuration: `${ANIMATION_DURATION}s`,
95
- animationTimingFunction: 'cubic-bezier(0.45, 0, 0.55, 1)',
96
- animationIterationCount: 'infinite',
97
- animationDelay: `${dot.delay}s`,
98
- opacity: 0,
99
- transform: 'scale(0)',
136
+ opacity: 0.35,
137
+ transform: 'scale(0.2)',
100
138
  } }, dot.id))), jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center", style: { pointerEvents: 'none' }, children: jsxRuntime.jsx("p", { className: utils.cn('text-xl font-semibold text-white', labelClassName), children: label }) })] }) }));
101
139
  }
102
140
 
@@ -1,7 +1,9 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from 'react/jsx-runtime';
3
+ import { useRef, useMemo, useEffect } from 'react';
3
4
  import { cn } from '@windrun-huaiin/lib/utils';
4
5
  import { themeSvgIconColor } from '@windrun-huaiin/base-ui/lib';
6
+ import { animate } from 'animejs';
5
7
 
6
8
  const NUM_ROWS = 15;
7
9
  const NUM_COLS = 15;
@@ -51,36 +53,77 @@ function createLoadingPalette(baseHex) {
51
53
  shiftColor(baseHex, { r: -24, g: -14, b: 6 }),
52
54
  ];
53
55
  }
54
- function Loading({ themeColor = themeSvgIconColor, compact = false, className, label = 'Loading...', labelClassName, } = {}) {
55
- const colors = createLoadingPalette(themeColor);
56
- const dots = [];
56
+ function Loading({ themeColor = themeSvgIconColor, compact = false, className, label = 'Loading...', labelClassName, paused = false, } = {}) {
57
+ const gridRef = useRef(null);
58
+ const animationRef = useRef(null);
59
+ const pausedRef = useRef(paused);
60
+ const colors = useMemo(() => createLoadingPalette(themeColor), [themeColor]);
57
61
  const centerX = (NUM_COLS - 1) / 2;
58
62
  const centerY = (NUM_ROWS - 1) / 2;
59
- for (let i = 0; i < NUM_ROWS; i++) {
60
- for (let j = 0; j < NUM_COLS; j++) {
61
- // Calculate distance from the center of the grid
62
- const distance = Math.sqrt(Math.pow(i - centerY, 2) + Math.pow(j - centerX, 2));
63
- dots.push({
64
- id: `${i}-${j}`,
65
- row: i,
66
- col: j,
67
- // Animation delay based on distance, creating a ripple effect
68
- delay: distance * STAGGER_DELAY_FACTOR,
69
- // Color selection based on distance rings
70
- color: colors[Math.floor(distance) % colors.length],
71
- });
63
+ const dots = useMemo(() => {
64
+ const nextDots = [];
65
+ for (let i = 0; i < NUM_ROWS; i++) {
66
+ for (let j = 0; j < NUM_COLS; j++) {
67
+ const distance = Math.sqrt(Math.pow(i - centerY, 2) + Math.pow(j - centerX, 2));
68
+ nextDots.push({
69
+ id: `${i}-${j}`,
70
+ row: i,
71
+ col: j,
72
+ delay: distance * STAGGER_DELAY_FACTOR,
73
+ color: colors[Math.floor(distance) % colors.length],
74
+ });
75
+ }
72
76
  }
73
- }
77
+ return nextDots;
78
+ }, [centerX, centerY, colors]);
74
79
  // Calculate the total width and height of the dot container
75
80
  const containerWidth = (NUM_COLS - 1) * SPACING + DOT_SIZE;
76
81
  const containerHeight = (NUM_ROWS - 1) * SPACING + DOT_SIZE;
77
- return (jsx("div", { className: cn('flex flex-col items-center justify-center bg-neutral-100 dark:bg-neutral-900', compact ? 'min-h-[250px] rounded-[28px] px-4 py-2' : 'min-h-screen', className), children: jsxs("div", { style: {
82
+ pausedRef.current = paused;
83
+ useEffect(() => {
84
+ var _a;
85
+ const grid = gridRef.current;
86
+ if (!grid) {
87
+ return undefined;
88
+ }
89
+ const dotNodes = Array.from(grid.querySelectorAll('[data-loading-dot]'));
90
+ (_a = animationRef.current) === null || _a === void 0 ? void 0 : _a.revert();
91
+ animationRef.current = animate(dotNodes, {
92
+ opacity: [0, 1, 0.7, 0],
93
+ scale: [0.2, 1.2, 0.8, 0.2],
94
+ duration: ANIMATION_DURATION * 1000,
95
+ delay: (target) => { var _a; return Number((_a = target === null || target === void 0 ? void 0 : target.dataset.loadingDelay) !== null && _a !== void 0 ? _a : 0) * 1000; },
96
+ ease: 'inOutSine',
97
+ loop: true,
98
+ });
99
+ if (pausedRef.current) {
100
+ animationRef.current.pause();
101
+ }
102
+ return () => {
103
+ var _a;
104
+ (_a = animationRef.current) === null || _a === void 0 ? void 0 : _a.revert();
105
+ animationRef.current = null;
106
+ };
107
+ }, [dots]);
108
+ useEffect(() => {
109
+ const animation = animationRef.current;
110
+ if (!animation) {
111
+ return;
112
+ }
113
+ if (paused) {
114
+ animation.pause();
115
+ }
116
+ else {
117
+ animation.play();
118
+ }
119
+ }, [paused]);
120
+ return (jsx("div", { className: cn('flex flex-col items-center justify-center bg-neutral-100 dark:bg-neutral-900', compact ? 'min-h-[250px] rounded-[28px] px-4 py-2' : 'min-h-screen', className), children: jsxs("div", { ref: gridRef, style: {
78
121
  width: containerWidth,
79
122
  height: containerHeight,
80
123
  position: 'relative',
81
124
  borderRadius: '50%', // Make the container circular
82
125
  overflow: 'hidden', // Clip dots outside the circle
83
- }, children: [dots.map(dot => (jsx("div", { style: {
126
+ }, children: [dots.map(dot => (jsx("div", { "data-loading-dot": "", "data-loading-delay": dot.delay, style: {
84
127
  position: 'absolute',
85
128
  left: dot.col * SPACING,
86
129
  top: dot.row * SPACING,
@@ -88,13 +131,8 @@ function Loading({ themeColor = themeSvgIconColor, compact = false, className, l
88
131
  height: DOT_SIZE,
89
132
  backgroundColor: dot.color,
90
133
  borderRadius: '50%',
91
- animationName: 'loading-dot-pulse',
92
- animationDuration: `${ANIMATION_DURATION}s`,
93
- animationTimingFunction: 'cubic-bezier(0.45, 0, 0.55, 1)',
94
- animationIterationCount: 'infinite',
95
- animationDelay: `${dot.delay}s`,
96
- opacity: 0,
97
- transform: 'scale(0)',
134
+ opacity: 0.35,
135
+ transform: 'scale(0.2)',
98
136
  } }, dot.id))), jsx("div", { className: "absolute inset-0 flex items-center justify-center", style: { pointerEvents: 'none' }, children: jsx("p", { className: cn('text-xl font-semibold text-white', labelClassName), children: label }) })] }) }));
99
137
  }
100
138
 
@@ -0,0 +1,7 @@
1
+ import { ReactNode } from 'react';
2
+ interface CreativeLeftPanelProps {
3
+ children: ReactNode;
4
+ className?: string;
5
+ }
6
+ export declare function CreativeLeftPanel({ children, className }: CreativeLeftPanelProps): import("react/jsx-runtime").JSX.Element;
7
+ export {};
@@ -0,0 +1,11 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var react = require('motion/react');
6
+
7
+ function CreativeLeftPanel({ children, className = '' }) {
8
+ return (jsxRuntime.jsx("div", { className: `relative h-full ${className}`, children: jsxRuntime.jsxs("div", { className: "relative h-full overflow-hidden rounded-[28px] border border-border/60 bg-background/95 backdrop-blur-2xl shadow-xl", children: [jsxRuntime.jsx("div", { className: "absolute -left-1 -top-1 z-30", children: jsxRuntime.jsxs("div", { className: "relative h-28 w-32 bg-linear-to-br from-orange-500 via-orange-600 to-orange-700 rounded-br-[2.75rem] shadow-lg", children: [jsxRuntime.jsx("div", { className: "absolute left-4 top-4 h-10 w-10 rounded-full bg-white/30 blur-sm" }), jsxRuntime.jsx("div", { className: "absolute left-6 top-6 h-5 w-14 rotate-12 rounded bg-white/20" })] }) }), jsxRuntime.jsxs("svg", { className: "absolute bottom-0 left-0 z-20 h-[380px] w-full pointer-events-none", viewBox: "0 0 680 420", preserveAspectRatio: "none", fill: "none", children: [jsxRuntime.jsx("defs", { children: jsxRuntime.jsxs("linearGradient", { id: "leftGlow", x1: "0%", y1: "100%", x2: "100%", y2: "30%", children: [jsxRuntime.jsx("stop", { offset: "0%", stopColor: "#f97316", stopOpacity: "0.25" }), jsxRuntime.jsx("stop", { offset: "100%", stopColor: "#fb923c", stopOpacity: "0.08" })] }) }), jsxRuntime.jsx(react.motion.path, { d: "M 0 380 \n Q 85 425 165 355 \n Q 255 265 355 285 \n Q 480 310 555 245 \n Q 615 195 680 235", stroke: "url(#leftGlow)", strokeWidth: "22", strokeLinecap: "round", strokeLinejoin: "round", initial: { pathLength: 0 }, animate: { pathLength: 1 }, transition: { duration: 2.4, ease: "easeOut" } }), jsxRuntime.jsx(react.motion.path, { d: "M 0 380 \n Q 85 425 165 355 \n Q 255 265 355 285 \n Q 480 310 555 245 \n Q 615 195 680 235", stroke: "#fbbf24", strokeWidth: "3", strokeOpacity: "0.45", initial: { pathLength: 0 }, animate: { pathLength: 1 }, transition: { duration: 2.6, ease: "easeOut" } })] }), jsxRuntime.jsx("div", { className: "relative z-10 h-full p-6 sm:p-8 pb-16", children: children })] }) }));
9
+ }
10
+
11
+ exports.CreativeLeftPanel = CreativeLeftPanel;
@@ -0,0 +1,9 @@
1
+ "use client";
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
+ import { motion } from 'motion/react';
4
+
5
+ function CreativeLeftPanel({ children, className = '' }) {
6
+ return (jsx("div", { className: `relative h-full ${className}`, children: jsxs("div", { className: "relative h-full overflow-hidden rounded-[28px] border border-border/60 bg-background/95 backdrop-blur-2xl shadow-xl", children: [jsx("div", { className: "absolute -left-1 -top-1 z-30", children: jsxs("div", { className: "relative h-28 w-32 bg-linear-to-br from-orange-500 via-orange-600 to-orange-700 rounded-br-[2.75rem] shadow-lg", children: [jsx("div", { className: "absolute left-4 top-4 h-10 w-10 rounded-full bg-white/30 blur-sm" }), jsx("div", { className: "absolute left-6 top-6 h-5 w-14 rotate-12 rounded bg-white/20" })] }) }), jsxs("svg", { className: "absolute bottom-0 left-0 z-20 h-[380px] w-full pointer-events-none", viewBox: "0 0 680 420", preserveAspectRatio: "none", fill: "none", children: [jsx("defs", { children: jsxs("linearGradient", { id: "leftGlow", x1: "0%", y1: "100%", x2: "100%", y2: "30%", children: [jsx("stop", { offset: "0%", stopColor: "#f97316", stopOpacity: "0.25" }), jsx("stop", { offset: "100%", stopColor: "#fb923c", stopOpacity: "0.08" })] }) }), jsx(motion.path, { d: "M 0 380 \n Q 85 425 165 355 \n Q 255 265 355 285 \n Q 480 310 555 245 \n Q 615 195 680 235", stroke: "url(#leftGlow)", strokeWidth: "22", strokeLinecap: "round", strokeLinejoin: "round", initial: { pathLength: 0 }, animate: { pathLength: 1 }, transition: { duration: 2.4, ease: "easeOut" } }), jsx(motion.path, { d: "M 0 380 \n Q 85 425 165 355 \n Q 255 265 355 285 \n Q 480 310 555 245 \n Q 615 195 680 235", stroke: "#fbbf24", strokeWidth: "3", strokeOpacity: "0.45", initial: { pathLength: 0 }, animate: { pathLength: 1 }, transition: { duration: 2.6, ease: "easeOut" } })] }), jsx("div", { className: "relative z-10 h-full p-6 sm:p-8 pb-16", children: children })] }) }));
7
+ }
8
+
9
+ export { CreativeLeftPanel };
@@ -0,0 +1,7 @@
1
+ import { ReactNode } from 'react';
2
+ interface CreativeRightPanelProps {
3
+ children: ReactNode;
4
+ className?: string;
5
+ }
6
+ export declare function CreativeRightPanel({ children, className }: CreativeRightPanelProps): import("react/jsx-runtime").JSX.Element;
7
+ export {};
@@ -0,0 +1,11 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var react = require('motion/react');
6
+
7
+ function CreativeRightPanel({ children, className = '' }) {
8
+ return (jsxRuntime.jsx("div", { className: `relative h-full ${className}`, children: jsxRuntime.jsxs("div", { className: "relative h-full overflow-hidden rounded-[28px] border border-border/60 bg-background/95 backdrop-blur-2xl shadow-xl", children: [jsxRuntime.jsx("svg", { className: "absolute bottom-0 right-0 z-20 h-[380px] w-full pointer-events-none", viewBox: "0 0 680 420", preserveAspectRatio: "none", fill: "none", children: jsxRuntime.jsx(react.motion.path, { d: "M 0 235 \n Q 65 195 145 245 \n Q 220 310 345 285 \n Q 445 265 535 355 \n Q 615 425 680 380", stroke: "#f97316", strokeWidth: "18", strokeOpacity: "0.18", strokeLinecap: "round", strokeLinejoin: "round", initial: { pathLength: 0 }, animate: { pathLength: 1 }, transition: { duration: 2.2, ease: "easeOut" } }) }), jsxRuntime.jsx("div", { className: "relative z-10 h-full p-6 sm:p-8 pb-12", children: children })] }) }));
9
+ }
10
+
11
+ exports.CreativeRightPanel = CreativeRightPanel;
@@ -0,0 +1,9 @@
1
+ "use client";
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
+ import { motion } from 'motion/react';
4
+
5
+ function CreativeRightPanel({ children, className = '' }) {
6
+ return (jsx("div", { className: `relative h-full ${className}`, children: jsxs("div", { className: "relative h-full overflow-hidden rounded-[28px] border border-border/60 bg-background/95 backdrop-blur-2xl shadow-xl", children: [jsx("svg", { className: "absolute bottom-0 right-0 z-20 h-[380px] w-full pointer-events-none", viewBox: "0 0 680 420", preserveAspectRatio: "none", fill: "none", children: jsx(motion.path, { d: "M 0 235 \n Q 65 195 145 245 \n Q 220 310 345 285 \n Q 445 265 535 355 \n Q 615 425 680 380", stroke: "#f97316", strokeWidth: "18", strokeOpacity: "0.18", strokeLinecap: "round", strokeLinejoin: "round", initial: { pathLength: 0 }, animate: { pathLength: 1 }, transition: { duration: 2.2, ease: "easeOut" } }) }), jsx("div", { className: "relative z-10 h-full p-6 sm:p-8 pb-12", children: children })] }) }));
7
+ }
8
+
9
+ export { CreativeRightPanel };
@@ -0,0 +1 @@
1
+ export { MotionBeamFrame, MotionBeamFrame as BeamFrame, type BeamFrameProps, type BeamFrameTone, } from './motion-beam-frame';
@@ -0,0 +1,9 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var motionBeamFrame = require('./motion-beam-frame.js');
5
+
6
+
7
+
8
+ exports.BeamFrame = motionBeamFrame.MotionBeamFrame;
9
+ exports.MotionBeamFrame = motionBeamFrame.MotionBeamFrame;
@@ -0,0 +1,2 @@
1
+ "use client";
2
+ export { MotionBeamFrame as BeamFrame, MotionBeamFrame } from './motion-beam-frame.mjs';
@@ -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 MotionBeamFrame(props: BeamFrameProps): import("react/jsx-runtime").JSX.Element;