@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,257 +0,0 @@
1
- "use client";
2
-
3
- import * as React from "react";
4
- import { Circle } from "lucide-react";
5
- import { cva, type VariantProps } from "class-variance-authority";
6
-
7
- import { cn } from "../../lib/utils";
8
-
9
- /**
10
- * Radio Group Component
11
- *
12
- * Accessible, customizable, and fully integrated with the theme system radio button group.
13
- * Allows users to select a single option from a group of choices.
14
- */
15
-
16
- const MoonUIradioGroupItemVariantsPro = cva(
17
- "aspect-square border focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
18
- {
19
- variants: {
20
- variant: {
21
- default: "border-border bg-background text-primary",
22
- outline: "border-border bg-transparent text-primary",
23
- filled: "border-primary bg-primary/10 text-primary",
24
- },
25
- size: {
26
- sm: "h-3.5 w-3.5",
27
- default: "h-4 w-4",
28
- md: "h-5 w-5",
29
- lg: "h-6 w-6",
30
- },
31
- },
32
- defaultVariants: {
33
- variant: "default",
34
- size: "default",
35
- },
36
- }
37
- );
38
-
39
- export interface RadioGroupProps extends React.HTMLAttributes<HTMLDivElement> {
40
- /**
41
- * Radio group value
42
- */
43
- value?: string;
44
- /**
45
- * Function to call when radio group value changes
46
- */
47
- onValueChange?: (value: string) => void;
48
- /**
49
- * Radio group disabled state
50
- */
51
- disabled?: boolean;
52
- /**
53
- * Radio group name
54
- */
55
- name?: string;
56
- }
57
-
58
- const MoonUIRadioGroupContextPro = React.createContext<{
59
- value?: string;
60
- onValueChange?: (value: string) => void;
61
- disabled?: boolean;
62
- name?: string;
63
- }>({});
64
-
65
- const MoonUIRadioGroupPro = React.forwardRef<HTMLDivElement, RadioGroupProps>(
66
- ({ className, value, onValueChange, disabled, name, ...props }, ref) => {
67
- return (
68
- <MoonUIRadioGroupContextPro.Provider value={{ value, onValueChange, disabled, name }}>
69
- <div
70
- ref={ref}
71
- role="radiogroup"
72
- className={cn("grid gap-2", className)}
73
- {...props}
74
- />
75
- </MoonUIRadioGroupContextPro.Provider>
76
- );
77
- }
78
- );
79
- MoonUIRadioGroupPro.displayName = "RadioGroupPro";
80
-
81
- export interface RadioGroupItemProps
82
- extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'>,
83
- VariantProps<typeof MoonUIradioGroupItemVariantsPro> {
84
- /**
85
- * Custom indicator component
86
- */
87
- indicator?: React.ReactNode;
88
- /**
89
- * HTML id for radio button
90
- */
91
- id?: string;
92
- /**
93
- * Radio button value
94
- */
95
- value: string;
96
- /**
97
- * Radio button disabled state
98
- */
99
- disabled?: boolean;
100
- }
101
-
102
- const MoonUIRadioGroupItemPro = React.forwardRef<
103
- HTMLInputElement,
104
- RadioGroupItemProps
105
- >(({ className, variant, size, indicator, id, value, disabled, ...props }, ref) => {
106
- // Get context values from radio group
107
- const radioGroup = React.useContext(MoonUIRadioGroupContextPro);
108
- const generatedId = React.useId();
109
- const radioId = id || generatedId;
110
- const isChecked = radioGroup.value === value;
111
-
112
- // Call onValueChange function when RadioGroupItem changes
113
- const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
114
- if (radioGroup.onValueChange) {
115
- radioGroup.onValueChange(e.target.value);
116
- }
117
-
118
- if (props.onChange) {
119
- props.onChange(e);
120
- }
121
- };
122
-
123
- return (
124
- <div className="relative flex items-center">
125
- <input
126
- type="radio"
127
- id={radioId}
128
- ref={ref}
129
- value={value}
130
- checked={isChecked}
131
- disabled={disabled || radioGroup.disabled}
132
- name={radioGroup.name}
133
- onChange={handleChange}
134
- className="sr-only"
135
- {...props}
136
- />
137
- <label
138
- htmlFor={radioId}
139
- className={cn(
140
- MoonUIradioGroupItemVariantsPro({ variant, size }),
141
- "rounded-full",
142
- "focus-visible:ring-primary/50",
143
- "relative inline-flex shrink-0 cursor-pointer items-center justify-center overflow-hidden",
144
- disabled && "cursor-not-allowed opacity-50",
145
- className
146
- )}
147
- >
148
- <span className={cn(
149
- "absolute inset-0 pointer-events-none",
150
- isChecked && "flex items-center justify-center"
151
- )}>
152
- {isChecked && (indicator || <Circle className="h-[60%] w-[60%] fill-current text-current" />)}
153
- </span>
154
- </label>
155
- </div>
156
- );
157
- });
158
- MoonUIRadioGroupItemPro.displayName = "RadioGroupItemPro";
159
-
160
- // Radio Label Component
161
- interface RadioLabelProps extends React.HTMLAttributes<HTMLLabelElement> {
162
- /**
163
- * HTML id for radio button
164
- */
165
- htmlFor?: string;
166
- /**
167
- * Label content
168
- */
169
- children: React.ReactNode;
170
- /**
171
- * Disabled state style
172
- */
173
- disabled?: boolean;
174
- }
175
-
176
- const MoonUIRadioLabelPro = React.forwardRef<HTMLLabelElement, RadioLabelProps>(
177
- ({ className, htmlFor, children, disabled = false, ...props }, ref) => {
178
- return (
179
- <label
180
- ref={ref}
181
- htmlFor={htmlFor}
182
- className={cn(
183
- "text-sm font-medium leading-none ml-2 text-foreground",
184
- disabled && "cursor-not-allowed opacity-70",
185
- className
186
- )}
187
- {...props}
188
- >
189
- {children}
190
- </label>
191
- );
192
- }
193
- );
194
- MoonUIRadioLabelPro.displayName = "RadioLabelPro";
195
-
196
- // Radio Item and Label combination
197
- interface RadioItemWithLabelProps extends RadioGroupItemProps {
198
- /**
199
- * Label content
200
- */
201
- label: React.ReactNode;
202
- /**
203
- * HTML classes for label
204
- */
205
- labelClassName?: string;
206
- /**
207
- * HTML id for radio button
208
- */
209
- id?: string;
210
- /**
211
- * Disabled state
212
- */
213
- disabled?: boolean;
214
- }
215
-
216
- const MoonUIRadioItemWithLabelPro = React.forwardRef<
217
- HTMLInputElement,
218
- RadioItemWithLabelProps
219
- >(({
220
- id,
221
- label,
222
- labelClassName,
223
- ...radioProps
224
- }, ref) => {
225
- const generatedId = React.useId();
226
- const radioId = id || generatedId;
227
-
228
- return (
229
- <div className="flex items-center">
230
- <MoonUIRadioGroupItemPro ref={ref} id={radioId} {...radioProps} />
231
- <MoonUIRadioLabelPro
232
- htmlFor={radioId}
233
- disabled={radioProps.disabled}
234
- className={labelClassName}
235
- >
236
- {label}
237
- </MoonUIRadioLabelPro>
238
- </div>
239
- );
240
- });
241
- MoonUIRadioItemWithLabelPro.displayName = "RadioItemWithLabelPro";
242
-
243
-
244
- // Internal aliases for Pro component usage
245
- export const radioGroupItemVariantsInternal = MoonUIradioGroupItemVariantsPro
246
- export const RadioGroupContextInternal = MoonUIRadioGroupContextPro
247
- export const RadioGroupInternal = MoonUIRadioGroupPro
248
- export const RadioGroupItemInternal = MoonUIRadioGroupItemPro
249
- export const radioGroupInternal = MoonUIRadioGroupPro
250
- export const RadioLabelInternal = MoonUIRadioLabelPro
251
- export const RadioItemWithLabelInternal = MoonUIRadioItemWithLabelPro
252
-
253
- // Pro exports
254
- export { MoonUIradioGroupItemVariantsPro, MoonUIRadioGroupContextPro, MoonUIRadioGroupPro, MoonUIRadioGroupItemPro, MoonUIRadioLabelPro, MoonUIRadioItemWithLabelPro }
255
-
256
- // Clean exports (without MoonUI prefix for easier usage)
257
- export { MoonUIradioGroupItemVariantsPro as radioGroupItemVariants, MoonUIRadioGroupContextPro as RadioGroupContext, MoonUIRadioGroupPro as RadioGroup, MoonUIRadioGroupItemPro as RadioGroupItem, MoonUIRadioLabelPro as RadioLabel, MoonUIRadioItemWithLabelPro as RadioItemWithLabel };
@@ -1,47 +0,0 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
5
- import { cn } from "../../lib/utils"
6
-
7
- const ScrollArea = React.forwardRef<
8
- React.ElementRef<typeof ScrollAreaPrimitive.Root>,
9
- React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
10
- >(({ className, children, ...props }, ref) => (
11
- <ScrollAreaPrimitive.Root
12
- ref={ref}
13
- className={cn("relative overflow-hidden", className)}
14
- {...props}
15
- >
16
- <ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">
17
- {children}
18
- </ScrollAreaPrimitive.Viewport>
19
- <ScrollBar />
20
- <ScrollAreaPrimitive.Corner />
21
- </ScrollAreaPrimitive.Root>
22
- ))
23
- ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName
24
-
25
- const ScrollBar = React.forwardRef<
26
- React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
27
- React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>
28
- >(({ className, orientation = "vertical", ...props }, ref) => (
29
- <ScrollAreaPrimitive.ScrollAreaScrollbar
30
- ref={ref}
31
- orientation={orientation}
32
- className={cn(
33
- "flex touch-none select-none transition-colors",
34
- orientation === "vertical" &&
35
- "h-full w-2.5 border-l border-l-transparent p-[1px]",
36
- orientation === "horizontal" &&
37
- "h-2.5 flex-col border-t border-t-transparent p-[1px]",
38
- className
39
- )}
40
- {...props}
41
- >
42
- <ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border" />
43
- </ScrollAreaPrimitive.ScrollAreaScrollbar>
44
- ))
45
- ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName
46
-
47
- export { ScrollArea, ScrollBar }
@@ -1,378 +0,0 @@
1
- "use client"
2
-
3
- import * as React from "react"
4
- import * as SelectPrimitive from "@radix-ui/react-select"
5
- import { Check, ChevronDown, ChevronUp, Loader2, Search, X } from "lucide-react"
6
-
7
- import { cn } from "../../lib/utils"
8
-
9
- /**
10
- * Premium Select Component
11
- *
12
- * Advanced dropdown/select component with variants, sizes and accessibility features.
13
- * Compatible with dark and light mode, providing a modern user experience with smooth animations.
14
- */
15
-
16
- // Directly re-exporting the Root component
17
- const MoonUISelectPro = SelectPrimitive.Root
18
- MoonUISelectPro.displayName = "MoonUISelectPro"
19
-
20
- const MoonUISelectGroupPro = SelectPrimitive.Group
21
-
22
- const MoonUISelectValuePro = SelectPrimitive.Value
23
-
24
- type SelectTriggerVariant = "standard" | "outline" | "ghost" | "underline";
25
- type SelectTriggerSize = "sm" | "md" | "lg";
26
-
27
- interface MoonUISelectTriggerProProps extends React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger> {
28
- /** Visual variant */
29
- variant?: SelectTriggerVariant;
30
- /** Size */
31
- size?: SelectTriggerSize;
32
- /** Error state */
33
- error?: boolean | string;
34
- /** Success state */
35
- success?: boolean;
36
- /** Loading state */
37
- loading?: boolean;
38
- /** Icon displayed on the left */
39
- leftIcon?: React.ReactNode;
40
- /** Icon displayed on the right (instead of default chevron) */
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;
48
- }
49
-
50
- const MoonUISelectTriggerPro = React.forwardRef<
51
- React.ElementRef<typeof SelectPrimitive.Trigger>,
52
- MoonUISelectTriggerProProps
53
- >(({ className, children, variant = "standard", size = "md", error, success, loading, leftIcon, rightIcon, ...props }, ref) => (
54
- <SelectPrimitive.Trigger
55
- ref={ref}
56
- className={cn(
57
- /* Base styles */
58
- "flex w-full items-center justify-between gap-1 rounded-md transition-all duration-200",
59
- "disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
60
- "focus-visible:outline-none",
61
- /* Error state */
62
- error && "border-error focus-visible:ring-error/30 focus-visible:border-error",
63
- /* Success state */
64
- success && "border-success focus-visible:ring-success/30 focus-visible:border-success",
65
- /* Size variants */
66
- size === "sm" && "h-8 text-xs px-2",
67
- size === "md" && "h-10 text-sm px-3",
68
- size === "lg" && "h-12 text-base px-4",
69
- /* Visual variants */
70
- variant === "standard" && "border border-gray-300 dark:border-gray-700 bg-background dark:bg-gray-900 hover:border-gray-400 dark:hover:border-gray-600 focus-visible:ring-2 focus-visible:ring-primary/30 dark:focus-visible:ring-primary/50 focus-visible:border-primary dark:focus-visible:border-primary",
71
- variant === "outline" && "border border-gray-300 dark:border-gray-700 bg-transparent hover:border-gray-400 dark:hover:border-gray-600 focus-visible:ring-2 focus-visible:ring-primary/30 dark:focus-visible:ring-primary/50 focus-visible:border-primary dark:focus-visible:border-primary",
72
- variant === "ghost" && "border-none bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 focus-visible:ring-2 focus-visible:ring-primary/30 dark:focus-visible:ring-primary/50",
73
- variant === "underline" && "border-t-0 border-l-0 border-r-0 border-b border-gray-300 dark:border-gray-600 rounded-none px-0 hover:border-gray-400 dark:hover:border-gray-500 focus-visible:ring-0 focus-visible:border-b-2 focus-visible:border-primary dark:focus-visible:border-primary",
74
- className
75
- )}
76
- {...props}
77
- disabled={props.disabled || loading}
78
- data-error={error ? true : undefined}
79
- data-success={success ? true : undefined}
80
- data-loading={loading ? true : undefined}
81
- >
82
- <div className="flex items-center flex-1 gap-2">
83
- {leftIcon && (
84
- <span className="flex items-center justify-center text-gray-500 dark:text-gray-400">
85
- {leftIcon}
86
- </span>
87
- )}
88
- {loading ? (
89
- <div className="flex items-center gap-2">
90
- <Loader2 className="h-3.5 w-3.5 animate-spin text-muted-foreground dark:text-gray-400" />
91
- <span className="text-muted-foreground dark:text-gray-400">Loading...</span>
92
- </div>
93
- ) : children}
94
- </div>
95
- {!loading && (
96
- <SelectPrimitive.Icon asChild>
97
- {rightIcon ? (
98
- <span className="opacity-60">{rightIcon}</span>
99
- ) : (
100
- <ChevronDown className="h-4 w-4 opacity-60 transition-transform duration-200 ease-out group-data-[state=open]:rotate-180" />
101
- )}
102
- </SelectPrimitive.Icon>
103
- )}
104
- </SelectPrimitive.Trigger>
105
- ))
106
- MoonUISelectTriggerPro.displayName = SelectPrimitive.Trigger.displayName
107
-
108
- /**
109
- * Scroll Up Button Component
110
- */
111
- const MoonUISelectScrollUpButtonPro = React.forwardRef<
112
- React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
113
- React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
114
- >(({ className, ...props }, ref) => (
115
- <SelectPrimitive.ScrollUpButton
116
- ref={ref}
117
- className={cn(
118
- "flex cursor-default items-center justify-center py-1 text-muted-foreground hover:text-foreground transition-colors",
119
- className
120
- )}
121
- {...props}
122
- >
123
- <ChevronUp className="h-4 w-4" />
124
- </SelectPrimitive.ScrollUpButton>
125
- ))
126
- MoonUISelectScrollUpButtonPro.displayName = SelectPrimitive.ScrollUpButton.displayName
127
-
128
- /**
129
- * Scroll Down Button Component
130
- */
131
- const MoonUISelectScrollDownButtonPro = React.forwardRef<
132
- React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
133
- React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
134
- >(({ className, ...props }, ref) => (
135
- <SelectPrimitive.ScrollDownButton
136
- ref={ref}
137
- className={cn(
138
- "flex cursor-default items-center justify-center py-1 text-muted-foreground hover:text-foreground transition-colors",
139
- className
140
- )}
141
- {...props}
142
- >
143
- <ChevronDown className="h-4 w-4" />
144
- </SelectPrimitive.ScrollDownButton>
145
- ))
146
- MoonUISelectScrollDownButtonPro.displayName =
147
- SelectPrimitive.ScrollDownButton.displayName
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
-
162
- const MoonUISelectContentPro = React.forwardRef<
163
- React.ElementRef<typeof SelectPrimitive.Content>,
164
- MoonUISelectContentProProps
165
- >(({ className, children, position = "popper", side = "bottom", align = "start", 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}
196
- className={cn(
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"],
205
- position === "popper" &&
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
208
- )}
209
- position={position}
210
- side={side}
211
- align={align}
212
- sideOffset={4}
213
- avoidCollisions={true}
214
- collisionPadding={10}
215
- {...props}
216
- >
217
- {enableSearch && (
218
- <div className="p-2 border-b border-gray-200 dark:border-gray-700">
219
- <div className="flex items-center gap-2 px-2 py-1.5 rounded-md bg-gray-100 dark:bg-gray-800">
220
- {searchIcon || <Search className="h-4 w-4 text-gray-500 dark:text-gray-400" />}
221
- <input
222
- type="text"
223
- placeholder={searchPlaceholder}
224
- value={searchValue}
225
- onChange={(e) => setSearchValue(e.target.value)}
226
- className="flex-1 bg-transparent outline-none text-sm placeholder:text-gray-500 dark:placeholder:text-gray-400"
227
- onClick={(e) => e.stopPropagation()}
228
- onKeyDown={(e) => e.stopPropagation()}
229
- />
230
- {searchValue && (
231
- <button
232
- onClick={(e) => {
233
- e.stopPropagation();
234
- setSearchValue("");
235
- }}
236
- className="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
237
- >
238
- <X className="h-3 w-3" />
239
- </button>
240
- )}
241
- </div>
242
- </div>
243
- )}
244
- <MoonUISelectScrollUpButtonPro />
245
- <SelectPrimitive.Viewport
246
- className={cn(
247
- "p-1",
248
- position === "popper" &&
249
- "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
250
- )}
251
- >
252
- {searchLoading ? (
253
- <div className="flex items-center justify-center py-8">
254
- <Loader2 className="h-5 w-5 animate-spin text-gray-400" />
255
- </div>
256
- ) : filteredChildren && React.Children.count(filteredChildren) > 0 ? (
257
- filteredChildren
258
- ) : enableSearch ? (
259
- <div className="py-6 text-center text-sm text-gray-500 dark:text-gray-400">
260
- {noResultsText}
261
- </div>
262
- ) : (
263
- children
264
- )}
265
- </SelectPrimitive.Viewport>
266
- <MoonUISelectScrollDownButtonPro />
267
- </SelectPrimitive.Content>
268
- </SelectPrimitive.Portal>
269
- );
270
- })
271
- MoonUISelectContentPro.displayName = SelectPrimitive.Content.displayName
272
-
273
- const MoonUISelectLabelPro = React.forwardRef<
274
- React.ElementRef<typeof SelectPrimitive.Label>,
275
- React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
276
- >(({ className, ...props }, ref) => (
277
- <SelectPrimitive.Label
278
- ref={ref}
279
- className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
280
- {...props}
281
- />
282
- ))
283
- MoonUISelectLabelPro.displayName = SelectPrimitive.Label.displayName
284
-
285
- type SelectItemVariant = "default" | "subtle" | "destructive" | "success" | "warning";
286
- type SelectItemSize = "sm" | "md" | "lg";
287
-
288
- interface MoonUISelectItemProProps extends React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item> {
289
- /** Visual variant */
290
- variant?: SelectItemVariant;
291
- /** Size */
292
- size?: SelectItemSize;
293
- /** Icon displayed on the right */
294
- rightIcon?: React.ReactNode;
295
- /** Custom indicator icon (instead of default check) */
296
- customIndicator?: React.ReactNode;
297
- /** Enable hover scale animation */
298
- enableHoverScale?: boolean;
299
- /** Description text shown below the main text */
300
- description?: string;
301
- }
302
-
303
- const MoonUISelectItemPro = React.forwardRef<
304
- React.ElementRef<typeof SelectPrimitive.Item>,
305
- MoonUISelectItemProProps
306
- >(({ className, children, variant = "default", size = "md", rightIcon, customIndicator, enableHoverScale, description, ...props }, ref) => (
307
- <SelectPrimitive.Item
308
- ref={ref}
309
- className={cn(
310
- "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",
311
-
312
- /* Size variants */
313
- size === "sm" && "py-1 pl-7 pr-2 text-xs",
314
- size === "md" && "py-1.5 pl-8 pr-2 text-sm",
315
- size === "lg" && "py-2 pl-9 pr-3 text-base",
316
-
317
- /* Color variants */
318
- variant === "default" && "focus:bg-accent focus:text-accent-foreground dark:focus:bg-gray-700 dark:focus:text-gray-100",
319
- variant === "subtle" && "focus:bg-gray-100 dark:focus:bg-gray-800 focus:text-foreground dark:focus:text-gray-200",
320
- variant === "destructive" && "text-error dark:text-red-400 focus:bg-error/10 dark:focus:bg-red-900/20 focus:text-error dark:focus:text-red-300",
321
- 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",
322
- 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",
323
-
324
- /* Hover scale animation */
325
- enableHoverScale && "hover:scale-[1.02] hover:pl-9",
326
-
327
- className
328
- )}
329
- {...props}
330
- >
331
- <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
332
- <SelectPrimitive.ItemIndicator>
333
- {customIndicator || <Check className="h-4 w-4" />}
334
- </SelectPrimitive.ItemIndicator>
335
- </span>
336
-
337
- <div className="flex-1">
338
- <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
339
- {description && (
340
- <p className="text-xs text-gray-500 dark:text-gray-400 mt-0.5">{description}</p>
341
- )}
342
- </div>
343
-
344
- {rightIcon && (
345
- <span className="ml-auto pl-2 opacity-70">
346
- {rightIcon}
347
- </span>
348
- )}
349
- </SelectPrimitive.Item>
350
- ))
351
- MoonUISelectItemPro.displayName = SelectPrimitive.Item.displayName
352
-
353
- const MoonUISelectSeparatorPro = React.forwardRef<
354
- React.ElementRef<typeof SelectPrimitive.Separator>,
355
- React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
356
- >(({ className, ...props }, ref) => (
357
- <SelectPrimitive.Separator
358
- ref={ref}
359
- className={cn("-mx-1 my-1 h-px bg-muted dark:bg-gray-700", className)}
360
- {...props}
361
- />
362
- ))
363
- MoonUISelectSeparatorPro.displayName = SelectPrimitive.Separator.displayName
364
-
365
- export { MoonUISelectPro,
366
- MoonUISelectGroupPro,
367
- MoonUISelectValuePro,
368
- MoonUISelectTriggerPro,
369
- MoonUISelectContentPro,
370
- MoonUISelectLabelPro,
371
- MoonUISelectItemPro,
372
- MoonUISelectSeparatorPro,
373
- MoonUISelectScrollUpButtonPro as SelectScrollUpButton,
374
- MoonUISelectScrollDownButtonPro as SelectScrollDownButton,
375
- };
376
-
377
- // Backward compatibility exports
378
- export { MoonUISelectPro as Select, MoonUISelectTriggerPro as SelectTrigger, MoonUISelectContentPro as SelectContent, MoonUISelectItemPro as SelectItem, MoonUISelectValuePro as SelectValue, MoonUISelectGroupPro as SelectGroup, MoonUISelectLabelPro as SelectLabel, MoonUISelectSeparatorPro as SelectSeparator }