@windrun-huaiin/third-ui 29.2.1 → 30.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/dist/fuma/mdx/cheet-table.d.ts +13 -0
  2. package/dist/fuma/mdx/cheet-table.js +295 -0
  3. package/dist/fuma/mdx/cheet-table.mjs +293 -0
  4. package/dist/fuma/mdx/index.d.ts +1 -0
  5. package/dist/fuma/mdx/index.js +2 -0
  6. package/dist/fuma/mdx/index.mjs +1 -0
  7. package/dist/fuma/server/features/widgets.js +2 -0
  8. package/dist/fuma/server/features/widgets.mjs +2 -0
  9. package/dist/lib/fuma-schema-check-util.d.ts +1 -1
  10. package/dist/main/alert-dialog/confirm-dialog.js +1 -1
  11. package/dist/main/alert-dialog/confirm-dialog.mjs +2 -2
  12. package/dist/main/alert-dialog/dialog-loading-action.js +5 -2
  13. package/dist/main/alert-dialog/dialog-loading-action.mjs +5 -2
  14. package/dist/main/alert-dialog/dialog-styles.d.ts +4 -2
  15. package/dist/main/alert-dialog/dialog-styles.js +8 -4
  16. package/dist/main/alert-dialog/dialog-styles.mjs +7 -5
  17. package/dist/main/alert-dialog/high-priority-confirm-dialog.js +5 -5
  18. package/dist/main/alert-dialog/high-priority-confirm-dialog.mjs +6 -6
  19. package/dist/main/alert-dialog/info-dialog.js +1 -1
  20. package/dist/main/alert-dialog/info-dialog.mjs +2 -2
  21. package/dist/main/alert-dialog/undoable-confirm-dialog.js +2 -2
  22. package/dist/main/alert-dialog/undoable-confirm-dialog.mjs +3 -3
  23. package/dist/main/anime/anime-beam-frame.d.ts +3 -0
  24. package/dist/main/anime/anime-beam-frame.js +63 -0
  25. package/dist/main/anime/anime-beam-frame.mjs +61 -0
  26. package/dist/main/anime/anime-spiral-loading.d.ts +10 -0
  27. package/dist/main/anime/anime-spiral-loading.js +77 -0
  28. package/dist/main/anime/anime-spiral-loading.mjs +75 -0
  29. package/dist/main/anime/index.d.ts +2 -0
  30. package/dist/main/anime/index.js +10 -0
  31. package/dist/main/anime/index.mjs +3 -0
  32. package/dist/main/beam-frame/animate.d.ts +3 -0
  33. package/dist/main/beam-frame/animate.js +63 -0
  34. package/dist/main/beam-frame/animate.mjs +61 -0
  35. package/dist/main/beam-frame/beam-frame.d.ts +4 -0
  36. package/dist/main/beam-frame/beam-frame.js +262 -0
  37. package/dist/main/beam-frame/beam-frame.mjs +258 -0
  38. package/dist/main/beam-frame/index.d.ts +4 -0
  39. package/dist/main/beam-frame/index.js +11 -0
  40. package/dist/main/beam-frame/index.mjs +3 -0
  41. package/dist/main/beam-frame/motion.d.ts +3 -0
  42. package/dist/main/beam-frame/motion.js +61 -0
  43. package/dist/main/beam-frame/motion.mjs +59 -0
  44. package/dist/main/beam-frame/share-config.d.ts +54 -0
  45. package/dist/main/beam-frame/share-config.js +161 -0
  46. package/dist/main/beam-frame/share-config.mjs +152 -0
  47. package/dist/main/beam-frame-config.d.ts +54 -0
  48. package/dist/main/beam-frame-config.js +161 -0
  49. package/dist/main/beam-frame-config.mjs +152 -0
  50. package/dist/main/calendar/random-date-range-dialog.js +177 -51
  51. package/dist/main/calendar/random-date-range-dialog.mjs +178 -52
  52. package/dist/main/cta.js +17 -1
  53. package/dist/main/cta.mjs +18 -2
  54. package/dist/main/delayed-img.d.ts +1 -1
  55. package/dist/main/delayed-img.js +8 -5
  56. package/dist/main/delayed-img.mjs +8 -5
  57. package/dist/main/info-tooltip.js +70 -9
  58. package/dist/main/info-tooltip.mjs +70 -9
  59. package/dist/main/loading-frame/index.d.ts +1 -0
  60. package/dist/main/loading.d.ts +2 -1
  61. package/dist/main/loading.js +64 -26
  62. package/dist/main/loading.mjs +64 -26
  63. package/dist/main/motion/index.d.ts +1 -0
  64. package/dist/main/motion/index.js +9 -0
  65. package/dist/main/motion/index.mjs +2 -0
  66. package/dist/main/motion/motion-beam-frame.d.ts +3 -0
  67. package/dist/main/motion/motion-beam-frame.js +61 -0
  68. package/dist/main/motion/motion-beam-frame.mjs +59 -0
  69. package/dist/main/snake-loading-frame.d.ts +7 -3
  70. package/dist/main/snake-loading-frame.js +44 -252
  71. package/dist/main/snake-loading-frame.mjs +46 -254
  72. package/package.json +16 -5
  73. package/src/fuma/mdx/cheet-table.tsx +650 -0
  74. package/src/fuma/mdx/index.ts +1 -0
  75. package/src/fuma/server/features/widgets.tsx +2 -0
  76. package/src/main/alert-dialog/confirm-dialog.tsx +2 -1
  77. package/src/main/alert-dialog/dialog-loading-action.tsx +7 -5
  78. package/src/main/alert-dialog/dialog-styles.ts +13 -3
  79. package/src/main/alert-dialog/high-priority-confirm-dialog.tsx +26 -23
  80. package/src/main/alert-dialog/info-dialog.tsx +2 -1
  81. package/src/main/alert-dialog/undoable-confirm-dialog.tsx +18 -17
  82. package/src/main/anime/anime-beam-frame.tsx +128 -0
  83. package/src/main/anime/anime-spiral-loading.tsx +123 -0
  84. package/src/main/anime/index.ts +9 -0
  85. package/src/main/beam-frame-config.tsx +341 -0
  86. package/src/main/calendar/random-date-range-dialog.tsx +225 -69
  87. package/src/main/cta.tsx +50 -21
  88. package/src/main/delayed-img.tsx +9 -4
  89. package/src/main/info-tooltip.tsx +116 -20
  90. package/src/main/loading-frame/index.ts +4 -0
  91. package/src/main/loading.tsx +75 -24
  92. package/src/main/motion/index.ts +8 -0
  93. package/src/main/motion/motion-beam-frame.tsx +137 -0
  94. package/src/main/snake-loading-frame.tsx +95 -496
  95. package/src/styles/cta.css +21 -4
  96. package/src/styles/third-ui.css +0 -20
@@ -0,0 +1,341 @@
1
+ 'use client';
2
+
3
+ import type { CSSProperties, DOMAttributes, ReactNode, RefObject } from 'react';
4
+ import { useEffect, useRef, useState } from 'react';
5
+ import { themeName } from '@windrun-huaiin/base-ui/lib';
6
+ import { cn } from '@windrun-huaiin/lib/utils';
7
+
8
+ export type BeamFrameTone = 'theme' | 'rainbow' | 'mono' | 'warm' | 'cool';
9
+
10
+ export type BeamFrameProps = {
11
+ children: ReactNode;
12
+ active?: boolean;
13
+ interactive?: boolean;
14
+ tone?: BeamFrameTone;
15
+ duration?: number;
16
+ radius?: number;
17
+ className?: string;
18
+ };
19
+
20
+ export type BeamFrameRenderProps = Required<
21
+ Pick<BeamFrameProps, 'active' | 'interactive' | 'tone' | 'duration'>
22
+ > &
23
+ Pick<BeamFrameProps, 'children' | 'className' | 'radius'>;
24
+
25
+ export type FrameSize = {
26
+ width: number;
27
+ height: number;
28
+ };
29
+
30
+ type BeamPalette = {
31
+ a: string;
32
+ b: string;
33
+ c: string;
34
+ };
35
+
36
+ const THEME_PALETTES: Record<string, BeamPalette> = {
37
+ purple: { a: '#AC62FD', b: '#EC4899', c: '#6366F1' },
38
+ orange: { a: '#F97316', b: '#F59E0B', c: '#EF4444' },
39
+ indigo: { a: '#6366F1', b: '#3B82F6', c: '#06B6D4' },
40
+ emerald: { a: '#10B981', b: '#14B8A6', c: '#22C55E' },
41
+ rose: { a: '#F43F5E', b: '#EC4899', c: '#FB7185' },
42
+ };
43
+
44
+ const TONE_PALETTES: Record<Exclude<BeamFrameTone, 'theme'>, BeamPalette> = {
45
+ rainbow: { a: '#FF3D77', b: '#3388FF', c: '#00FF88' },
46
+ mono: { a: '#E5E7EB', b: '#94A3B8', c: '#FFFFFF' },
47
+ warm: { a: '#F97316', b: '#FBBF24', c: '#EF4444' },
48
+ cool: { a: '#06B6D4', b: '#6366F1', c: '#14B8A6' },
49
+ };
50
+
51
+ const BEAM_FRAME_STYLE = {
52
+ ambientGlowOpacity: 0.24,
53
+ beamOpacity: 1.0,
54
+ auraOpacity: 0.86,
55
+ auraLength: 0.08,
56
+ traceLength: 0.42,
57
+ traceWidth: 1.15,
58
+ ambientGlowWidth: 7,
59
+ auraWidth: 8.5,
60
+ };
61
+
62
+ const BASE_BORDER_OPACITY = 0.18;
63
+
64
+ export const BASE_DURATION_SECONDS = 3.6;
65
+ export const DEFAULT_RADIUS = 24;
66
+
67
+ function getPalette(tone: BeamFrameTone): BeamPalette {
68
+ if (tone !== 'theme') {
69
+ return TONE_PALETTES[tone];
70
+ }
71
+
72
+ return THEME_PALETTES[themeName] ?? THEME_PALETTES.purple;
73
+ }
74
+
75
+ export function normalizeDuration(duration: number): number {
76
+ if (!Number.isFinite(duration)) {
77
+ return BASE_DURATION_SECONDS;
78
+ }
79
+
80
+ return Math.max(0.4, duration);
81
+ }
82
+
83
+ export function useMeasuredFrameSize<T extends HTMLElement>() {
84
+ const ref = useRef<T | null>(null);
85
+ const [size, setSize] = useState<FrameSize>({ width: 0, height: 0 });
86
+
87
+ useEffect(() => {
88
+ const node = ref.current;
89
+
90
+ if (!node) {
91
+ return undefined;
92
+ }
93
+
94
+ const updateSize = () => {
95
+ const rect = node.getBoundingClientRect();
96
+ setSize({
97
+ width: Math.max(0, rect.width),
98
+ height: Math.max(0, rect.height),
99
+ });
100
+ };
101
+
102
+ updateSize();
103
+
104
+ const observer = new ResizeObserver(updateSize);
105
+ observer.observe(node);
106
+
107
+ return () => observer.disconnect();
108
+ }, []);
109
+
110
+ return { ref, size };
111
+ }
112
+
113
+ export function useInteractiveRunning(active: boolean, interactive: boolean) {
114
+ const [isInteractiveRunning, setIsInteractiveRunning] = useState(false);
115
+ const interactionProps: Pick<
116
+ DOMAttributes<HTMLDivElement>,
117
+ 'onBlur' | 'onFocus' | 'onMouseEnter' | 'onMouseLeave'
118
+ > = interactive
119
+ ? {
120
+ onMouseEnter: () => setIsInteractiveRunning(true),
121
+ onMouseLeave: () => setIsInteractiveRunning(false),
122
+ onFocus: () => setIsInteractiveRunning(true),
123
+ onBlur: () => setIsInteractiveRunning(false),
124
+ }
125
+ : {};
126
+
127
+ return {
128
+ isRunning: active || isInteractiveRunning,
129
+ interactionProps,
130
+ };
131
+ }
132
+
133
+ function createRootStyle({
134
+ tone,
135
+ radius,
136
+ }: Pick<BeamFrameRenderProps, 'tone' | 'radius'>): CSSProperties {
137
+ const palette = getPalette(tone);
138
+ const frameRadius = radius ?? DEFAULT_RADIUS;
139
+
140
+ return {
141
+ '--beam-frame-radius': `${frameRadius}px`,
142
+ '--beam-frame-color-a': palette.a,
143
+ '--beam-frame-color-b': palette.b,
144
+ '--beam-frame-color-c': palette.c,
145
+ '--beam-frame-border-opacity': BASE_BORDER_OPACITY,
146
+ '--beam-frame-ambient-glow-opacity': BEAM_FRAME_STYLE.ambientGlowOpacity,
147
+ '--beam-frame-beam-opacity': BEAM_FRAME_STYLE.beamOpacity,
148
+ '--beam-frame-aura-opacity': BEAM_FRAME_STYLE.auraOpacity,
149
+ '--beam-frame-aura-length': BEAM_FRAME_STYLE.auraLength,
150
+ '--beam-frame-aura-dash-pattern':
151
+ 'var(--beam-frame-aura-length) calc(1 - var(--beam-frame-aura-length))',
152
+ '--beam-frame-trace-length': BEAM_FRAME_STYLE.traceLength,
153
+ '--beam-frame-trace-dash-pattern':
154
+ 'var(--beam-frame-trace-length) calc(1 - var(--beam-frame-trace-length))',
155
+ '--beam-frame-trace-width': BEAM_FRAME_STYLE.traceWidth,
156
+ '--beam-frame-ambient-glow-width': BEAM_FRAME_STYLE.ambientGlowWidth,
157
+ '--beam-frame-aura-width': BEAM_FRAME_STYLE.auraWidth,
158
+ } as CSSProperties;
159
+ }
160
+
161
+ export function BeamFrameShell({
162
+ children,
163
+ className,
164
+ tone,
165
+ radius,
166
+ isRunning,
167
+ interactionProps,
168
+ renderBeam,
169
+ rootRef,
170
+ }: BeamFrameRenderProps & {
171
+ isRunning: boolean;
172
+ interactionProps: Pick<
173
+ DOMAttributes<HTMLDivElement>,
174
+ 'onBlur' | 'onFocus' | 'onMouseEnter' | 'onMouseLeave'
175
+ >;
176
+ renderBeam: () => ReactNode;
177
+ rootRef: RefObject<HTMLDivElement | null>;
178
+ }) {
179
+ return (
180
+ <div
181
+ ref={rootRef}
182
+ className={cn(
183
+ 'group/beam-frame relative isolate overflow-hidden rounded-(--beam-frame-radius) p-px',
184
+ className,
185
+ )}
186
+ data-beam-running={isRunning ? 'true' : 'false'}
187
+ style={createRootStyle({ tone, radius })}
188
+ {...interactionProps}
189
+ >
190
+ {renderBeam()}
191
+ <div className="relative z-10 rounded-[calc(var(--beam-frame-radius)-1px)]">
192
+ {children}
193
+ </div>
194
+ </div>
195
+ );
196
+ }
197
+
198
+ export function createBeamGeometry({
199
+ radius,
200
+ size,
201
+ }: {
202
+ radius?: number;
203
+ size: FrameSize;
204
+ }) {
205
+ const strokeWidth = 3;
206
+ const width = Math.max(1, size.width);
207
+ const height = Math.max(1, size.height);
208
+ const rectOffset = strokeWidth / 2;
209
+ const rectWidth = Math.max(1, width - strokeWidth);
210
+ const rectHeight = Math.max(1, height - strokeWidth);
211
+ const rectRadius = Math.max(0, Math.min(radius ?? DEFAULT_RADIUS, rectWidth / 2, rectHeight / 2));
212
+ const rectRight = rectOffset + rectWidth;
213
+ const rectBottom = rectOffset + rectHeight;
214
+ const roundedPathLap = [
215
+ `H ${rectRight - rectRadius}`,
216
+ `A ${rectRadius} ${rectRadius} 0 0 1 ${rectRight} ${rectOffset + rectRadius}`,
217
+ `V ${rectBottom - rectRadius}`,
218
+ `A ${rectRadius} ${rectRadius} 0 0 1 ${rectRight - rectRadius} ${rectBottom}`,
219
+ `H ${rectOffset + rectRadius}`,
220
+ `A ${rectRadius} ${rectRadius} 0 0 1 ${rectOffset} ${rectBottom - rectRadius}`,
221
+ `V ${rectOffset + rectRadius}`,
222
+ `A ${rectRadius} ${rectRadius} 0 0 1 ${rectOffset + rectRadius} ${rectOffset}`,
223
+ ].join(' ');
224
+ const extendedRoundedPath = `M ${rectOffset + rectRadius} ${rectOffset} ${roundedPathLap} ${roundedPathLap}`;
225
+
226
+ return {
227
+ width,
228
+ height,
229
+ rectOffset,
230
+ rectWidth,
231
+ rectHeight,
232
+ rectRadius,
233
+ rectRight,
234
+ rectBottom,
235
+ extendedRoundedPath,
236
+ };
237
+ }
238
+
239
+ export function BeamSvgLayer({
240
+ beamRef,
241
+ auraGradientId,
242
+ softGlowFilterId,
243
+ radius,
244
+ size,
245
+ }: {
246
+ beamRef: RefObject<SVGGElement | null>;
247
+ auraGradientId: string;
248
+ softGlowFilterId: string;
249
+ radius?: number;
250
+ size: FrameSize;
251
+ }) {
252
+ const {
253
+ width,
254
+ height,
255
+ rectOffset,
256
+ rectWidth,
257
+ rectHeight,
258
+ rectRadius,
259
+ rectRight,
260
+ rectBottom,
261
+ extendedRoundedPath,
262
+ } = createBeamGeometry({
263
+ radius,
264
+ size,
265
+ });
266
+
267
+ return (
268
+ <svg
269
+ aria-hidden="true"
270
+ className="pointer-events-none absolute inset-0 z-20 h-full w-full overflow-visible"
271
+ preserveAspectRatio="none"
272
+ viewBox={`0 0 ${width} ${height}`}
273
+ >
274
+ <g ref={beamRef} opacity="0" style={{ mixBlendMode: 'plus-lighter' }}>
275
+ <rect
276
+ x={rectOffset}
277
+ y={rectOffset}
278
+ width={rectWidth}
279
+ height={rectHeight}
280
+ rx={rectRadius}
281
+ ry={rectRadius}
282
+ pathLength="1"
283
+ fill="none"
284
+ stroke={`url(#${auraGradientId})`}
285
+ strokeLinecap="round"
286
+ strokeWidth="var(--beam-frame-ambient-glow-width)"
287
+ vectorEffect="non-scaling-stroke"
288
+ filter={`url(#${softGlowFilterId})`}
289
+ opacity="var(--beam-frame-ambient-glow-opacity)"
290
+ />
291
+ <path
292
+ d={extendedRoundedPath}
293
+ pathLength="2"
294
+ fill="none"
295
+ stroke={`url(#${auraGradientId})`}
296
+ strokeLinecap="round"
297
+ strokeWidth="var(--beam-frame-aura-width)"
298
+ vectorEffect="non-scaling-stroke"
299
+ filter={`url(#${softGlowFilterId})`}
300
+ style={{
301
+ strokeDasharray: 'var(--beam-frame-aura-dash-pattern)',
302
+ }}
303
+ opacity="var(--beam-frame-aura-opacity)"
304
+ />
305
+ <path
306
+ d={extendedRoundedPath}
307
+ pathLength="2"
308
+ fill="none"
309
+ stroke={`url(#${auraGradientId})`}
310
+ strokeLinecap="round"
311
+ strokeWidth="var(--beam-frame-trace-width)"
312
+ vectorEffect="non-scaling-stroke"
313
+ style={{
314
+ strokeDasharray: 'var(--beam-frame-trace-dash-pattern)',
315
+ }}
316
+ opacity="var(--beam-frame-beam-opacity)"
317
+ />
318
+ </g>
319
+ <defs>
320
+ <filter id={softGlowFilterId} x="-40%" y="-40%" width="180%" height="180%">
321
+ <feGaussianBlur stdDeviation="8" />
322
+ </filter>
323
+ <linearGradient
324
+ id={auraGradientId}
325
+ x1={rectOffset}
326
+ x2={rectRight}
327
+ y1={rectOffset}
328
+ y2={rectBottom}
329
+ gradientUnits="userSpaceOnUse"
330
+ >
331
+ <stop offset="0%" stopColor="var(--beam-frame-color-a)" stopOpacity="0.58" />
332
+ <stop offset="22%" stopColor="var(--beam-frame-color-b)" stopOpacity="0.78" />
333
+ <stop offset="44%" stopColor="var(--beam-frame-color-c)" stopOpacity="0.96" />
334
+ <stop offset="58%" stopColor="var(--beam-frame-color-b)" stopOpacity="1" />
335
+ <stop offset="78%" stopColor="var(--beam-frame-color-a)" stopOpacity="0.82" />
336
+ <stop offset="100%" stopColor="var(--beam-frame-color-c)" stopOpacity="0.58" />
337
+ </linearGradient>
338
+ </defs>
339
+ </svg>
340
+ );
341
+ }