@djangocfg/ui-nextjs 2.1.319 → 2.1.321

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.
@@ -1,646 +0,0 @@
1
- 'use client';
2
-
3
- import React, { useMemo } from 'react';
4
-
5
- import { cn } from '@djangocfg/ui-core/lib';
6
-
7
- export type BackgroundVariant =
8
- | 'aurora-borealis'
9
- | 'mesh-gradient'
10
- | 'floating-orbs'
11
- | 'geometric-flow'
12
- | 'liquid-gradient'
13
- | 'spotlight'
14
- | 'none'
15
- // Legacy aliases
16
- | 'gradient-mesh'
17
- | 'dot-matrix'
18
- | 'grid-lines'
19
- | 'aurora'
20
- | 'particles'
21
- | 'waves';
22
-
23
- interface AnimatedBackgroundProps {
24
- variant?: BackgroundVariant;
25
- className?: string;
26
- intensity?: 'subtle' | 'medium' | 'strong';
27
- /** Color scheme - 'vibrant' uses multiple colors, 'monochrome' uses primary only */
28
- colorScheme?: 'vibrant' | 'monochrome' | 'cool' | 'warm';
29
- }
30
-
31
- // Map legacy variants to new ones
32
- const variantMap: Record<string, BackgroundVariant> = {
33
- 'gradient-mesh': 'mesh-gradient',
34
- 'dot-matrix': 'geometric-flow',
35
- 'grid-lines': 'geometric-flow',
36
- 'aurora': 'aurora-borealis',
37
- 'particles': 'floating-orbs',
38
- 'waves': 'liquid-gradient',
39
- };
40
-
41
- export const AnimatedBackground: React.FC<AnimatedBackgroundProps> = ({
42
- variant = 'mesh-gradient',
43
- className,
44
- intensity = 'medium',
45
- colorScheme = 'vibrant',
46
- }) => {
47
- // Map legacy variants
48
- const resolvedVariant = variantMap[variant] || variant;
49
-
50
- const intensityConfig = useMemo(() => ({
51
- subtle: { opacity: 0.15, blur: 'blur-3xl', scale: 0.8 },
52
- medium: { opacity: 0.25, blur: 'blur-2xl', scale: 1 },
53
- strong: { opacity: 0.4, blur: 'blur-xl', scale: 1.2 },
54
- }[intensity]), [intensity]);
55
-
56
- // Color palettes using CSS variables
57
- const colors = useMemo(() => {
58
- const palettes = {
59
- vibrant: [
60
- 'hsl(var(--chart-1))', // Blue
61
- 'hsl(var(--chart-2))', // Green
62
- 'hsl(var(--chart-3))', // Purple
63
- 'hsl(var(--chart-4))', // Orange
64
- 'hsl(var(--chart-5))', // Red
65
- ],
66
- monochrome: [
67
- 'hsl(var(--primary))',
68
- 'hsl(var(--primary) / 0.8)',
69
- 'hsl(var(--primary) / 0.6)',
70
- ],
71
- cool: [
72
- 'hsl(var(--chart-1))', // Blue
73
- 'hsl(var(--chart-3))', // Purple
74
- 'hsl(210 100% 50%)', // Bright blue
75
- 'hsl(260 100% 60%)', // Violet
76
- ],
77
- warm: [
78
- 'hsl(var(--chart-4))', // Orange
79
- 'hsl(var(--chart-5))', // Red
80
- 'hsl(35 100% 55%)', // Gold
81
- 'hsl(350 100% 60%)', // Rose
82
- ],
83
- };
84
- return palettes[colorScheme];
85
- }, [colorScheme]);
86
-
87
- if (resolvedVariant === 'none') {
88
- return null;
89
- }
90
-
91
- return (
92
- <div
93
- className={cn("absolute overflow-hidden pointer-events-none", className)}
94
- style={{ inset: 0, width: '100%', height: '100%' }}
95
- >
96
- {resolvedVariant === 'aurora-borealis' && (
97
- <AuroraBorealis colors={colors} intensity={intensityConfig} />
98
- )}
99
-
100
- {resolvedVariant === 'mesh-gradient' && (
101
- <MeshGradient colors={colors} intensity={intensityConfig} />
102
- )}
103
-
104
- {resolvedVariant === 'floating-orbs' && (
105
- <FloatingOrbs colors={colors} intensity={intensityConfig} />
106
- )}
107
-
108
- {resolvedVariant === 'geometric-flow' && (
109
- <GeometricFlow colors={colors} intensity={intensityConfig} />
110
- )}
111
-
112
- {resolvedVariant === 'liquid-gradient' && (
113
- <LiquidGradient colors={colors} intensity={intensityConfig} />
114
- )}
115
-
116
- {resolvedVariant === 'spotlight' && (
117
- <Spotlight colors={colors} intensity={intensityConfig} />
118
- )}
119
-
120
- <AnimationStyles />
121
- </div>
122
- );
123
- };
124
-
125
- // =============================================================================
126
- // Aurora Borealis - Flowing northern lights effect
127
- // =============================================================================
128
-
129
- interface VariantProps {
130
- colors: string[];
131
- intensity: { opacity: number; blur: string; scale: number };
132
- }
133
-
134
- const AuroraBorealis: React.FC<VariantProps> = ({ colors, intensity }) => (
135
- <>
136
- {/* Base layer - subtle gradient */}
137
- <div
138
- className="absolute inset-0"
139
- style={{
140
- background: `linear-gradient(135deg, ${colors[0]} 0%, transparent 50%, ${colors[1]} 100%)`,
141
- opacity: intensity.opacity * 0.3,
142
- }}
143
- />
144
-
145
- {/* Aurora bands */}
146
- <div
147
- className={cn("absolute inset-0", intensity.blur)}
148
- style={{
149
- background: `linear-gradient(110deg,
150
- transparent 0%,
151
- ${colors[0]} 20%,
152
- ${colors[2] || colors[0]} 35%,
153
- ${colors[1]} 50%,
154
- ${colors[3] || colors[1]} 65%,
155
- ${colors[0]} 80%,
156
- transparent 100%
157
- )`,
158
- opacity: intensity.opacity,
159
- animation: 'aurora-shift 15s ease-in-out infinite',
160
- transform: `translateY(-30%) scaleY(${intensity.scale})`,
161
- }}
162
- />
163
-
164
- {/* Secondary aurora layer */}
165
- <div
166
- className={cn("absolute inset-0", intensity.blur)}
167
- style={{
168
- background: `linear-gradient(70deg,
169
- transparent 0%,
170
- ${colors[1]} 25%,
171
- ${colors[2] || colors[0]} 50%,
172
- ${colors[0]} 75%,
173
- transparent 100%
174
- )`,
175
- opacity: intensity.opacity * 0.7,
176
- animation: 'aurora-shift 20s ease-in-out infinite reverse',
177
- animationDelay: '-5s',
178
- transform: `translateY(-20%) scaleY(${intensity.scale * 0.8})`,
179
- }}
180
- />
181
-
182
- {/* Shimmer overlay */}
183
- <div
184
- className="absolute inset-0"
185
- style={{
186
- background: `radial-gradient(ellipse 100% 50% at 50% 0%,
187
- ${colors[2] || colors[0]} 0%,
188
- transparent 70%
189
- )`,
190
- opacity: intensity.opacity * 0.4,
191
- animation: 'aurora-shimmer 8s ease-in-out infinite',
192
- }}
193
- />
194
- </>
195
- );
196
-
197
- // =============================================================================
198
- // Mesh Gradient - Modern Apple-style gradient mesh
199
- // =============================================================================
200
-
201
- const MeshGradient: React.FC<VariantProps> = ({ colors, intensity }) => (
202
- <>
203
- {/* Large gradient orbs with different colors */}
204
- <div
205
- className={cn("absolute rounded-full", intensity.blur)}
206
- style={{
207
- width: '60%',
208
- height: '60%',
209
- top: '-10%',
210
- right: '-10%',
211
- background: `radial-gradient(circle, ${colors[0]} 0%, transparent 70%)`,
212
- opacity: intensity.opacity,
213
- animation: 'mesh-float-1 25s ease-in-out infinite',
214
- transform: `scale(${intensity.scale})`,
215
- }}
216
- />
217
- <div
218
- className={cn("absolute rounded-full", intensity.blur)}
219
- style={{
220
- width: '50%',
221
- height: '50%',
222
- bottom: '-5%',
223
- left: '-5%',
224
- background: `radial-gradient(circle, ${colors[1]} 0%, transparent 70%)`,
225
- opacity: intensity.opacity,
226
- animation: 'mesh-float-2 30s ease-in-out infinite',
227
- transform: `scale(${intensity.scale})`,
228
- }}
229
- />
230
- <div
231
- className={cn("absolute rounded-full", intensity.blur)}
232
- style={{
233
- width: '40%',
234
- height: '40%',
235
- top: '30%',
236
- left: '25%',
237
- background: `radial-gradient(circle, ${colors[2] || colors[0]} 0%, transparent 70%)`,
238
- opacity: intensity.opacity * 0.8,
239
- animation: 'mesh-float-3 20s ease-in-out infinite',
240
- transform: `scale(${intensity.scale})`,
241
- }}
242
- />
243
- {colors[3] && (
244
- <div
245
- className={cn("absolute rounded-full", intensity.blur)}
246
- style={{
247
- width: '35%',
248
- height: '35%',
249
- bottom: '20%',
250
- right: '15%',
251
- background: `radial-gradient(circle, ${colors[3]} 0%, transparent 70%)`,
252
- opacity: intensity.opacity * 0.6,
253
- animation: 'mesh-float-4 22s ease-in-out infinite',
254
- transform: `scale(${intensity.scale})`,
255
- }}
256
- />
257
- )}
258
- </>
259
- );
260
-
261
- // =============================================================================
262
- // Floating Orbs - Animated glowing spheres
263
- // =============================================================================
264
-
265
- const FloatingOrbs: React.FC<VariantProps> = ({ colors, intensity }) => {
266
- const orbs = useMemo(() => {
267
- return Array.from({ length: 12 }).map((_, i) => ({
268
- id: i,
269
- size: 60 + (i % 4) * 40,
270
- x: (i * 23) % 100,
271
- y: (i * 31) % 100,
272
- color: colors[i % colors.length],
273
- duration: 15 + (i % 5) * 5,
274
- delay: i * 1.5,
275
- }));
276
- }, [colors]);
277
-
278
- return (
279
- <>
280
- {orbs.map((orb) => (
281
- <div
282
- key={orb.id}
283
- className={cn("absolute rounded-full", intensity.blur)}
284
- style={{
285
- width: `${orb.size * intensity.scale}px`,
286
- height: `${orb.size * intensity.scale}px`,
287
- left: `${orb.x}%`,
288
- top: `${orb.y}%`,
289
- background: `radial-gradient(circle at 30% 30%, ${orb.color}, transparent 70%)`,
290
- opacity: intensity.opacity * (0.5 + (orb.id % 3) * 0.2),
291
- animation: `orb-float-${(orb.id % 4) + 1} ${orb.duration}s ease-in-out infinite`,
292
- animationDelay: `${orb.delay}s`,
293
- }}
294
- />
295
- ))}
296
- </>
297
- );
298
- };
299
-
300
- // =============================================================================
301
- // Geometric Flow - Clean geometric patterns
302
- // =============================================================================
303
-
304
- const GeometricFlow: React.FC<VariantProps> = ({ colors, intensity }) => (
305
- <>
306
- {/* Gradient base */}
307
- <div
308
- className="absolute inset-0"
309
- style={{
310
- background: `linear-gradient(135deg,
311
- ${colors[0]} 0%,
312
- transparent 30%,
313
- transparent 70%,
314
- ${colors[1]} 100%
315
- )`,
316
- opacity: intensity.opacity * 0.3,
317
- }}
318
- />
319
-
320
- {/* Animated grid */}
321
- <div
322
- className="absolute inset-0"
323
- style={{
324
- backgroundImage: `
325
- linear-gradient(${colors[0]}20 1px, transparent 1px),
326
- linear-gradient(90deg, ${colors[0]}20 1px, transparent 1px)
327
- `,
328
- backgroundSize: '60px 60px',
329
- animation: 'grid-drift 30s linear infinite',
330
- opacity: intensity.opacity,
331
- }}
332
- />
333
-
334
- {/* Diagonal lines */}
335
- <div
336
- className="absolute inset-0"
337
- style={{
338
- backgroundImage: `repeating-linear-gradient(
339
- 45deg,
340
- transparent,
341
- transparent 80px,
342
- ${colors[2] || colors[0]}10 80px,
343
- ${colors[2] || colors[0]}10 82px
344
- )`,
345
- animation: 'diagonal-shift 20s linear infinite',
346
- opacity: intensity.opacity,
347
- }}
348
- />
349
-
350
- {/* Glowing intersection points */}
351
- <div
352
- className={cn("absolute rounded-full", intensity.blur)}
353
- style={{
354
- width: '40%',
355
- height: '40%',
356
- top: '20%',
357
- left: '50%',
358
- transform: 'translateX(-50%)',
359
- background: `radial-gradient(circle, ${colors[0]} 0%, transparent 70%)`,
360
- opacity: intensity.opacity * 0.5,
361
- animation: 'pulse-glow 8s ease-in-out infinite',
362
- }}
363
- />
364
- </>
365
- );
366
-
367
- // =============================================================================
368
- // Liquid Gradient - Smooth flowing liquid effect
369
- // =============================================================================
370
-
371
- const LiquidGradient: React.FC<VariantProps> = ({ colors, intensity }) => (
372
- <>
373
- {/* Base gradient */}
374
- <div
375
- className="absolute inset-0"
376
- style={{
377
- background: `linear-gradient(180deg,
378
- transparent 0%,
379
- ${colors[0]}15 30%,
380
- ${colors[1]}20 50%,
381
- ${colors[2] || colors[0]}15 70%,
382
- transparent 100%
383
- )`,
384
- opacity: intensity.opacity,
385
- }}
386
- />
387
-
388
- {/* Liquid blob 1 */}
389
- <div
390
- className={cn("absolute", intensity.blur)}
391
- style={{
392
- width: '120%',
393
- height: '50%',
394
- bottom: '-10%',
395
- left: '-10%',
396
- background: `linear-gradient(90deg,
397
- ${colors[0]} 0%,
398
- ${colors[1]} 33%,
399
- ${colors[2] || colors[0]} 66%,
400
- ${colors[0]} 100%
401
- )`,
402
- opacity: intensity.opacity,
403
- borderRadius: '50% 50% 0 0',
404
- animation: 'liquid-flow-1 12s ease-in-out infinite',
405
- transform: `scaleY(${intensity.scale})`,
406
- }}
407
- />
408
-
409
- {/* Liquid blob 2 */}
410
- <div
411
- className={cn("absolute", intensity.blur)}
412
- style={{
413
- width: '100%',
414
- height: '40%',
415
- bottom: '-5%',
416
- left: '0',
417
- background: `linear-gradient(90deg,
418
- ${colors[1]} 0%,
419
- ${colors[2] || colors[0]} 50%,
420
- ${colors[3] || colors[1]} 100%
421
- )`,
422
- opacity: intensity.opacity * 0.8,
423
- borderRadius: '60% 40% 0 0',
424
- animation: 'liquid-flow-2 15s ease-in-out infinite',
425
- transform: `scaleY(${intensity.scale * 0.9})`,
426
- }}
427
- />
428
-
429
- {/* Floating bubbles */}
430
- {Array.from({ length: 6 }).map((_, i) => (
431
- <div
432
- key={i}
433
- className="absolute rounded-full"
434
- style={{
435
- width: `${12 + i * 4}px`,
436
- height: `${12 + i * 4}px`,
437
- left: `${15 + i * 15}%`,
438
- bottom: '10%',
439
- background: `radial-gradient(circle at 30% 30%,
440
- ${colors[i % colors.length]}80,
441
- ${colors[i % colors.length]}20
442
- )`,
443
- border: `1px solid ${colors[i % colors.length]}40`,
444
- opacity: intensity.opacity,
445
- animation: `bubble-float ${8 + i * 2}s ease-in-out infinite`,
446
- animationDelay: `${i * 2}s`,
447
- }}
448
- />
449
- ))}
450
- </>
451
- );
452
-
453
- // =============================================================================
454
- // Spotlight - Dramatic spotlight effect
455
- // =============================================================================
456
-
457
- const Spotlight: React.FC<VariantProps> = ({ colors, intensity }) => (
458
- <>
459
- {/* Main spotlight */}
460
- <div
461
- className={cn("absolute", intensity.blur)}
462
- style={{
463
- width: '80%',
464
- height: '80%',
465
- top: '-20%',
466
- left: '50%',
467
- transform: 'translateX(-50%)',
468
- background: `conic-gradient(from 180deg at 50% 50%,
469
- ${colors[0]} 0deg,
470
- ${colors[1]} 60deg,
471
- ${colors[2] || colors[0]} 120deg,
472
- ${colors[3] || colors[1]} 180deg,
473
- ${colors[0]} 240deg,
474
- ${colors[1]} 300deg,
475
- ${colors[0]} 360deg
476
- )`,
477
- opacity: intensity.opacity,
478
- animation: 'spotlight-rotate 30s linear infinite',
479
- }}
480
- />
481
-
482
- {/* Center fade */}
483
- <div
484
- className="absolute inset-0"
485
- style={{
486
- background: `radial-gradient(circle at 50% 30%,
487
- transparent 0%,
488
- hsl(var(--background)) 70%
489
- )`,
490
- }}
491
- />
492
-
493
- {/* Accent glow */}
494
- <div
495
- className={cn("absolute rounded-full", intensity.blur)}
496
- style={{
497
- width: '50%',
498
- height: '50%',
499
- top: '10%',
500
- left: '25%',
501
- background: `radial-gradient(circle, ${colors[0]} 0%, transparent 70%)`,
502
- opacity: intensity.opacity * 0.5,
503
- animation: 'pulse-glow 6s ease-in-out infinite',
504
- }}
505
- />
506
- </>
507
- );
508
-
509
- // =============================================================================
510
- // Animation Styles
511
- // =============================================================================
512
-
513
- const AnimationStyles: React.FC = () => (
514
- <style>{`
515
- @keyframes aurora-shift {
516
- 0%, 100% {
517
- transform: translateX(-10%) translateY(-30%) scaleX(1.1);
518
- }
519
- 50% {
520
- transform: translateX(10%) translateY(-25%) scaleX(0.9);
521
- }
522
- }
523
-
524
- @keyframes aurora-shimmer {
525
- 0%, 100% {
526
- opacity: 0.2;
527
- transform: scale(1);
528
- }
529
- 50% {
530
- opacity: 0.4;
531
- transform: scale(1.05);
532
- }
533
- }
534
-
535
- @keyframes mesh-float-1 {
536
- 0%, 100% { transform: translate(0, 0) scale(1); }
537
- 25% { transform: translate(-5%, 10%) scale(1.05); }
538
- 50% { transform: translate(5%, 5%) scale(0.95); }
539
- 75% { transform: translate(-3%, -5%) scale(1.02); }
540
- }
541
-
542
- @keyframes mesh-float-2 {
543
- 0%, 100% { transform: translate(0, 0) scale(1); }
544
- 33% { transform: translate(8%, -8%) scale(1.08); }
545
- 66% { transform: translate(-6%, 6%) scale(0.92); }
546
- }
547
-
548
- @keyframes mesh-float-3 {
549
- 0%, 100% { transform: translate(0, 0) scale(1); }
550
- 50% { transform: translate(10%, 10%) scale(1.1); }
551
- }
552
-
553
- @keyframes mesh-float-4 {
554
- 0%, 100% { transform: translate(0, 0) scale(1); }
555
- 25% { transform: translate(5%, -10%) scale(0.95); }
556
- 75% { transform: translate(-8%, 5%) scale(1.05); }
557
- }
558
-
559
- @keyframes orb-float-1 {
560
- 0%, 100% { transform: translate(0, 0); }
561
- 50% { transform: translate(30px, -40px); }
562
- }
563
-
564
- @keyframes orb-float-2 {
565
- 0%, 100% { transform: translate(0, 0); }
566
- 50% { transform: translate(-25px, 35px); }
567
- }
568
-
569
- @keyframes orb-float-3 {
570
- 0%, 100% { transform: translate(0, 0); }
571
- 33% { transform: translate(40px, 20px); }
572
- 66% { transform: translate(-20px, -30px); }
573
- }
574
-
575
- @keyframes orb-float-4 {
576
- 0%, 100% { transform: translate(0, 0); }
577
- 25% { transform: translate(-35px, -25px); }
578
- 75% { transform: translate(25px, 40px); }
579
- }
580
-
581
- @keyframes grid-drift {
582
- 0% { transform: translate(0, 0); }
583
- 100% { transform: translate(60px, 60px); }
584
- }
585
-
586
- @keyframes diagonal-shift {
587
- 0% { transform: translateX(0); }
588
- 100% { transform: translateX(160px); }
589
- }
590
-
591
- @keyframes pulse-glow {
592
- 0%, 100% { opacity: 0.3; transform: translateX(-50%) scale(1); }
593
- 50% { opacity: 0.6; transform: translateX(-50%) scale(1.1); }
594
- }
595
-
596
- @keyframes liquid-flow-1 {
597
- 0%, 100% {
598
- transform: translateY(0) scaleX(1);
599
- border-radius: 50% 50% 0 0;
600
- }
601
- 25% {
602
- transform: translateY(-30px) scaleX(1.05);
603
- border-radius: 45% 55% 0 0;
604
- }
605
- 50% {
606
- transform: translateY(-50px) scaleX(0.95);
607
- border-radius: 55% 45% 0 0;
608
- }
609
- 75% {
610
- transform: translateY(-25px) scaleX(1.02);
611
- border-radius: 48% 52% 0 0;
612
- }
613
- }
614
-
615
- @keyframes liquid-flow-2 {
616
- 0%, 100% {
617
- transform: translateY(0) scaleX(1);
618
- border-radius: 60% 40% 0 0;
619
- }
620
- 33% {
621
- transform: translateY(-40px) scaleX(1.08);
622
- border-radius: 40% 60% 0 0;
623
- }
624
- 66% {
625
- transform: translateY(-60px) scaleX(0.92);
626
- border-radius: 55% 45% 0 0;
627
- }
628
- }
629
-
630
- @keyframes bubble-float {
631
- 0%, 100% {
632
- transform: translateY(0) scale(1);
633
- opacity: 0.6;
634
- }
635
- 50% {
636
- transform: translateY(-100px) scale(1.2);
637
- opacity: 0.3;
638
- }
639
- }
640
-
641
- @keyframes spotlight-rotate {
642
- 0% { transform: translateX(-50%) rotate(0deg); }
643
- 100% { transform: translateX(-50%) rotate(360deg); }
644
- }
645
- `}</style>
646
- );