@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.
- package/dist/fuma/fuma-page-genarator.d.ts +2 -6
- package/dist/fuma/fuma-page-genarator.js +3 -2
- package/dist/fuma/fuma-page-genarator.mjs +3 -2
- package/dist/fuma/mdx/cheet-table.d.ts +13 -0
- package/dist/fuma/mdx/cheet-table.js +295 -0
- package/dist/fuma/mdx/cheet-table.mjs +293 -0
- package/dist/fuma/mdx/index.d.ts +1 -0
- package/dist/fuma/mdx/index.js +2 -0
- package/dist/fuma/mdx/index.mjs +1 -0
- package/dist/fuma/server/features/widgets.js +2 -0
- package/dist/fuma/server/features/widgets.mjs +2 -0
- package/dist/lib/fuma-schema-check-util.d.ts +1 -1
- package/dist/main/404-page.d.ts +12 -0
- package/dist/main/404-page.js +66 -0
- package/dist/main/404-page.mjs +64 -0
- package/dist/main/alert-dialog/confirm-dialog.js +1 -1
- package/dist/main/alert-dialog/confirm-dialog.mjs +2 -2
- package/dist/main/alert-dialog/dialog-loading-action.js +5 -2
- package/dist/main/alert-dialog/dialog-loading-action.mjs +5 -2
- package/dist/main/alert-dialog/dialog-styles.d.ts +4 -2
- package/dist/main/alert-dialog/dialog-styles.js +8 -4
- package/dist/main/alert-dialog/dialog-styles.mjs +7 -5
- package/dist/main/alert-dialog/high-priority-confirm-dialog.js +5 -5
- package/dist/main/alert-dialog/high-priority-confirm-dialog.mjs +6 -6
- package/dist/main/alert-dialog/info-dialog.js +1 -1
- package/dist/main/alert-dialog/info-dialog.mjs +2 -2
- package/dist/main/alert-dialog/undoable-confirm-dialog.js +2 -2
- package/dist/main/alert-dialog/undoable-confirm-dialog.mjs +3 -3
- package/dist/main/anime/anime-404-page.d.ts +14 -0
- package/dist/main/anime/anime-404-page.js +197 -0
- package/dist/main/anime/anime-404-page.mjs +195 -0
- package/dist/main/anime/anime-beam-frame.d.ts +3 -0
- package/dist/main/anime/anime-beam-frame.js +63 -0
- package/dist/main/anime/anime-beam-frame.mjs +61 -0
- package/dist/main/anime/anime-not-found-page.d.ts +7 -0
- package/dist/main/anime/anime-not-found-page.js +142 -0
- package/dist/main/anime/anime-not-found-page.mjs +140 -0
- package/dist/main/anime/anime-spiral-loading.d.ts +10 -0
- package/dist/main/anime/anime-spiral-loading.js +77 -0
- package/dist/main/anime/anime-spiral-loading.mjs +75 -0
- package/dist/main/anime/index.d.ts +3 -0
- package/dist/main/anime/index.js +12 -0
- package/dist/main/anime/index.mjs +4 -0
- package/dist/main/beam-frame/animate.d.ts +3 -0
- package/dist/main/beam-frame/animate.js +63 -0
- package/dist/main/beam-frame/animate.mjs +61 -0
- package/dist/main/beam-frame/beam-frame.d.ts +4 -0
- package/dist/main/beam-frame/beam-frame.js +262 -0
- package/dist/main/beam-frame/beam-frame.mjs +258 -0
- package/dist/main/beam-frame/index.d.ts +4 -0
- package/dist/main/beam-frame/index.js +11 -0
- package/dist/main/beam-frame/index.mjs +3 -0
- package/dist/main/beam-frame/motion.d.ts +3 -0
- package/dist/main/beam-frame/motion.js +61 -0
- package/dist/main/beam-frame/motion.mjs +59 -0
- package/dist/main/beam-frame/share-config.d.ts +54 -0
- package/dist/main/beam-frame/share-config.js +161 -0
- package/dist/main/beam-frame/share-config.mjs +152 -0
- package/dist/main/beam-frame-config.d.ts +54 -0
- package/dist/main/beam-frame-config.js +161 -0
- package/dist/main/beam-frame-config.mjs +152 -0
- package/dist/main/calendar/random-date-range-dialog.js +177 -51
- package/dist/main/calendar/random-date-range-dialog.mjs +178 -52
- package/dist/main/cta.js +17 -1
- package/dist/main/cta.mjs +18 -2
- package/dist/main/delayed-img.d.ts +1 -1
- package/dist/main/delayed-img.js +8 -5
- package/dist/main/delayed-img.mjs +8 -5
- package/dist/main/index.d.ts +1 -0
- package/dist/main/index.js +2 -0
- package/dist/main/index.mjs +1 -0
- package/dist/main/info-tooltip.js +70 -9
- package/dist/main/info-tooltip.mjs +70 -9
- package/dist/main/loading-frame/index.d.ts +1 -0
- package/dist/main/loading.d.ts +2 -1
- package/dist/main/loading.js +64 -26
- package/dist/main/loading.mjs +64 -26
- package/dist/main/motion/creative-left-panel.d.ts +7 -0
- package/dist/main/motion/creative-left-panel.js +11 -0
- package/dist/main/motion/creative-left-panel.mjs +9 -0
- package/dist/main/motion/creative-right-panel.d.ts +7 -0
- package/dist/main/motion/creative-right-panel.js +11 -0
- package/dist/main/motion/creative-right-panel.mjs +9 -0
- package/dist/main/motion/index.d.ts +1 -0
- package/dist/main/motion/index.js +9 -0
- package/dist/main/motion/index.mjs +2 -0
- package/dist/main/motion/motion-beam-frame.d.ts +3 -0
- package/dist/main/motion/motion-beam-frame.js +61 -0
- package/dist/main/motion/motion-beam-frame.mjs +59 -0
- package/dist/main/snake-loading-frame.d.ts +7 -3
- package/dist/main/snake-loading-frame.js +45 -252
- package/dist/main/snake-loading-frame.mjs +47 -254
- package/package.json +16 -5
- package/src/fuma/fuma-page-genarator.tsx +2 -22
- package/src/fuma/mdx/cheet-table.tsx +650 -0
- package/src/fuma/mdx/index.ts +1 -0
- package/src/fuma/server/features/widgets.tsx +2 -0
- package/src/main/404-page.tsx +162 -0
- package/src/main/alert-dialog/confirm-dialog.tsx +2 -1
- package/src/main/alert-dialog/dialog-loading-action.tsx +7 -5
- package/src/main/alert-dialog/dialog-styles.ts +13 -3
- package/src/main/alert-dialog/high-priority-confirm-dialog.tsx +26 -23
- package/src/main/alert-dialog/info-dialog.tsx +2 -1
- package/src/main/alert-dialog/undoable-confirm-dialog.tsx +18 -17
- package/src/main/anime/anime-404-page.tsx +344 -0
- package/src/main/anime/anime-beam-frame.tsx +128 -0
- package/src/main/anime/anime-spiral-loading.tsx +123 -0
- package/src/main/anime/index.ts +10 -0
- package/src/main/beam-frame-config.tsx +341 -0
- package/src/main/calendar/random-date-range-dialog.tsx +225 -69
- package/src/main/cta.tsx +50 -21
- package/src/main/delayed-img.tsx +9 -4
- package/src/main/index.ts +1 -0
- package/src/main/info-tooltip.tsx +116 -20
- package/src/main/loading-frame/index.ts +4 -0
- package/src/main/loading.tsx +75 -24
- package/src/main/motion/index.ts +8 -0
- package/src/main/motion/motion-beam-frame.tsx +137 -0
- package/src/main/snake-loading-frame.tsx +95 -496
- package/src/styles/cta.css +21 -4
- package/src/styles/third-ui.css +0 -20
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx, jsxs
|
|
3
|
-
import { useState, useRef, useEffect
|
|
4
|
-
import { motion } from '
|
|
2
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
+
import { useState, useRef, useEffect } from 'react';
|
|
4
|
+
import { motion } from 'motion/react';
|
|
5
5
|
import { cn } from '@windrun-huaiin/lib/utils';
|
|
6
|
+
import { AnimeBeamFrame } from './anime/anime-beam-frame.mjs';
|
|
7
|
+
import 'animejs';
|
|
8
|
+
import './anime/anime-404-page.mjs';
|
|
6
9
|
|
|
7
10
|
const DEFAULT_THEME_COLOR = '#3b82f6';
|
|
8
|
-
const TRACK_COLOR = 'rgba(148, 163, 184, 0.22)';
|
|
9
|
-
const BODY_LENGTH_RATIO = 0.26;
|
|
10
11
|
const EXIT_DURATION_MS = 260;
|
|
11
12
|
const LOOP_DURATION_SECONDS = 1.85;
|
|
12
13
|
const DEFAULT_CIRCLE_STROKE = 0.5;
|
|
13
14
|
const DEFAULT_RECT_STROKE = 1;
|
|
14
|
-
const MIN_FRAME_SIZE = 2;
|
|
15
|
-
const MIN_BODY_LENGTH = 24;
|
|
16
|
-
const MAX_BODY_LENGTH_RATIO = 0.36;
|
|
17
|
-
const RECT_MIN_STROKE_WIDTH = 1;
|
|
18
15
|
function clampProgress(progress) {
|
|
19
16
|
if (!Number.isFinite(progress)) {
|
|
20
17
|
return 0;
|
|
@@ -39,188 +36,45 @@ function createBodyTailColor(themeColor) {
|
|
|
39
36
|
}
|
|
40
37
|
return `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, 0.18)`;
|
|
41
38
|
}
|
|
42
|
-
function
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return { x: 0, y: 0 };
|
|
63
|
-
}
|
|
64
|
-
if (parts.length === 1) {
|
|
65
|
-
return { x: parts[0], y: parts[0] };
|
|
66
|
-
}
|
|
67
|
-
return { x: parts[0], y: parts[1] };
|
|
68
|
-
}
|
|
69
|
-
function clampCornerRadius(radius, maxX, maxY) {
|
|
70
|
-
return {
|
|
71
|
-
x: Math.max(0, Math.min(radius.x, maxX)),
|
|
72
|
-
y: Math.max(0, Math.min(radius.y, maxY)),
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
function scaleHorizontalPair(start, end, limit) {
|
|
76
|
-
const sum = start.x + end.x;
|
|
77
|
-
if (sum <= limit || sum === 0) {
|
|
78
|
-
return [start, end];
|
|
79
|
-
}
|
|
80
|
-
const scale = limit / sum;
|
|
81
|
-
return [
|
|
82
|
-
Object.assign(Object.assign({}, start), { x: start.x * scale }),
|
|
83
|
-
Object.assign(Object.assign({}, end), { x: end.x * scale }),
|
|
84
|
-
];
|
|
85
|
-
}
|
|
86
|
-
function scaleVerticalPair(start, end, limit) {
|
|
87
|
-
const sum = start.y + end.y;
|
|
88
|
-
if (sum <= limit || sum === 0) {
|
|
89
|
-
return [start, end];
|
|
90
|
-
}
|
|
91
|
-
const scale = limit / sum;
|
|
92
|
-
return [
|
|
93
|
-
Object.assign(Object.assign({}, start), { y: start.y * scale }),
|
|
94
|
-
Object.assign(Object.assign({}, end), { y: end.y * scale }),
|
|
95
|
-
];
|
|
96
|
-
}
|
|
97
|
-
function normalizeRectRadii(width, height, input) {
|
|
98
|
-
let topLeft = clampCornerRadius(input.topLeft, width / 2, height / 2);
|
|
99
|
-
let topRight = clampCornerRadius(input.topRight, width / 2, height / 2);
|
|
100
|
-
let bottomRight = clampCornerRadius(input.bottomRight, width / 2, height / 2);
|
|
101
|
-
let bottomLeft = clampCornerRadius(input.bottomLeft, width / 2, height / 2);
|
|
102
|
-
[topLeft, topRight] = scaleHorizontalPair(topLeft, topRight, width);
|
|
103
|
-
[bottomLeft, bottomRight] = scaleHorizontalPair(bottomLeft, bottomRight, width);
|
|
104
|
-
[topLeft, bottomLeft] = scaleVerticalPair(topLeft, bottomLeft, height);
|
|
105
|
-
[topRight, bottomRight] = scaleVerticalPair(topRight, bottomRight, height);
|
|
106
|
-
return {
|
|
107
|
-
topLeft,
|
|
108
|
-
topRight,
|
|
109
|
-
bottomRight,
|
|
110
|
-
bottomLeft,
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
function buildRoundedRectPath(x, y, width, height, radii) {
|
|
114
|
-
const { topLeft, topRight, bottomRight, bottomLeft } = normalizeRectRadii(width, height, radii);
|
|
115
|
-
return [
|
|
116
|
-
`M ${x + topLeft.x} ${y}`,
|
|
117
|
-
`H ${x + Math.max(topLeft.x, width - topRight.x)}`,
|
|
118
|
-
topRight.x > 0 || topRight.y > 0
|
|
119
|
-
? `A ${topRight.x} ${topRight.y} 0 0 1 ${x + width} ${y + topRight.y}`
|
|
120
|
-
: `L ${x + width} ${y}`,
|
|
121
|
-
`V ${y + Math.max(topRight.y, height - bottomRight.y)}`,
|
|
122
|
-
bottomRight.x > 0 || bottomRight.y > 0
|
|
123
|
-
? `A ${bottomRight.x} ${bottomRight.y} 0 0 1 ${x + width - bottomRight.x} ${y + height}`
|
|
124
|
-
: `L ${x + width} ${y + height}`,
|
|
125
|
-
`H ${x + Math.min(width - bottomRight.x, bottomLeft.x)}`,
|
|
126
|
-
bottomLeft.x > 0 || bottomLeft.y > 0
|
|
127
|
-
? `A ${bottomLeft.x} ${bottomLeft.y} 0 0 1 ${x} ${y + height - bottomLeft.y}`
|
|
128
|
-
: `L ${x} ${y + height}`,
|
|
129
|
-
`V ${y + Math.min(height - bottomLeft.y, topLeft.y)}`,
|
|
130
|
-
topLeft.x > 0 || topLeft.y > 0
|
|
131
|
-
? `A ${topLeft.x} ${topLeft.y} 0 0 1 ${x + topLeft.x} ${y}`
|
|
132
|
-
: `L ${x} ${y}`,
|
|
133
|
-
'Z',
|
|
134
|
-
].join(' ');
|
|
135
|
-
}
|
|
136
|
-
function createCircleGeometry(width, height, strokeWidth) {
|
|
137
|
-
const safeWidth = Math.max(width, MIN_FRAME_SIZE);
|
|
138
|
-
const safeHeight = Math.max(height, MIN_FRAME_SIZE);
|
|
139
|
-
const radius = Math.max(0, Math.min(safeWidth, safeHeight) / 2 - strokeWidth / 2);
|
|
140
|
-
const centerX = safeWidth / 2;
|
|
141
|
-
const centerY = safeHeight / 2;
|
|
142
|
-
return {
|
|
143
|
-
viewBox: `0 0 ${safeWidth} ${safeHeight}`,
|
|
144
|
-
path: `M ${centerX} ${centerY - radius} A ${radius} ${radius} 0 1 1 ${centerX} ${centerY + radius} A ${radius} ${radius} 0 1 1 ${centerX} ${centerY - radius}`,
|
|
145
|
-
length: Math.max(0, 2 * Math.PI * radius),
|
|
146
|
-
strokeWidth,
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
function createRoundedRectGeometry(width, height, strokeWidth, radii) {
|
|
150
|
-
const safeWidth = Math.max(width, MIN_FRAME_SIZE);
|
|
151
|
-
const safeHeight = Math.max(height, MIN_FRAME_SIZE);
|
|
152
|
-
const inset = strokeWidth / 2;
|
|
153
|
-
const innerWidth = Math.max(safeWidth - strokeWidth, MIN_FRAME_SIZE);
|
|
154
|
-
const innerHeight = Math.max(safeHeight - strokeWidth, MIN_FRAME_SIZE);
|
|
155
|
-
const adjustedRadii = normalizeRectRadii(innerWidth, innerHeight, {
|
|
156
|
-
topLeft: {
|
|
157
|
-
x: Math.max(0, radii.topLeft.x - inset),
|
|
158
|
-
y: Math.max(0, radii.topLeft.y - inset),
|
|
159
|
-
},
|
|
160
|
-
topRight: {
|
|
161
|
-
x: Math.max(0, radii.topRight.x - inset),
|
|
162
|
-
y: Math.max(0, radii.topRight.y - inset),
|
|
163
|
-
},
|
|
164
|
-
bottomRight: {
|
|
165
|
-
x: Math.max(0, radii.bottomRight.x - inset),
|
|
166
|
-
y: Math.max(0, radii.bottomRight.y - inset),
|
|
167
|
-
},
|
|
168
|
-
bottomLeft: {
|
|
169
|
-
x: Math.max(0, radii.bottomLeft.x - inset),
|
|
170
|
-
y: Math.max(0, radii.bottomLeft.y - inset),
|
|
171
|
-
},
|
|
172
|
-
});
|
|
173
|
-
return {
|
|
174
|
-
viewBox: `0 0 ${safeWidth} ${safeHeight}`,
|
|
175
|
-
path: buildRoundedRectPath(inset, inset, innerWidth, innerHeight, adjustedRadii),
|
|
176
|
-
length: 0,
|
|
177
|
-
strokeWidth,
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
function readRectRadii(element) {
|
|
181
|
-
const computedStyle = window.getComputedStyle(element);
|
|
182
|
-
return {
|
|
183
|
-
topLeft: parseRadiusValue(computedStyle.borderTopLeftRadius),
|
|
184
|
-
topRight: parseRadiusValue(computedStyle.borderTopRightRadius),
|
|
185
|
-
bottomRight: parseRadiusValue(computedStyle.borderBottomRightRadius),
|
|
186
|
-
bottomLeft: parseRadiusValue(computedStyle.borderBottomLeftRadius),
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
function SnakeRingSvg({ containerRef, shape, themeColor, progressRatio, animate, strokeWidth, }) {
|
|
190
|
-
var _a, _b;
|
|
191
|
-
const gradientId = useId().replace(/:/g, '-');
|
|
192
|
-
createBodyTailColor(themeColor);
|
|
193
|
-
const headGlowColor = createHeadGlowColor(themeColor);
|
|
194
|
-
const sweepTailColor = createSweepTailColor(themeColor);
|
|
195
|
-
const [geometry, setGeometry] = useState(null);
|
|
196
|
-
const pathMeasureRef = useRef(null);
|
|
197
|
-
const measuredLengthRef = useRef(0);
|
|
39
|
+
function StaticProgressFrame({ shape, progress, themeColor, }) {
|
|
40
|
+
const trackColor = 'rgba(148, 163, 184, 0.22)';
|
|
41
|
+
const progressRatio = clampProgress(progress);
|
|
42
|
+
return (jsx("div", { "aria-hidden": "true", className: cn('pointer-events-none absolute inset-0 p-px', shape === 'circle' ? 'rounded-full' : 'rounded-[inherit]'), style: {
|
|
43
|
+
background: `conic-gradient(${themeColor} 0% ${progressRatio}%, ${trackColor} ${progressRatio}% 100%)`,
|
|
44
|
+
mask: 'linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0)',
|
|
45
|
+
maskComposite: 'exclude',
|
|
46
|
+
WebkitMask: 'linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0)',
|
|
47
|
+
WebkitMaskComposite: 'xor',
|
|
48
|
+
} }));
|
|
49
|
+
}
|
|
50
|
+
function SnakeFrameBase({ shape, loading, children, paused = false, className, themeColor = DEFAULT_THEME_COLOR, tone = 'rainbow', previewProgress, strokeWidth, contentClassName, }) {
|
|
51
|
+
const containerRef = useRef(null);
|
|
52
|
+
const [frameRadius, setFrameRadius] = useState(shape === 'circle' ? 999 : undefined);
|
|
53
|
+
const [showOverlay, setShowOverlay] = useState(loading || previewProgress !== undefined);
|
|
54
|
+
const exitTimerRef = useRef(null);
|
|
55
|
+
const resolvedStrokeWidth = strokeWidth !== null && strokeWidth !== void 0 ? strokeWidth : (shape === 'circle' ? DEFAULT_CIRCLE_STROKE : DEFAULT_RECT_STROKE);
|
|
56
|
+
const circleContentInset = shape === 'circle' ? Math.max(6, resolvedStrokeWidth + 4) : 0;
|
|
57
|
+
const isPreview = previewProgress !== undefined;
|
|
58
|
+
const isActivelyLoading = loading && !paused && !isPreview;
|
|
198
59
|
useEffect(() => {
|
|
199
|
-
|
|
200
|
-
|
|
60
|
+
if (shape === 'circle') {
|
|
61
|
+
setFrameRadius(999);
|
|
201
62
|
return;
|
|
202
63
|
}
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
: createRoundedRectGeometry(rect.width, rect.height, resolvedStrokeWidth, readRectRadii(container));
|
|
212
|
-
measuredLengthRef.current = 0;
|
|
213
|
-
setGeometry(nextGeometry);
|
|
64
|
+
const node = containerRef.current;
|
|
65
|
+
if (!node) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const updateRadius = () => {
|
|
69
|
+
const computedStyle = window.getComputedStyle(node);
|
|
70
|
+
const nextRadius = Number.parseFloat(computedStyle.borderTopLeftRadius);
|
|
71
|
+
setFrameRadius(Number.isFinite(nextRadius) ? nextRadius : undefined);
|
|
214
72
|
};
|
|
215
|
-
|
|
216
|
-
const resizeObserver = new ResizeObserver(
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
updateGeometry();
|
|
221
|
-
});
|
|
222
|
-
resizeObserver.observe(container);
|
|
223
|
-
mutationObserver.observe(container, {
|
|
73
|
+
updateRadius();
|
|
74
|
+
const resizeObserver = new ResizeObserver(updateRadius);
|
|
75
|
+
const mutationObserver = new MutationObserver(updateRadius);
|
|
76
|
+
resizeObserver.observe(node);
|
|
77
|
+
mutationObserver.observe(node, {
|
|
224
78
|
attributes: true,
|
|
225
79
|
attributeFilter: ['class', 'style'],
|
|
226
80
|
});
|
|
@@ -228,70 +82,9 @@ function SnakeRingSvg({ containerRef, shape, themeColor, progressRatio, animate,
|
|
|
228
82
|
resizeObserver.disconnect();
|
|
229
83
|
mutationObserver.disconnect();
|
|
230
84
|
};
|
|
231
|
-
}, [
|
|
232
|
-
useEffect(() => {
|
|
233
|
-
if (!geometry || shape === 'circle' || !pathMeasureRef.current) {
|
|
234
|
-
return;
|
|
235
|
-
}
|
|
236
|
-
const measuredLength = pathMeasureRef.current.getTotalLength();
|
|
237
|
-
const normalizedLength = Number.isFinite(measuredLength)
|
|
238
|
-
? Math.max(0, measuredLength)
|
|
239
|
-
: 0;
|
|
240
|
-
if (normalizedLength <= 0) {
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
if (Math.abs(measuredLengthRef.current - normalizedLength) < 0.1) {
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
measuredLengthRef.current = normalizedLength;
|
|
247
|
-
setGeometry((current) => {
|
|
248
|
-
if (!current || current.path !== geometry.path) {
|
|
249
|
-
return current;
|
|
250
|
-
}
|
|
251
|
-
if (Math.abs(current.length - normalizedLength) < 0.1) {
|
|
252
|
-
return current;
|
|
253
|
-
}
|
|
254
|
-
return Object.assign(Object.assign({}, current), { length: normalizedLength });
|
|
255
|
-
});
|
|
256
|
-
}, [geometry, shape]);
|
|
257
|
-
const resolvedGeometry = useMemo(() => geometry, [geometry]);
|
|
258
|
-
if (!resolvedGeometry) {
|
|
259
|
-
return null;
|
|
260
|
-
}
|
|
261
|
-
const effectiveLength = resolvedGeometry.length > 0
|
|
262
|
-
? resolvedGeometry.length
|
|
263
|
-
: Math.max(1, 2 * Math.max(0, resolvedGeometry.strokeWidth), 2 *
|
|
264
|
-
(Math.max(0, Number.parseFloat((_a = resolvedGeometry.viewBox.split(' ')[2]) !== null && _a !== void 0 ? _a : '0')) +
|
|
265
|
-
Math.max(0, Number.parseFloat((_b = resolvedGeometry.viewBox.split(' ')[3]) !== null && _b !== void 0 ? _b : '0'))));
|
|
266
|
-
const [, , viewBoxWidthRaw, viewBoxHeightRaw] = resolvedGeometry.viewBox.split(' ');
|
|
267
|
-
const viewBoxWidth = Math.max(0, Number.parseFloat(viewBoxWidthRaw !== null && viewBoxWidthRaw !== void 0 ? viewBoxWidthRaw : '0'));
|
|
268
|
-
const viewBoxHeight = Math.max(0, Number.parseFloat(viewBoxHeightRaw !== null && viewBoxHeightRaw !== void 0 ? viewBoxHeightRaw : '0'));
|
|
269
|
-
const centerX = viewBoxWidth / 2;
|
|
270
|
-
const centerY = viewBoxHeight / 2;
|
|
271
|
-
const isCircle = shape === 'circle';
|
|
272
|
-
const tailTransparentStart = isCircle ? '18%' : '26%';
|
|
273
|
-
const tailColorStart = isCircle ? '39%' : '46%';
|
|
274
|
-
const tailTransparentEnd = isCircle ? '90%' : '82%';
|
|
275
|
-
const headTransparentStart = isCircle ? '32%' : '40%';
|
|
276
|
-
const headColorStart = isCircle ? '48%' : '53%';
|
|
277
|
-
const headTransparentEnd = isCircle ? '82%' : '73%';
|
|
278
|
-
const bodyLength = Math.min(effectiveLength * MAX_BODY_LENGTH_RATIO, Math.max(MIN_BODY_LENGTH, effectiveLength * BODY_LENGTH_RATIO));
|
|
279
|
-
const bodyDashArray = `${bodyLength} ${effectiveLength}`;
|
|
280
|
-
const staticDashOffset = effectiveLength * (1 - progressRatio);
|
|
281
|
-
const tailStrokeWidth = shape === 'circle'
|
|
282
|
-
? resolvedGeometry.strokeWidth + 1.2
|
|
283
|
-
: resolvedGeometry.strokeWidth + Math.min(1.2, resolvedGeometry.strokeWidth * 0.32);
|
|
284
|
-
return (jsxs("svg", { className: "pointer-events-none absolute inset-0 h-full w-full", viewBox: resolvedGeometry.viewBox, preserveAspectRatio: "none", "aria-hidden": "true", children: [shape === 'rounded-rect' ? (jsx("path", { ref: pathMeasureRef, d: resolvedGeometry.path, fill: "none", stroke: "transparent" })) : null, animate ? (jsxs("defs", { children: [jsxs("linearGradient", { id: `${gradientId}-sweep-tail`, x1: "0", y1: "0", x2: String(viewBoxWidth), y2: "0", gradientUnits: "userSpaceOnUse", children: [jsx("stop", { offset: "0%", stopColor: "transparent" }), jsx("stop", { offset: tailTransparentStart, stopColor: "transparent" }), jsx("stop", { offset: tailColorStart, stopColor: sweepTailColor }), jsx("stop", { offset: "64%", stopColor: headGlowColor }), jsx("stop", { offset: tailTransparentEnd, stopColor: "transparent" }), jsx("stop", { offset: "100%", stopColor: "transparent" }), jsx("animateTransform", { attributeName: "gradientTransform", type: "rotate", from: `0 ${centerX} ${centerY}`, to: `360 ${centerX} ${centerY}`, dur: `${LOOP_DURATION_SECONDS}s`, repeatCount: "indefinite" })] }), jsxs("linearGradient", { id: `${gradientId}-sweep-head`, x1: "0", y1: "0", x2: String(viewBoxWidth), y2: "0", gradientUnits: "userSpaceOnUse", children: [jsx("stop", { offset: "0%", stopColor: "transparent" }), jsx("stop", { offset: headTransparentStart, stopColor: "transparent" }), jsx("stop", { offset: headColorStart, stopColor: themeColor }), jsx("stop", { offset: "63%", stopColor: headGlowColor }), jsx("stop", { offset: headTransparentEnd, stopColor: "transparent" }), jsx("stop", { offset: "100%", stopColor: "transparent" }), jsx("animateTransform", { attributeName: "gradientTransform", type: "rotate", from: `0 ${centerX} ${centerY}`, to: `360 ${centerX} ${centerY}`, dur: `${LOOP_DURATION_SECONDS}s`, repeatCount: "indefinite" })] })] })) : null, jsx("path", { d: resolvedGeometry.path, fill: "none", stroke: TRACK_COLOR, strokeWidth: resolvedGeometry.strokeWidth, strokeLinecap: "round", strokeLinejoin: "round" }), animate ? (jsxs(Fragment, { children: [jsx("path", { d: resolvedGeometry.path, fill: "none", stroke: `url(#${gradientId}-sweep-tail)`, strokeWidth: tailStrokeWidth, strokeLinecap: "round", strokeLinejoin: "round" }), jsx("path", { d: resolvedGeometry.path, fill: "none", stroke: `url(#${gradientId}-sweep-head)`, strokeWidth: resolvedGeometry.strokeWidth, strokeLinecap: "round", strokeLinejoin: "round" })] })) : null, !animate ? (jsx("path", { d: resolvedGeometry.path, fill: "none", stroke: themeColor, strokeWidth: resolvedGeometry.strokeWidth, strokeLinecap: "round", strokeLinejoin: "round", strokeDasharray: bodyDashArray, strokeDashoffset: staticDashOffset })) : null] }));
|
|
285
|
-
}
|
|
286
|
-
function SnakeFrameBase({ shape, loading, children, className, themeColor = DEFAULT_THEME_COLOR, previewProgress, strokeWidth, contentClassName, }) {
|
|
287
|
-
const containerRef = useRef(null);
|
|
288
|
-
const [showOverlay, setShowOverlay] = useState(loading || previewProgress !== undefined);
|
|
289
|
-
const exitTimerRef = useRef(null);
|
|
290
|
-
const resolvedStrokeWidth = strokeWidth !== null && strokeWidth !== void 0 ? strokeWidth : (shape === 'circle' ? DEFAULT_CIRCLE_STROKE : DEFAULT_RECT_STROKE);
|
|
291
|
-
const circleContentInset = shape === 'circle' ? Math.max(6, resolvedStrokeWidth + 4) : 0;
|
|
292
|
-
const progressRatio = clampProgress(previewProgress !== null && previewProgress !== void 0 ? previewProgress : 0) / 100;
|
|
85
|
+
}, [shape]);
|
|
293
86
|
useEffect(() => {
|
|
294
|
-
if (
|
|
87
|
+
if (isPreview) {
|
|
295
88
|
setShowOverlay(true);
|
|
296
89
|
return;
|
|
297
90
|
}
|
|
@@ -313,24 +106,24 @@ function SnakeFrameBase({ shape, loading, children, className, themeColor = DEFA
|
|
|
313
106
|
exitTimerRef.current = null;
|
|
314
107
|
}
|
|
315
108
|
};
|
|
316
|
-
}, [
|
|
109
|
+
}, [isPreview, loading]);
|
|
317
110
|
return (jsxs("div", { ref: containerRef, className: cn('relative isolate', shape === 'circle' ? 'rounded-full' : 'rounded-none', className), children: [jsx("div", { className: cn('relative z-0 overflow-hidden', shape === 'circle'
|
|
318
111
|
? 'absolute flex items-center justify-center rounded-full'
|
|
319
112
|
: 'h-full w-full', contentClassName), style: shape === 'circle'
|
|
320
113
|
? {
|
|
321
114
|
inset: circleContentInset,
|
|
322
115
|
}
|
|
323
|
-
: undefined, children: children }), showOverlay ? (jsx(motion.div, { className: "pointer-events-none absolute inset-0 overflow-visible", initial: false, animate: { opacity: loading ||
|
|
116
|
+
: undefined, children: children }), showOverlay ? (jsx(motion.div, { className: "pointer-events-none absolute inset-0 overflow-visible", initial: false, animate: { opacity: loading || isPreview ? 1 : 0 }, transition: { duration: EXIT_DURATION_MS / 1000, ease: 'easeOut' }, children: isPreview ? (jsx(StaticProgressFrame, { shape: shape, progress: previewProgress, themeColor: themeColor })) : (jsx(AnimeBeamFrame, { active: isActivelyLoading, interactive: false, tone: tone, duration: LOOP_DURATION_SECONDS, radius: frameRadius, className: "absolute inset-0 h-full w-full", children: jsx("div", { className: "h-full w-full" }) })) })) : null] }));
|
|
324
117
|
}
|
|
325
118
|
function SnakeLoadingFrame(props) {
|
|
326
119
|
return jsx(SnakeFrameBase, Object.assign({}, props));
|
|
327
120
|
}
|
|
328
|
-
function SnakeLoadingPreview({ shape, children, className, themeColor = DEFAULT_THEME_COLOR, defaultProgress = 32, strokeWidth, contentClassName, }) {
|
|
121
|
+
function SnakeLoadingPreview({ shape, children, className, themeColor = DEFAULT_THEME_COLOR, tone = 'rainbow', defaultProgress = 32, strokeWidth, contentClassName, }) {
|
|
329
122
|
const [progress, setProgress] = useState(clampProgress(defaultProgress));
|
|
330
123
|
const sliderFillColor = themeColor;
|
|
331
124
|
const sliderGlowColor = createBodyTailColor(themeColor);
|
|
332
125
|
const sliderBackground = `linear-gradient(90deg, ${sliderGlowColor} 0%, ${sliderFillColor} ${progress}%, rgba(148, 163, 184, 0.24) ${progress}%, rgba(148, 163, 184, 0.24) 100%)`;
|
|
333
|
-
return (jsxs("div", { className: "space-y-3", children: [jsx(SnakeFrameBase, { shape: shape, loading: true, previewProgress: progress, className: className, themeColor: themeColor, strokeWidth: strokeWidth, contentClassName: contentClassName, children: children }), jsxs("div", { className: "space-y-2", children: [jsxs("div", { className: "flex items-center justify-between text-[11px] font-medium uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400", children: [jsx("span", { children: "Snake Preview" }), jsxs("span", { children: [progress, "%"] })] }), jsx("input", { type: "range", min: 0, max: 100, value: progress, onChange: (event) => {
|
|
126
|
+
return (jsxs("div", { className: "space-y-3", children: [jsx(SnakeFrameBase, { shape: shape, loading: true, previewProgress: progress, className: className, themeColor: themeColor, tone: tone, strokeWidth: strokeWidth, contentClassName: contentClassName, children: children }), jsxs("div", { className: "space-y-2", children: [jsxs("div", { className: "flex items-center justify-between text-[11px] font-medium uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400", children: [jsx("span", { children: "Snake Preview" }), jsxs("span", { children: [progress, "%"] })] }), jsx("input", { type: "range", min: 0, max: 100, value: progress, onChange: (event) => {
|
|
334
127
|
setProgress(clampProgress(Number(event.target.value)));
|
|
335
128
|
}, className: "h-2 w-full cursor-pointer appearance-none rounded-full", style: {
|
|
336
129
|
background: sliderBackground,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@windrun-huaiin/third-ui",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "30.1.0",
|
|
4
4
|
"description": "Third-party integrated UI components for windrun-huaiin projects",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./clerk": {
|
|
@@ -38,6 +38,16 @@
|
|
|
38
38
|
"import": "./dist/main/buttons/index.mjs",
|
|
39
39
|
"require": "./dist/main/buttons/index.js"
|
|
40
40
|
},
|
|
41
|
+
"./main/motion": {
|
|
42
|
+
"types": "./dist/main/motion/index.d.ts",
|
|
43
|
+
"import": "./dist/main/motion/index.mjs",
|
|
44
|
+
"require": "./dist/main/motion/index.js"
|
|
45
|
+
},
|
|
46
|
+
"./main/anime": {
|
|
47
|
+
"types": "./dist/main/anime/index.d.ts",
|
|
48
|
+
"import": "./dist/main/anime/index.mjs",
|
|
49
|
+
"require": "./dist/main/anime/index.js"
|
|
50
|
+
},
|
|
41
51
|
"./main/calendar": {
|
|
42
52
|
"types": "./dist/main/calendar/index.d.ts",
|
|
43
53
|
"import": "./dist/main/calendar/index.mjs",
|
|
@@ -215,13 +225,14 @@
|
|
|
215
225
|
"@clerk/nextjs": "^7.0.5",
|
|
216
226
|
"@clerk/shared": "^4.3.1",
|
|
217
227
|
"@fingerprintjs/fingerprintjs": "^5.1.0",
|
|
228
|
+
"animejs": "^4.4.1",
|
|
218
229
|
"class-variance-authority": "^0.7.1",
|
|
219
|
-
"framer-motion": "^12.23.24",
|
|
220
230
|
"fumadocs-core": "16.8.2",
|
|
221
231
|
"fumadocs-ui": "16.8.2",
|
|
222
232
|
"hast-util-to-jsx-runtime": "^2.3.6",
|
|
223
233
|
"katex": "^0.16.33",
|
|
224
234
|
"mermaid": "11.12.1",
|
|
235
|
+
"motion": "^12.38.0",
|
|
225
236
|
"react-medium-image-zoom": "^5.4.1",
|
|
226
237
|
"remark": "^15.0.1",
|
|
227
238
|
"remark-gfm": "^4.0.1",
|
|
@@ -232,9 +243,9 @@
|
|
|
232
243
|
"tslib": "^2.8.1",
|
|
233
244
|
"unified": "^11.0.5",
|
|
234
245
|
"zod": "^4.3.6",
|
|
235
|
-
"@windrun-huaiin/base-ui": "^
|
|
236
|
-
"@windrun-huaiin/
|
|
237
|
-
"@windrun-huaiin/
|
|
246
|
+
"@windrun-huaiin/base-ui": "^30.1.0",
|
|
247
|
+
"@windrun-huaiin/lib": "^30.0.0",
|
|
248
|
+
"@windrun-huaiin/contracts": "^30.0.0"
|
|
238
249
|
},
|
|
239
250
|
"peerDependencies": {
|
|
240
251
|
"clsx": "^2.1.1",
|
|
@@ -3,6 +3,7 @@ import { ReactNode, ReactElement, cloneElement, type CSSProperties } from 'react
|
|
|
3
3
|
import { TocFooterWrapper } from './mdx/toc-footer-wrapper';
|
|
4
4
|
import type { LLMCopyButtonProps, LLMCopyButton } from './mdx/toc-base';
|
|
5
5
|
import { getAsNeededLocalizedUrl } from '@windrun-huaiin/lib/utils';
|
|
6
|
+
import { notFound } from 'next/navigation';
|
|
6
7
|
import { PortableClerkTOC, PortableClerkTOCTitle } from './mdx/toc-clerk-portable';
|
|
7
8
|
import { themeSvgIconColor } from '@windrun-huaiin/base-ui/lib';
|
|
8
9
|
|
|
@@ -36,14 +37,6 @@ interface FumaPageParams {
|
|
|
36
37
|
* The copy button component, must be LLMCopyButton
|
|
37
38
|
*/
|
|
38
39
|
copyButtonComponent?: ReactElement<LLMCopyButtonProps, typeof LLMCopyButton>;
|
|
39
|
-
/*
|
|
40
|
-
* The site icon component to use in NotFoundPage
|
|
41
|
-
*/
|
|
42
|
-
siteIcon: ReactNode;
|
|
43
|
-
/*
|
|
44
|
-
* The fallback page component to use when the page is not found
|
|
45
|
-
*/
|
|
46
|
-
FallbackPage: React.ComponentType<{ siteIcon: ReactNode }>;
|
|
47
40
|
/*
|
|
48
41
|
* Supported locales for generating alternates metadata, defaults to ['en']
|
|
49
42
|
*/
|
|
@@ -89,8 +82,6 @@ export function createFumaPage({
|
|
|
89
82
|
mdxSourceDir,
|
|
90
83
|
githubBaseUrl,
|
|
91
84
|
copyButtonComponent,
|
|
92
|
-
siteIcon,
|
|
93
|
-
FallbackPage,
|
|
94
85
|
supportedLocales = ['en'],
|
|
95
86
|
showBreadcrumb = true,
|
|
96
87
|
showTableOfContent = true,
|
|
@@ -138,18 +129,7 @@ export function createFumaPage({
|
|
|
138
129
|
totalElapsedMs: durationMs(pageStartedAt),
|
|
139
130
|
});
|
|
140
131
|
if (!page) {
|
|
141
|
-
|
|
142
|
-
<DocsPage
|
|
143
|
-
full
|
|
144
|
-
breadcrumb={{ enabled: false }}
|
|
145
|
-
footer={{ enabled: false }}
|
|
146
|
-
tableOfContent={{ enabled: false }}
|
|
147
|
-
tableOfContentPopover={{ enabled: false }}
|
|
148
|
-
className="max-w-none px-0 py-0"
|
|
149
|
-
>
|
|
150
|
-
<FallbackPage siteIcon={siteIcon} />
|
|
151
|
-
</DocsPage>
|
|
152
|
-
);
|
|
132
|
+
notFound();
|
|
153
133
|
}
|
|
154
134
|
|
|
155
135
|
const path = githubBaseUrl ? `${mdxSourceDir}/${page.path}` : undefined;
|