@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
@@ -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;
@@ -0,0 +1,75 @@
1
+ "use client";
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import { useRef, useMemo, useEffect } from 'react';
4
+ import { utils, createTimeline, stagger } from 'animejs';
5
+ import { cn } from '@windrun-huaiin/lib/utils';
6
+
7
+ const DEFAULT_DOT_COUNT = 2024;
8
+ const DEFAULT_DURATION = 10000;
9
+ const DEFAULT_DISTANCE_REM = 20;
10
+ const DEFAULT_DOT_SIZE_EM = 1;
11
+ const DEFAULT_FONT_SIZE = 20;
12
+ 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, }) {
13
+ const rootRef = useRef(null);
14
+ const timelineRef = useRef(null);
15
+ const pausedRef = useRef(paused);
16
+ const safeDotCount = Math.max(1, Math.floor(dotCount));
17
+ const safeDuration = Math.max(1, duration);
18
+ const angle = useMemo(() => (index) => utils.mapRange(index, 0, safeDotCount, 0, Math.PI * 100), [safeDotCount]);
19
+ const dots = useMemo(() => Array.from({ length: safeDotCount }, (_, index) => {
20
+ const hue = utils.round((360 / safeDotCount) * index, 0);
21
+ return {
22
+ id: index,
23
+ background: `hsl(${hue}, 60%, 60%)`,
24
+ };
25
+ }), [safeDotCount]);
26
+ pausedRef.current = paused;
27
+ useEffect(() => {
28
+ var _a;
29
+ const root = rootRef.current;
30
+ if (!root) {
31
+ return undefined;
32
+ }
33
+ const dotNodes = Array.from(root.querySelectorAll('[data-anime-spiral-dot]'));
34
+ (_a = timelineRef.current) === null || _a === void 0 ? void 0 : _a.revert();
35
+ timelineRef.current = createTimeline()
36
+ .add(dotNodes, {
37
+ x: (_target, i) => `${Math.sin(angle(i)) * distanceRem}rem`,
38
+ y: (_target, i) => `${Math.cos(angle(i)) * distanceRem}rem`,
39
+ scale: [0, 0.4, 0.2, 0.9, 0],
40
+ playbackEase: 'inOutSine',
41
+ loop: true,
42
+ duration: safeDuration,
43
+ }, stagger([0, safeDuration]))
44
+ .init()
45
+ .seek(safeDuration);
46
+ if (pausedRef.current) {
47
+ timelineRef.current.pause();
48
+ }
49
+ return () => {
50
+ var _a;
51
+ (_a = timelineRef.current) === null || _a === void 0 ? void 0 : _a.revert();
52
+ timelineRef.current = null;
53
+ };
54
+ }, [angle, distanceRem, safeDuration, dots]);
55
+ useEffect(() => {
56
+ const timeline = timelineRef.current;
57
+ if (!timeline) {
58
+ return;
59
+ }
60
+ if (paused) {
61
+ timeline.pause();
62
+ }
63
+ else {
64
+ timeline.play();
65
+ }
66
+ }, [paused]);
67
+ return (jsx("div", { ref: rootRef, className: cn('relative h-dvh w-full overflow-hidden', className), style: { fontSize }, "aria-hidden": "true", children: dots.map(dot => (jsx("div", { "data-anime-spiral-dot": "", className: "absolute left-1/2 top-1/2 rounded-full", style: {
68
+ width: `${dotSizeEm}em`,
69
+ height: `${dotSizeEm}em`,
70
+ margin: `${dotSizeEm / -2}em 0 0 ${dotSizeEm / -2}em`,
71
+ backgroundColor: dot.background,
72
+ } }, dot.id))) }));
73
+ }
74
+
75
+ export { AnimeSpiralLoading };
@@ -0,0 +1,3 @@
1
+ export { AnimeBeamFrame, type BeamFrameProps, type BeamFrameTone, } from './anime-beam-frame';
2
+ export { AnimeSpiralLoading, type AnimeSpiralLoadingProps } from './anime-spiral-loading';
3
+ export { AnimeNotFoundPage, type AnimeNotFoundPageProps } from './anime-404-page';
@@ -0,0 +1,12 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var animeBeamFrame = require('./anime-beam-frame.js');
5
+ var animeSpiralLoading = require('./anime-spiral-loading.js');
6
+ var anime404Page = require('./anime-404-page.js');
7
+
8
+
9
+
10
+ exports.AnimeBeamFrame = animeBeamFrame.AnimeBeamFrame;
11
+ exports.AnimeSpiralLoading = animeSpiralLoading.AnimeSpiralLoading;
12
+ exports.AnimeNotFoundPage = anime404Page.AnimeNotFoundPage;
@@ -0,0 +1,4 @@
1
+ "use client";
2
+ export { AnimeBeamFrame } from './anime-beam-frame.mjs';
3
+ export { AnimeSpiralLoading } from './anime-spiral-loading.mjs';
4
+ export { AnimeNotFoundPage } from './anime-404-page.mjs';
@@ -0,0 +1,3 @@
1
+ import { type BeamFrameProps } from './share-config';
2
+ export type { BeamFrameProps, BeamFrameTone } from './share-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 shareConfig = require('./share-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 = shareConfig.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: shareConfig.BASE_DURATION_SECONDS * 1000,
39
+ ease: 'linear',
40
+ });
41
+ animationRef.current.speed = shareConfig.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(shareConfig.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 = shareConfig.BASE_DURATION_SECONDS, radius, className, } = props;
55
+ const prefersReducedMotion = react.useReducedMotion();
56
+ const { isRunning, interactionProps } = shareConfig.useInteractiveRunning(active, interactive);
57
+ const shouldRun = isRunning && !prefersReducedMotion;
58
+ const normalizedDuration = shareConfig.normalizeDuration(duration);
59
+ const { ref, size } = shareConfig.useMeasuredFrameSize();
60
+ return (jsxRuntime.jsx(shareConfig.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 './share-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,4 @@
1
+ export { AnimeBeamFrame } from './animate';
2
+ export { MotionBeamFrame } from './motion';
3
+ export { MotionBeamFrame as BeamFrame } from './motion';
4
+ export type { BeamFrameProps, BeamFrameTone } from './share-config';
@@ -0,0 +1,262 @@
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 lib = require('@windrun-huaiin/base-ui/lib');
9
+ var utils = require('@windrun-huaiin/lib/utils');
10
+
11
+ const THEME_PALETTES = {
12
+ purple: { a: '#AC62FD', b: '#EC4899', c: '#6366F1' },
13
+ orange: { a: '#F97316', b: '#F59E0B', c: '#EF4444' },
14
+ indigo: { a: '#6366F1', b: '#3B82F6', c: '#06B6D4' },
15
+ emerald: { a: '#10B981', b: '#14B8A6', c: '#22C55E' },
16
+ rose: { a: '#F43F5E', b: '#EC4899', c: '#FB7185' },
17
+ };
18
+ const TONE_PALETTES = {
19
+ rainbow: { a: '#22D3EE', b: '#A855F7', c: '#F97316' },
20
+ mono: { a: '#E5E7EB', b: '#94A3B8', c: '#FFFFFF' },
21
+ warm: { a: '#F97316', b: '#FBBF24', c: '#EF4444' },
22
+ cool: { a: '#06B6D4', b: '#6366F1', c: '#14B8A6' },
23
+ };
24
+ const INTENSITY_STYLE = {
25
+ subtle: {
26
+ beamOpacity: 0.86,
27
+ glowOpacity: 0.16,
28
+ beamLength: 0.24,
29
+ beamWidth: 2.2,
30
+ haloWidth: 6,
31
+ },
32
+ regular: {
33
+ beamOpacity: 1,
34
+ glowOpacity: 0.24,
35
+ beamLength: 0.34,
36
+ beamWidth: 3,
37
+ haloWidth: 8,
38
+ },
39
+ strong: {
40
+ beamOpacity: 1,
41
+ glowOpacity: 0.32,
42
+ beamLength: 0.46,
43
+ beamWidth: 4,
44
+ haloWidth: 10,
45
+ },
46
+ };
47
+ const BASE_BORDER_OPACITY = 0.18;
48
+ const BASE_DURATION_SECONDS = 1.8;
49
+ const DEFAULT_RADIUS = 24;
50
+ function getPalette(tone) {
51
+ var _a;
52
+ if (tone !== 'theme') {
53
+ return TONE_PALETTES[tone];
54
+ }
55
+ return (_a = THEME_PALETTES[lib.themeName]) !== null && _a !== void 0 ? _a : THEME_PALETTES.purple;
56
+ }
57
+ function normalizeDuration(duration) {
58
+ if (!Number.isFinite(duration)) {
59
+ return 1.8;
60
+ }
61
+ return Math.max(0.4, duration);
62
+ }
63
+ function useMeasuredFrameSize() {
64
+ const ref = React.useRef(null);
65
+ const [size, setSize] = React.useState({ width: 0, height: 0 });
66
+ React.useEffect(() => {
67
+ const node = ref.current;
68
+ if (!node) {
69
+ return undefined;
70
+ }
71
+ const updateSize = () => {
72
+ const rect = node.getBoundingClientRect();
73
+ setSize({
74
+ width: Math.max(0, rect.width),
75
+ height: Math.max(0, rect.height),
76
+ });
77
+ };
78
+ updateSize();
79
+ const observer = new ResizeObserver(updateSize);
80
+ observer.observe(node);
81
+ return () => observer.disconnect();
82
+ }, []);
83
+ return { ref, size };
84
+ }
85
+ function useInteractiveRunning(active, interactive) {
86
+ const [isInteractiveRunning, setIsInteractiveRunning] = React.useState(false);
87
+ const interactionProps = interactive
88
+ ? {
89
+ onMouseEnter: () => setIsInteractiveRunning(true),
90
+ onMouseLeave: () => setIsInteractiveRunning(false),
91
+ onFocus: () => setIsInteractiveRunning(true),
92
+ onBlur: () => setIsInteractiveRunning(false),
93
+ }
94
+ : {};
95
+ return {
96
+ isRunning: active || isInteractiveRunning,
97
+ interactionProps,
98
+ };
99
+ }
100
+ function createRootStyle({ intensity, tone, radius, }) {
101
+ const palette = getPalette(tone);
102
+ const intensityStyle = INTENSITY_STYLE[intensity];
103
+ const frameRadius = radius !== null && radius !== void 0 ? radius : DEFAULT_RADIUS;
104
+ const svgRadius = Math.max(0, Math.min(49, frameRadius));
105
+ return {
106
+ '--beam-frame-radius': `${frameRadius}px`,
107
+ '--beam-frame-svg-radius': svgRadius,
108
+ '--beam-frame-color-a': palette.a,
109
+ '--beam-frame-color-b': palette.b,
110
+ '--beam-frame-color-c': palette.c,
111
+ '--beam-frame-border-opacity': BASE_BORDER_OPACITY,
112
+ '--beam-frame-beam-opacity': intensityStyle.beamOpacity,
113
+ '--beam-frame-glow-opacity': intensityStyle.glowOpacity,
114
+ '--beam-frame-beam-length': intensityStyle.beamLength,
115
+ '--beam-frame-beam-width': intensityStyle.beamWidth,
116
+ '--beam-frame-halo-width': intensityStyle.haloWidth,
117
+ };
118
+ }
119
+ function createBaseBorderBackground() {
120
+ return 'rgba(148, 163, 184, var(--beam-frame-border-opacity))';
121
+ }
122
+ function createBorderRingMask() {
123
+ return {
124
+ WebkitMask: 'linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0)',
125
+ WebkitMaskComposite: 'xor',
126
+ maskComposite: 'exclude',
127
+ padding: '1px',
128
+ };
129
+ }
130
+ function BeamFrameShell({ children, className, tone, intensity, radius, isRunning, interactionProps, renderBeam, rootRef, }) {
131
+ return (jsxRuntime.jsxs("div", Object.assign({ ref: rootRef, className: utils.cn('group/beam-frame relative isolate overflow-hidden rounded-[var(--beam-frame-radius)] p-px', className), "data-beam-running": isRunning ? 'true' : 'false', style: createRootStyle({ intensity, tone, radius }) }, interactionProps, { children: [jsxRuntime.jsx("div", { "aria-hidden": "true", className: "pointer-events-none absolute inset-0 z-0 rounded-[inherit]", style: Object.assign({ background: createBaseBorderBackground() }, createBorderRingMask()) }), renderBeam(isRunning), jsxRuntime.jsx("div", { className: "relative z-10 rounded-[calc(var(--beam-frame-radius)-1px)]", children: children })] })));
132
+ }
133
+ function MotionAroundBeam({ isRunning, duration, radius, size, }) {
134
+ const gradientId = React.useId().replace(/:/g, '');
135
+ const haloGradientId = React.useId().replace(/:/g, '');
136
+ const beamGroupRef = React.useRef(null);
137
+ const controlsRef = React.useRef(null);
138
+ const hasStartedRef = React.useRef(false);
139
+ const strokeWidth = 3;
140
+ const width = Math.max(1, size.width);
141
+ const height = Math.max(1, size.height);
142
+ const rectOffset = strokeWidth / 2;
143
+ const rectWidth = Math.max(1, width - strokeWidth);
144
+ const rectHeight = Math.max(1, height - strokeWidth);
145
+ const rectRadius = Math.max(0, Math.min(radius !== null && radius !== void 0 ? radius : DEFAULT_RADIUS, rectWidth / 2, rectHeight / 2));
146
+ React.useEffect(() => {
147
+ var _a;
148
+ const node = beamGroupRef.current;
149
+ if (!node) {
150
+ return undefined;
151
+ }
152
+ if (isRunning) {
153
+ hasStartedRef.current = true;
154
+ }
155
+ node.style.opacity = isRunning || hasStartedRef.current ? 'var(--beam-frame-beam-opacity)' : '0';
156
+ if (!isRunning) {
157
+ (_a = controlsRef.current) === null || _a === void 0 ? void 0 : _a.pause();
158
+ return undefined;
159
+ }
160
+ if (controlsRef.current) {
161
+ controlsRef.current.speed = BASE_DURATION_SECONDS / duration;
162
+ controlsRef.current.play();
163
+ return undefined;
164
+ }
165
+ controlsRef.current = react.animate(node, { strokeDashoffset: [0, -1] }, {
166
+ duration: BASE_DURATION_SECONDS,
167
+ repeat: Infinity,
168
+ ease: 'linear',
169
+ });
170
+ controlsRef.current.speed = BASE_DURATION_SECONDS / duration;
171
+ return undefined;
172
+ }, [duration, isRunning]);
173
+ React.useEffect(() => {
174
+ return () => {
175
+ var _a;
176
+ (_a = controlsRef.current) === null || _a === void 0 ? void 0 : _a.stop();
177
+ controlsRef.current = null;
178
+ };
179
+ }, []);
180
+ return (jsxRuntime.jsxs("svg", { "aria-hidden": "true", className: "pointer-events-none absolute inset-0 z-0 h-full w-full overflow-visible", preserveAspectRatio: "none", viewBox: `0 0 ${width} ${height}`, children: [jsxRuntime.jsxs("g", { ref: beamGroupRef, opacity: "0", children: [jsxRuntime.jsx("rect", { x: rectOffset, y: rectOffset, width: rectWidth, height: rectHeight, rx: rectRadius, ry: rectRadius, pathLength: "1", fill: "none", stroke: `url(#${haloGradientId})`, strokeLinecap: "round", strokeWidth: "var(--beam-frame-halo-width)", vectorEffect: "non-scaling-stroke", style: {
181
+ strokeDasharray: 'calc(var(--beam-frame-beam-length) * 0.86) calc(1 - var(--beam-frame-beam-length) * 0.86)',
182
+ }, opacity: "var(--beam-frame-glow-opacity)" }), jsxRuntime.jsx("rect", { x: rectOffset, y: rectOffset, width: rectWidth, height: rectHeight, rx: rectRadius, ry: rectRadius, pathLength: "1", fill: "none", stroke: `url(#${gradientId})`, strokeLinecap: "round", strokeWidth: "var(--beam-frame-beam-width)", vectorEffect: "non-scaling-stroke", style: {
183
+ strokeDasharray: 'var(--beam-frame-beam-length) calc(1 - var(--beam-frame-beam-length))',
184
+ } })] }), jsxRuntime.jsxs("defs", { children: [jsxRuntime.jsxs("linearGradient", { id: haloGradientId, x1: "0%", x2: "100%", y1: "0%", y2: "100%", children: [jsxRuntime.jsx("stop", { offset: "0%", stopColor: "var(--beam-frame-color-a)", stopOpacity: "0.18" }), jsxRuntime.jsx("stop", { offset: "34%", stopColor: "var(--beam-frame-color-b)", stopOpacity: "0.72" }), jsxRuntime.jsx("stop", { offset: "54%", stopColor: "var(--beam-frame-color-c)", stopOpacity: "1" }), jsxRuntime.jsx("stop", { offset: "74%", stopColor: "var(--beam-frame-color-a)", stopOpacity: "0.66" }), jsxRuntime.jsx("stop", { offset: "100%", stopColor: "var(--beam-frame-color-b)", stopOpacity: "0.18" })] }), jsxRuntime.jsxs("linearGradient", { id: gradientId, x1: "0%", x2: "100%", y1: "0%", y2: "100%", children: [jsxRuntime.jsx("stop", { offset: "0%", stopColor: "var(--beam-frame-color-a)", stopOpacity: "0.52" }), jsxRuntime.jsx("stop", { offset: "34%", stopColor: "var(--beam-frame-color-b)", stopOpacity: "0.9" }), jsxRuntime.jsx("stop", { offset: "50%", stopColor: "var(--beam-frame-color-c)", stopOpacity: "1" }), jsxRuntime.jsx("stop", { offset: "68%", stopColor: "var(--beam-frame-color-a)", stopOpacity: "0.86" }), jsxRuntime.jsx("stop", { offset: "100%", stopColor: "var(--beam-frame-color-c)", stopOpacity: "0.52" })] })] })] }));
185
+ }
186
+ function MotionBeamFrame(props) {
187
+ const { children, active = false, interactive = true, intensity = 'regular', tone = 'theme', duration = 1.8, radius, className, } = props;
188
+ const prefersReducedMotion = react.useReducedMotion();
189
+ const { isRunning, interactionProps } = useInteractiveRunning(active, interactive);
190
+ const shouldRun = isRunning && !prefersReducedMotion;
191
+ const normalizedDuration = normalizeDuration(duration);
192
+ const { ref, size } = useMeasuredFrameSize();
193
+ return (jsxRuntime.jsx(BeamFrameShell, { active: active, interactive: interactive, intensity: intensity, tone: tone, duration: normalizedDuration, radius: radius, className: className, isRunning: shouldRun, interactionProps: interactionProps, rootRef: ref, renderBeam: () => (jsxRuntime.jsx(MotionAroundBeam, { isRunning: shouldRun, duration: normalizedDuration, radius: radius, size: size })), children: children }));
194
+ }
195
+ function AnimeBeamLayer({ isRunning, duration, radius, size, }) {
196
+ const aroundBeamRef = React.useRef(null);
197
+ const animationRef = React.useRef(null);
198
+ const hasStartedRef = React.useRef(false);
199
+ const gradientId = React.useId().replace(/:/g, '');
200
+ const haloGradientId = React.useId().replace(/:/g, '');
201
+ const strokeWidth = 3;
202
+ const width = Math.max(1, size.width);
203
+ const height = Math.max(1, size.height);
204
+ const rectOffset = strokeWidth / 2;
205
+ const rectWidth = Math.max(1, width - strokeWidth);
206
+ const rectHeight = Math.max(1, height - strokeWidth);
207
+ const rectRadius = Math.max(0, Math.min(radius !== null && radius !== void 0 ? radius : DEFAULT_RADIUS, rectWidth / 2, rectHeight / 2));
208
+ React.useEffect(() => {
209
+ var _a;
210
+ const node = aroundBeamRef.current;
211
+ if (!node) {
212
+ return undefined;
213
+ }
214
+ if (isRunning) {
215
+ hasStartedRef.current = true;
216
+ }
217
+ node.style.opacity = isRunning || hasStartedRef.current ? 'var(--beam-frame-beam-opacity)' : '0';
218
+ if (!isRunning) {
219
+ (_a = animationRef.current) === null || _a === void 0 ? void 0 : _a.pause();
220
+ return undefined;
221
+ }
222
+ if (animationRef.current) {
223
+ animationRef.current.playbackRate = BASE_DURATION_SECONDS / duration;
224
+ animationRef.current.play();
225
+ return undefined;
226
+ }
227
+ animationRef.current = animejs.waapi.animate(node, {
228
+ strokeDashoffset: [0, -1],
229
+ loop: true,
230
+ duration: BASE_DURATION_SECONDS * 1000,
231
+ ease: 'linear',
232
+ });
233
+ animationRef.current.playbackRate = BASE_DURATION_SECONDS / duration;
234
+ return undefined;
235
+ }, [duration, isRunning]);
236
+ React.useEffect(() => {
237
+ return () => {
238
+ var _a;
239
+ (_a = animationRef.current) === null || _a === void 0 ? void 0 : _a.revert();
240
+ animationRef.current = null;
241
+ };
242
+ }, []);
243
+ return (jsxRuntime.jsxs("svg", { "aria-hidden": "true", className: "pointer-events-none absolute inset-0 z-0 h-full w-full overflow-visible", preserveAspectRatio: "none", viewBox: `0 0 ${width} ${height}`, children: [jsxRuntime.jsxs("g", { ref: aroundBeamRef, opacity: "0", children: [jsxRuntime.jsx("rect", { x: rectOffset, y: rectOffset, width: rectWidth, height: rectHeight, rx: rectRadius, ry: rectRadius, pathLength: "1", fill: "none", stroke: `url(#${haloGradientId})`, strokeLinecap: "round", strokeWidth: "var(--beam-frame-halo-width)", vectorEffect: "non-scaling-stroke", style: {
244
+ strokeDasharray: 'calc(var(--beam-frame-beam-length) * 0.86) calc(1 - var(--beam-frame-beam-length) * 0.86)',
245
+ }, opacity: "var(--beam-frame-glow-opacity)" }), jsxRuntime.jsx("rect", { x: rectOffset, y: rectOffset, width: rectWidth, height: rectHeight, rx: rectRadius, ry: rectRadius, pathLength: "1", fill: "none", stroke: `url(#${gradientId})`, strokeLinecap: "round", strokeWidth: "var(--beam-frame-beam-width)", vectorEffect: "non-scaling-stroke", style: {
246
+ strokeDasharray: 'var(--beam-frame-beam-length) calc(1 - var(--beam-frame-beam-length))',
247
+ } })] }), jsxRuntime.jsxs("defs", { children: [jsxRuntime.jsxs("linearGradient", { id: haloGradientId, x1: "0%", x2: "100%", y1: "0%", y2: "100%", children: [jsxRuntime.jsx("stop", { offset: "0%", stopColor: "var(--beam-frame-color-a)", stopOpacity: "0.18" }), jsxRuntime.jsx("stop", { offset: "34%", stopColor: "var(--beam-frame-color-b)", stopOpacity: "0.72" }), jsxRuntime.jsx("stop", { offset: "54%", stopColor: "var(--beam-frame-color-c)", stopOpacity: "1" }), jsxRuntime.jsx("stop", { offset: "74%", stopColor: "var(--beam-frame-color-a)", stopOpacity: "0.66" }), jsxRuntime.jsx("stop", { offset: "100%", stopColor: "var(--beam-frame-color-b)", stopOpacity: "0.18" })] }), jsxRuntime.jsxs("linearGradient", { id: gradientId, x1: "0%", x2: "100%", y1: "0%", y2: "100%", children: [jsxRuntime.jsx("stop", { offset: "0%", stopColor: "var(--beam-frame-color-a)", stopOpacity: "0.52" }), jsxRuntime.jsx("stop", { offset: "34%", stopColor: "var(--beam-frame-color-b)", stopOpacity: "0.9" }), jsxRuntime.jsx("stop", { offset: "50%", stopColor: "var(--beam-frame-color-c)", stopOpacity: "1" }), jsxRuntime.jsx("stop", { offset: "68%", stopColor: "var(--beam-frame-color-a)", stopOpacity: "0.86" }), jsxRuntime.jsx("stop", { offset: "100%", stopColor: "var(--beam-frame-color-c)", stopOpacity: "0.52" })] })] })] }));
248
+ }
249
+ function AnimeBeamFrame(props) {
250
+ const { children, active = false, interactive = true, intensity = 'regular', tone = 'theme', duration = 1.8, radius, className, } = props;
251
+ const prefersReducedMotion = react.useReducedMotion();
252
+ const { isRunning, interactionProps } = useInteractiveRunning(active, interactive);
253
+ const shouldRun = isRunning && !prefersReducedMotion;
254
+ const normalizedDuration = normalizeDuration(duration);
255
+ const { ref, size } = useMeasuredFrameSize();
256
+ return (jsxRuntime.jsx(BeamFrameShell, { active: active, interactive: interactive, intensity: intensity, 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 }));
257
+ }
258
+ const BeamFrame = MotionBeamFrame;
259
+
260
+ exports.AnimeBeamFrame = AnimeBeamFrame;
261
+ exports.BeamFrame = BeamFrame;
262
+ exports.MotionBeamFrame = MotionBeamFrame;