@windrun-huaiin/third-ui 29.2.0 → 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 (102) 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.d.ts +2 -1
  11. package/dist/main/alert-dialog/confirm-dialog.js +3 -3
  12. package/dist/main/alert-dialog/confirm-dialog.mjs +4 -4
  13. package/dist/main/alert-dialog/dialog-loading-action.d.ts +2 -1
  14. package/dist/main/alert-dialog/dialog-loading-action.js +6 -3
  15. package/dist/main/alert-dialog/dialog-loading-action.mjs +6 -3
  16. package/dist/main/alert-dialog/dialog-styles.d.ts +4 -2
  17. package/dist/main/alert-dialog/dialog-styles.js +8 -4
  18. package/dist/main/alert-dialog/dialog-styles.mjs +7 -5
  19. package/dist/main/alert-dialog/high-priority-confirm-dialog.d.ts +2 -1
  20. package/dist/main/alert-dialog/high-priority-confirm-dialog.js +7 -7
  21. package/dist/main/alert-dialog/high-priority-confirm-dialog.mjs +8 -8
  22. package/dist/main/alert-dialog/info-dialog.d.ts +2 -1
  23. package/dist/main/alert-dialog/info-dialog.js +3 -3
  24. package/dist/main/alert-dialog/info-dialog.mjs +4 -4
  25. package/dist/main/alert-dialog/undoable-confirm-dialog.d.ts +2 -1
  26. package/dist/main/alert-dialog/undoable-confirm-dialog.js +4 -4
  27. package/dist/main/alert-dialog/undoable-confirm-dialog.mjs +5 -5
  28. package/dist/main/anime/anime-beam-frame.d.ts +3 -0
  29. package/dist/main/anime/anime-beam-frame.js +63 -0
  30. package/dist/main/anime/anime-beam-frame.mjs +61 -0
  31. package/dist/main/anime/anime-spiral-loading.d.ts +10 -0
  32. package/dist/main/anime/anime-spiral-loading.js +77 -0
  33. package/dist/main/anime/anime-spiral-loading.mjs +75 -0
  34. package/dist/main/anime/index.d.ts +2 -0
  35. package/dist/main/anime/index.js +10 -0
  36. package/dist/main/anime/index.mjs +3 -0
  37. package/dist/main/beam-frame/animate.d.ts +3 -0
  38. package/dist/main/beam-frame/animate.js +63 -0
  39. package/dist/main/beam-frame/animate.mjs +61 -0
  40. package/dist/main/beam-frame/beam-frame.d.ts +4 -0
  41. package/dist/main/beam-frame/beam-frame.js +262 -0
  42. package/dist/main/beam-frame/beam-frame.mjs +258 -0
  43. package/dist/main/beam-frame/index.d.ts +4 -0
  44. package/dist/main/beam-frame/index.js +11 -0
  45. package/dist/main/beam-frame/index.mjs +3 -0
  46. package/dist/main/beam-frame/motion.d.ts +3 -0
  47. package/dist/main/beam-frame/motion.js +61 -0
  48. package/dist/main/beam-frame/motion.mjs +59 -0
  49. package/dist/main/beam-frame/share-config.d.ts +54 -0
  50. package/dist/main/beam-frame/share-config.js +161 -0
  51. package/dist/main/beam-frame/share-config.mjs +152 -0
  52. package/dist/main/beam-frame-config.d.ts +54 -0
  53. package/dist/main/beam-frame-config.js +161 -0
  54. package/dist/main/beam-frame-config.mjs +152 -0
  55. package/dist/main/calendar/random-date-range-dialog.d.ts +5 -2
  56. package/dist/main/calendar/random-date-range-dialog.js +239 -109
  57. package/dist/main/calendar/random-date-range-dialog.mjs +242 -112
  58. package/dist/main/cta.js +17 -1
  59. package/dist/main/cta.mjs +18 -2
  60. package/dist/main/delayed-img.d.ts +1 -1
  61. package/dist/main/delayed-img.js +8 -5
  62. package/dist/main/delayed-img.mjs +8 -5
  63. package/dist/main/info-tooltip.js +70 -9
  64. package/dist/main/info-tooltip.mjs +70 -9
  65. package/dist/main/loading-frame/index.d.ts +1 -0
  66. package/dist/main/loading.d.ts +2 -1
  67. package/dist/main/loading.js +64 -26
  68. package/dist/main/loading.mjs +64 -26
  69. package/dist/main/motion/index.d.ts +1 -0
  70. package/dist/main/motion/index.js +9 -0
  71. package/dist/main/motion/index.mjs +2 -0
  72. package/dist/main/motion/motion-beam-frame.d.ts +3 -0
  73. package/dist/main/motion/motion-beam-frame.js +61 -0
  74. package/dist/main/motion/motion-beam-frame.mjs +59 -0
  75. package/dist/main/snake-loading-frame.d.ts +7 -3
  76. package/dist/main/snake-loading-frame.js +44 -252
  77. package/dist/main/snake-loading-frame.mjs +46 -254
  78. package/package.json +16 -5
  79. package/src/fuma/mdx/cheet-table.tsx +650 -0
  80. package/src/fuma/mdx/index.ts +1 -0
  81. package/src/fuma/server/features/widgets.tsx +2 -0
  82. package/src/main/alert-dialog/confirm-dialog.tsx +5 -2
  83. package/src/main/alert-dialog/dialog-loading-action.tsx +22 -5
  84. package/src/main/alert-dialog/dialog-styles.ts +13 -3
  85. package/src/main/alert-dialog/high-priority-confirm-dialog.tsx +29 -24
  86. package/src/main/alert-dialog/info-dialog.tsx +5 -2
  87. package/src/main/alert-dialog/undoable-confirm-dialog.tsx +21 -18
  88. package/src/main/anime/anime-beam-frame.tsx +128 -0
  89. package/src/main/anime/anime-spiral-loading.tsx +123 -0
  90. package/src/main/anime/index.ts +9 -0
  91. package/src/main/beam-frame-config.tsx +341 -0
  92. package/src/main/calendar/random-date-range-dialog.tsx +242 -74
  93. package/src/main/cta.tsx +50 -21
  94. package/src/main/delayed-img.tsx +9 -4
  95. package/src/main/info-tooltip.tsx +116 -20
  96. package/src/main/loading-frame/index.ts +4 -0
  97. package/src/main/loading.tsx +75 -24
  98. package/src/main/motion/index.ts +8 -0
  99. package/src/main/motion/motion-beam-frame.tsx +137 -0
  100. package/src/main/snake-loading-frame.tsx +95 -496
  101. package/src/styles/cta.css +21 -4
  102. 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
+ }