@djangocfg/ui-nextjs 2.1.66 → 2.1.68

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 (90) hide show
  1. package/package.json +8 -6
  2. package/src/stores/index.ts +8 -0
  3. package/src/stores/mediaCache.ts +474 -0
  4. package/src/tools/AudioPlayer/@refactoring/00-PLAN.md +148 -0
  5. package/src/tools/AudioPlayer/@refactoring/01-TYPES.md +301 -0
  6. package/src/tools/AudioPlayer/@refactoring/02-HOOKS.md +281 -0
  7. package/src/tools/AudioPlayer/@refactoring/03-CONTEXT.md +328 -0
  8. package/src/tools/AudioPlayer/@refactoring/04-COMPONENTS.md +251 -0
  9. package/src/tools/AudioPlayer/@refactoring/05-EFFECTS.md +427 -0
  10. package/src/tools/AudioPlayer/@refactoring/06-UTILS-AND-INDEX.md +193 -0
  11. package/src/tools/AudioPlayer/@refactoring/07-EXECUTION-CHECKLIST.md +146 -0
  12. package/src/tools/AudioPlayer/README.md +35 -11
  13. package/src/tools/AudioPlayer/{AudioEqualizer.tsx → components/AudioEqualizer.tsx} +29 -64
  14. package/src/tools/AudioPlayer/{AudioPlayer.tsx → components/AudioPlayer.tsx} +22 -14
  15. package/src/tools/AudioPlayer/{AudioShortcutsPopover.tsx → components/AudioShortcutsPopover.tsx} +6 -2
  16. package/src/tools/AudioPlayer/components/ReactiveCover/AudioReactiveCover.tsx +147 -0
  17. package/src/tools/AudioPlayer/components/ReactiveCover/effects/GlowEffect.tsx +110 -0
  18. package/src/tools/AudioPlayer/components/ReactiveCover/effects/MeshEffect.tsx +58 -0
  19. package/src/tools/AudioPlayer/components/ReactiveCover/effects/OrbsEffect.tsx +45 -0
  20. package/src/tools/AudioPlayer/components/ReactiveCover/effects/SpotlightEffect.tsx +82 -0
  21. package/src/tools/AudioPlayer/components/ReactiveCover/effects/index.ts +8 -0
  22. package/src/tools/AudioPlayer/components/ReactiveCover/index.ts +6 -0
  23. package/src/tools/AudioPlayer/{SimpleAudioPlayer.tsx → components/SimpleAudioPlayer.tsx} +12 -7
  24. package/src/tools/AudioPlayer/{VisualizationToggle.tsx → components/VisualizationToggle.tsx} +2 -6
  25. package/src/tools/AudioPlayer/components/index.ts +21 -0
  26. package/src/tools/AudioPlayer/context/AudioProvider.tsx +292 -0
  27. package/src/tools/AudioPlayer/context/index.ts +11 -0
  28. package/src/tools/AudioPlayer/context/selectors.ts +96 -0
  29. package/src/tools/AudioPlayer/hooks/index.ts +29 -0
  30. package/src/tools/AudioPlayer/hooks/useAudioAnalysis.ts +110 -0
  31. package/src/tools/AudioPlayer/{useAudioHotkeys.ts → hooks/useAudioHotkeys.ts} +11 -4
  32. package/src/tools/AudioPlayer/hooks/useSharedWebAudio.ts +106 -0
  33. package/src/tools/AudioPlayer/{useAudioVisualization.tsx → hooks/useVisualization.tsx} +11 -5
  34. package/src/tools/AudioPlayer/index.ts +104 -49
  35. package/src/tools/AudioPlayer/types/audio.ts +107 -0
  36. package/src/tools/AudioPlayer/{types.ts → types/components.ts} +20 -84
  37. package/src/tools/AudioPlayer/types/effects.ts +73 -0
  38. package/src/tools/AudioPlayer/types/index.ts +35 -0
  39. package/src/tools/AudioPlayer/utils/formatTime.ts +10 -0
  40. package/src/tools/AudioPlayer/utils/index.ts +5 -0
  41. package/src/tools/ImageViewer/@refactoring/00-PLAN.md +71 -0
  42. package/src/tools/ImageViewer/@refactoring/01-TYPES.md +121 -0
  43. package/src/tools/ImageViewer/@refactoring/02-UTILS.md +143 -0
  44. package/src/tools/ImageViewer/@refactoring/03-HOOKS.md +261 -0
  45. package/src/tools/ImageViewer/@refactoring/04-COMPONENTS.md +427 -0
  46. package/src/tools/ImageViewer/@refactoring/05-EXECUTION-CHECKLIST.md +126 -0
  47. package/src/tools/ImageViewer/README.md +16 -3
  48. package/src/tools/ImageViewer/components/ImageInfo.tsx +44 -0
  49. package/src/tools/ImageViewer/components/ImageToolbar.tsx +150 -0
  50. package/src/tools/ImageViewer/components/ImageViewer.tsx +235 -0
  51. package/src/tools/ImageViewer/components/index.ts +7 -0
  52. package/src/tools/ImageViewer/hooks/index.ts +9 -0
  53. package/src/tools/ImageViewer/hooks/useImageLoading.ts +153 -0
  54. package/src/tools/ImageViewer/hooks/useImageTransform.ts +101 -0
  55. package/src/tools/ImageViewer/index.ts +47 -3
  56. package/src/tools/ImageViewer/types.ts +75 -0
  57. package/src/tools/ImageViewer/utils/constants.ts +59 -0
  58. package/src/tools/ImageViewer/utils/index.ts +16 -0
  59. package/src/tools/ImageViewer/utils/lqip.ts +47 -0
  60. package/src/tools/VideoPlayer/@refactoring/00-PLAN.md +91 -0
  61. package/src/tools/VideoPlayer/@refactoring/01-TYPES.md +284 -0
  62. package/src/tools/VideoPlayer/@refactoring/02-UTILS.md +141 -0
  63. package/src/tools/VideoPlayer/@refactoring/03-HOOKS.md +178 -0
  64. package/src/tools/VideoPlayer/@refactoring/04-COMPONENTS.md +95 -0
  65. package/src/tools/VideoPlayer/@refactoring/05-EXECUTION-CHECKLIST.md +139 -0
  66. package/src/tools/VideoPlayer/README.md +26 -10
  67. package/src/tools/VideoPlayer/{VideoControls.tsx → components/VideoControls.tsx} +8 -9
  68. package/src/tools/VideoPlayer/{VideoErrorFallback.tsx → components/VideoErrorFallback.tsx} +2 -2
  69. package/src/tools/VideoPlayer/{VideoPlayer.tsx → components/VideoPlayer.tsx} +4 -5
  70. package/src/tools/VideoPlayer/components/index.ts +14 -0
  71. package/src/tools/VideoPlayer/context/VideoPlayerContext.tsx +52 -0
  72. package/src/tools/VideoPlayer/context/index.ts +8 -0
  73. package/src/tools/VideoPlayer/hooks/index.ts +9 -0
  74. package/src/tools/VideoPlayer/hooks/useVideoPositionCache.ts +109 -0
  75. package/src/tools/VideoPlayer/index.ts +29 -20
  76. package/src/tools/VideoPlayer/providers/StreamProvider.tsx +118 -28
  77. package/src/tools/VideoPlayer/providers/VidstackProvider.tsx +89 -11
  78. package/src/tools/VideoPlayer/types/index.ts +38 -0
  79. package/src/tools/VideoPlayer/types/player.ts +116 -0
  80. package/src/tools/VideoPlayer/types/provider.ts +93 -0
  81. package/src/tools/VideoPlayer/types/sources.ts +97 -0
  82. package/src/tools/VideoPlayer/utils/fileSource.ts +78 -0
  83. package/src/tools/VideoPlayer/utils/index.ts +11 -0
  84. package/src/tools/VideoPlayer/utils/resolvers.ts +75 -0
  85. package/src/tools/index.ts +10 -0
  86. package/src/tools/AudioPlayer/AudioReactiveCover.tsx +0 -389
  87. package/src/tools/AudioPlayer/context.tsx +0 -426
  88. package/src/tools/ImageViewer/ImageViewer.tsx +0 -416
  89. package/src/tools/VideoPlayer/VideoPlayerContext.tsx +0 -125
  90. package/src/tools/VideoPlayer/types.ts +0 -367
@@ -0,0 +1,110 @@
1
+ 'use client';
2
+
3
+ /**
4
+ * GlowEffect - Multi-layer glow effect with pulse rings
5
+ */
6
+
7
+ import { cn } from '@djangocfg/ui-nextjs';
8
+ import type { calculateGlowLayers } from '../../../effects';
9
+
10
+ // =============================================================================
11
+ // TYPES
12
+ // =============================================================================
13
+
14
+ export interface GlowEffectData {
15
+ layers: ReturnType<typeof calculateGlowLayers>;
16
+ hueShift: number;
17
+ showPulseRings: boolean;
18
+ showSparkle: boolean;
19
+ }
20
+
21
+ interface GlowEffectProps {
22
+ data: GlowEffectData;
23
+ colors: string[];
24
+ isPlaying: boolean;
25
+ }
26
+
27
+ // =============================================================================
28
+ // COMPONENT
29
+ // =============================================================================
30
+
31
+ export function GlowEffect({ data, colors, isPlaying }: GlowEffectProps) {
32
+ const { layers, hueShift, showPulseRings, showSparkle } = data;
33
+
34
+ return (
35
+ <>
36
+ {/* Main glow layers */}
37
+ {layers.map((layer, i) => (
38
+ <div
39
+ key={i}
40
+ className={cn('absolute rounded-2xl -z-10', layer.blur)}
41
+ style={{
42
+ inset: `-${layer.inset}px`,
43
+ background: layer.background,
44
+ opacity: isPlaying ? layer.opacity : 0,
45
+ transform: i < 2 ? `scaleY(${layer.scale})` : `scale(${layer.scale})`,
46
+ animation: isPlaying && layer.animation ? layer.animation : 'none',
47
+ transition: 'opacity 0.3s',
48
+ }}
49
+ />
50
+ ))}
51
+
52
+ {/* Rotating color sweep */}
53
+ <div
54
+ className="absolute rounded-2xl blur-xl overflow-hidden -z-10"
55
+ style={{
56
+ inset: '-75px',
57
+ opacity: isPlaying ? 0.6 : 0,
58
+ transition: 'opacity 0.5s',
59
+ }}
60
+ >
61
+ <div
62
+ className="absolute inset-0"
63
+ style={{
64
+ background: `conic-gradient(
65
+ from ${hueShift}deg at 50% 50%,
66
+ hsl(${colors[0]} / 0.4) 0deg,
67
+ hsl(${colors[1] || colors[0]} / 0.3) 90deg,
68
+ hsl(${colors[2] || colors[0]} / 0.3) 180deg,
69
+ hsl(${colors[3] || colors[0]} / 0.3) 270deg,
70
+ hsl(${colors[0]} / 0.4) 360deg
71
+ )`,
72
+ animation: isPlaying ? 'glow-rotate 6s linear infinite' : 'none',
73
+ }}
74
+ />
75
+ </div>
76
+
77
+ {/* Pulse rings on bass hits */}
78
+ {showPulseRings && (
79
+ <>
80
+ <div
81
+ className="absolute -inset-6 rounded-xl border-2 animate-ping -z-10"
82
+ style={{
83
+ borderColor: `hsl(${colors[0]} / 0.4)`,
84
+ animationDuration: '1s',
85
+ }}
86
+ />
87
+ <div
88
+ className="absolute -inset-12 rounded-2xl border animate-ping -z-10"
89
+ style={{
90
+ borderColor: `hsl(${colors[1] || colors[0]} / 0.3)`,
91
+ animationDuration: '1.5s',
92
+ animationDelay: '0.2s',
93
+ }}
94
+ />
95
+ </>
96
+ )}
97
+
98
+ {/* Sparkle on high frequencies */}
99
+ {showSparkle && (
100
+ <div
101
+ className="absolute -inset-18 rounded-3xl -z-10"
102
+ style={{
103
+ background: `radial-gradient(circle at 50% 30%, hsl(${colors[2] || colors[0]} / 0.5) 0%, transparent 30%)`,
104
+ animation: 'sparkle-move 0.5s ease-out',
105
+ }}
106
+ />
107
+ )}
108
+ </>
109
+ );
110
+ }
@@ -0,0 +1,58 @@
1
+ 'use client';
2
+
3
+ /**
4
+ * MeshEffect - Mesh gradient blobs that react to audio
5
+ */
6
+
7
+ import { cn } from '@djangocfg/ui-nextjs';
8
+ import type { calculateMeshGradients } from '../../../effects';
9
+
10
+ // =============================================================================
11
+ // TYPES
12
+ // =============================================================================
13
+
14
+ interface MeshEffectProps {
15
+ gradients: ReturnType<typeof calculateMeshGradients>;
16
+ blur: string;
17
+ isPlaying: boolean;
18
+ }
19
+
20
+ // =============================================================================
21
+ // COMPONENT
22
+ // =============================================================================
23
+
24
+ export function MeshEffect({ gradients, isPlaying }: MeshEffectProps) {
25
+ return (
26
+ <>
27
+ {gradients.map((g, i) => {
28
+ const isCenter = 'isCenter' in g && g.isCenter;
29
+ const scale = 'scale' in g ? g.scale : 1;
30
+ const rotation = 'rotation' in g ? g.rotation : 0;
31
+ const itemBlur = 'blur' in g ? g.blur : 'blur-2xl';
32
+
33
+ return (
34
+ <div
35
+ key={i}
36
+ className={cn('absolute rounded-full -z-10', itemBlur)}
37
+ style={{
38
+ width: g.width,
39
+ height: g.height,
40
+ top: 'top' in g ? g.top : undefined,
41
+ bottom: 'bottom' in g ? g.bottom : undefined,
42
+ left: 'left' in g ? g.left : undefined,
43
+ right: 'right' in g ? g.right : undefined,
44
+ background: isCenter
45
+ ? `radial-gradient(circle, hsl(${g.color} / 0.6) 0%, hsl(${g.color} / 0.3) 30%, transparent 60%)`
46
+ : `radial-gradient(circle, hsl(${g.color}) 0%, hsl(${g.color} / 0.5) 30%, transparent 65%)`,
47
+ opacity: isPlaying ? g.opacity : 0,
48
+ transform: isCenter
49
+ ? `translate(-50%, -50%) scale(${scale})`
50
+ : `scale(${scale}) rotate(${rotation}deg)`,
51
+ transition: 'all 0.08s ease-out',
52
+ }}
53
+ />
54
+ );
55
+ })}
56
+ </>
57
+ );
58
+ }
@@ -0,0 +1,45 @@
1
+ 'use client';
2
+
3
+ /**
4
+ * OrbsEffect - Floating orb particles that react to audio
5
+ */
6
+
7
+ import { cn } from '@djangocfg/ui-nextjs';
8
+ import type { calculateOrbs } from '../../../effects';
9
+
10
+ // =============================================================================
11
+ // TYPES
12
+ // =============================================================================
13
+
14
+ interface OrbsEffectProps {
15
+ orbs: ReturnType<typeof calculateOrbs>;
16
+ blur: string;
17
+ isPlaying: boolean;
18
+ }
19
+
20
+ // =============================================================================
21
+ // COMPONENT
22
+ // =============================================================================
23
+
24
+ export function OrbsEffect({ orbs, blur, isPlaying }: OrbsEffectProps) {
25
+ return (
26
+ <>
27
+ {orbs.map((orb, i) => (
28
+ <div
29
+ key={i}
30
+ className={cn('absolute rounded-full -z-10', blur)}
31
+ style={{
32
+ width: orb.size,
33
+ height: orb.size,
34
+ left: `${orb.x}%`,
35
+ top: `${orb.y}%`,
36
+ background: `radial-gradient(circle at 30% 30%, hsl(${orb.color}) 0%, hsl(${orb.color} / 0.5) 40%, transparent 70%)`,
37
+ opacity: isPlaying ? orb.opacity : 0,
38
+ transform: `translate(-50%, -50%) scale(${orb.scale})`,
39
+ transition: 'all 0.08s ease-out',
40
+ }}
41
+ />
42
+ ))}
43
+ </>
44
+ );
45
+ }
@@ -0,0 +1,82 @@
1
+ 'use client';
2
+
3
+ /**
4
+ * SpotlightEffect - Rotating spotlight with conic gradients
5
+ */
6
+
7
+ import { cn } from '@djangocfg/ui-nextjs';
8
+ import type { calculateSpotlight } from '../../../effects';
9
+
10
+ // =============================================================================
11
+ // TYPES
12
+ // =============================================================================
13
+
14
+ interface SpotlightEffectProps {
15
+ data: ReturnType<typeof calculateSpotlight>;
16
+ colors: string[];
17
+ blur: string;
18
+ isPlaying: boolean;
19
+ }
20
+
21
+ // =============================================================================
22
+ // COMPONENT
23
+ // =============================================================================
24
+
25
+ export function SpotlightEffect({ data, colors, blur, isPlaying }: SpotlightEffectProps) {
26
+ const inset = 'inset' in data ? data.inset : 12;
27
+ const pulseInset = 'pulseInset' in data ? data.pulseInset : 24;
28
+ const ringOpacity = 'ringOpacity' in data ? data.ringOpacity : 0.3;
29
+ const ringScale = 'ringScale' in data ? data.ringScale : 1;
30
+
31
+ return (
32
+ <>
33
+ {/* Rotating conic gradient - reactive size */}
34
+ <div
35
+ className={cn('absolute rounded-xl -z-10', blur)}
36
+ style={{
37
+ inset: `-${inset}px`,
38
+ background: `conic-gradient(
39
+ from ${data.rotation}deg,
40
+ hsl(${colors[0]} / ${data.colors[0]?.opacity || 0.5}),
41
+ hsl(${colors[1] || colors[0]} / ${data.colors[1]?.opacity || 0.7}),
42
+ hsl(${colors[2] || colors[0]} / ${data.colors[2]?.opacity || 0.5}),
43
+ hsl(${colors[0]} / ${data.colors[1]?.opacity || 0.7}),
44
+ hsl(${colors[0]} / ${data.colors[0]?.opacity || 0.5})
45
+ )`,
46
+ opacity: isPlaying ? 1 : 0,
47
+ transition: 'all 0.08s ease-out',
48
+ }}
49
+ />
50
+
51
+ {/* Inner border */}
52
+ <div
53
+ className="absolute -inset-1 rounded-lg bg-background -z-10"
54
+ style={{ opacity: isPlaying ? 1 : 0, transition: 'opacity 0.1s' }}
55
+ />
56
+
57
+ {/* Bass pulse glow - reactive size */}
58
+ <div
59
+ className={cn('absolute rounded-2xl -z-10', blur)}
60
+ style={{
61
+ inset: `-${pulseInset}px`,
62
+ background: `radial-gradient(circle, hsl(${colors[0]} / 0.7) 0%, hsl(${colors[0]} / 0.3) 50%, transparent 70%)`,
63
+ opacity: isPlaying ? data.pulseOpacity : 0,
64
+ transform: `scale(${data.pulseScale})`,
65
+ transition: 'all 0.08s ease-out',
66
+ }}
67
+ />
68
+
69
+ {/* Outer ring glow */}
70
+ <div
71
+ className="absolute rounded-3xl -z-10 blur-2xl"
72
+ style={{
73
+ inset: `-${pulseInset + 30}px`,
74
+ background: `radial-gradient(circle, hsl(${colors[1] || colors[0]} / 0.4) 0%, transparent 60%)`,
75
+ opacity: isPlaying ? ringOpacity : 0,
76
+ transform: `scale(${ringScale})`,
77
+ transition: 'all 0.08s ease-out',
78
+ }}
79
+ />
80
+ </>
81
+ );
82
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * ReactiveCover effects - Audio-reactive visual effects
3
+ */
4
+
5
+ export { GlowEffect, type GlowEffectData } from './GlowEffect';
6
+ export { OrbsEffect } from './OrbsEffect';
7
+ export { SpotlightEffect } from './SpotlightEffect';
8
+ export { MeshEffect } from './MeshEffect';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * ReactiveCover - Audio-reactive cover art component
3
+ */
4
+
5
+ export { AudioReactiveCover, type AudioReactiveCoverProps } from './AudioReactiveCover';
6
+ export { GlowEffect, OrbsEffect, SpotlightEffect, MeshEffect, type GlowEffectData } from './effects';
@@ -37,13 +37,13 @@ import { useRef, type ReactNode } from 'react';
37
37
  import { Music } from 'lucide-react';
38
38
  import { cn } from '@djangocfg/ui-core';
39
39
 
40
- import { AudioProvider } from './context';
40
+ import { AudioProvider } from '../context';
41
41
  import { AudioPlayer } from './AudioPlayer';
42
- import { AudioReactiveCover } from './AudioReactiveCover';
43
- import { VisualizationProvider, useAudioVisualization } from './useAudioVisualization';
44
- import type { WaveformOptions, EqualizerOptions } from './types';
45
- import type { EffectIntensity, EffectColorScheme } from './effects';
46
- import type { VisualizationVariant } from './useAudioVisualization';
42
+ import { AudioReactiveCover } from './ReactiveCover';
43
+ import { VisualizationProvider, useVisualization } from '../hooks';
44
+ import type { WaveformOptions, EqualizerOptions } from '../types';
45
+ import type { EffectIntensity, EffectColorScheme } from '../effects';
46
+ import type { VisualizationVariant } from '../hooks';
47
47
 
48
48
  // =============================================================================
49
49
  // TYPES
@@ -77,6 +77,9 @@ export interface SimpleAudioPlayerProps {
77
77
  /** Show volume control */
78
78
  showVolume?: boolean;
79
79
 
80
+ /** Show loop/repeat button */
81
+ showLoop?: boolean;
82
+
80
83
  /** Enable audio-reactive cover effects */
81
84
  reactiveCover?: boolean;
82
85
 
@@ -137,6 +140,7 @@ function SimpleAudioPlayerContent({
137
140
  showEqualizer = false,
138
141
  showTimer = true,
139
142
  showVolume = true,
143
+ showLoop = true,
140
144
  reactiveCover = true,
141
145
  variant,
142
146
  intensity,
@@ -148,7 +152,7 @@ function SimpleAudioPlayerContent({
148
152
  className,
149
153
  }: SimpleAudioPlayerProps) {
150
154
  const containerRef = useRef<HTMLDivElement>(null);
151
- const { settings: vizSettings, nextVariant } = useAudioVisualization();
155
+ const { settings: vizSettings, nextVariant } = useVisualization();
152
156
 
153
157
  // Determine effective variant (from props or localStorage settings)
154
158
  const effectiveVariant = variant ?? (vizSettings.variant !== 'none' ? vizSettings.variant : 'spotlight');
@@ -263,6 +267,7 @@ function SimpleAudioPlayerContent({
263
267
  showEqualizer={showEqualizer}
264
268
  showTimer={showTimer}
265
269
  showVolume={showVolume}
270
+ showLoop={showLoop}
266
271
  equalizerOptions={equalizerOptions}
267
272
  className="border-0 bg-transparent"
268
273
  />
@@ -9,11 +9,7 @@
9
9
 
10
10
  import { Sparkles } from 'lucide-react';
11
11
  import { Button, cn } from '@djangocfg/ui-nextjs';
12
- import {
13
- useAudioVisualization,
14
- VARIANT_INFO,
15
- type VisualizationVariant,
16
- } from './useAudioVisualization';
12
+ import { useVisualization, VARIANT_INFO } from '../hooks';
17
13
 
18
14
  // =============================================================================
19
15
  // TYPES
@@ -34,7 +30,7 @@ export function VisualizationToggle({
34
30
  compact = false,
35
31
  className,
36
32
  }: VisualizationToggleProps) {
37
- const { settings, nextVariant } = useAudioVisualization();
33
+ const { settings, nextVariant } = useVisualization();
38
34
 
39
35
  const currentInfo = VARIANT_INFO[settings.variant];
40
36
  const isEnabled = settings.variant !== 'none';
@@ -0,0 +1,21 @@
1
+ /**
2
+ * AudioPlayer components - Public API
3
+ */
4
+
5
+ // Main components
6
+ export { AudioPlayer } from './AudioPlayer';
7
+ export { SimpleAudioPlayer, type SimpleAudioPlayerProps } from './SimpleAudioPlayer';
8
+ export { AudioEqualizer } from './AudioEqualizer';
9
+ export { AudioShortcutsPopover } from './AudioShortcutsPopover';
10
+ export { VisualizationToggle, type VisualizationToggleProps } from './VisualizationToggle';
11
+
12
+ // ReactiveCover
13
+ export {
14
+ AudioReactiveCover,
15
+ type AudioReactiveCoverProps,
16
+ GlowEffect,
17
+ OrbsEffect,
18
+ SpotlightEffect,
19
+ MeshEffect,
20
+ type GlowEffectData,
21
+ } from './ReactiveCover';