@moontra/moonui-pro 2.20.2 → 2.20.3
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/package.json +8 -3
- package/plugin/index.d.ts +86 -0
- package/plugin/index.js +308 -0
- package/scripts/postinstall.js +176 -23
- package/src/components/advanced-chart/index.tsx +0 -1246
- package/src/components/advanced-forms/index.tsx +0 -585
- package/src/components/animated-button/index.tsx +0 -385
- package/src/components/calendar/event-dialog.tsx +0 -377
- package/src/components/calendar/index.tsx +0 -1220
- package/src/components/calendar-pro/index.tsx +0 -1697
- package/src/components/color-picker/index.tsx +0 -432
- package/src/components/credit-card-input/index.tsx +0 -406
- package/src/components/dashboard/dashboard-grid.tsx +0 -480
- package/src/components/dashboard/demo.tsx +0 -425
- package/src/components/dashboard/index.tsx +0 -1046
- package/src/components/dashboard/time-range-picker.tsx +0 -336
- package/src/components/dashboard/types.ts +0 -225
- package/src/components/dashboard/widgets/activity-feed.tsx +0 -349
- package/src/components/dashboard/widgets/chart-widget.tsx +0 -418
- package/src/components/dashboard/widgets/comparison-widget.tsx +0 -177
- package/src/components/dashboard/widgets/index.ts +0 -5
- package/src/components/dashboard/widgets/metric-card.tsx +0 -363
- package/src/components/dashboard/widgets/progress-widget.tsx +0 -113
- package/src/components/data-table/data-table-bulk-actions.tsx +0 -204
- package/src/components/data-table/data-table-column-toggle.tsx +0 -169
- package/src/components/data-table/data-table-export.ts +0 -156
- package/src/components/data-table/data-table-filter-drawer.tsx +0 -448
- package/src/components/data-table/index.tsx +0 -845
- package/src/components/draggable-list/index.tsx +0 -100
- package/src/components/error-boundary/index.tsx +0 -232
- package/src/components/file-upload/index.tsx +0 -1660
- package/src/components/floating-action-button/index.tsx +0 -206
- package/src/components/form-wizard/form-wizard-context.tsx +0 -335
- package/src/components/form-wizard/form-wizard-navigation.tsx +0 -118
- package/src/components/form-wizard/form-wizard-progress.tsx +0 -329
- package/src/components/form-wizard/form-wizard-step.tsx +0 -111
- package/src/components/form-wizard/index.tsx +0 -102
- package/src/components/form-wizard/types.ts +0 -77
- package/src/components/gesture-drawer/index.tsx +0 -551
- package/src/components/github-stars/github-api.ts +0 -426
- package/src/components/github-stars/hooks.ts +0 -517
- package/src/components/github-stars/index.tsx +0 -375
- package/src/components/github-stars/types.ts +0 -148
- package/src/components/github-stars/variants.tsx +0 -515
- package/src/components/health-check/index.tsx +0 -439
- package/src/components/hover-card-3d/index.tsx +0 -529
- package/src/components/index.ts +0 -130
- package/src/components/internal/index.ts +0 -78
- package/src/components/kanban/add-card-modal.tsx +0 -502
- package/src/components/kanban/card-detail-modal.tsx +0 -761
- package/src/components/kanban/index.ts +0 -13
- package/src/components/kanban/kanban.tsx +0 -1689
- package/src/components/kanban/types.ts +0 -168
- package/src/components/lazy-component/index.tsx +0 -823
- package/src/components/license-error/index.tsx +0 -31
- package/src/components/magnetic-button/index.tsx +0 -216
- package/src/components/memory-efficient-data/index.tsx +0 -1018
- package/src/components/moonui-quiz-form/index.tsx +0 -817
- package/src/components/navbar/index.tsx +0 -781
- package/src/components/optimized-image/index.tsx +0 -425
- package/src/components/performance-debugger/index.tsx +0 -613
- package/src/components/performance-monitor/index.tsx +0 -808
- package/src/components/phone-number-input/index.tsx +0 -343
- package/src/components/phone-number-input/phone-number-input-simple.tsx +0 -167
- package/src/components/pinch-zoom/index.tsx +0 -566
- package/src/components/quiz-form/index.tsx +0 -479
- package/src/components/rich-text-editor/index.tsx +0 -2322
- package/src/components/rich-text-editor/slash-commands-extension.ts +0 -230
- package/src/components/rich-text-editor/slash-commands.css +0 -35
- package/src/components/rich-text-editor/table-styles.css +0 -65
- package/src/components/sidebar/index.tsx +0 -884
- package/src/components/spotlight-card/index.tsx +0 -191
- package/src/components/swipeable-card/index.tsx +0 -100
- package/src/components/timeline/index.tsx +0 -1183
- package/src/components/ui/accordion.tsx +0 -581
- package/src/components/ui/alert-dialog.tsx +0 -141
- package/src/components/ui/alert.tsx +0 -141
- package/src/components/ui/aspect-ratio.tsx +0 -245
- package/src/components/ui/avatar.tsx +0 -155
- package/src/components/ui/badge.tsx +0 -230
- package/src/components/ui/breadcrumb.tsx +0 -216
- package/src/components/ui/button.tsx +0 -228
- package/src/components/ui/calendar.tsx +0 -387
- package/src/components/ui/card.tsx +0 -216
- package/src/components/ui/checkbox.tsx +0 -259
- package/src/components/ui/collapsible.tsx +0 -631
- package/src/components/ui/color-picker.tsx +0 -97
- package/src/components/ui/command.tsx +0 -948
- package/src/components/ui/dialog.tsx +0 -752
- package/src/components/ui/dropdown-menu.tsx +0 -706
- package/src/components/ui/gesture-drawer.tsx +0 -11
- package/src/components/ui/hover-card.tsx +0 -29
- package/src/components/ui/index.ts +0 -222
- package/src/components/ui/input.tsx +0 -224
- package/src/components/ui/label.tsx +0 -29
- package/src/components/ui/lightbox.tsx +0 -606
- package/src/components/ui/magnetic-button.tsx +0 -129
- package/src/components/ui/media-gallery.tsx +0 -611
- package/src/components/ui/navigation-menu.tsx +0 -130
- package/src/components/ui/pagination.tsx +0 -125
- package/src/components/ui/popover.tsx +0 -185
- package/src/components/ui/progress.tsx +0 -30
- package/src/components/ui/radio-group.tsx +0 -257
- package/src/components/ui/scroll-area.tsx +0 -47
- package/src/components/ui/select.tsx +0 -378
- package/src/components/ui/separator.tsx +0 -145
- package/src/components/ui/sheet.tsx +0 -139
- package/src/components/ui/skeleton.tsx +0 -20
- package/src/components/ui/slider.tsx +0 -354
- package/src/components/ui/spotlight-card.tsx +0 -119
- package/src/components/ui/switch.tsx +0 -86
- package/src/components/ui/table.tsx +0 -331
- package/src/components/ui/tabs-pro.tsx +0 -542
- package/src/components/ui/tabs.tsx +0 -54
- package/src/components/ui/textarea.tsx +0 -28
- package/src/components/ui/toast.tsx +0 -317
- package/src/components/ui/toggle.tsx +0 -119
- package/src/components/ui/tooltip.tsx +0 -151
- package/src/components/virtual-list/index.tsx +0 -668
- package/src/hooks/use-chart.ts +0 -205
- package/src/hooks/use-data-table.ts +0 -182
- package/src/hooks/use-docs-pro-access.ts +0 -13
- package/src/hooks/use-license-check.ts +0 -65
- package/src/hooks/use-subscription.ts +0 -19
- package/src/hooks/use-toast.ts +0 -15
- package/src/index.ts +0 -22
- package/src/lib/ai-providers.ts +0 -377
- package/src/lib/component-metadata.ts +0 -18
- package/src/lib/micro-interactions.ts +0 -255
- package/src/lib/paddle.ts +0 -17
- package/src/lib/utils.ts +0 -6
- package/src/patterns/login-form/index.tsx +0 -276
- package/src/patterns/login-form/types.ts +0 -67
- package/src/setupTests.ts +0 -41
- package/src/styles/advanced-chart.css +0 -239
- package/src/styles/calendar.css +0 -35
- package/src/styles/design-system.css +0 -363
- package/src/styles/index.css +0 -681
- package/src/styles/tailwind.css +0 -7
- package/src/styles/tokens.css +0 -455
- package/src/types/next-auth.d.ts +0 -21
- package/src/use-intersection-observer.tsx +0 -154
- package/src/use-local-storage.tsx +0 -71
- package/src/use-paddle.ts +0 -138
- package/src/use-performance-optimizer.ts +0 -389
- package/src/use-pro-access.ts +0 -141
- package/src/use-scroll-animation.ts +0 -219
- package/src/use-subscription.ts +0 -37
- package/src/use-toast.ts +0 -32
- package/src/utils/chart-helpers.ts +0 -357
- package/src/utils/cn.ts +0 -6
- package/src/utils/data-processing.ts +0 -151
- package/src/utils/license-validator.tsx +0 -183
|
@@ -1,631 +0,0 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import * as React from "react"
|
|
4
|
-
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"
|
|
5
|
-
import { cva, type VariantProps } from "class-variance-authority"
|
|
6
|
-
import {
|
|
7
|
-
ChevronDown,
|
|
8
|
-
ChevronRight,
|
|
9
|
-
ChevronUp,
|
|
10
|
-
Loader2,
|
|
11
|
-
ExternalLink,
|
|
12
|
-
AlertCircle,
|
|
13
|
-
CheckCircle2,
|
|
14
|
-
XCircle,
|
|
15
|
-
Info,
|
|
16
|
-
Clock,
|
|
17
|
-
Hash
|
|
18
|
-
} from "lucide-react"
|
|
19
|
-
|
|
20
|
-
import { cn } from "../../lib/utils"
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* MoonUICollapsiblePro - Advanced Collapsible Component
|
|
24
|
-
*
|
|
25
|
-
* A feature-rich collapsible component with professional features:
|
|
26
|
-
* - Multiple visual variants (elevated, bordered, gradient, glassmorphism, card)
|
|
27
|
-
* - Size options (xs, sm, md, lg, xl)
|
|
28
|
-
* - Animation modes (spring, smooth, fade, bounce, slide)
|
|
29
|
-
* - Loading states with skeletons
|
|
30
|
-
* - Icon support (left/right icons, custom chevrons)
|
|
31
|
-
* - Progress indicators
|
|
32
|
-
* - Badge system with variants
|
|
33
|
-
* - Lazy loading for performance
|
|
34
|
-
* - Auto-collapse timer
|
|
35
|
-
* - Keyboard shortcuts
|
|
36
|
-
* - Analytics tracking
|
|
37
|
-
* - Memory persistence
|
|
38
|
-
* - Nested collapsibles support
|
|
39
|
-
*/
|
|
40
|
-
|
|
41
|
-
// Type definitions
|
|
42
|
-
type CollapsibleSize = "xs" | "sm" | "md" | "lg" | "xl";
|
|
43
|
-
type CollapsibleVariant = "default" | "bordered" | "elevated" | "gradient" | "glassmorphism" | "card";
|
|
44
|
-
type AnimationMode = "spring" | "smooth" | "fade" | "bounce" | "slide";
|
|
45
|
-
type BadgeVariant = "default" | "primary" | "secondary" | "success" | "warning" | "danger" | "info";
|
|
46
|
-
|
|
47
|
-
// Enhanced Collapsible Root component
|
|
48
|
-
interface MoonUICollapsibleProProps {
|
|
49
|
-
/** Visual variant */
|
|
50
|
-
variant?: CollapsibleVariant;
|
|
51
|
-
/** Size preset */
|
|
52
|
-
size?: CollapsibleSize;
|
|
53
|
-
/** Animation mode */
|
|
54
|
-
animationMode?: AnimationMode;
|
|
55
|
-
/** Auto-collapse after X milliseconds */
|
|
56
|
-
autoCollapseAfter?: number;
|
|
57
|
-
/** Analytics tracking callback */
|
|
58
|
-
onToggleChange?: (isOpen: boolean) => void;
|
|
59
|
-
/** Memory persistence key */
|
|
60
|
-
persistKey?: string;
|
|
61
|
-
/** Loading state */
|
|
62
|
-
loading?: boolean;
|
|
63
|
-
/** Progress percentage (0-100) */
|
|
64
|
-
progress?: number;
|
|
65
|
-
/** Badge content */
|
|
66
|
-
badge?: React.ReactNode;
|
|
67
|
-
/** Badge variant */
|
|
68
|
-
badgeVariant?: BadgeVariant;
|
|
69
|
-
/** Custom keyboard shortcut */
|
|
70
|
-
shortcut?: string;
|
|
71
|
-
/** Lazy load content */
|
|
72
|
-
lazy?: boolean;
|
|
73
|
-
/** Additional className */
|
|
74
|
-
className?: string;
|
|
75
|
-
/** Control open state */
|
|
76
|
-
open?: boolean;
|
|
77
|
-
/** Default open state */
|
|
78
|
-
defaultOpen?: boolean;
|
|
79
|
-
/** Callback when open state changes */
|
|
80
|
-
onOpenChange?: (open: boolean) => void;
|
|
81
|
-
/** Children elements */
|
|
82
|
-
children?: React.ReactNode;
|
|
83
|
-
/** Disabled state */
|
|
84
|
-
disabled?: boolean;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const MoonUICollapsiblePro = React.forwardRef<
|
|
88
|
-
React.ElementRef<typeof CollapsiblePrimitive.Root>,
|
|
89
|
-
MoonUICollapsibleProProps
|
|
90
|
-
>(({
|
|
91
|
-
className,
|
|
92
|
-
variant = "default",
|
|
93
|
-
size = "md",
|
|
94
|
-
animationMode = "smooth",
|
|
95
|
-
autoCollapseAfter,
|
|
96
|
-
onToggleChange,
|
|
97
|
-
persistKey,
|
|
98
|
-
loading,
|
|
99
|
-
progress,
|
|
100
|
-
badge,
|
|
101
|
-
badgeVariant = "default",
|
|
102
|
-
shortcut,
|
|
103
|
-
lazy,
|
|
104
|
-
open: controlledOpen,
|
|
105
|
-
defaultOpen,
|
|
106
|
-
onOpenChange,
|
|
107
|
-
children,
|
|
108
|
-
disabled
|
|
109
|
-
}, ref) => {
|
|
110
|
-
const [localOpen, setLocalOpen] = React.useState(() => {
|
|
111
|
-
// Check memory persistence
|
|
112
|
-
if (persistKey && typeof window !== 'undefined') {
|
|
113
|
-
const stored = localStorage.getItem(`collapsible-${persistKey}`);
|
|
114
|
-
if (stored !== null) {
|
|
115
|
-
return stored === 'true';
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
return defaultOpen || false;
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
const [hasBeenOpened, setHasBeenOpened] = React.useState(!lazy);
|
|
122
|
-
|
|
123
|
-
const isOpen = controlledOpen !== undefined ? controlledOpen : localOpen;
|
|
124
|
-
|
|
125
|
-
const handleOpenChange = React.useCallback((open: boolean) => {
|
|
126
|
-
if (!loading) {
|
|
127
|
-
setLocalOpen(open);
|
|
128
|
-
onOpenChange?.(open);
|
|
129
|
-
onToggleChange?.(open);
|
|
130
|
-
|
|
131
|
-
// Persist state
|
|
132
|
-
if (persistKey && typeof window !== 'undefined') {
|
|
133
|
-
localStorage.setItem(`collapsible-${persistKey}`, String(open));
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Track lazy loading
|
|
137
|
-
if (lazy && open && !hasBeenOpened) {
|
|
138
|
-
setHasBeenOpened(true);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Auto-collapse timer
|
|
142
|
-
if (open && autoCollapseAfter) {
|
|
143
|
-
setTimeout(() => {
|
|
144
|
-
setLocalOpen(false);
|
|
145
|
-
onOpenChange?.(false);
|
|
146
|
-
onToggleChange?.(false);
|
|
147
|
-
}, autoCollapseAfter);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}, [loading, onOpenChange, onToggleChange, persistKey, lazy, hasBeenOpened, autoCollapseAfter]);
|
|
151
|
-
|
|
152
|
-
// Keyboard shortcut handler
|
|
153
|
-
React.useEffect(() => {
|
|
154
|
-
if (shortcut) {
|
|
155
|
-
const handleKeyPress = (e: KeyboardEvent) => {
|
|
156
|
-
const keys = shortcut.toLowerCase().split('+');
|
|
157
|
-
const ctrlKey = keys.includes('ctrl') || keys.includes('cmd');
|
|
158
|
-
const shiftKey = keys.includes('shift');
|
|
159
|
-
const altKey = keys.includes('alt');
|
|
160
|
-
const key = keys[keys.length - 1];
|
|
161
|
-
|
|
162
|
-
if (
|
|
163
|
-
e.ctrlKey === ctrlKey &&
|
|
164
|
-
e.shiftKey === shiftKey &&
|
|
165
|
-
e.altKey === altKey &&
|
|
166
|
-
e.key.toLowerCase() === key
|
|
167
|
-
) {
|
|
168
|
-
e.preventDefault();
|
|
169
|
-
handleOpenChange(!isOpen);
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
window.addEventListener('keydown', handleKeyPress);
|
|
174
|
-
return () => window.removeEventListener('keydown', handleKeyPress);
|
|
175
|
-
}
|
|
176
|
-
}, [shortcut, isOpen, handleOpenChange]);
|
|
177
|
-
|
|
178
|
-
// Progress ring calculation
|
|
179
|
-
const progressOffset = progress ? 188.4 - (188.4 * progress) / 100 : 188.4;
|
|
180
|
-
|
|
181
|
-
return (
|
|
182
|
-
<div className={cn(
|
|
183
|
-
"relative",
|
|
184
|
-
variant === "bordered" && "border border-border rounded-lg",
|
|
185
|
-
variant === "elevated" && "border border-border rounded-lg shadow-lg hover:shadow-xl transition-shadow",
|
|
186
|
-
variant === "gradient" && "rounded-lg bg-gradient-to-r from-primary/5 via-accent/5 to-secondary/5",
|
|
187
|
-
variant === "glassmorphism" && "rounded-lg backdrop-blur-md bg-white/10 border border-white/20",
|
|
188
|
-
variant === "card" && "border border-border rounded-lg bg-card",
|
|
189
|
-
loading && "opacity-60 pointer-events-none",
|
|
190
|
-
className
|
|
191
|
-
)}>
|
|
192
|
-
{/* Progress indicator */}
|
|
193
|
-
{progress !== undefined && (
|
|
194
|
-
<div className="absolute top-2 right-2 w-6 h-6 z-10">
|
|
195
|
-
<svg className="w-6 h-6 -rotate-90" viewBox="0 0 64 64">
|
|
196
|
-
<circle
|
|
197
|
-
cx="32"
|
|
198
|
-
cy="32"
|
|
199
|
-
r="30"
|
|
200
|
-
fill="none"
|
|
201
|
-
stroke="currentColor"
|
|
202
|
-
strokeWidth="2"
|
|
203
|
-
className="text-muted-foreground/20"
|
|
204
|
-
/>
|
|
205
|
-
<circle
|
|
206
|
-
cx="32"
|
|
207
|
-
cy="32"
|
|
208
|
-
r="30"
|
|
209
|
-
fill="none"
|
|
210
|
-
stroke="currentColor"
|
|
211
|
-
strokeWidth="2"
|
|
212
|
-
strokeDasharray="188.4"
|
|
213
|
-
strokeDashoffset={progressOffset}
|
|
214
|
-
strokeLinecap="round"
|
|
215
|
-
className="text-primary transition-all duration-500"
|
|
216
|
-
/>
|
|
217
|
-
</svg>
|
|
218
|
-
<span className="absolute inset-0 flex items-center justify-center text-xs font-medium">
|
|
219
|
-
{Math.round(progress)}
|
|
220
|
-
</span>
|
|
221
|
-
</div>
|
|
222
|
-
)}
|
|
223
|
-
|
|
224
|
-
{/* Badge */}
|
|
225
|
-
{badge && (
|
|
226
|
-
<div className="absolute -top-3 right-4 z-20">
|
|
227
|
-
<div className={cn(
|
|
228
|
-
"text-xs px-2.5 py-1 rounded-full font-semibold shadow-md",
|
|
229
|
-
badgeVariant === "default" && "bg-background text-foreground border border-border",
|
|
230
|
-
badgeVariant === "primary" && "bg-primary text-primary-foreground",
|
|
231
|
-
badgeVariant === "secondary" && "bg-secondary text-secondary-foreground",
|
|
232
|
-
badgeVariant === "success" && "bg-green-500 text-white",
|
|
233
|
-
badgeVariant === "warning" && "bg-amber-500 text-white",
|
|
234
|
-
badgeVariant === "danger" && "bg-red-500 text-white",
|
|
235
|
-
badgeVariant === "info" && "bg-blue-500 text-white"
|
|
236
|
-
)}>
|
|
237
|
-
{badge}
|
|
238
|
-
</div>
|
|
239
|
-
</div>
|
|
240
|
-
)}
|
|
241
|
-
|
|
242
|
-
{/* Loading spinner */}
|
|
243
|
-
{loading && (
|
|
244
|
-
<div className="absolute top-1/2 right-4 -translate-y-1/2 z-10">
|
|
245
|
-
<Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />
|
|
246
|
-
</div>
|
|
247
|
-
)}
|
|
248
|
-
|
|
249
|
-
<CollapsiblePrimitive.Root
|
|
250
|
-
ref={ref}
|
|
251
|
-
open={isOpen}
|
|
252
|
-
onOpenChange={handleOpenChange}
|
|
253
|
-
disabled={disabled || loading}
|
|
254
|
-
className={cn(
|
|
255
|
-
"w-full",
|
|
256
|
-
animationMode === "spring" && "[&_[data-state=open]]:animate-[collapsible-down_0.3s_cubic-bezier(0.34,1.56,0.64,1)]",
|
|
257
|
-
animationMode === "bounce" && "[&_[data-state=open]]:animate-[collapsible-down_0.4s_cubic-bezier(0.68,-0.55,0.265,1.55)]",
|
|
258
|
-
animationMode === "fade" && "[&_[data-state=open]]:animate-[collapsible-down_0.2s_ease-in-out]",
|
|
259
|
-
animationMode === "slide" && "[&_[data-state=open]]:animate-[slide-down_0.3s_ease-out]"
|
|
260
|
-
)}
|
|
261
|
-
>
|
|
262
|
-
{/* Provide context for children */}
|
|
263
|
-
<CollapsibleContext.Provider value={{
|
|
264
|
-
variant,
|
|
265
|
-
size,
|
|
266
|
-
animationMode,
|
|
267
|
-
lazy: lazy && !hasBeenOpened,
|
|
268
|
-
shortcut
|
|
269
|
-
}}>
|
|
270
|
-
{children}
|
|
271
|
-
</CollapsibleContext.Provider>
|
|
272
|
-
</CollapsiblePrimitive.Root>
|
|
273
|
-
</div>
|
|
274
|
-
);
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
MoonUICollapsiblePro.displayName = "MoonUICollapsiblePro"
|
|
278
|
-
|
|
279
|
-
// Context definition
|
|
280
|
-
const CollapsibleContext = React.createContext<{
|
|
281
|
-
variant?: CollapsibleVariant;
|
|
282
|
-
size?: CollapsibleSize;
|
|
283
|
-
animationMode?: AnimationMode;
|
|
284
|
-
lazy?: boolean;
|
|
285
|
-
shortcut?: string;
|
|
286
|
-
}>({});
|
|
287
|
-
|
|
288
|
-
// Enhanced Trigger component with variants
|
|
289
|
-
const collapsibleTriggerVariants = cva(
|
|
290
|
-
"flex w-full items-center gap-3 transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
291
|
-
{
|
|
292
|
-
variants: {
|
|
293
|
-
variant: {
|
|
294
|
-
default: "text-foreground hover:text-primary",
|
|
295
|
-
bordered: "text-foreground hover:text-primary hover:bg-primary/5 rounded-t-lg",
|
|
296
|
-
elevated: "text-foreground hover:text-primary hover:bg-primary/5 rounded-t-lg",
|
|
297
|
-
gradient: "text-foreground hover:text-primary",
|
|
298
|
-
glassmorphism: "text-foreground hover:text-primary hover:bg-white/10",
|
|
299
|
-
card: "text-foreground hover:text-primary hover:bg-accent/5 rounded-t-lg"
|
|
300
|
-
},
|
|
301
|
-
size: {
|
|
302
|
-
xs: "text-xs py-2 px-3 min-h-[2.5rem]",
|
|
303
|
-
sm: "text-sm py-2.5 px-3.5 min-h-[3rem]",
|
|
304
|
-
md: "text-base py-3 px-4 min-h-[3.5rem]",
|
|
305
|
-
lg: "text-lg py-4 px-5 min-h-[4rem]",
|
|
306
|
-
xl: "text-xl py-5 px-6 min-h-[4.5rem]"
|
|
307
|
-
},
|
|
308
|
-
},
|
|
309
|
-
defaultVariants: {
|
|
310
|
-
variant: "default",
|
|
311
|
-
size: "md",
|
|
312
|
-
},
|
|
313
|
-
}
|
|
314
|
-
)
|
|
315
|
-
|
|
316
|
-
interface MoonUICollapsibleTriggerProProps
|
|
317
|
-
extends React.ComponentPropsWithoutRef<typeof CollapsiblePrimitive.Trigger>,
|
|
318
|
-
VariantProps<typeof collapsibleTriggerVariants> {
|
|
319
|
-
/** Icon to show on the left */
|
|
320
|
-
leftIcon?: React.ReactNode;
|
|
321
|
-
/** Icon to show on the right (excluding chevron) */
|
|
322
|
-
rightIcon?: React.ReactNode;
|
|
323
|
-
/** Subtitle / description */
|
|
324
|
-
description?: string;
|
|
325
|
-
/** External link indicator */
|
|
326
|
-
external?: boolean;
|
|
327
|
-
/** Custom chevron icon */
|
|
328
|
-
customChevron?: React.ReactNode;
|
|
329
|
-
/** Hide chevron */
|
|
330
|
-
hideChevron?: boolean;
|
|
331
|
-
/** Status indicator */
|
|
332
|
-
status?: "success" | "warning" | "error" | "info";
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
const MoonUICollapsibleTriggerPro = React.forwardRef<
|
|
336
|
-
React.ElementRef<typeof CollapsiblePrimitive.Trigger>,
|
|
337
|
-
MoonUICollapsibleTriggerProProps
|
|
338
|
-
>(({
|
|
339
|
-
className,
|
|
340
|
-
children,
|
|
341
|
-
variant: triggerVariant,
|
|
342
|
-
size: triggerSize,
|
|
343
|
-
asChild,
|
|
344
|
-
leftIcon,
|
|
345
|
-
rightIcon,
|
|
346
|
-
description,
|
|
347
|
-
external,
|
|
348
|
-
customChevron,
|
|
349
|
-
hideChevron,
|
|
350
|
-
status,
|
|
351
|
-
...props
|
|
352
|
-
}, ref) => {
|
|
353
|
-
const { variant, size, shortcut } = React.useContext(CollapsibleContext);
|
|
354
|
-
const finalVariant = triggerVariant || variant || "default";
|
|
355
|
-
const finalSize = triggerSize || size || "md";
|
|
356
|
-
|
|
357
|
-
// Status icon mapping
|
|
358
|
-
const statusIcon = status && {
|
|
359
|
-
success: <CheckCircle2 className="h-4 w-4 text-green-500" />,
|
|
360
|
-
warning: <AlertCircle className="h-4 w-4 text-amber-500" />,
|
|
361
|
-
error: <XCircle className="h-4 w-4 text-red-500" />,
|
|
362
|
-
info: <Info className="h-4 w-4 text-blue-500" />
|
|
363
|
-
}[status];
|
|
364
|
-
|
|
365
|
-
// If asChild, render minimal wrapper
|
|
366
|
-
if (asChild) {
|
|
367
|
-
return (
|
|
368
|
-
<CollapsiblePrimitive.Trigger
|
|
369
|
-
ref={ref}
|
|
370
|
-
className={cn(collapsibleTriggerVariants({ variant: finalVariant, size: finalSize }), className)}
|
|
371
|
-
asChild={asChild}
|
|
372
|
-
{...props}
|
|
373
|
-
>
|
|
374
|
-
{children}
|
|
375
|
-
</CollapsiblePrimitive.Trigger>
|
|
376
|
-
)
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
return (
|
|
380
|
-
<CollapsiblePrimitive.Trigger
|
|
381
|
-
ref={ref}
|
|
382
|
-
className={cn(
|
|
383
|
-
collapsibleTriggerVariants({ variant: finalVariant, size: finalSize }),
|
|
384
|
-
"[&[data-state=open]>.chevron]:rotate-180",
|
|
385
|
-
"[&[data-state=open]]:text-primary",
|
|
386
|
-
className
|
|
387
|
-
)}
|
|
388
|
-
{...props}
|
|
389
|
-
>
|
|
390
|
-
{/* Left icon */}
|
|
391
|
-
{leftIcon && (
|
|
392
|
-
<span className="text-muted-foreground">{leftIcon}</span>
|
|
393
|
-
)}
|
|
394
|
-
|
|
395
|
-
{/* Status icon */}
|
|
396
|
-
{statusIcon && !leftIcon && statusIcon}
|
|
397
|
-
|
|
398
|
-
{/* Main content */}
|
|
399
|
-
<div className="flex-1 text-left">
|
|
400
|
-
<div className="flex items-center gap-2">
|
|
401
|
-
{/* Main title */}
|
|
402
|
-
<span className="font-medium">{children}</span>
|
|
403
|
-
|
|
404
|
-
{/* External link indicator */}
|
|
405
|
-
{external && (
|
|
406
|
-
<ExternalLink className="h-3 w-3 text-muted-foreground" />
|
|
407
|
-
)}
|
|
408
|
-
</div>
|
|
409
|
-
|
|
410
|
-
{/* Description */}
|
|
411
|
-
{description && (
|
|
412
|
-
<div className="text-sm text-muted-foreground mt-1">
|
|
413
|
-
{description}
|
|
414
|
-
</div>
|
|
415
|
-
)}
|
|
416
|
-
</div>
|
|
417
|
-
|
|
418
|
-
{/* Right side elements */}
|
|
419
|
-
<div className="flex items-center gap-2">
|
|
420
|
-
{/* Keyboard shortcut */}
|
|
421
|
-
{shortcut && (
|
|
422
|
-
<kbd className="hidden sm:inline-flex h-6 px-2 items-center rounded border bg-muted text-xs font-medium text-muted-foreground">
|
|
423
|
-
{shortcut}
|
|
424
|
-
</kbd>
|
|
425
|
-
)}
|
|
426
|
-
|
|
427
|
-
{/* Right icon */}
|
|
428
|
-
{rightIcon && (
|
|
429
|
-
<span className="text-muted-foreground">{rightIcon}</span>
|
|
430
|
-
)}
|
|
431
|
-
|
|
432
|
-
{/* Chevron */}
|
|
433
|
-
{!hideChevron && (
|
|
434
|
-
<span className="chevron transition-transform duration-200 text-muted-foreground">
|
|
435
|
-
{customChevron || <ChevronDown className="h-4 w-4" />}
|
|
436
|
-
</span>
|
|
437
|
-
)}
|
|
438
|
-
</div>
|
|
439
|
-
</CollapsiblePrimitive.Trigger>
|
|
440
|
-
)
|
|
441
|
-
})
|
|
442
|
-
MoonUICollapsibleTriggerPro.displayName = "MoonUICollapsibleTriggerPro"
|
|
443
|
-
|
|
444
|
-
// Enhanced Content component with animations
|
|
445
|
-
const collapsibleContentVariants = cva(
|
|
446
|
-
"overflow-hidden transition-all",
|
|
447
|
-
{
|
|
448
|
-
variants: {
|
|
449
|
-
variant: {
|
|
450
|
-
default: "text-muted-foreground",
|
|
451
|
-
bordered: "text-muted-foreground border-x border-b border-border rounded-b-lg",
|
|
452
|
-
elevated: "text-muted-foreground bg-muted/20",
|
|
453
|
-
gradient: "text-muted-foreground",
|
|
454
|
-
glassmorphism: "text-muted-foreground bg-white/5",
|
|
455
|
-
card: "text-muted-foreground border-x border-b border-border rounded-b-lg bg-card/50"
|
|
456
|
-
},
|
|
457
|
-
size: {
|
|
458
|
-
xs: "text-xs",
|
|
459
|
-
sm: "text-sm",
|
|
460
|
-
md: "text-base",
|
|
461
|
-
lg: "text-lg",
|
|
462
|
-
xl: "text-xl"
|
|
463
|
-
},
|
|
464
|
-
},
|
|
465
|
-
defaultVariants: {
|
|
466
|
-
variant: "default",
|
|
467
|
-
size: "md",
|
|
468
|
-
},
|
|
469
|
-
}
|
|
470
|
-
)
|
|
471
|
-
|
|
472
|
-
interface MoonUICollapsibleContentProProps
|
|
473
|
-
extends React.ComponentPropsWithoutRef<typeof CollapsiblePrimitive.Content>,
|
|
474
|
-
VariantProps<typeof collapsibleContentVariants> {
|
|
475
|
-
/** Content loading state */
|
|
476
|
-
contentLoading?: boolean;
|
|
477
|
-
/** Dynamic content loading function */
|
|
478
|
-
loadContent?: () => Promise<React.ReactNode>;
|
|
479
|
-
/** Remove padding */
|
|
480
|
-
noPadding?: boolean;
|
|
481
|
-
/** Custom padding */
|
|
482
|
-
padding?: string;
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
const MoonUICollapsibleContentPro = React.forwardRef<
|
|
486
|
-
React.ElementRef<typeof CollapsiblePrimitive.Content>,
|
|
487
|
-
MoonUICollapsibleContentProProps
|
|
488
|
-
>(({
|
|
489
|
-
className,
|
|
490
|
-
children,
|
|
491
|
-
variant: contentVariant,
|
|
492
|
-
size: contentSize,
|
|
493
|
-
contentLoading,
|
|
494
|
-
loadContent,
|
|
495
|
-
noPadding,
|
|
496
|
-
padding,
|
|
497
|
-
...props
|
|
498
|
-
}, ref) => {
|
|
499
|
-
const { variant, size, animationMode, lazy } = React.useContext(CollapsibleContext);
|
|
500
|
-
const finalVariant = contentVariant || variant || "default";
|
|
501
|
-
const finalSize = contentSize || size || "md";
|
|
502
|
-
|
|
503
|
-
const [dynamicContent, setDynamicContent] = React.useState<React.ReactNode>(null);
|
|
504
|
-
const [isLoading, setIsLoading] = React.useState(false);
|
|
505
|
-
|
|
506
|
-
// Dynamic content loading
|
|
507
|
-
React.useEffect(() => {
|
|
508
|
-
if (loadContent && !dynamicContent) {
|
|
509
|
-
setIsLoading(true);
|
|
510
|
-
loadContent()
|
|
511
|
-
.then(setDynamicContent)
|
|
512
|
-
.finally(() => setIsLoading(false));
|
|
513
|
-
}
|
|
514
|
-
}, [loadContent, dynamicContent]);
|
|
515
|
-
|
|
516
|
-
// Determine padding based on size
|
|
517
|
-
const defaultPadding = !noPadding && {
|
|
518
|
-
xs: "p-3",
|
|
519
|
-
sm: "p-3.5",
|
|
520
|
-
md: "p-4",
|
|
521
|
-
lg: "p-5",
|
|
522
|
-
xl: "p-6"
|
|
523
|
-
}[finalSize];
|
|
524
|
-
|
|
525
|
-
return (
|
|
526
|
-
<CollapsiblePrimitive.Content
|
|
527
|
-
ref={ref}
|
|
528
|
-
className={cn(
|
|
529
|
-
collapsibleContentVariants({ variant: finalVariant, size: finalSize }),
|
|
530
|
-
// Animation modes
|
|
531
|
-
animationMode === "spring" && "data-[state=closed]:animate-[collapsible-up_0.3s_cubic-bezier(0.34,1.56,0.64,1)] data-[state=open]:animate-[collapsible-down_0.3s_cubic-bezier(0.34,1.56,0.64,1)]",
|
|
532
|
-
animationMode === "bounce" && "data-[state=closed]:animate-[collapsible-up_0.4s_cubic-bezier(0.68,-0.55,0.265,1.55)] data-[state=open]:animate-[collapsible-down_0.4s_cubic-bezier(0.68,-0.55,0.265,1.55)]",
|
|
533
|
-
animationMode === "fade" && "data-[state=closed]:animate-[collapsible-up_0.2s_ease-in-out] data-[state=open]:animate-[collapsible-down_0.2s_ease-in-out]",
|
|
534
|
-
animationMode === "slide" && "data-[state=closed]:animate-[slide-up_0.3s_ease-out] data-[state=open]:animate-[slide-down_0.3s_ease-out]",
|
|
535
|
-
animationMode === "smooth" && "data-[state=closed]:animate-collapse-up data-[state=open]:animate-collapse-down",
|
|
536
|
-
className
|
|
537
|
-
)}
|
|
538
|
-
{...props}
|
|
539
|
-
>
|
|
540
|
-
<div className={cn(padding || defaultPadding)}>
|
|
541
|
-
{lazy ? (
|
|
542
|
-
<div className="flex items-center gap-2 py-4">
|
|
543
|
-
<Clock className="h-4 w-4 animate-pulse" />
|
|
544
|
-
<span className="text-sm">Click to load content...</span>
|
|
545
|
-
</div>
|
|
546
|
-
) : (contentLoading || isLoading) ? (
|
|
547
|
-
<div className="flex items-center gap-2 py-4">
|
|
548
|
-
<Loader2 className="h-4 w-4 animate-spin" />
|
|
549
|
-
<span className="text-sm">Loading content...</span>
|
|
550
|
-
</div>
|
|
551
|
-
) : (
|
|
552
|
-
dynamicContent || children
|
|
553
|
-
)}
|
|
554
|
-
</div>
|
|
555
|
-
</CollapsiblePrimitive.Content>
|
|
556
|
-
)
|
|
557
|
-
})
|
|
558
|
-
MoonUICollapsibleContentPro.displayName = "MoonUICollapsibleContentPro"
|
|
559
|
-
|
|
560
|
-
// Utility Hooks
|
|
561
|
-
export const useCollapsibleAnalytics = () => {
|
|
562
|
-
const [analytics, setAnalytics] = React.useState<{
|
|
563
|
-
openCount: number;
|
|
564
|
-
lastOpened: Date | null;
|
|
565
|
-
totalTimeOpen: number;
|
|
566
|
-
}>({
|
|
567
|
-
openCount: 0,
|
|
568
|
-
lastOpened: null,
|
|
569
|
-
totalTimeOpen: 0
|
|
570
|
-
});
|
|
571
|
-
|
|
572
|
-
const trackOpen = React.useCallback(() => {
|
|
573
|
-
setAnalytics(prev => ({
|
|
574
|
-
...prev,
|
|
575
|
-
openCount: prev.openCount + 1,
|
|
576
|
-
lastOpened: new Date()
|
|
577
|
-
}));
|
|
578
|
-
}, []);
|
|
579
|
-
|
|
580
|
-
const trackClose = React.useCallback(() => {
|
|
581
|
-
setAnalytics(prev => {
|
|
582
|
-
if (prev.lastOpened) {
|
|
583
|
-
const timeOpen = Date.now() - prev.lastOpened.getTime();
|
|
584
|
-
return {
|
|
585
|
-
...prev,
|
|
586
|
-
totalTimeOpen: prev.totalTimeOpen + timeOpen,
|
|
587
|
-
lastOpened: null
|
|
588
|
-
};
|
|
589
|
-
}
|
|
590
|
-
return prev;
|
|
591
|
-
});
|
|
592
|
-
}, []);
|
|
593
|
-
|
|
594
|
-
return { analytics, trackOpen, trackClose };
|
|
595
|
-
};
|
|
596
|
-
|
|
597
|
-
// Internal aliases for Pro component usage
|
|
598
|
-
export const CollapsibleInternal = MoonUICollapsiblePro
|
|
599
|
-
export const collapsibleTriggerVariantsInternal = collapsibleTriggerVariants
|
|
600
|
-
export const CollapsibleTriggerInternal = MoonUICollapsibleTriggerPro
|
|
601
|
-
export const collapsibleContentVariantsInternal = collapsibleContentVariants
|
|
602
|
-
export const CollapsibleContentInternal = MoonUICollapsibleContentPro
|
|
603
|
-
|
|
604
|
-
// Pro exports
|
|
605
|
-
export {
|
|
606
|
-
MoonUICollapsiblePro,
|
|
607
|
-
collapsibleTriggerVariants as MoonUIcollapsibleTriggerVariantsPro,
|
|
608
|
-
MoonUICollapsibleTriggerPro,
|
|
609
|
-
collapsibleContentVariants as MoonUIcollapsibleContentVariantsPro,
|
|
610
|
-
MoonUICollapsibleContentPro
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
// Clean exports (without MoonUI prefix for easier usage)
|
|
614
|
-
export {
|
|
615
|
-
MoonUICollapsiblePro as Collapsible,
|
|
616
|
-
collapsibleTriggerVariants,
|
|
617
|
-
MoonUICollapsibleTriggerPro as CollapsibleTrigger,
|
|
618
|
-
collapsibleContentVariants,
|
|
619
|
-
MoonUICollapsibleContentPro as CollapsibleContent
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
// Type exports
|
|
623
|
-
export type {
|
|
624
|
-
MoonUICollapsibleProProps,
|
|
625
|
-
MoonUICollapsibleTriggerProProps,
|
|
626
|
-
MoonUICollapsibleContentProProps,
|
|
627
|
-
CollapsibleSize,
|
|
628
|
-
CollapsibleVariant,
|
|
629
|
-
AnimationMode,
|
|
630
|
-
BadgeVariant
|
|
631
|
-
}
|