@moontra/moonui-pro 2.18.6 → 2.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/index.d.ts +3251 -0
  2. package/dist/index.mjs +2704 -1479
  3. package/package.json +137 -136
  4. package/src/__tests__/use-local-storage.test.tsx +2 -2
  5. package/src/components/advanced-chart/index.tsx +6 -6
  6. package/src/components/animated-button/index.tsx +240 -53
  7. package/src/components/calendar/event-dialog.tsx +1 -1
  8. package/src/components/calendar/index.tsx +1 -1
  9. package/src/components/calendar-pro/index.tsx +2 -4
  10. package/src/components/dashboard/demo.tsx +2 -2
  11. package/src/components/dashboard/widgets/activity-feed.tsx +1 -1
  12. package/src/components/dashboard/widgets/metric-card.tsx +1 -1
  13. package/src/components/enhanced/button.tsx +13 -13
  14. package/src/components/file-upload/file-upload.test.tsx +20 -19
  15. package/src/components/form-wizard/form-wizard-progress.tsx +7 -7
  16. package/src/components/gesture-drawer/index.tsx +551 -0
  17. package/src/components/github-stars/hooks.ts +1 -1
  18. package/src/components/github-stars/index.tsx +1 -1
  19. package/src/components/github-stars/types.ts +1 -0
  20. package/src/components/health-check/index.tsx +2 -2
  21. package/src/components/hover-card-3d/index.tsx +437 -74
  22. package/src/components/index.ts +15 -2
  23. package/src/components/lazy-component/index.tsx +4 -2
  24. package/src/components/license-error/index.tsx +29 -0
  25. package/src/components/memory-efficient-data/index.tsx +1 -1
  26. package/src/components/pinch-zoom/index.tsx +438 -42
  27. package/src/components/rich-text-editor/index.tsx +12 -12
  28. package/src/components/timeline/index.tsx +2 -2
  29. package/src/components/ui/aspect-ratio.tsx +186 -22
  30. package/src/components/ui/button.tsx +47 -50
  31. package/src/components/ui/card.tsx +98 -30
  32. package/src/components/ui/gesture-drawer.tsx +11 -0
  33. package/src/components/ui/index.ts +18 -1
  34. package/src/components/ui/lightbox.tsx +606 -0
  35. package/src/components/ui/media-gallery.tsx +612 -0
  36. package/src/components/ui/select.tsx +134 -35
  37. package/src/components/ui/toggle.tsx +78 -15
  38. package/src/components/virtual-list/index.tsx +7 -7
  39. package/src/index.ts +4 -4
  40. package/src/lib/component-metadata.ts +18 -0
  41. package/src/lib/paddle.ts +17 -0
  42. package/src/patterns/login-form/index.tsx +1 -1
  43. package/src/patterns/login-form/types.ts +6 -6
  44. package/src/styles/index.css +14 -4
  45. package/src/types/next-auth.d.ts +21 -0
  46. package/src/use-local-storage.tsx +3 -3
  47. package/src/use-scroll-animation.ts +3 -5
  48. package/src/components/ui/animated-button.tsx +0 -185
  49. package/src/components/ui/hover-card-3d.tsx +0 -103
@@ -2,7 +2,7 @@
2
2
 
3
3
  import * as React from "react"
4
4
  import * as SelectPrimitive from "@radix-ui/react-select"
5
- import { Check, ChevronDown, ChevronUp, Loader2 } from "lucide-react"
5
+ import { Check, ChevronDown, ChevronUp, Loader2, Search, X } from "lucide-react"
6
6
 
7
7
  import { cn } from "../../lib/utils"
8
8
 
@@ -39,6 +39,12 @@ interface MoonUISelectTriggerProProps extends React.ComponentPropsWithoutRef<typ
39
39
  leftIcon?: React.ReactNode;
40
40
  /** Icon displayed on the right (instead of default chevron) */
41
41
  rightIcon?: React.ReactNode;
42
+ /** Enable clear button */
43
+ clearable?: boolean;
44
+ /** On clear callback */
45
+ onClear?: () => void;
46
+ /** Custom placeholder when value is selected */
47
+ selectedPlaceholder?: string;
42
48
  }
43
49
 
44
50
  const MoonUISelectTriggerPro = React.forwardRef<
@@ -140,43 +146,124 @@ const MoonUISelectScrollDownButtonPro = React.forwardRef<
140
146
  MoonUISelectScrollDownButtonPro.displayName =
141
147
  SelectPrimitive.ScrollDownButton.displayName
142
148
 
149
+ interface MoonUISelectContentProProps extends React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content> {
150
+ /** Enable search functionality */
151
+ enableSearch?: boolean;
152
+ /** Search placeholder */
153
+ searchPlaceholder?: string;
154
+ /** No results text */
155
+ noResultsText?: string;
156
+ /** Loading search results */
157
+ searchLoading?: boolean;
158
+ /** Custom search icon */
159
+ searchIcon?: React.ReactNode;
160
+ }
161
+
143
162
  const MoonUISelectContentPro = React.forwardRef<
144
163
  React.ElementRef<typeof SelectPrimitive.Content>,
145
- React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
146
- >(({ className, children, position = "item-aligned", ...props }, ref) => (
147
- <SelectPrimitive.Portal>
148
- <SelectPrimitive.Content
149
- ref={ref}
150
- className={cn(
151
- ["relative z-50 max-h-96 min-w-[8rem] overflow-hidden",
152
- "rounded-md border border-gray-200 dark:border-gray-700",
153
- "bg-white dark:bg-gray-900 text-foreground",
154
- "shadow-lg dark:shadow-gray-900/20",
155
- "data-[state=open]:animate-in data-[state=closed]:animate-out",
156
- "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
157
- "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
158
- "data-[state=open]:duration-150"],
159
- position === "popper" &&
160
- "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
161
- className
162
- )}
163
- position={position}
164
- {...props}
165
- >
166
- <MoonUISelectScrollUpButtonPro />
167
- <SelectPrimitive.Viewport
164
+ MoonUISelectContentProProps
165
+ >(({ className, children, position = "popper", enableSearch, searchPlaceholder = "Search...", noResultsText = "No results found", searchLoading, searchIcon, ...props }, ref) => {
166
+ const [searchValue, setSearchValue] = React.useState("");
167
+
168
+ // Filter children based on search
169
+ const filteredChildren = React.useMemo(() => {
170
+ if (!enableSearch || !searchValue) return children;
171
+
172
+ const searchLower = searchValue.toLowerCase();
173
+ return React.Children.toArray(children).filter((child) => {
174
+ if (!React.isValidElement(child)) return true;
175
+
176
+ // Keep groups and labels
177
+ if (child.type === MoonUISelectGroupPro || child.type === MoonUISelectLabelPro || child.type === MoonUISelectSeparatorPro) {
178
+ return true;
179
+ }
180
+
181
+ // Filter items
182
+ if (child.type === MoonUISelectItemPro) {
183
+ const reactChild = child as React.ReactElement<any>;
184
+ const text = reactChild.props.children?.toString().toLowerCase() || "";
185
+ return text.includes(searchLower);
186
+ }
187
+
188
+ return true;
189
+ });
190
+ }, [children, searchValue, enableSearch]);
191
+
192
+ return (
193
+ <SelectPrimitive.Portal>
194
+ <SelectPrimitive.Content
195
+ ref={ref}
168
196
  className={cn(
169
- "p-1",
197
+ ["relative z-50 max-h-96 min-w-[8rem] overflow-hidden",
198
+ "rounded-md border border-gray-200 dark:border-gray-700",
199
+ "bg-white dark:bg-gray-900 text-foreground",
200
+ "shadow-lg dark:shadow-gray-900/20",
201
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
202
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
203
+ "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
204
+ "data-[state=open]:duration-150"],
170
205
  position === "popper" &&
171
- "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
206
+ "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
207
+ className
172
208
  )}
209
+ position={position}
210
+ sideOffset={5}
211
+ {...props}
173
212
  >
174
- {children}
175
- </SelectPrimitive.Viewport>
176
- <MoonUISelectScrollDownButtonPro />
177
- </SelectPrimitive.Content>
178
- </SelectPrimitive.Portal>
179
- ))
213
+ {enableSearch && (
214
+ <div className="p-2 border-b border-gray-200 dark:border-gray-700">
215
+ <div className="flex items-center gap-2 px-2 py-1.5 rounded-md bg-gray-100 dark:bg-gray-800">
216
+ {searchIcon || <Search className="h-4 w-4 text-gray-500 dark:text-gray-400" />}
217
+ <input
218
+ type="text"
219
+ placeholder={searchPlaceholder}
220
+ value={searchValue}
221
+ onChange={(e) => setSearchValue(e.target.value)}
222
+ className="flex-1 bg-transparent outline-none text-sm placeholder:text-gray-500 dark:placeholder:text-gray-400"
223
+ onClick={(e) => e.stopPropagation()}
224
+ onKeyDown={(e) => e.stopPropagation()}
225
+ />
226
+ {searchValue && (
227
+ <button
228
+ onClick={(e) => {
229
+ e.stopPropagation();
230
+ setSearchValue("");
231
+ }}
232
+ className="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
233
+ >
234
+ <X className="h-3 w-3" />
235
+ </button>
236
+ )}
237
+ </div>
238
+ </div>
239
+ )}
240
+ <MoonUISelectScrollUpButtonPro />
241
+ <SelectPrimitive.Viewport
242
+ className={cn(
243
+ "p-1",
244
+ position === "popper" &&
245
+ "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
246
+ )}
247
+ >
248
+ {searchLoading ? (
249
+ <div className="flex items-center justify-center py-8">
250
+ <Loader2 className="h-5 w-5 animate-spin text-gray-400" />
251
+ </div>
252
+ ) : filteredChildren && React.Children.count(filteredChildren) > 0 ? (
253
+ filteredChildren
254
+ ) : enableSearch ? (
255
+ <div className="py-6 text-center text-sm text-gray-500 dark:text-gray-400">
256
+ {noResultsText}
257
+ </div>
258
+ ) : (
259
+ children
260
+ )}
261
+ </SelectPrimitive.Viewport>
262
+ <MoonUISelectScrollDownButtonPro />
263
+ </SelectPrimitive.Content>
264
+ </SelectPrimitive.Portal>
265
+ );
266
+ })
180
267
  MoonUISelectContentPro.displayName = SelectPrimitive.Content.displayName
181
268
 
182
269
  const MoonUISelectLabelPro = React.forwardRef<
@@ -203,16 +290,20 @@ interface MoonUISelectItemProProps extends React.ComponentPropsWithoutRef<typeof
203
290
  rightIcon?: React.ReactNode;
204
291
  /** Custom indicator icon (instead of default check) */
205
292
  customIndicator?: React.ReactNode;
293
+ /** Enable hover scale animation */
294
+ enableHoverScale?: boolean;
295
+ /** Description text shown below the main text */
296
+ description?: string;
206
297
  }
207
298
 
208
299
  const MoonUISelectItemPro = React.forwardRef<
209
300
  React.ElementRef<typeof SelectPrimitive.Item>,
210
301
  MoonUISelectItemProProps
211
- >(({ className, children, variant = "default", size = "md", rightIcon, customIndicator, ...props }, ref) => (
302
+ >(({ className, children, variant = "default", size = "md", rightIcon, customIndicator, enableHoverScale, description, ...props }, ref) => (
212
303
  <SelectPrimitive.Item
213
304
  ref={ref}
214
305
  className={cn(
215
- "relative flex w-full cursor-default select-none items-center rounded-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
306
+ "relative flex w-full cursor-default select-none items-center rounded-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 transition-all duration-150",
216
307
 
217
308
  /* Size variants */
218
309
  size === "sm" && "py-1 pl-7 pr-2 text-xs",
@@ -226,6 +317,9 @@ const MoonUISelectItemPro = React.forwardRef<
226
317
  variant === "success" && "text-success dark:text-green-400 focus:bg-success/10 dark:focus:bg-green-900/20 focus:text-success dark:focus:text-green-300",
227
318
  variant === "warning" && "text-warning dark:text-yellow-400 focus:bg-warning/10 dark:focus:bg-yellow-900/20 focus:text-warning dark:focus:text-yellow-300",
228
319
 
320
+ /* Hover scale animation */
321
+ enableHoverScale && "hover:scale-[1.02] hover:pl-9",
322
+
229
323
  className
230
324
  )}
231
325
  {...props}
@@ -236,7 +330,12 @@ const MoonUISelectItemPro = React.forwardRef<
236
330
  </SelectPrimitive.ItemIndicator>
237
331
  </span>
238
332
 
239
- <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
333
+ <div className="flex-1">
334
+ <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
335
+ {description && (
336
+ <p className="text-xs text-gray-500 dark:text-gray-400 mt-0.5">{description}</p>
337
+ )}
338
+ </div>
240
339
 
241
340
  {rightIcon && (
242
341
  <span className="ml-auto pl-2 opacity-70">
@@ -7,39 +7,102 @@ import { cva, type VariantProps } from "class-variance-authority"
7
7
  import { cn } from "../../lib/utils"
8
8
 
9
9
  const MoonUItoggleVariantsPro = cva(
10
- "inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground 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=on]:bg-accent data-[state=on]:text-accent-foreground",
10
+ "inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
11
11
  {
12
12
  variants: {
13
13
  variant: {
14
- default: "bg-transparent",
15
- outline:
16
- "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground",
14
+ default: "bg-transparent hover:bg-muted hover:text-muted-foreground data-[state=on]:bg-accent data-[state=on]:text-accent-foreground dark:hover:bg-muted dark:hover:text-muted-foreground dark:data-[state=on]:bg-accent dark:data-[state=on]:text-accent-foreground",
15
+ outline: "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground data-[state=on]:bg-accent data-[state=on]:text-accent-foreground dark:border-input dark:hover:bg-accent dark:hover:text-accent-foreground dark:data-[state=on]:bg-accent dark:data-[state=on]:text-accent-foreground",
16
+ ghost: "hover:bg-accent hover:text-accent-foreground data-[state=on]:bg-transparent data-[state=on]:text-accent-foreground dark:hover:bg-accent dark:hover:text-accent-foreground dark:data-[state=on]:text-accent-foreground",
17
+ primary: "bg-transparent hover:bg-primary/10 hover:text-primary data-[state=on]:bg-primary data-[state=on]:text-primary-foreground dark:hover:bg-primary/20 dark:hover:text-primary dark:data-[state=on]:bg-primary dark:data-[state=on]:text-primary-foreground",
18
+ secondary: "bg-transparent hover:bg-secondary/10 hover:text-secondary data-[state=on]:bg-secondary data-[state=on]:text-secondary-foreground dark:hover:bg-secondary/20 dark:hover:text-secondary dark:data-[state=on]:bg-secondary dark:data-[state=on]:text-secondary-foreground",
19
+ success: "bg-transparent hover:bg-success/10 hover:text-success data-[state=on]:bg-success data-[state=on]:text-success-foreground dark:hover:bg-success/20 dark:hover:text-success dark:data-[state=on]:bg-success dark:data-[state=on]:text-success-foreground",
20
+ warning: "bg-transparent hover:bg-warning/10 hover:text-warning data-[state=on]:bg-warning data-[state=on]:text-warning-foreground dark:hover:bg-warning/20 dark:hover:text-warning dark:data-[state=on]:bg-warning dark:data-[state=on]:text-warning-foreground",
21
+ danger: "bg-transparent hover:bg-destructive/10 hover:text-destructive data-[state=on]:bg-destructive data-[state=on]:text-destructive-foreground dark:hover:bg-destructive/20 dark:hover:text-destructive dark:data-[state=on]:bg-destructive dark:data-[state=on]:text-destructive-foreground",
22
+ gradient: "bg-transparent hover:bg-gradient-to-r hover:from-purple-500/10 hover:to-pink-500/10 hover:text-purple-600 data-[state=on]:bg-gradient-to-r data-[state=on]:from-purple-600 data-[state=on]:to-pink-600 data-[state=on]:text-white dark:hover:from-purple-500/20 dark:hover:to-pink-500/20 dark:hover:text-purple-400 dark:data-[state=on]:from-purple-600 dark:data-[state=on]:to-pink-600 dark:data-[state=on]:text-white",
17
23
  },
18
24
  size: {
19
- default: "h-10 px-3",
20
- sm: "h-9 px-2.5",
21
- lg: "h-11 px-5",
25
+ xs: "h-7 px-2 text-xs",
26
+ sm: "h-8 px-2.5 text-xs",
27
+ default: "h-9 px-3",
28
+ md: "h-10 px-4",
29
+ lg: "h-11 px-6",
30
+ xl: "h-12 px-8 text-base",
31
+ },
32
+ shape: {
33
+ default: "rounded-md",
34
+ square: "rounded-none",
35
+ rounded: "rounded-lg",
36
+ pill: "rounded-full",
22
37
  },
23
38
  },
24
39
  defaultVariants: {
25
40
  variant: "default",
26
41
  size: "default",
42
+ shape: "default",
27
43
  },
28
44
  }
29
45
  )
30
46
 
31
- export interface MoonUIToggleProProps extends React.ComponentPropsWithoutRef<typeof TogglePrimitive.Root>, VariantProps<typeof MoonUItoggleVariantsPro> {}
47
+ export interface MoonUIToggleProProps extends React.ComponentPropsWithoutRef<typeof TogglePrimitive.Root>, VariantProps<typeof MoonUItoggleVariantsPro> {
48
+ /** Loading state */
49
+ loading?: boolean;
50
+ /** Show a badge with a count */
51
+ badge?: string | number;
52
+ /** Badge variant */
53
+ badgeVariant?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";
54
+ /** Icon to show when toggled on */
55
+ iconOn?: React.ReactNode;
56
+ /** Icon to show when toggled off */
57
+ iconOff?: React.ReactNode;
58
+ /** Position of icon relative to text */
59
+ iconPosition?: "left" | "right";
60
+ }
32
61
 
33
62
  const MoonUITogglePro = React.forwardRef<
34
63
  React.ElementRef<typeof TogglePrimitive.Root>,
35
64
  MoonUIToggleProProps
36
- >(({ className, variant, size, ...props }, ref) => (
37
- <TogglePrimitive.Root
38
- ref={ref}
39
- className={cn(MoonUItoggleVariantsPro({ variant, size, className }))}
40
- {...props}
41
- />
42
- ))
65
+ >(({ className, variant, size, shape, loading, badge, badgeVariant = "default", iconOn, iconOff, iconPosition = "left", children, pressed, onPressedChange, defaultPressed, ...props }, ref) => {
66
+ const icon = pressed ? iconOn : iconOff;
67
+
68
+ return (
69
+ <TogglePrimitive.Root
70
+ ref={ref}
71
+ className={cn(MoonUItoggleVariantsPro({ variant, size, shape }), className)}
72
+ pressed={pressed}
73
+ onPressedChange={onPressedChange}
74
+ defaultPressed={defaultPressed}
75
+ disabled={loading || props.disabled}
76
+ {...props}
77
+ >
78
+ {loading ? (
79
+ <div className="flex items-center gap-2">
80
+ <div className="h-3 w-3 animate-spin rounded-full border-2 border-current border-t-transparent" />
81
+ {children && <span>{children}</span>}
82
+ </div>
83
+ ) : (
84
+ <div className="flex items-center gap-2">
85
+ {icon && iconPosition === "left" && <span className="flex-shrink-0">{icon}</span>}
86
+ {children && <span>{children}</span>}
87
+ {icon && iconPosition === "right" && <span className="flex-shrink-0">{icon}</span>}
88
+ {badge !== undefined && (
89
+ <span className={cn(
90
+ "ml-1 inline-flex items-center justify-center rounded-full px-1.5 text-xs font-semibold",
91
+ badgeVariant === "default" && "bg-muted text-muted-foreground",
92
+ badgeVariant === "primary" && "bg-primary text-primary-foreground",
93
+ badgeVariant === "secondary" && "bg-secondary text-secondary-foreground",
94
+ badgeVariant === "success" && "bg-success text-success-foreground",
95
+ badgeVariant === "warning" && "bg-warning text-warning-foreground",
96
+ badgeVariant === "danger" && "bg-destructive text-destructive-foreground",
97
+ )}>
98
+ {badge}
99
+ </span>
100
+ )}
101
+ </div>
102
+ )}
103
+ </TogglePrimitive.Root>
104
+ )
105
+ })
43
106
 
44
107
  MoonUITogglePro.displayName = TogglePrimitive.Root.displayName
45
108
 
@@ -25,15 +25,15 @@ export interface VirtualListProps<T = any> {
25
25
  // Animation props
26
26
  enableAnimations?: boolean
27
27
  itemEnterAnimation?: {
28
- initial?: object
29
- animate?: object
30
- exit?: object
31
- transition?: object
28
+ initial?: any
29
+ animate?: any
30
+ exit?: any
31
+ transition?: any
32
32
  }
33
33
  listAnimation?: {
34
- initial?: object
35
- animate?: object
36
- transition?: object
34
+ initial?: any
35
+ animate?: any
36
+ transition?: any
37
37
  }
38
38
  staggerDelay?: number
39
39
  }
package/src/index.ts CHANGED
@@ -2,13 +2,13 @@
2
2
  // Development environment imports from local packages
3
3
 
4
4
  // Import CSS for auto-loading
5
- import "./styles/index.css"
5
+ import "./styles/index.css";
6
6
 
7
7
  // Utilities
8
- export { cn } from "./lib/utils"
8
+ export { cn } from "./lib/utils";
9
9
 
10
10
  // Pro Components (Commercial License) - from packages/moonui-pro
11
- export * from "./components"
11
+ export * from "./components";
12
12
 
13
13
  // Enhanced Components - Premium animations and effects
14
- export * as Enhanced from "./components/enhanced"
14
+ // export * from "./components/enhanced"
@@ -0,0 +1,18 @@
1
+ export interface ComponentMetadata {
2
+ name: string
3
+ category: string
4
+ isPro: boolean
5
+ path: string
6
+ }
7
+
8
+ export const componentsMetadata: Record<string, ComponentMetadata> = {
9
+ 'button': { name: 'Button', category: 'ui', isPro: false, path: 'button' },
10
+ 'enhanced-button': { name: 'Enhanced Button', category: 'enhanced', isPro: true, path: 'enhanced/button' },
11
+ 'data-table': { name: 'Data Table', category: 'data', isPro: true, path: 'data-table' },
12
+ 'calendar-pro': { name: 'Calendar Pro', category: 'data', isPro: true, path: 'calendar-pro' },
13
+ // Add more components as needed
14
+ }
15
+
16
+ export function getComponentMetadata(componentName: string): ComponentMetadata | undefined {
17
+ return componentsMetadata[componentName]
18
+ }
@@ -0,0 +1,17 @@
1
+ export interface PaddleEnvironment {
2
+ vendor: number
3
+ environment: 'production' | 'sandbox'
4
+ }
5
+
6
+ export interface PaddleCheckout {
7
+ Items: Array<{
8
+ price_id: string
9
+ quantity: number
10
+ }>
11
+ custom_data?: Record<string, any>
12
+ }
13
+
14
+ export const paddleConfig: PaddleEnvironment = {
15
+ vendor: parseInt(process.env.NEXT_PUBLIC_PADDLE_VENDOR_ID || '0'),
16
+ environment: (process.env.NEXT_PUBLIC_PADDLE_ENVIRONMENT || 'sandbox') as 'production' | 'sandbox'
17
+ }
@@ -2,7 +2,7 @@ import React, { useState } from 'react'
2
2
  import { cn } from '../../utils/cn'
3
3
  import { useLicenseCheck } from '../../hooks/use-license-check'
4
4
  import { LicenseError } from '../../components/license-error'
5
- import { Skeleton } from '../../components/skeleton'
5
+ import { Skeleton } from '../../components/ui/skeleton'
6
6
  import type { LoginFormProps, LoginData } from './types'
7
7
 
8
8
  export function LoginFormCore({
@@ -1,4 +1,4 @@
1
- interface LoginFormTheme {
1
+ export interface LoginFormTheme {
2
2
  primary?: string
3
3
  secondary?: string
4
4
  background?: string
@@ -7,7 +7,7 @@ interface LoginFormTheme {
7
7
  spacing?: 'compact' | 'normal' | 'relaxed'
8
8
  }
9
9
 
10
- interface LoginFormFeatures {
10
+ export interface LoginFormFeatures {
11
11
  socialLogin?: boolean | string[]
12
12
  rememberMe?: boolean
13
13
  forgotPassword?: boolean
@@ -15,7 +15,7 @@ interface LoginFormFeatures {
15
15
  passwordStrength?: boolean
16
16
  }
17
17
 
18
- interface LoginFormTexts {
18
+ export interface LoginFormTexts {
19
19
  title?: string
20
20
  subtitle?: string
21
21
  emailLabel?: string
@@ -27,18 +27,18 @@ interface LoginFormTexts {
27
27
  orContinueWith?: string
28
28
  }
29
29
 
30
- interface LoginData {
30
+ export interface LoginData {
31
31
  email: string
32
32
  password: string
33
33
  rememberMe?: boolean
34
34
  }
35
35
 
36
- interface ValidationRules {
36
+ export interface ValidationRules {
37
37
  email?: (value: string) => string | null
38
38
  password?: (value: string) => string | null
39
39
  }
40
40
 
41
- interface LoginFormProps {
41
+ export interface LoginFormProps {
42
42
  // Stil özelleştirme
43
43
  theme?: LoginFormTheme
44
44
  className?: string
@@ -1,8 +1,8 @@
1
1
  /* MoonUI Pro - Complete CSS System */
2
- @import "./tailwind.css";
3
- /* Tokens and design-system CSS removed to prevent global scope pollution */
4
- /* @import "./tokens.css"; */
5
- /* @import "./design-system.css"; */
2
+ @tailwind base;
3
+ @tailwind components;
4
+ @tailwind utilities;
5
+
6
6
  @import "./advanced-chart.css";
7
7
  @import "./calendar.css";
8
8
 
@@ -10,6 +10,16 @@
10
10
  @import "react-grid-layout/css/styles.css";
11
11
  @import "react-resizable/css/styles.css";
12
12
 
13
+ /* Global Keyframes */
14
+ @keyframes spin {
15
+ from {
16
+ transform: rotate(0deg);
17
+ }
18
+ to {
19
+ transform: rotate(360deg);
20
+ }
21
+ }
22
+
13
23
  /* Dashboard Grid Layout Overrides */
14
24
  .react-grid-layout {
15
25
  position: relative !important;
@@ -0,0 +1,21 @@
1
+ import { DefaultSession } from "next-auth";
2
+
3
+ declare module "next-auth" {
4
+ interface User {
5
+ id: string;
6
+ email?: string | null;
7
+ name?: string | null;
8
+ image?: string | null;
9
+ role?: string;
10
+ subscription?: {
11
+ status: string;
12
+ plan?: string;
13
+ currentPeriodEnd?: string;
14
+ expiresAt?: string;
15
+ };
16
+ }
17
+
18
+ interface Session extends DefaultSession {
19
+ user: User;
20
+ }
21
+ }
@@ -4,10 +4,10 @@ import { useState, useEffect } from 'react'
4
4
  export function useLocalStorage<T>(
5
5
  key: string,
6
6
  initialValue: T
7
- ): [T, (value: T | ((val: T) => T)) => void] {
7
+ ): [T | undefined, (value: T | undefined | ((val: T | undefined) => T | undefined)) => void] {
8
8
  // State to store our value
9
9
  // Pass initial state function to useState so logic is only executed once
10
- const [storedValue, setStoredValue] = useState<T>(() => {
10
+ const [storedValue, setStoredValue] = useState<T | undefined>(() => {
11
11
  if (typeof window === 'undefined') {
12
12
  return initialValue
13
13
  }
@@ -25,7 +25,7 @@ export function useLocalStorage<T>(
25
25
  })
26
26
 
27
27
  // Return a wrapped version of useState's setter function that persists the new value to localStorage
28
- const setValue = (value: T | ((val: T) => T)) => {
28
+ const setValue = (value: T | undefined | ((val: T | undefined) => T | undefined)) => {
29
29
  try {
30
30
  // Allow value to be a function so we have the same API as useState
31
31
  const valueToStore = value instanceof Function ? value(storedValue) : value
@@ -12,9 +12,8 @@ interface UseScrollAnimationOptions {
12
12
  export function useScrollAnimation(options: UseScrollAnimationOptions = {}) {
13
13
  const ref = useRef<HTMLElement>(null)
14
14
  const isInView = useInView(ref, {
15
- threshold: options.threshold || 0.1,
15
+ amount: options.threshold || 0.1,
16
16
  once: options.triggerOnce ?? true,
17
- margin: options.rootMargin || '-100px',
18
17
  })
19
18
 
20
19
  return { ref, isInView }
@@ -106,8 +105,7 @@ export function useInfiniteScroll(
106
105
  ) {
107
106
  const ref = useRef<HTMLElement>(null)
108
107
  const isInView = useInView(ref, {
109
- threshold: options.threshold || 0.1,
110
- margin: options.rootMargin || '100px',
108
+ amount: options.threshold || 0.1,
111
109
  })
112
110
 
113
111
  useEffect(() => {
@@ -153,7 +151,7 @@ export function useScrollTriggeredCounter(
153
151
  const ref = useRef<HTMLElement>(null)
154
152
 
155
153
  const isInView = useInView(ref, {
156
- threshold: 0.5,
154
+ amount: 0.5,
157
155
  once: true
158
156
  })
159
157