@moontra/moonui-pro 2.20.2 → 2.20.4

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 (153) hide show
  1. package/package.json +8 -3
  2. package/plugin/index.d.ts +86 -0
  3. package/plugin/index.js +308 -0
  4. package/scripts/postinstall.js +191 -23
  5. package/src/components/advanced-chart/index.tsx +0 -1246
  6. package/src/components/advanced-forms/index.tsx +0 -585
  7. package/src/components/animated-button/index.tsx +0 -385
  8. package/src/components/calendar/event-dialog.tsx +0 -377
  9. package/src/components/calendar/index.tsx +0 -1220
  10. package/src/components/calendar-pro/index.tsx +0 -1697
  11. package/src/components/color-picker/index.tsx +0 -432
  12. package/src/components/credit-card-input/index.tsx +0 -406
  13. package/src/components/dashboard/dashboard-grid.tsx +0 -480
  14. package/src/components/dashboard/demo.tsx +0 -425
  15. package/src/components/dashboard/index.tsx +0 -1046
  16. package/src/components/dashboard/time-range-picker.tsx +0 -336
  17. package/src/components/dashboard/types.ts +0 -225
  18. package/src/components/dashboard/widgets/activity-feed.tsx +0 -349
  19. package/src/components/dashboard/widgets/chart-widget.tsx +0 -418
  20. package/src/components/dashboard/widgets/comparison-widget.tsx +0 -177
  21. package/src/components/dashboard/widgets/index.ts +0 -5
  22. package/src/components/dashboard/widgets/metric-card.tsx +0 -363
  23. package/src/components/dashboard/widgets/progress-widget.tsx +0 -113
  24. package/src/components/data-table/data-table-bulk-actions.tsx +0 -204
  25. package/src/components/data-table/data-table-column-toggle.tsx +0 -169
  26. package/src/components/data-table/data-table-export.ts +0 -156
  27. package/src/components/data-table/data-table-filter-drawer.tsx +0 -448
  28. package/src/components/data-table/index.tsx +0 -845
  29. package/src/components/draggable-list/index.tsx +0 -100
  30. package/src/components/error-boundary/index.tsx +0 -232
  31. package/src/components/file-upload/index.tsx +0 -1660
  32. package/src/components/floating-action-button/index.tsx +0 -206
  33. package/src/components/form-wizard/form-wizard-context.tsx +0 -335
  34. package/src/components/form-wizard/form-wizard-navigation.tsx +0 -118
  35. package/src/components/form-wizard/form-wizard-progress.tsx +0 -329
  36. package/src/components/form-wizard/form-wizard-step.tsx +0 -111
  37. package/src/components/form-wizard/index.tsx +0 -102
  38. package/src/components/form-wizard/types.ts +0 -77
  39. package/src/components/gesture-drawer/index.tsx +0 -551
  40. package/src/components/github-stars/github-api.ts +0 -426
  41. package/src/components/github-stars/hooks.ts +0 -517
  42. package/src/components/github-stars/index.tsx +0 -375
  43. package/src/components/github-stars/types.ts +0 -148
  44. package/src/components/github-stars/variants.tsx +0 -515
  45. package/src/components/health-check/index.tsx +0 -439
  46. package/src/components/hover-card-3d/index.tsx +0 -529
  47. package/src/components/index.ts +0 -130
  48. package/src/components/internal/index.ts +0 -78
  49. package/src/components/kanban/add-card-modal.tsx +0 -502
  50. package/src/components/kanban/card-detail-modal.tsx +0 -761
  51. package/src/components/kanban/index.ts +0 -13
  52. package/src/components/kanban/kanban.tsx +0 -1689
  53. package/src/components/kanban/types.ts +0 -168
  54. package/src/components/lazy-component/index.tsx +0 -823
  55. package/src/components/license-error/index.tsx +0 -31
  56. package/src/components/magnetic-button/index.tsx +0 -216
  57. package/src/components/memory-efficient-data/index.tsx +0 -1018
  58. package/src/components/moonui-quiz-form/index.tsx +0 -817
  59. package/src/components/navbar/index.tsx +0 -781
  60. package/src/components/optimized-image/index.tsx +0 -425
  61. package/src/components/performance-debugger/index.tsx +0 -613
  62. package/src/components/performance-monitor/index.tsx +0 -808
  63. package/src/components/phone-number-input/index.tsx +0 -343
  64. package/src/components/phone-number-input/phone-number-input-simple.tsx +0 -167
  65. package/src/components/pinch-zoom/index.tsx +0 -566
  66. package/src/components/quiz-form/index.tsx +0 -479
  67. package/src/components/rich-text-editor/index.tsx +0 -2322
  68. package/src/components/rich-text-editor/slash-commands-extension.ts +0 -230
  69. package/src/components/rich-text-editor/slash-commands.css +0 -35
  70. package/src/components/rich-text-editor/table-styles.css +0 -65
  71. package/src/components/sidebar/index.tsx +0 -884
  72. package/src/components/spotlight-card/index.tsx +0 -191
  73. package/src/components/swipeable-card/index.tsx +0 -100
  74. package/src/components/timeline/index.tsx +0 -1183
  75. package/src/components/ui/accordion.tsx +0 -581
  76. package/src/components/ui/alert-dialog.tsx +0 -141
  77. package/src/components/ui/alert.tsx +0 -141
  78. package/src/components/ui/aspect-ratio.tsx +0 -245
  79. package/src/components/ui/avatar.tsx +0 -155
  80. package/src/components/ui/badge.tsx +0 -230
  81. package/src/components/ui/breadcrumb.tsx +0 -216
  82. package/src/components/ui/button.tsx +0 -228
  83. package/src/components/ui/calendar.tsx +0 -387
  84. package/src/components/ui/card.tsx +0 -216
  85. package/src/components/ui/checkbox.tsx +0 -259
  86. package/src/components/ui/collapsible.tsx +0 -631
  87. package/src/components/ui/color-picker.tsx +0 -97
  88. package/src/components/ui/command.tsx +0 -948
  89. package/src/components/ui/dialog.tsx +0 -752
  90. package/src/components/ui/dropdown-menu.tsx +0 -706
  91. package/src/components/ui/gesture-drawer.tsx +0 -11
  92. package/src/components/ui/hover-card.tsx +0 -29
  93. package/src/components/ui/index.ts +0 -222
  94. package/src/components/ui/input.tsx +0 -224
  95. package/src/components/ui/label.tsx +0 -29
  96. package/src/components/ui/lightbox.tsx +0 -606
  97. package/src/components/ui/magnetic-button.tsx +0 -129
  98. package/src/components/ui/media-gallery.tsx +0 -611
  99. package/src/components/ui/navigation-menu.tsx +0 -130
  100. package/src/components/ui/pagination.tsx +0 -125
  101. package/src/components/ui/popover.tsx +0 -185
  102. package/src/components/ui/progress.tsx +0 -30
  103. package/src/components/ui/radio-group.tsx +0 -257
  104. package/src/components/ui/scroll-area.tsx +0 -47
  105. package/src/components/ui/select.tsx +0 -378
  106. package/src/components/ui/separator.tsx +0 -145
  107. package/src/components/ui/sheet.tsx +0 -139
  108. package/src/components/ui/skeleton.tsx +0 -20
  109. package/src/components/ui/slider.tsx +0 -354
  110. package/src/components/ui/spotlight-card.tsx +0 -119
  111. package/src/components/ui/switch.tsx +0 -86
  112. package/src/components/ui/table.tsx +0 -331
  113. package/src/components/ui/tabs-pro.tsx +0 -542
  114. package/src/components/ui/tabs.tsx +0 -54
  115. package/src/components/ui/textarea.tsx +0 -28
  116. package/src/components/ui/toast.tsx +0 -317
  117. package/src/components/ui/toggle.tsx +0 -119
  118. package/src/components/ui/tooltip.tsx +0 -151
  119. package/src/components/virtual-list/index.tsx +0 -668
  120. package/src/hooks/use-chart.ts +0 -205
  121. package/src/hooks/use-data-table.ts +0 -182
  122. package/src/hooks/use-docs-pro-access.ts +0 -13
  123. package/src/hooks/use-license-check.ts +0 -65
  124. package/src/hooks/use-subscription.ts +0 -19
  125. package/src/hooks/use-toast.ts +0 -15
  126. package/src/index.ts +0 -22
  127. package/src/lib/ai-providers.ts +0 -377
  128. package/src/lib/component-metadata.ts +0 -18
  129. package/src/lib/micro-interactions.ts +0 -255
  130. package/src/lib/paddle.ts +0 -17
  131. package/src/lib/utils.ts +0 -6
  132. package/src/patterns/login-form/index.tsx +0 -276
  133. package/src/patterns/login-form/types.ts +0 -67
  134. package/src/setupTests.ts +0 -41
  135. package/src/styles/advanced-chart.css +0 -239
  136. package/src/styles/calendar.css +0 -35
  137. package/src/styles/design-system.css +0 -363
  138. package/src/styles/index.css +0 -681
  139. package/src/styles/tailwind.css +0 -7
  140. package/src/styles/tokens.css +0 -455
  141. package/src/types/next-auth.d.ts +0 -21
  142. package/src/use-intersection-observer.tsx +0 -154
  143. package/src/use-local-storage.tsx +0 -71
  144. package/src/use-paddle.ts +0 -138
  145. package/src/use-performance-optimizer.ts +0 -389
  146. package/src/use-pro-access.ts +0 -141
  147. package/src/use-scroll-animation.ts +0 -219
  148. package/src/use-subscription.ts +0 -37
  149. package/src/use-toast.ts +0 -32
  150. package/src/utils/chart-helpers.ts +0 -357
  151. package/src/utils/cn.ts +0 -6
  152. package/src/utils/data-processing.ts +0 -151
  153. package/src/utils/license-validator.tsx +0 -183
@@ -1,542 +0,0 @@
1
- "use client"
2
-
3
- import * as React from "react";
4
- import * as TabsPrimitive from "@radix-ui/react-tabs";
5
- import { cva, type VariantProps } from "class-variance-authority";
6
- import { motion, AnimatePresence, type Variants } from "framer-motion";
7
- import { X, Plus, ChevronLeft, ChevronRight, MoreHorizontal, Loader2 } from "lucide-react";
8
- import { cn } from "../../lib/utils";
9
- import { Button } from "./button";
10
- import {
11
- DropdownMenu,
12
- DropdownMenuContent,
13
- DropdownMenuItem,
14
- DropdownMenuTrigger,
15
- } from "./dropdown-menu";
16
-
17
- // Animation variants
18
- const contentVariants: Record<string, Variants> = {
19
- fade: {
20
- initial: { opacity: 0 },
21
- animate: { opacity: 1 },
22
- exit: { opacity: 0 },
23
- },
24
- slide: {
25
- initial: { x: 20, opacity: 0 },
26
- animate: { x: 0, opacity: 1 },
27
- exit: { x: -20, opacity: 0 },
28
- },
29
- scale: {
30
- initial: { scale: 0.95, opacity: 0 },
31
- animate: { scale: 1, opacity: 1 },
32
- exit: { scale: 1.05, opacity: 0 },
33
- },
34
- flip: {
35
- initial: { rotateY: 90, opacity: 0 },
36
- animate: { rotateY: 0, opacity: 1 },
37
- exit: { rotateY: -90, opacity: 0 },
38
- },
39
- morph: {
40
- initial: { scale: 0.8, opacity: 0, filter: "blur(10px)" },
41
- animate: { scale: 1, opacity: 1, filter: "blur(0px)" },
42
- exit: { scale: 1.2, opacity: 0, filter: "blur(10px)" },
43
- },
44
- };
45
-
46
- // Tab item type
47
- interface TabItem {
48
- value: string;
49
- label: React.ReactNode;
50
- icon?: React.ReactNode;
51
- badge?: React.ReactNode;
52
- closeable?: boolean;
53
- disabled?: boolean;
54
- content?: React.ReactNode;
55
- lazy?: boolean;
56
- tooltip?: string;
57
- }
58
-
59
- // Pro Tabs Root
60
- interface MoonUITabsProProps extends Omit<React.ComponentPropsWithoutRef<typeof TabsPrimitive.Root>, 'orientation'> {
61
- /** Visual variant */
62
- variant?: "default" | "pills" | "underline" | "cards" | "minimal" | "gradient" | "glassmorphism" | "neon";
63
- /** Animation mode */
64
- animationMode?: "fade" | "slide" | "scale" | "flip" | "morph" | "none";
65
- /** Orientation */
66
- orientation?: "horizontal" | "vertical";
67
- /** Allow closing tabs */
68
- closeable?: boolean;
69
- /** Allow adding tabs */
70
- addable?: boolean;
71
- /** Allow reordering tabs */
72
- draggable?: boolean;
73
- /** Persist state to localStorage */
74
- persistKey?: string;
75
- /** Sync with URL */
76
- urlSync?: boolean;
77
- /** Lazy load tab content */
78
- lazy?: boolean;
79
- /** Tab items for dynamic tabs */
80
- items?: TabItem[];
81
- /** Callback when tabs change */
82
- onTabsChange?: (items: TabItem[]) => void;
83
- /** Callback when tab is closed */
84
- onTabClose?: (value: string) => void;
85
- /** Callback when tab is added */
86
- onTabAdd?: () => void;
87
- /** Loading state */
88
- loading?: boolean;
89
- /** Swipeable on mobile */
90
- swipeable?: boolean;
91
- /** Show scroll buttons */
92
- scrollable?: boolean;
93
- /** Analytics callback */
94
- onAnalytics?: (event: string, data: any) => void;
95
- /** Tab validation before switching */
96
- onBeforeChange?: (from: string, to: string) => boolean | Promise<boolean>;
97
- /** Keyboard shortcuts */
98
- shortcuts?: boolean;
99
- /** Max tabs */
100
- maxTabs?: number;
101
- /** Tab groups */
102
- groups?: Array<{ label: string; tabs: string[] }>;
103
- className?: string;
104
- children?: React.ReactNode;
105
- }
106
-
107
- const MoonUITabsPro = React.forwardRef<
108
- React.ElementRef<typeof TabsPrimitive.Root>,
109
- MoonUITabsProProps
110
- >(({
111
- variant = "default",
112
- animationMode = "fade",
113
- orientation = "horizontal",
114
- closeable = false,
115
- addable = false,
116
- draggable = false,
117
- persistKey,
118
- urlSync = false,
119
- lazy = false,
120
- items: initialItems = [],
121
- onTabsChange,
122
- onTabClose,
123
- onTabAdd,
124
- loading = false,
125
- swipeable = false,
126
- scrollable = false,
127
- onAnalytics,
128
- onBeforeChange,
129
- shortcuts = false,
130
- maxTabs,
131
- groups,
132
- className,
133
- children,
134
- value: controlledValue,
135
- defaultValue,
136
- onValueChange,
137
- ...props
138
- }, ref) => {
139
- const [items, setItems] = React.useState<TabItem[]>(initialItems);
140
- const [localValue, setLocalValue] = React.useState(() => {
141
- // Check persistence
142
- if (persistKey && typeof window !== 'undefined') {
143
- const stored = localStorage.getItem(`tabs-${persistKey}`);
144
- if (stored) {
145
- const parsed = JSON.parse(stored);
146
- return parsed.activeTab || defaultValue || items[0]?.value;
147
- }
148
- }
149
- // Check URL
150
- if (urlSync && typeof window !== 'undefined') {
151
- const params = new URLSearchParams(window.location.search);
152
- const tabParam = params.get('tab');
153
- if (tabParam) return tabParam;
154
- }
155
- return defaultValue || items[0]?.value;
156
- });
157
-
158
- const [loadedTabs, setLoadedTabs] = React.useState<Set<string>>(new Set());
159
- const [isChanging, setIsChanging] = React.useState(false);
160
- const scrollRef = React.useRef<HTMLDivElement>(null);
161
-
162
- const value = controlledValue !== undefined ? controlledValue : localValue;
163
-
164
- // Handle value change
165
- const handleValueChange = React.useCallback(async (newValue: string) => {
166
- if (loading || isChanging) return;
167
-
168
- // Validation
169
- if (onBeforeChange) {
170
- setIsChanging(true);
171
- const canChange = await onBeforeChange(value || '', newValue);
172
- setIsChanging(false);
173
- if (!canChange) return;
174
- }
175
-
176
- setLocalValue(newValue);
177
- onValueChange?.(newValue);
178
-
179
- // Track lazy loading
180
- if (lazy && !loadedTabs.has(newValue)) {
181
- setLoadedTabs(prev => new Set([...prev, newValue]));
182
- }
183
-
184
- // Analytics
185
- onAnalytics?.('tab_switch', { from: value, to: newValue });
186
-
187
- // Persistence
188
- if (persistKey && typeof window !== 'undefined') {
189
- localStorage.setItem(`tabs-${persistKey}`, JSON.stringify({
190
- activeTab: newValue,
191
- tabs: items
192
- }));
193
- }
194
-
195
- // URL sync
196
- if (urlSync && typeof window !== 'undefined') {
197
- const params = new URLSearchParams(window.location.search);
198
- params.set('tab', newValue);
199
- window.history.replaceState({}, '', `${window.location.pathname}?${params}`);
200
- }
201
- }, [value, loading, isChanging, onBeforeChange, onValueChange, lazy, loadedTabs, onAnalytics, persistKey, items, urlSync]);
202
-
203
- // Handle tab close
204
- const handleTabClose = React.useCallback((tabValue: string, e: React.MouseEvent) => {
205
- e.stopPropagation();
206
-
207
- const newItems = items.filter(item => item.value !== tabValue);
208
- setItems(newItems);
209
- onTabsChange?.(newItems);
210
- onTabClose?.(tabValue);
211
- onAnalytics?.('tab_close', { value: tabValue });
212
-
213
- // If closing active tab, switch to first available
214
- if (value === tabValue && newItems.length > 0) {
215
- handleValueChange(newItems[0].value);
216
- }
217
- }, [items, value, onTabsChange, onTabClose, onAnalytics, handleValueChange]);
218
-
219
- // Handle tab add
220
- const handleTabAdd = React.useCallback(() => {
221
- if (maxTabs && items.length >= maxTabs) {
222
- onAnalytics?.('tab_add_blocked', { reason: 'max_tabs' });
223
- return;
224
- }
225
-
226
- onTabAdd?.();
227
- onAnalytics?.('tab_add', { count: items.length + 1 });
228
- }, [items.length, maxTabs, onTabAdd, onAnalytics]);
229
-
230
- // Keyboard shortcuts
231
- React.useEffect(() => {
232
- if (!shortcuts) return;
233
-
234
- const handleKeyDown = (e: KeyboardEvent) => {
235
- // Ctrl/Cmd + number to switch tabs
236
- if ((e.metaKey || e.ctrlKey) && e.key >= '1' && e.key <= '9') {
237
- e.preventDefault();
238
- const index = parseInt(e.key) - 1;
239
- if (items[index]) {
240
- handleValueChange(items[index].value);
241
- }
242
- }
243
- // Ctrl/Cmd + W to close current tab
244
- if ((e.metaKey || e.ctrlKey) && e.key === 'w' && closeable) {
245
- e.preventDefault();
246
- const currentTab = items.find(item => item.value === value);
247
- if (currentTab?.closeable !== false) {
248
- handleTabClose(value || '', new MouseEvent('click') as any);
249
- }
250
- }
251
- // Ctrl/Cmd + T to add new tab
252
- if ((e.metaKey || e.ctrlKey) && e.key === 't' && addable) {
253
- e.preventDefault();
254
- handleTabAdd();
255
- }
256
- };
257
-
258
- document.addEventListener('keydown', handleKeyDown);
259
- return () => document.removeEventListener('keydown', handleKeyDown);
260
- }, [shortcuts, items, value, closeable, addable, handleValueChange, handleTabClose, handleTabAdd]);
261
-
262
- // Scroll buttons
263
- const scrollLeft = () => {
264
- if (scrollRef.current) {
265
- scrollRef.current.scrollBy({ left: -200, behavior: 'smooth' });
266
- }
267
- };
268
-
269
- const scrollRight = () => {
270
- if (scrollRef.current) {
271
- scrollRef.current.scrollBy({ left: 200, behavior: 'smooth' });
272
- }
273
- };
274
-
275
- return (
276
- <div className={cn(
277
- "relative w-full",
278
- variant === "gradient" && "bg-gradient-to-r from-primary/10 to-secondary/10 rounded-lg p-1",
279
- variant === "glassmorphism" && "backdrop-blur-xl bg-white/10 dark:bg-black/10 border border-white/20 dark:border-white/10 rounded-lg p-1",
280
- variant === "neon" && "bg-black rounded-lg p-1 shadow-[0_0_20px_rgba(139,92,246,0.3)]",
281
- className
282
- )}>
283
- {loading && (
284
- <div className="absolute inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm rounded-lg">
285
- <Loader2 className="h-6 w-6 animate-spin text-primary" />
286
- </div>
287
- )}
288
-
289
- <TabsPrimitive.Root
290
- ref={ref}
291
- value={value}
292
- onValueChange={handleValueChange}
293
- orientation={orientation}
294
- {...props}
295
- >
296
- {/* If items are provided, render items-based tabs */}
297
- {items.length > 0 ? (
298
- <>
299
- <div className={cn(
300
- "relative flex items-center",
301
- orientation === "vertical" && "flex-col items-start"
302
- )}>
303
- {/* Scroll button left */}
304
- {scrollable && orientation === "horizontal" && (
305
- <Button
306
- variant="ghost"
307
- size="sm"
308
- className="h-8 w-8 p-0 absolute left-0 z-10"
309
- onClick={scrollLeft}
310
- >
311
- <ChevronLeft className="h-4 w-4" />
312
- </Button>
313
- )}
314
-
315
- {/* Tabs List */}
316
- <div
317
- ref={scrollRef}
318
- className={cn(
319
- "flex-1 overflow-x-auto scrollbar-hide",
320
- scrollable && orientation === "horizontal" && "mx-10"
321
- )}
322
- >
323
- <TabsPrimitive.List
324
- className={cn(
325
- "flex items-center gap-1",
326
- orientation === "vertical" && "flex-col items-start w-full",
327
- variant === "underline" && "border-b border-border"
328
- )}
329
- >
330
- {items.map((item, index) => (
331
- <motion.div
332
- key={item.value}
333
- layout
334
- drag={draggable ? orientation === "horizontal" ? "x" : "y" : false}
335
- dragConstraints={{ left: 0, right: 0, top: 0, bottom: 0 }}
336
- dragElastic={0.2}
337
- whileDrag={{ scale: 1.05, zIndex: 50 }}
338
- className="relative"
339
- >
340
- <TabsPrimitive.Trigger
341
- value={item.value}
342
- disabled={item.disabled}
343
- className={cn(
344
- "relative inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
345
- // Variant styles
346
- variant === "default" && "data-[state=active]:bg-background data-[state=active]:shadow-sm",
347
- variant === "pills" && "rounded-full data-[state=active]:bg-primary data-[state=active]:text-primary-foreground",
348
- variant === "underline" && "rounded-none border-b-2 border-transparent data-[state=active]:border-primary",
349
- variant === "cards" && "bg-muted/50 data-[state=active]:bg-background data-[state=active]:shadow-md",
350
- variant === "minimal" && "hover:bg-muted/50 data-[state=active]:bg-transparent data-[state=active]:underline",
351
- variant === "gradient" && "data-[state=active]:bg-gradient-to-r data-[state=active]:from-primary data-[state=active]:to-secondary data-[state=active]:text-white",
352
- variant === "glassmorphism" && "backdrop-blur-md data-[state=active]:bg-white/20 dark:data-[state=active]:bg-white/10",
353
- variant === "neon" && "text-purple-400 data-[state=active]:text-white data-[state=active]:shadow-[0_0_10px_rgba(139,92,246,0.8)]",
354
- orientation === "vertical" && "w-full justify-start"
355
- )}
356
- >
357
- {item.icon && <span className="mr-2">{item.icon}</span>}
358
- {item.label}
359
- {item.badge && <span className="ml-2">{item.badge}</span>}
360
- {closeable && item.closeable !== false && (
361
- <button
362
- onClick={(e) => handleTabClose(item.value, e)}
363
- className="ml-2 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2"
364
- >
365
- <X className="h-3 w-3" />
366
- </button>
367
- )}
368
- </TabsPrimitive.Trigger>
369
-
370
- {/* Active indicator animation */}
371
- {value === item.value && animationMode !== "none" && (
372
- <motion.div
373
- layoutId="active-tab"
374
- className={cn(
375
- "absolute inset-0 -z-10",
376
- variant === "default" && "bg-background shadow-sm rounded-md",
377
- variant === "pills" && "bg-primary rounded-full",
378
- variant === "underline" && "bottom-0 h-0.5 bg-primary"
379
- )}
380
- transition={{
381
- type: "spring",
382
- stiffness: 500,
383
- damping: 30
384
- }}
385
- />
386
- )}
387
- </motion.div>
388
- ))}
389
-
390
- {/* Add tab button */}
391
- {addable && (
392
- <Button
393
- variant="ghost"
394
- size="sm"
395
- onClick={handleTabAdd}
396
- className="h-8 w-8 p-0 ml-2"
397
- disabled={maxTabs ? items.length >= maxTabs : false}
398
- >
399
- <Plus className="h-4 w-4" />
400
- </Button>
401
- )}
402
- </TabsPrimitive.List>
403
- </div>
404
-
405
- {/* Scroll button right */}
406
- {scrollable && orientation === "horizontal" && (
407
- <Button
408
- variant="ghost"
409
- size="sm"
410
- className="h-8 w-8 p-0 absolute right-0 z-10"
411
- onClick={scrollRight}
412
- >
413
- <ChevronRight className="h-4 w-4" />
414
- </Button>
415
- )}
416
-
417
- {/* Overflow menu for hidden tabs */}
418
- {items.length > 5 && (
419
- <DropdownMenu>
420
- <DropdownMenuTrigger asChild>
421
- <Button variant="ghost" size="sm" className="h-8 w-8 p-0 ml-2">
422
- <MoreHorizontal className="h-4 w-4" />
423
- </Button>
424
- </DropdownMenuTrigger>
425
- <DropdownMenuContent align="end">
426
- {items.slice(5).map(item => (
427
- <DropdownMenuItem
428
- key={item.value}
429
- onClick={() => handleValueChange(item.value)}
430
- >
431
- {item.icon && <span className="mr-2">{item.icon}</span>}
432
- {item.label}
433
- </DropdownMenuItem>
434
- ))}
435
- </DropdownMenuContent>
436
- </DropdownMenu>
437
- )}
438
- </div>
439
-
440
- {/* Tab contents with animations */}
441
- {animationMode !== "none" ? (
442
- <AnimatePresence mode="wait">
443
- {items.map(item => {
444
- if (value !== item.value) return null;
445
-
446
- return (
447
- <TabsPrimitive.Content
448
- key={item.value}
449
- value={item.value}
450
- forceMount
451
- className="mt-4 focus-visible:outline-none"
452
- >
453
- <motion.div
454
- initial="initial"
455
- animate="animate"
456
- exit="exit"
457
- variants={contentVariants[animationMode]}
458
- transition={{ duration: 0.3 }}
459
- >
460
- {item.content || children}
461
- </motion.div>
462
- </TabsPrimitive.Content>
463
- );
464
- })}
465
- </AnimatePresence>
466
- ) : (
467
- items.map(item => (
468
- <TabsPrimitive.Content
469
- key={item.value}
470
- value={item.value}
471
- className="mt-4 focus-visible:outline-none"
472
- >
473
- {item.content || children}
474
- </TabsPrimitive.Content>
475
- ))
476
- )}
477
- </>
478
- ) : (
479
- /* Otherwise, render children-based tabs */
480
- children
481
- )}
482
- </TabsPrimitive.Root>
483
- </div>
484
- );
485
- });
486
-
487
- MoonUITabsPro.displayName = "MoonUITabsPro";
488
-
489
- // Additional Pro Tab Components
490
- const MoonUITabsListPro = React.forwardRef<
491
- React.ElementRef<typeof TabsPrimitive.List>,
492
- React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
493
- >(({ className, ...props }, ref) => (
494
- <TabsPrimitive.List
495
- ref={ref}
496
- className={cn(
497
- "inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
498
- className
499
- )}
500
- {...props}
501
- />
502
- ));
503
- MoonUITabsListPro.displayName = "MoonUITabsListPro";
504
-
505
- const MoonUITabsTriggerPro = React.forwardRef<
506
- React.ElementRef<typeof TabsPrimitive.Trigger>,
507
- React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
508
- >(({ className, ...props }, ref) => (
509
- <TabsPrimitive.Trigger
510
- ref={ref}
511
- className={cn(
512
- "inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
513
- className
514
- )}
515
- {...props}
516
- />
517
- ));
518
- MoonUITabsTriggerPro.displayName = "MoonUITabsTriggerPro";
519
-
520
- const MoonUITabsContentPro = React.forwardRef<
521
- React.ElementRef<typeof TabsPrimitive.Content>,
522
- React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
523
- >(({ className, ...props }, ref) => (
524
- <TabsPrimitive.Content
525
- ref={ref}
526
- className={cn(
527
- "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
528
- className
529
- )}
530
- {...props}
531
- />
532
- ));
533
- MoonUITabsContentPro.displayName = "MoonUITabsContentPro";
534
-
535
- export {
536
- MoonUITabsPro,
537
- MoonUITabsListPro,
538
- MoonUITabsTriggerPro,
539
- MoonUITabsContentPro,
540
- type TabItem,
541
- type MoonUITabsProProps
542
- };
@@ -1,54 +0,0 @@
1
- "use client"
2
-
3
- import * as React from "react";
4
- import * as TabsPrimitive from "@radix-ui/react-tabs";
5
- import { cn } from "../../lib/utils";
6
-
7
- const Tabs = TabsPrimitive.Root;
8
-
9
- const TabsList = React.forwardRef<
10
- React.ElementRef<typeof TabsPrimitive.List>,
11
- React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
12
- >(({ className, ...props }, ref) => (
13
- <TabsPrimitive.List
14
- ref={ref}
15
- className={cn(
16
- "inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
17
- className
18
- )}
19
- {...props}
20
- />
21
- ));
22
- TabsList.displayName = TabsPrimitive.List.displayName;
23
-
24
- const TabsTrigger = React.forwardRef<
25
- React.ElementRef<typeof TabsPrimitive.Trigger>,
26
- React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
27
- >(({ className, ...props }, ref) => (
28
- <TabsPrimitive.Trigger
29
- ref={ref}
30
- className={cn(
31
- "inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
32
- className
33
- )}
34
- {...props}
35
- />
36
- ));
37
- TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
38
-
39
- const TabsContent = React.forwardRef<
40
- React.ElementRef<typeof TabsPrimitive.Content>,
41
- React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
42
- >(({ className, ...props }, ref) => (
43
- <TabsPrimitive.Content
44
- ref={ref}
45
- className={cn(
46
- "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
47
- className
48
- )}
49
- {...props}
50
- />
51
- ));
52
- TabsContent.displayName = TabsPrimitive.Content.displayName;
53
-
54
- export { Tabs, TabsList, TabsTrigger, TabsContent };
@@ -1,28 +0,0 @@
1
- "use client"
2
-
3
- import React from "react"
4
- import { cn } from "../../lib/utils"
5
-
6
- export interface MoonUITextareaProProps
7
- extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
8
-
9
- const MoonUITextareaPro = React.forwardRef<HTMLTextAreaElement, MoonUITextareaProProps>(
10
- ({ className, ...props }, ref) => {
11
- return (
12
- <textarea
13
- className={cn(
14
- "flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
15
- className
16
- )}
17
- ref={ref}
18
- {...props}
19
- />
20
- )
21
- }
22
- )
23
- MoonUITextareaPro.displayName = "MoonUITextareaPro"
24
-
25
- export { MoonUITextareaPro };
26
-
27
- // Backward compatibility exports
28
- export { MoonUITextareaPro as Textarea }