nexoreui-cli 0.1.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.
package/dist/index.js ADDED
@@ -0,0 +1,999 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
+ // If the importer is in node compatibility mode or this is not an ESM
19
+ // file that has been converted to a CommonJS file using a Babel-
20
+ // compatible transform (i.e. "__esModule" has not been set), then set
21
+ // "default" to the CommonJS "module.exports" for node compatibility.
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
+ mod
24
+ ));
25
+
26
+ // src/commands/add.ts
27
+ var fs3 = __toESM(require("fs"));
28
+ var path3 = __toESM(require("path"));
29
+
30
+ // src/registry/button.ts
31
+ var button = {
32
+ name: "button",
33
+ dependencies: [
34
+ "class-variance-authority",
35
+ "clsx",
36
+ "tailwind-merge",
37
+ "framer-motion"
38
+ ],
39
+ fileName: "button.tsx",
40
+ content: `'use client';
41
+
42
+ import * as React from 'react';
43
+ import { cva, type VariantProps } from 'class-variance-authority';
44
+ import { cn } from '../utils/cn';
45
+ import { motion, HTMLMotionProps, AnimatePresence } from 'framer-motion';
46
+
47
+ const buttonVariants = cva(
48
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg 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 active:scale-95",
49
+ {
50
+ variants: {
51
+ variant: {
52
+ default: "bg-gradient-to-br from-primary to-primary/80 text-primary-foreground shadow-lg shadow-primary/20 hover:shadow-xl hover:shadow-primary/30",
53
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 border border-border/50",
54
+ destructive: "bg-gradient-to-br from-destructive to-destructive/80 text-destructive-foreground shadow-lg shadow-destructive/20 hover:shadow-xl hover:shadow-destructive/30",
55
+ outline: "border-2 border-input bg-background hover:bg-accent hover:text-accent-foreground hover:border-accent",
56
+ ghost: "hover:bg-accent hover:text-accent-foreground",
57
+ link: "text-primary underline-offset-4 hover:underline",
58
+ // New WOW Variants
59
+ premium: "bg-gradient-to-r from-violet-600 via-pink-600 to-orange-500 text-white shadow-lg shadow-purple-500/20 hover:shadow-xl hover:shadow-purple-500/30",
60
+ neon: "bg-background border-2 border-primary text-foreground shadow-[0_0_15px_rgba(var(--primary-rgb),0.5)] hover:shadow-[0_0_25px_rgba(var(--primary-rgb),0.7)]",
61
+ glass: "backdrop-blur-md bg-white/10 dark:bg-black/20 border border-white/20 dark:border-white/10 text-foreground hover:bg-white/20 dark:hover:bg-black/30 shadow-lg",
62
+ shimmer: "relative overflow-hidden bg-slate-900 text-white dark:bg-white dark:text-black",
63
+ },
64
+ size: {
65
+ default: "h-10 px-5 py-2",
66
+ sm: "h-9 rounded-md px-3 text-xs",
67
+ lg: "h-11 rounded-xl px-8 text-base",
68
+ icon: "h-10 w-10 rounded-full",
69
+ },
70
+ },
71
+ defaultVariants: {
72
+ variant: "default",
73
+ size: "default",
74
+ },
75
+ }
76
+ );
77
+
78
+ export interface ButtonProps
79
+ extends React.ButtonHTMLAttributes<HTMLButtonElement>,
80
+ VariantProps<typeof buttonVariants> {
81
+ /** Enable hover/tap motion animation @default true */
82
+ animate?: boolean;
83
+ /** Enable shimmer light effect across the button */
84
+ shimmer?: boolean;
85
+ /** Enable neon glow effect */
86
+ glow?: boolean;
87
+ children?: React.ReactNode;
88
+ className?: string;
89
+ }
90
+
91
+ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
92
+ ({ className, variant, size, animate = true, shimmer = false, glow = false, children, ...props }, ref) => {
93
+
94
+ const isShimmer = variant === 'shimmer' || shimmer;
95
+
96
+ const buttonContent = (
97
+ <>
98
+ {isShimmer && (
99
+ <motion.div
100
+ className="absolute inset-0 w-[200%] bg-gradient-to-r from-transparent via-white/20 to-transparent"
101
+ initial={{ x: '-100%' }}
102
+ animate={{ x: '100%' }}
103
+ transition={{
104
+ repeat: Infinity,
105
+ repeatType: 'loop',
106
+ duration: 2,
107
+ ease: 'linear',
108
+ }}
109
+ style={{ transform: 'skewX(-20deg)' }}
110
+ />
111
+ )}
112
+ <span className="relative z-10 flex items-center gap-2">{children}</span>
113
+ </>
114
+ );
115
+
116
+ if (!animate) {
117
+ return (
118
+ <button
119
+ className={cn(buttonVariants({ variant, size, className }), isShimmer && "relative overflow-hidden")}
120
+ ref={ref}
121
+ {...props}
122
+ >
123
+ {buttonContent}
124
+ </button>
125
+ );
126
+ }
127
+
128
+ // Destructure HTML-only event handlers that shouldn't go to motion.button
129
+ const { onDrag, onDragStart, onDragEnd, onAnimationStart, ...motionSafeProps } = props;
130
+
131
+ return (
132
+ <motion.button
133
+ className={cn(buttonVariants({ variant, size, className }))}
134
+ ref={ref}
135
+ whileHover={{
136
+ scale: 1.03,
137
+ y: -1,
138
+ }}
139
+ whileTap={{ scale: 0.97 }}
140
+ transition={{ type: "spring", stiffness: 400, damping: 15 }}
141
+ {...motionSafeProps as HTMLMotionProps<"button">}
142
+ >
143
+ {buttonContent}
144
+ </motion.button>
145
+ );
146
+ }
147
+ );
148
+ Button.displayName = "Button";
149
+
150
+ export { Button, buttonVariants };
151
+ `
152
+ };
153
+
154
+ // src/registry/modal.ts
155
+ var modal = {
156
+ name: "modal",
157
+ dependencies: [
158
+ "@radix-ui/react-dialog",
159
+ "class-variance-authority",
160
+ "clsx",
161
+ "tailwind-merge",
162
+ "lucide-react",
163
+ "framer-motion"
164
+ ],
165
+ componentsDependencies: ["button"],
166
+ fileName: "modal.tsx",
167
+ content: `"use client"
168
+
169
+ import * as React from "react"
170
+ import * as DialogPrimitive from "@radix-ui/react-dialog"
171
+ import { X, AlertTriangle, CheckCircle } from "lucide-react"
172
+ import { cn } from "../utils/cn"
173
+ import { Button } from "./button"
174
+
175
+ const Dialog = DialogPrimitive.Root
176
+
177
+ const DialogTrigger = DialogPrimitive.Trigger
178
+
179
+ const DialogPortal = DialogPrimitive.Portal
180
+
181
+ const DialogClose = DialogPrimitive.Close
182
+
183
+ const DialogOverlay = React.forwardRef<
184
+ React.ElementRef<typeof DialogPrimitive.Overlay>,
185
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
186
+ >(({ className, ...props }, ref) => (
187
+ <DialogPrimitive.Overlay
188
+ ref={ref}
189
+ className={cn(
190
+ "fixed inset-0 z-50 bg-black/50 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
191
+ className
192
+ )}
193
+ {...props}
194
+ />
195
+ ))
196
+ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
197
+
198
+ const DialogContent = React.forwardRef<
199
+ React.ElementRef<typeof DialogPrimitive.Content>,
200
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
201
+ >((({ className, children, ...props }, ref) => (
202
+ <DialogPortal>
203
+ <DialogOverlay />
204
+ <DialogPrimitive.Content
205
+ ref={ref}
206
+ className={cn(
207
+ "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border border-border/50 bg-background/95 backdrop-blur-md p-6 shadow-2xl duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:scale-95 data-[state=open]:scale-100 data-[state=closed]:translate-y-[-48%] data-[state=open]:translate-y-[-50%] rounded-2xl",
208
+ className
209
+ )}
210
+ {...props}
211
+ >
212
+ {children}
213
+ <DialogPrimitive.Close className="absolute right-4 top-4 rounded-full p-1 opacity-70 ring-offset-background transition-opacity hover:opacity-100 hover:bg-muted focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none">
214
+ <X className="h-4 w-4" />
215
+ <span className="sr-only">Close</span>
216
+ </DialogPrimitive.Close>
217
+ </DialogPrimitive.Content>
218
+ </DialogPortal>
219
+ ))
220
+ DialogContent.displayName = DialogPrimitive.Content.displayName
221
+
222
+ const DialogHeader = ({
223
+ className,
224
+ ...props
225
+ }: React.HTMLAttributes<HTMLDivElement>) => (
226
+ <div
227
+ className={cn(
228
+ "flex flex-col space-y-1.5 text-center sm:text-left",
229
+ className
230
+ )}
231
+ {...props}
232
+ />
233
+ )
234
+ DialogHeader.displayName = "DialogHeader"
235
+
236
+ const DialogFooter = ({
237
+ className,
238
+ ...props
239
+ }: React.HTMLAttributes<HTMLDivElement>) => (
240
+ <div
241
+ className={cn(
242
+ "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
243
+ className
244
+ )}
245
+ {...props}
246
+ />
247
+ )
248
+ DialogFooter.displayName = "DialogFooter"
249
+
250
+ const DialogTitle = React.forwardRef<
251
+ React.ElementRef<typeof DialogPrimitive.Title>,
252
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
253
+ >(({ className, ...props }, ref) => (
254
+ <DialogPrimitive.Title
255
+ ref={ref}
256
+ className={cn(
257
+ "text-xl font-semibold leading-none tracking-tight bg-gradient-to-br from-foreground to-foreground/70 bg-clip-text text-transparent",
258
+ className
259
+ )}
260
+ {...props}
261
+ />
262
+ ))
263
+ DialogTitle.displayName = DialogPrimitive.Title.displayName
264
+
265
+ const DialogDescription = React.forwardRef<
266
+ React.ElementRef<typeof DialogPrimitive.Description>,
267
+ React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
268
+ >(({ className, ...props }, ref) => (
269
+ <DialogPrimitive.Description
270
+ ref={ref}
271
+ className={cn("text-sm text-muted-foreground leading-relaxed", className)}
272
+ {...props}
273
+ />
274
+ ))
275
+ DialogDescription.displayName = DialogPrimitive.Description.displayName
276
+
277
+ export {
278
+ Dialog,
279
+ DialogPortal,
280
+ DialogOverlay,
281
+ DialogClose,
282
+ DialogTrigger,
283
+ DialogContent,
284
+ DialogHeader,
285
+ DialogFooter,
286
+ DialogTitle,
287
+ DialogDescription,
288
+ }
289
+
290
+ export interface ModalProps {
291
+ /**
292
+ * The title of the modal
293
+ */
294
+ title?: React.ReactNode;
295
+ /**
296
+ * The description of the modal
297
+ */
298
+ description?: React.ReactNode;
299
+ /**
300
+ * The content of the modal
301
+ */
302
+ children?: React.ReactNode;
303
+ /**
304
+ * The trigger element to open the modal
305
+ */
306
+ trigger?: React.ReactNode;
307
+ /**
308
+ * Callback function called when the confirm button is clicked
309
+ */
310
+ onConfirm?: () => void;
311
+ /**
312
+ * Callback function called when the cancel button is clicked
313
+ */
314
+ onCancel?: () => void;
315
+ /**
316
+ * The text for the confirm button
317
+ * @default "Confirm"
318
+ */
319
+ confirmText?: string;
320
+ /**
321
+ * The text for the cancel button
322
+ * @default "Cancel"
323
+ */
324
+ cancelText?: string;
325
+ /**
326
+ * Whether the modal is open
327
+ */
328
+ isOpen?: boolean;
329
+ /**
330
+ * Callback function called when the open state changes
331
+ */
332
+ onOpenChange?: (open: boolean) => void;
333
+ /**
334
+ * The variant of the modal
335
+ * @default "default"
336
+ */
337
+ variant?: "default" | "glass" | "destructive" | "success" | "fullscreen" | "drawer";
338
+ /**
339
+ * Whether the content is scrollable
340
+ * @default false
341
+ */
342
+ scrollable?: boolean;
343
+ /**
344
+ * Additional className for the dialog content
345
+ */
346
+ className?: string;
347
+ }
348
+
349
+ export function Modal({
350
+ title,
351
+ description,
352
+ children,
353
+ trigger,
354
+ onConfirm,
355
+ onCancel,
356
+ confirmText = "Confirm",
357
+ cancelText = "Cancel",
358
+ isOpen,
359
+ onOpenChange,
360
+ variant = "default",
361
+ scrollable = false,
362
+ className,
363
+ }: ModalProps) {
364
+ const variantClasses = {
365
+ default: "",
366
+ glass: "bg-white/10 backdrop-blur-xl border-white/20 shadow-2xl",
367
+ destructive: "border-destructive/20",
368
+ success: "border-green-500/20",
369
+ fullscreen: "max-w-full h-screen rounded-none",
370
+ drawer: "sm:max-w-full sm:h-[50vh] sm:rounded-b-none sm:rounded-t-[20px] fixed bottom-0 top-auto translate-y-0",
371
+ }
372
+
373
+ const isDestructive = variant === "destructive";
374
+ const isSuccess = variant === "success";
375
+
376
+ return (
377
+ <Dialog open={isOpen} onOpenChange={onOpenChange}>
378
+ {trigger && <DialogTrigger asChild>{trigger}</DialogTrigger>}
379
+ <DialogContent className={cn(variantClasses[variant], scrollable ? "max-h-[80vh] overflow-y-auto" : "", className)}>
380
+ {(title || description || isDestructive || isSuccess) && (
381
+ <DialogHeader className={cn((isDestructive || isSuccess) ? "flex flex-col items-center text-center sm:text-center" : "")}>
382
+ {isDestructive && (
383
+ <div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-destructive/10 mb-4">
384
+ <AlertTriangle className="h-6 w-6 text-destructive" />
385
+ </div>
386
+ )}
387
+ {isSuccess && (
388
+ <div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-500/10 mb-4">
389
+ <CheckCircle className="h-6 w-6 text-green-500" />
390
+ </div>
391
+ )}
392
+ {title && <DialogTitle className={cn((isDestructive || isSuccess) ? "text-xl" : "")}>{title}</DialogTitle>}
393
+ {description && <DialogDescription>{description}</DialogDescription>}
394
+ </DialogHeader>
395
+ )}
396
+ <div className="py-4">{children}</div>
397
+ {(onConfirm || onCancel || isDestructive || isSuccess) && (
398
+ <DialogFooter className={cn((isDestructive || isSuccess) ? "sm:justify-center flex-col sm:flex-row gap-2" : "")}>
399
+ {onCancel && (
400
+ <DialogPrimitive.Close asChild>
401
+ <Button variant="outline" className={cn((isDestructive || isSuccess) ? "w-full sm:w-auto" : "")} onClick={onCancel}>{cancelText}</Button>
402
+ </DialogPrimitive.Close>
403
+ )}
404
+ {onConfirm && (
405
+ <Button
406
+ variant={isDestructive ? "destructive" : "default"}
407
+ className={cn((isDestructive || isSuccess) ? "w-full sm:w-auto" : "", isSuccess ? "bg-green-500 hover:bg-green-600" : "")}
408
+ onClick={onConfirm}
409
+ >
410
+ {confirmText}
411
+ </Button>
412
+ )}
413
+ </DialogFooter>
414
+ )}
415
+ </DialogContent>
416
+ </Dialog>
417
+ )
418
+ }
419
+ `
420
+ };
421
+
422
+ // src/registry/card.ts
423
+ var card = {
424
+ name: "card",
425
+ dependencies: [
426
+ "class-variance-authority",
427
+ "clsx",
428
+ "tailwind-merge",
429
+ "framer-motion"
430
+ ],
431
+ fileName: "card.tsx",
432
+ content: `'use client';
433
+
434
+ import * as React from "react"
435
+ import { cn } from "../utils/cn"
436
+ import { motion, HTMLMotionProps } from "framer-motion"
437
+ import { cva, type VariantProps } from "class-variance-authority"
438
+
439
+ const cardVariants = cva(
440
+ "rounded-2xl text-card-foreground transition-all duration-300",
441
+ {
442
+ variants: {
443
+ variant: {
444
+ default: "border bg-card text-card-foreground shadow-sm hover:shadow-md",
445
+ glass: "backdrop-blur-md bg-white/10 dark:bg-black/20 border border-white/20 dark:border-white/10 shadow-lg",
446
+ gradient: "bg-gradient-to-br from-violet-500/10 via-pink-500/10 to-orange-500/10 border border-purple-500/20 shadow-lg shadow-purple-500/5",
447
+ glow: "bg-card border-2 border-primary/20 shadow-[0_0_15px_rgba(var(--primary-rgb),0.1)] hover:shadow-[0_0_25px_rgba(var(--primary-rgb),0.2)]",
448
+ },
449
+ hover: {
450
+ none: "",
451
+ lift: "hover:-translate-y-1 hover:shadow-lg",
452
+ glow: "hover:border-primary/50 hover:shadow-[0_0_20px_rgba(var(--primary-rgb),0.15)]",
453
+ }
454
+ },
455
+ defaultVariants: {
456
+ variant: "default",
457
+ hover: "lift",
458
+ }
459
+ }
460
+ )
461
+
462
+ export interface CardProps
463
+ extends Omit<React.HTMLAttributes<HTMLDivElement>, keyof HTMLMotionProps<"div">>,
464
+ VariantProps<typeof cardVariants> {
465
+ /**
466
+ * Whether to enable hover animations
467
+ * @default true
468
+ */
469
+ animate?: boolean;
470
+ /**
471
+ * The title of the card
472
+ */
473
+ title?: React.ReactNode;
474
+ /**
475
+ * The description of the card
476
+ */
477
+ description?: React.ReactNode;
478
+ /**
479
+ * The footer content of the card
480
+ */
481
+ footer?: React.ReactNode;
482
+ /**
483
+ * An image URL to display at the top of the card
484
+ */
485
+ image?: string;
486
+ }
487
+
488
+ const Card = React.forwardRef<HTMLDivElement, CardProps & HTMLMotionProps<"div">>(
489
+ ({ className, variant, hover, animate = true, title, description, footer, image, children, ...props }, ref) => {
490
+ const isCompound = !title && !description && !footer && !image;
491
+
492
+ const content = isCompound ? (
493
+ children
494
+ ) : (
495
+ <>
496
+ {image && (
497
+ <div className="relative w-full h-48 overflow-hidden rounded-t-2xl">
498
+ <img src={image} alt={typeof title === 'string' ? title : 'Card image'} className="object-cover w-full h-full" />
499
+ </div>
500
+ )}
501
+ {(title || description) && (
502
+ <CardHeader>
503
+ {title && <CardTitle>{title}</CardTitle>}
504
+ {description && <CardDescription>{description}</CardDescription>}
505
+ </CardHeader>
506
+ )}
507
+ {children && <CardContent>{children as React.ReactNode}</CardContent>}
508
+ {footer && <CardFooter>{footer}</CardFooter>}
509
+ </>
510
+ );
511
+
512
+ if (animate) {
513
+ return (
514
+ <motion.div
515
+ ref={ref}
516
+ className={cn(cardVariants({ variant, hover, className }))}
517
+ whileHover={{ scale: 1.01 }}
518
+ transition={{ type: "spring", stiffness: 300, damping: 20 }}
519
+ {...props}
520
+ >
521
+ {content as React.ReactNode}
522
+ </motion.div>
523
+ );
524
+ }
525
+
526
+ return (
527
+ <div
528
+ ref={ref}
529
+ className={cn(cardVariants({ variant, hover, className }))}
530
+ {...(props as React.HTMLAttributes<HTMLDivElement>)}
531
+ >
532
+ {content as React.ReactNode}
533
+ </div>
534
+ );
535
+ }
536
+ )
537
+ Card.displayName = "Card"
538
+
539
+ const CardHeader = React.forwardRef<
540
+ HTMLDivElement,
541
+ React.HTMLAttributes<HTMLDivElement>
542
+ >(({ className, ...props }, ref) => (
543
+ <div
544
+ ref={ref}
545
+ className={cn("flex flex-col space-y-1.5 p-6", className)}
546
+ {...props}
547
+ />
548
+ ))
549
+ CardHeader.displayName = "CardHeader"
550
+
551
+ const CardTitle = React.forwardRef<
552
+ HTMLParagraphElement,
553
+ React.HTMLAttributes<HTMLHeadingElement>
554
+ >(({ className, ...props }, ref) => (
555
+ <h3
556
+ ref={ref}
557
+ className="font-semibold leading-none tracking-tight text-xl bg-gradient-to-br from-foreground to-foreground/70 bg-clip-text text-transparent"
558
+ {...props}
559
+ />
560
+ ))
561
+ CardTitle.displayName = "CardTitle"
562
+
563
+ const CardDescription = React.forwardRef<
564
+ HTMLParagraphElement,
565
+ React.HTMLAttributes<HTMLParagraphElement>
566
+ >(({ className, ...props }, ref) => (
567
+ <p
568
+ ref={ref}
569
+ className={cn("text-sm text-muted-foreground", className)}
570
+ {...props}
571
+ />
572
+ ))
573
+ CardDescription.displayName = "CardDescription"
574
+
575
+ const CardContent = React.forwardRef<
576
+ HTMLDivElement,
577
+ React.HTMLAttributes<HTMLDivElement>
578
+ >(({ className, ...props }, ref) => (
579
+ <div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
580
+ ))
581
+ CardContent.displayName = "CardContent"
582
+
583
+ const CardFooter = React.forwardRef<
584
+ HTMLDivElement,
585
+ React.HTMLAttributes<HTMLDivElement>
586
+ >(({ className, ...props }, ref) => (
587
+ <div
588
+ ref={ref}
589
+ className={cn("flex items-center p-6 pt-0", className)}
590
+ {...props}
591
+ />
592
+ ))
593
+ CardFooter.displayName = "CardFooter"
594
+
595
+ export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
596
+ `
597
+ };
598
+
599
+ // src/registry/alert.ts
600
+ var alert = {
601
+ name: "alert",
602
+ dependencies: [
603
+ "class-variance-authority",
604
+ "clsx",
605
+ "tailwind-merge",
606
+ "framer-motion"
607
+ ],
608
+ fileName: "alert.tsx",
609
+ content: `"use client"
610
+
611
+ import * as React from "react"
612
+ import { cva, type VariantProps } from "class-variance-authority"
613
+ import { cn } from "../utils/cn"
614
+ import { motion, HTMLMotionProps } from "framer-motion"
615
+
616
+ const alertVariants = cva(
617
+ "relative w-full rounded-xl border p-4 [&>svg~*]:pl-7 [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 transition-all duration-300",
618
+ {
619
+ variants: {
620
+ variant: {
621
+ default: "bg-background/50 border-border text-foreground",
622
+ destructive: "border-red-500/20 bg-red-500/10 text-red-600 dark:text-red-400 [&>svg]:text-red-600 dark:[&>svg]:text-red-400",
623
+ success: "border-emerald-500/20 bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 [&>svg]:text-emerald-600 dark:[&>svg]:text-emerald-400",
624
+ warning: "border-amber-500/20 bg-amber-500/10 text-amber-600 dark:text-amber-400 [&>svg]:text-amber-600 dark:[&>svg]:text-amber-400",
625
+ info: "border-blue-500/20 bg-blue-500/10 text-blue-600 dark:text-blue-400 [&>svg]:text-blue-600 dark:[&>svg]:text-blue-400",
626
+ glass: "backdrop-blur-md bg-white/5 dark:bg-black/20 border-white/10 dark:border-white/5 text-foreground",
627
+ },
628
+ },
629
+ defaultVariants: {
630
+ variant: "default",
631
+ },
632
+ }
633
+ )
634
+
635
+ export interface AlertProps
636
+ extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'>,
637
+ VariantProps<typeof alertVariants> {
638
+ /**
639
+ * Whether to enable entry animations
640
+ * @default true
641
+ */
642
+ animate?: boolean;
643
+ /**
644
+ * The title of the alert
645
+ */
646
+ title?: React.ReactNode;
647
+ /**
648
+ * The description of the alert
649
+ */
650
+ description?: React.ReactNode;
651
+ /**
652
+ * An optional icon to display
653
+ */
654
+ icon?: React.ReactNode;
655
+ /**
656
+ * Whether the alert can be dismissed
657
+ */
658
+ dismissible?: boolean;
659
+ /**
660
+ * Callback function called when the alert is dismissed
661
+ */
662
+ onDismiss?: () => void;
663
+ }
664
+
665
+ const Alert = React.forwardRef<HTMLDivElement, AlertProps>(
666
+ ({ className, variant, animate = true, title, description, icon, dismissible, onDismiss, children, ...props }, ref) => {
667
+ const isCompound = !title && !description && !icon;
668
+ const [isOpen, setIsOpen] = React.useState(true);
669
+
670
+ if (!isOpen) return null;
671
+
672
+ const content = isCompound ? (
673
+ children
674
+ ) : (
675
+ <>
676
+ {icon && <div className="absolute left-4 top-4">{icon}</div>}
677
+ <div className={cn(icon ? "pl-7" : "")}>
678
+ {title && <AlertTitle>{title}</AlertTitle>}
679
+ {description && <AlertDescription>{description}</AlertDescription>}
680
+ {!title && !description && children}
681
+ </div>
682
+ {dismissible && (
683
+ <button
684
+ onClick={() => {
685
+ setIsOpen(false);
686
+ onDismiss?.();
687
+ }}
688
+ className="absolute right-4 top-4 opacity-70 hover:opacity-100 transition-opacity"
689
+ aria-label="Dismiss"
690
+ >
691
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
692
+ </button>
693
+ )}
694
+ </>
695
+ );
696
+
697
+ if (animate) {
698
+ return (
699
+ <motion.div
700
+ ref={ref}
701
+ role="alert"
702
+ initial={{ opacity: 0, y: 10 }}
703
+ animate={{ opacity: 1, y: 0 }}
704
+ exit={{ opacity: 0, y: 10 }}
705
+ transition={{ duration: 0.3 }}
706
+ className={cn(alertVariants({ variant }), className)}
707
+ {...(props as unknown as HTMLMotionProps<"div">)}
708
+ >
709
+ {content}
710
+ </motion.div>
711
+ );
712
+ }
713
+
714
+ return (
715
+ <div
716
+ ref={ref}
717
+ role="alert"
718
+ className={cn(alertVariants({ variant }), className)}
719
+ {...props}
720
+ >
721
+ {content}
722
+ </div>
723
+ );
724
+ }
725
+ )
726
+ Alert.displayName = "Alert"
727
+
728
+ const AlertTitle = React.forwardRef<
729
+ HTMLParagraphElement,
730
+ React.HTMLAttributes<HTMLHeadingElement>
731
+ >(({ className, ...props }, ref) => (
732
+ <h5
733
+ ref={ref}
734
+ className={cn("mb-1 font-semibold leading-none tracking-tight text-base", className)}
735
+ {...props}
736
+ />
737
+ ))
738
+ AlertTitle.displayName = "AlertTitle"
739
+
740
+ const AlertDescription = React.forwardRef<
741
+ HTMLParagraphElement,
742
+ React.HTMLAttributes<HTMLParagraphElement>
743
+ >(({ className, ...props }, ref) => (
744
+ <div
745
+ ref={ref}
746
+ className={cn("text-sm opacity-90 [&_p]:leading-relaxed", className)}
747
+ {...props}
748
+ />
749
+ ))
750
+ AlertDescription.displayName = "AlertDescription"
751
+
752
+ export { Alert, AlertTitle, AlertDescription }
753
+ `
754
+ };
755
+
756
+ // src/registry/badge.ts
757
+ var badge = {
758
+ name: "badge",
759
+ dependencies: [
760
+ "class-variance-authority",
761
+ "clsx",
762
+ "tailwind-merge",
763
+ "framer-motion"
764
+ ],
765
+ fileName: "badge.tsx",
766
+ content: `'use client';
767
+
768
+ import * as React from "react"
769
+ import { cva, type VariantProps } from "class-variance-authority"
770
+ import { cn } from "../utils/cn"
771
+ import { motion } from "framer-motion"
772
+
773
+ const badgeVariants = cva(
774
+ "inline-flex items-center gap-1 rounded-full border font-semibold transition-all focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 cursor-default",
775
+ {
776
+ variants: {
777
+ variant: {
778
+ default: "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
779
+ secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
780
+ destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
781
+ outline: "text-foreground border-border hover:bg-accent",
782
+ // New WOW Variants
783
+ gradient: "border-transparent bg-gradient-to-r from-violet-500 to-pink-500 text-white shadow-sm",
784
+ neon: "border-primary/50 bg-primary/10 text-primary shadow-[0_0_10px_rgba(var(--primary-rgb),0.3)]",
785
+ success: "border-transparent bg-emerald-500/20 text-emerald-600 dark:text-emerald-400",
786
+ },
787
+ size: {
788
+ default: "px-2.5 py-0.5 text-xs",
789
+ sm: "px-1.5 py-0.5 text-[10px]",
790
+ lg: "px-3 py-1 text-sm",
791
+ }
792
+ },
793
+ defaultVariants: {
794
+ variant: "default",
795
+ size: "default",
796
+ },
797
+ }
798
+ )
799
+
800
+ export interface BadgeProps
801
+ extends React.HTMLAttributes<HTMLDivElement>,
802
+ VariantProps<typeof badgeVariants> {
803
+ /**
804
+ * Whether to show a pulse animation on the dot
805
+ * @default false
806
+ */
807
+ pulse?: boolean;
808
+ /**
809
+ * Whether to show a dot indicator
810
+ * @default false
811
+ */
812
+ dot?: boolean;
813
+ }
814
+
815
+ function Badge({ className, variant, size, pulse = false, dot = false, children, ...props }: BadgeProps) {
816
+ const showDot = dot || pulse;
817
+
818
+ return (
819
+ <div className={cn(badgeVariants({ variant, size }), className)} {...props}>
820
+ {showDot && (
821
+ <span className="relative flex h-2 w-2 mr-1">
822
+ {pulse && (
823
+ <span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-current opacity-75"></span>
824
+ )}
825
+ <span className="relative inline-flex rounded-full h-2 w-2 bg-current"></span>
826
+ </span>
827
+ )}
828
+ {children}
829
+ </div>
830
+ )
831
+ }
832
+
833
+ export { Badge, badgeVariants }
834
+ `
835
+ };
836
+
837
+ // src/registry/index.ts
838
+ var registry = {
839
+ button,
840
+ modal,
841
+ card,
842
+ alert,
843
+ badge
844
+ };
845
+
846
+ // src/utils/detect.ts
847
+ var fs = __toESM(require("fs"));
848
+ var path = __toESM(require("path"));
849
+ function detectProject() {
850
+ const cwd = process.cwd();
851
+ if (fs.existsSync(path.join(cwd, "next.config.ts")) || fs.existsSync(path.join(cwd, "next.config.js")) || fs.existsSync(path.join(cwd, "next.config.mjs"))) {
852
+ if (fs.existsSync(path.join(cwd, "app"))) {
853
+ return { framework: "Next.js (App Router)", componentsDir: "app/components/ui" };
854
+ }
855
+ if (fs.existsSync(path.join(cwd, "src", "app"))) {
856
+ return { framework: "Next.js (App Router)", componentsDir: "src/app/components/ui" };
857
+ }
858
+ return { framework: "Next.js (Pages Router)", componentsDir: "components/ui" };
859
+ }
860
+ if (fs.existsSync(path.join(cwd, "vite.config.ts")) || fs.existsSync(path.join(cwd, "vite.config.js"))) {
861
+ if (fs.existsSync(path.join(cwd, "src"))) {
862
+ return { framework: "Vite", componentsDir: "src/components/ui" };
863
+ }
864
+ return { framework: "Vite", componentsDir: "components/ui" };
865
+ }
866
+ if (fs.existsSync(path.join(cwd, "src"))) {
867
+ return { framework: "React", componentsDir: "src/components/ui" };
868
+ }
869
+ return { framework: "Unknown", componentsDir: "components/ui" };
870
+ }
871
+
872
+ // src/utils/copy.ts
873
+ var fs2 = __toESM(require("fs"));
874
+ var path2 = __toESM(require("path"));
875
+ function copyComponent(name, entry, outputDir) {
876
+ const filePath = path2.join(outputDir, entry.fileName);
877
+ const dir = path2.dirname(filePath);
878
+ if (!fs2.existsSync(dir)) {
879
+ fs2.mkdirSync(dir, { recursive: true });
880
+ }
881
+ fs2.writeFileSync(filePath, entry.content, "utf-8");
882
+ }
883
+
884
+ // src/commands/add.ts
885
+ async function addCommand(components, options) {
886
+ if (components.length === 0) {
887
+ console.error("\x1B[31mPlease specify at least one component to add.\x1B[0m");
888
+ console.log("Example: npx nexoreui add button modal card");
889
+ console.log("Run \x1B[32mnpx nexoreui list\x1B[0m to see all available components.");
890
+ process.exit(1);
891
+ }
892
+ const invalid = components.filter((c) => !registry[c]);
893
+ if (invalid.length > 0) {
894
+ console.error(`\x1B[31mUnknown component(s): ${invalid.join(", ")}\x1B[0m`);
895
+ console.log("Run \x1B[32mnpx nexoreui list\x1B[0m to see all available components.");
896
+ process.exit(1);
897
+ }
898
+ const projectInfo = detectProject();
899
+ const outputDir = path3.resolve(process.cwd(), projectInfo.componentsDir);
900
+ console.log(`
901
+ \x1B[34m\x1B[1mNexoreUI CLI\x1B[0m`);
902
+ console.log(`Detected: \x1B[36m${projectInfo.framework}\x1B[0m project`);
903
+ console.log(`Output: \x1B[36m${outputDir}\x1B[0m
904
+ `);
905
+ if (!fs3.existsSync(outputDir)) {
906
+ fs3.mkdirSync(outputDir, { recursive: true });
907
+ }
908
+ let successCount = 0;
909
+ for (const name of components) {
910
+ const entry = registry[name];
911
+ if (!entry) continue;
912
+ try {
913
+ copyComponent(name, entry, outputDir);
914
+ console.log(` \x1B[32m\u2713\x1B[0m ${name} \u2192 ${entry.fileName}`);
915
+ successCount++;
916
+ } catch (err) {
917
+ console.error(` \x1B[31m\u2717\x1B[0m ${name}: ${err.message}`);
918
+ }
919
+ }
920
+ const allDeps = /* @__PURE__ */ new Set();
921
+ for (const name of components) {
922
+ const entry = registry[name];
923
+ if (entry?.dependencies) {
924
+ entry.dependencies.forEach((d) => allDeps.add(d));
925
+ }
926
+ }
927
+ console.log(`
928
+ \x1B[32m${successCount} component(s) added successfully.\x1B[0m`);
929
+ if (allDeps.size > 0) {
930
+ console.log(`
931
+ Install peer dependencies:`);
932
+ console.log(` \x1B[36mpnpm add ${Array.from(allDeps).join(" ")}\x1B[0m
933
+ `);
934
+ }
935
+ }
936
+
937
+ // src/commands/list.ts
938
+ function listCommand() {
939
+ const names = Object.keys(registry);
940
+ console.log(`
941
+ \x1B[34m\x1B[1mNexoreUI \u2014 Available Components\x1B[0m
942
+ `);
943
+ names.forEach((name) => {
944
+ const entry = registry[name];
945
+ console.log(` \x1B[32m${name.padEnd(15)}\x1B[0m \u2192 ${entry.fileName}`);
946
+ });
947
+ console.log(`
948
+ \x1B[90mTotal: ${names.length} components\x1B[0m`);
949
+ console.log(`Usage: \x1B[36mnpx nexoreui add ${names[0]}\x1B[0m
950
+ `);
951
+ }
952
+
953
+ // src/index.ts
954
+ async function main() {
955
+ const args = process.argv.slice(2);
956
+ const command = args[0];
957
+ if (!command || command === "-h" || command === "--help") {
958
+ printHelp();
959
+ return;
960
+ }
961
+ if (command === "list") {
962
+ listCommand();
963
+ } else if (command === "add") {
964
+ const components = [];
965
+ let yes = false;
966
+ for (let i = 1; i < args.length; i++) {
967
+ const arg = args[i];
968
+ if (arg === "-y" || arg === "--yes") {
969
+ yes = true;
970
+ } else if (!arg.startsWith("-")) {
971
+ components.push(arg);
972
+ }
973
+ }
974
+ await addCommand(components, { yes });
975
+ } else {
976
+ console.error(`\x1B[31mUnknown command: ${command}\x1B[0m`);
977
+ printHelp();
978
+ }
979
+ }
980
+ function printHelp() {
981
+ console.log(`
982
+ \x1B[34m\x1B[1mNexoreUI CLI\x1B[0m
983
+ Usage:
984
+ npx nexoreui [command] [options]
985
+
986
+ Commands:
987
+ \x1B[32madd [components...]\x1B[0m Add components to your project (e.g., button, modal, card, alert, badge)
988
+ \x1B[32mlist\x1B[0m List all available components
989
+
990
+ Options:
991
+ \x1B[33m-y, --yes\x1B[0m Skip prompts and use default paths
992
+ \x1B[33m-h, --help\x1B[0m Show help information
993
+ `);
994
+ }
995
+ main().catch((err) => {
996
+ console.error("\x1B[31mAn unexpected error occurred:\x1B[0m", err);
997
+ process.exit(1);
998
+ });
999
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/add.ts","../src/registry/button.ts","../src/registry/modal.ts","../src/registry/card.ts","../src/registry/alert.ts","../src/registry/badge.ts","../src/registry/index.ts","../src/utils/detect.ts","../src/utils/copy.ts","../src/commands/list.ts","../src/index.ts"],"sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport { registry } from '../registry/index.js';\nimport { detectProject } from '../utils/detect.js';\nimport { copyComponent } from '../utils/copy.js';\n\nexport async function addCommand(components: string[], options: { yes?: boolean }) {\n if (components.length === 0) {\n console.error('\\x1b[31mPlease specify at least one component to add.\\x1b[0m');\n console.log('Example: npx nexoreui add button modal card');\n console.log('Run \\x1b[32mnpx nexoreui list\\x1b[0m to see all available components.');\n process.exit(1);\n }\n\n // Validate all components exist before starting\n const invalid = components.filter((c) => !registry[c]);\n if (invalid.length > 0) {\n console.error(`\\x1b[31mUnknown component(s): ${invalid.join(', ')}\\x1b[0m`);\n console.log('Run \\x1b[32mnpx nexoreui list\\x1b[0m to see all available components.');\n process.exit(1);\n }\n\n const projectInfo = detectProject();\n const outputDir = path.resolve(process.cwd(), projectInfo.componentsDir);\n\n console.log(`\\n\\x1b[34m\\x1b[1mNexoreUI CLI\\x1b[0m`);\n console.log(`Detected: \\x1b[36m${projectInfo.framework}\\x1b[0m project`);\n console.log(`Output: \\x1b[36m${outputDir}\\x1b[0m\\n`);\n\n // Ensure output directory exists\n if (!fs.existsSync(outputDir)) {\n fs.mkdirSync(outputDir, { recursive: true });\n }\n\n let successCount = 0;\n\n for (const name of components) {\n const entry = registry[name];\n if (!entry) continue;\n\n try {\n copyComponent(name, entry, outputDir);\n console.log(` \\x1b[32m✓\\x1b[0m ${name} → ${entry.fileName}`);\n successCount++;\n } catch (err: any) {\n console.error(` \\x1b[31m✗\\x1b[0m ${name}: ${err.message}`);\n }\n }\n\n // Collect all dependencies\n const allDeps = new Set<string>();\n for (const name of components) {\n const entry = registry[name];\n if (entry?.dependencies) {\n entry.dependencies.forEach((d) => allDeps.add(d));\n }\n }\n\n console.log(`\\n\\x1b[32m${successCount} component(s) added successfully.\\x1b[0m`);\n if (allDeps.size > 0) {\n console.log(`\\nInstall peer dependencies:`);\n console.log(` \\x1b[36mpnpm add ${Array.from(allDeps).join(' ')}\\x1b[0m\\n`);\n }\n}\n","export const button = {\n name: \"button\",\n dependencies: [\n \"class-variance-authority\",\n \"clsx\",\n \"tailwind-merge\",\n \"framer-motion\"\n ],\n fileName: \"button.tsx\",\n content: `'use client';\n\nimport * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../utils/cn';\nimport { motion, HTMLMotionProps, AnimatePresence } from 'framer-motion';\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg 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 active:scale-95\",\n {\n variants: {\n variant: {\n default: \"bg-gradient-to-br from-primary to-primary/80 text-primary-foreground shadow-lg shadow-primary/20 hover:shadow-xl hover:shadow-primary/30\",\n secondary: \"bg-secondary text-secondary-foreground hover:bg-secondary/80 border border-border/50\",\n destructive: \"bg-gradient-to-br from-destructive to-destructive/80 text-destructive-foreground shadow-lg shadow-destructive/20 hover:shadow-xl hover:shadow-destructive/30\",\n outline: \"border-2 border-input bg-background hover:bg-accent hover:text-accent-foreground hover:border-accent\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n // New WOW Variants\n premium: \"bg-gradient-to-r from-violet-600 via-pink-600 to-orange-500 text-white shadow-lg shadow-purple-500/20 hover:shadow-xl hover:shadow-purple-500/30\",\n neon: \"bg-background border-2 border-primary text-foreground shadow-[0_0_15px_rgba(var(--primary-rgb),0.5)] hover:shadow-[0_0_25px_rgba(var(--primary-rgb),0.7)]\",\n glass: \"backdrop-blur-md bg-white/10 dark:bg-black/20 border border-white/20 dark:border-white/10 text-foreground hover:bg-white/20 dark:hover:bg-black/30 shadow-lg\",\n shimmer: \"relative overflow-hidden bg-slate-900 text-white dark:bg-white dark:text-black\",\n },\n size: {\n default: \"h-10 px-5 py-2\",\n sm: \"h-9 rounded-md px-3 text-xs\",\n lg: \"h-11 rounded-xl px-8 text-base\",\n icon: \"h-10 w-10 rounded-full\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n);\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n /** Enable hover/tap motion animation @default true */\n animate?: boolean;\n /** Enable shimmer light effect across the button */\n shimmer?: boolean;\n /** Enable neon glow effect */\n glow?: boolean;\n children?: React.ReactNode;\n className?: string;\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, animate = true, shimmer = false, glow = false, children, ...props }, ref) => {\n \n const isShimmer = variant === 'shimmer' || shimmer;\n\n const buttonContent = (\n <>\n {isShimmer && (\n <motion.div\n className=\"absolute inset-0 w-[200%] bg-gradient-to-r from-transparent via-white/20 to-transparent\"\n initial={{ x: '-100%' }}\n animate={{ x: '100%' }}\n transition={{\n repeat: Infinity,\n repeatType: 'loop',\n duration: 2,\n ease: 'linear',\n }}\n style={{ transform: 'skewX(-20deg)' }}\n />\n )}\n <span className=\"relative z-10 flex items-center gap-2\">{children}</span>\n </>\n );\n\n if (!animate) {\n return (\n <button\n className={cn(buttonVariants({ variant, size, className }), isShimmer && \"relative overflow-hidden\")}\n ref={ref}\n {...props}\n >\n {buttonContent}\n </button>\n );\n }\n\n // Destructure HTML-only event handlers that shouldn't go to motion.button\n const { onDrag, onDragStart, onDragEnd, onAnimationStart, ...motionSafeProps } = props;\n\n return (\n <motion.button\n className={cn(buttonVariants({ variant, size, className }))}\n ref={ref}\n whileHover={{ \n scale: 1.03,\n y: -1,\n }}\n whileTap={{ scale: 0.97 }}\n transition={{ type: \"spring\", stiffness: 400, damping: 15 }}\n {...motionSafeProps as HTMLMotionProps<\"button\">}\n >\n {buttonContent}\n </motion.button>\n );\n }\n);\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants };\n`\n};\n","export const modal = {\n name: \"modal\",\n dependencies: [\n \"@radix-ui/react-dialog\",\n \"class-variance-authority\",\n \"clsx\",\n \"tailwind-merge\",\n \"lucide-react\",\n \"framer-motion\"\n ],\n componentsDependencies: [\"button\"],\n fileName: \"modal.tsx\",\n content: `\"use client\"\n\nimport * as React from \"react\"\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\"\nimport { X, AlertTriangle, CheckCircle } from \"lucide-react\"\nimport { cn } from \"../utils/cn\"\nimport { Button } from \"./button\"\n\nconst Dialog = DialogPrimitive.Root\n\nconst DialogTrigger = DialogPrimitive.Trigger\n\nconst DialogPortal = DialogPrimitive.Portal\n\nconst DialogClose = DialogPrimitive.Close\n\nconst DialogOverlay = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Overlay\n ref={ref}\n className={cn(\n \"fixed inset-0 z-50 bg-black/50 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className\n )}\n {...props}\n />\n))\nDialogOverlay.displayName = DialogPrimitive.Overlay.displayName\n\nconst DialogContent = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>\n>((({ className, children, ...props }, ref) => (\n <DialogPortal>\n <DialogOverlay />\n <DialogPrimitive.Content\n ref={ref}\n className={cn(\n \"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border border-border/50 bg-background/95 backdrop-blur-md p-6 shadow-2xl duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:scale-95 data-[state=open]:scale-100 data-[state=closed]:translate-y-[-48%] data-[state=open]:translate-y-[-50%] rounded-2xl\",\n className\n )}\n {...props}\n >\n {children}\n <DialogPrimitive.Close className=\"absolute right-4 top-4 rounded-full p-1 opacity-70 ring-offset-background transition-opacity hover:opacity-100 hover:bg-muted focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none\">\n <X className=\"h-4 w-4\" />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n </DialogPrimitive.Content>\n </DialogPortal>\n))\nDialogContent.displayName = DialogPrimitive.Content.displayName\n\nconst DialogHeader = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex flex-col space-y-1.5 text-center sm:text-left\",\n className\n )}\n {...props}\n />\n)\nDialogHeader.displayName = \"DialogHeader\"\n\nconst DialogFooter = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\",\n className\n )}\n {...props}\n />\n)\nDialogFooter.displayName = \"DialogFooter\"\n\nconst DialogTitle = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Title\n ref={ref}\n className={cn(\n \"text-xl font-semibold leading-none tracking-tight bg-gradient-to-br from-foreground to-foreground/70 bg-clip-text text-transparent\",\n className\n )}\n {...props}\n />\n))\nDialogTitle.displayName = DialogPrimitive.Title.displayName\n\nconst DialogDescription = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Description\n ref={ref}\n className={cn(\"text-sm text-muted-foreground leading-relaxed\", className)}\n {...props}\n />\n))\nDialogDescription.displayName = DialogPrimitive.Description.displayName\n\nexport {\n Dialog,\n DialogPortal,\n DialogOverlay,\n DialogClose,\n DialogTrigger,\n DialogContent,\n DialogHeader,\n DialogFooter,\n DialogTitle,\n DialogDescription,\n}\n\nexport interface ModalProps {\n /**\n * The title of the modal\n */\n title?: React.ReactNode;\n /**\n * The description of the modal\n */\n description?: React.ReactNode;\n /**\n * The content of the modal\n */\n children?: React.ReactNode;\n /**\n * The trigger element to open the modal\n */\n trigger?: React.ReactNode;\n /**\n * Callback function called when the confirm button is clicked\n */\n onConfirm?: () => void;\n /**\n * Callback function called when the cancel button is clicked\n */\n onCancel?: () => void;\n /**\n * The text for the confirm button\n * @default \"Confirm\"\n */\n confirmText?: string;\n /**\n * The text for the cancel button\n * @default \"Cancel\"\n */\n cancelText?: string;\n /**\n * Whether the modal is open\n */\n isOpen?: boolean;\n /**\n * Callback function called when the open state changes\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * The variant of the modal\n * @default \"default\"\n */\n variant?: \"default\" | \"glass\" | \"destructive\" | \"success\" | \"fullscreen\" | \"drawer\";\n /**\n * Whether the content is scrollable\n * @default false\n */\n scrollable?: boolean;\n /**\n * Additional className for the dialog content\n */\n className?: string;\n}\n\nexport function Modal({\n title,\n description,\n children,\n trigger,\n onConfirm,\n onCancel,\n confirmText = \"Confirm\",\n cancelText = \"Cancel\",\n isOpen,\n onOpenChange,\n variant = \"default\",\n scrollable = false,\n className,\n}: ModalProps) {\n const variantClasses = {\n default: \"\",\n glass: \"bg-white/10 backdrop-blur-xl border-white/20 shadow-2xl\",\n destructive: \"border-destructive/20\",\n success: \"border-green-500/20\",\n fullscreen: \"max-w-full h-screen rounded-none\",\n drawer: \"sm:max-w-full sm:h-[50vh] sm:rounded-b-none sm:rounded-t-[20px] fixed bottom-0 top-auto translate-y-0\",\n }\n\n const isDestructive = variant === \"destructive\";\n const isSuccess = variant === \"success\";\n\n return (\n <Dialog open={isOpen} onOpenChange={onOpenChange}>\n {trigger && <DialogTrigger asChild>{trigger}</DialogTrigger>}\n <DialogContent className={cn(variantClasses[variant], scrollable ? \"max-h-[80vh] overflow-y-auto\" : \"\", className)}>\n {(title || description || isDestructive || isSuccess) && (\n <DialogHeader className={cn((isDestructive || isSuccess) ? \"flex flex-col items-center text-center sm:text-center\" : \"\")}>\n {isDestructive && (\n <div className=\"mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-destructive/10 mb-4\">\n <AlertTriangle className=\"h-6 w-6 text-destructive\" />\n </div>\n )}\n {isSuccess && (\n <div className=\"mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-500/10 mb-4\">\n <CheckCircle className=\"h-6 w-6 text-green-500\" />\n </div>\n )}\n {title && <DialogTitle className={cn((isDestructive || isSuccess) ? \"text-xl\" : \"\")}>{title}</DialogTitle>}\n {description && <DialogDescription>{description}</DialogDescription>}\n </DialogHeader>\n )}\n <div className=\"py-4\">{children}</div>\n {(onConfirm || onCancel || isDestructive || isSuccess) && (\n <DialogFooter className={cn((isDestructive || isSuccess) ? \"sm:justify-center flex-col sm:flex-row gap-2\" : \"\")}>\n {onCancel && (\n <DialogPrimitive.Close asChild>\n <Button variant=\"outline\" className={cn((isDestructive || isSuccess) ? \"w-full sm:w-auto\" : \"\")} onClick={onCancel}>{cancelText}</Button>\n </DialogPrimitive.Close>\n )}\n {onConfirm && (\n <Button \n variant={isDestructive ? \"destructive\" : \"default\"} \n className={cn((isDestructive || isSuccess) ? \"w-full sm:w-auto\" : \"\", isSuccess ? \"bg-green-500 hover:bg-green-600\" : \"\")} \n onClick={onConfirm}\n >\n {confirmText}\n </Button>\n )}\n </DialogFooter>\n )}\n </DialogContent>\n </Dialog>\n )\n}\n`\n};\n","export const card = {\n name: \"card\",\n dependencies: [\n \"class-variance-authority\",\n \"clsx\",\n \"tailwind-merge\",\n \"framer-motion\"\n ],\n fileName: \"card.tsx\",\n content: `'use client';\n\nimport * as React from \"react\"\nimport { cn } from \"../utils/cn\"\nimport { motion, HTMLMotionProps } from \"framer-motion\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nconst cardVariants = cva(\n \"rounded-2xl text-card-foreground transition-all duration-300\",\n {\n variants: {\n variant: {\n default: \"border bg-card text-card-foreground shadow-sm hover:shadow-md\",\n glass: \"backdrop-blur-md bg-white/10 dark:bg-black/20 border border-white/20 dark:border-white/10 shadow-lg\",\n gradient: \"bg-gradient-to-br from-violet-500/10 via-pink-500/10 to-orange-500/10 border border-purple-500/20 shadow-lg shadow-purple-500/5\",\n glow: \"bg-card border-2 border-primary/20 shadow-[0_0_15px_rgba(var(--primary-rgb),0.1)] hover:shadow-[0_0_25px_rgba(var(--primary-rgb),0.2)]\",\n },\n hover: {\n none: \"\",\n lift: \"hover:-translate-y-1 hover:shadow-lg\",\n glow: \"hover:border-primary/50 hover:shadow-[0_0_20px_rgba(var(--primary-rgb),0.15)]\",\n }\n },\n defaultVariants: {\n variant: \"default\",\n hover: \"lift\",\n }\n }\n)\n\nexport interface CardProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, keyof HTMLMotionProps<\"div\">>,\n VariantProps<typeof cardVariants> {\n /**\n * Whether to enable hover animations\n * @default true\n */\n animate?: boolean;\n /**\n * The title of the card\n */\n title?: React.ReactNode;\n /**\n * The description of the card\n */\n description?: React.ReactNode;\n /**\n * The footer content of the card\n */\n footer?: React.ReactNode;\n /**\n * An image URL to display at the top of the card\n */\n image?: string;\n}\n\nconst Card = React.forwardRef<HTMLDivElement, CardProps & HTMLMotionProps<\"div\">>(\n ({ className, variant, hover, animate = true, title, description, footer, image, children, ...props }, ref) => {\n const isCompound = !title && !description && !footer && !image;\n \n const content = isCompound ? (\n children\n ) : (\n <>\n {image && (\n <div className=\"relative w-full h-48 overflow-hidden rounded-t-2xl\">\n <img src={image} alt={typeof title === 'string' ? title : 'Card image'} className=\"object-cover w-full h-full\" />\n </div>\n )}\n {(title || description) && (\n <CardHeader>\n {title && <CardTitle>{title}</CardTitle>}\n {description && <CardDescription>{description}</CardDescription>}\n </CardHeader>\n )}\n {children && <CardContent>{children as React.ReactNode}</CardContent>}\n {footer && <CardFooter>{footer}</CardFooter>}\n </>\n );\n\n if (animate) {\n return (\n <motion.div\n ref={ref}\n className={cn(cardVariants({ variant, hover, className }))}\n whileHover={{ scale: 1.01 }}\n transition={{ type: \"spring\", stiffness: 300, damping: 20 }}\n {...props}\n >\n {content as React.ReactNode}\n </motion.div>\n );\n }\n\n return (\n <div\n ref={ref}\n className={cn(cardVariants({ variant, hover, className }))}\n {...(props as React.HTMLAttributes<HTMLDivElement>)}\n >\n {content as React.ReactNode}\n </div>\n );\n }\n)\nCard.displayName = \"Card\"\n\nconst CardHeader = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"flex flex-col space-y-1.5 p-6\", className)}\n {...props}\n />\n))\nCardHeader.displayName = \"CardHeader\"\n\nconst CardTitle = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h3\n ref={ref}\n className=\"font-semibold leading-none tracking-tight text-xl bg-gradient-to-br from-foreground to-foreground/70 bg-clip-text text-transparent\"\n {...props}\n />\n))\nCardTitle.displayName = \"CardTitle\"\n\nconst CardDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <p\n ref={ref}\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n))\nCardDescription.displayName = \"CardDescription\"\n\nconst CardContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div ref={ref} className={cn(\"p-6 pt-0\", className)} {...props} />\n))\nCardContent.displayName = \"CardContent\"\n\nconst CardFooter = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"flex items-center p-6 pt-0\", className)}\n {...props}\n />\n))\nCardFooter.displayName = \"CardFooter\"\n\nexport { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }\n`\n};\n","export const alert = {\n name: \"alert\",\n dependencies: [\n \"class-variance-authority\",\n \"clsx\",\n \"tailwind-merge\",\n \"framer-motion\"\n ],\n fileName: \"alert.tsx\",\n content: `\"use client\"\n\nimport * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"../utils/cn\"\nimport { motion, HTMLMotionProps } from \"framer-motion\"\n\nconst alertVariants = cva(\n \"relative w-full rounded-xl border p-4 [&>svg~*]:pl-7 [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 transition-all duration-300\",\n {\n variants: {\n variant: {\n default: \"bg-background/50 border-border text-foreground\",\n destructive: \"border-red-500/20 bg-red-500/10 text-red-600 dark:text-red-400 [&>svg]:text-red-600 dark:[&>svg]:text-red-400\",\n success: \"border-emerald-500/20 bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 [&>svg]:text-emerald-600 dark:[&>svg]:text-emerald-400\",\n warning: \"border-amber-500/20 bg-amber-500/10 text-amber-600 dark:text-amber-400 [&>svg]:text-amber-600 dark:[&>svg]:text-amber-400\",\n info: \"border-blue-500/20 bg-blue-500/10 text-blue-600 dark:text-blue-400 [&>svg]:text-blue-600 dark:[&>svg]:text-blue-400\",\n glass: \"backdrop-blur-md bg-white/5 dark:bg-black/20 border-white/10 dark:border-white/5 text-foreground\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nexport interface AlertProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'>,\n VariantProps<typeof alertVariants> {\n /**\n * Whether to enable entry animations\n * @default true\n */\n animate?: boolean;\n /**\n * The title of the alert\n */\n title?: React.ReactNode;\n /**\n * The description of the alert\n */\n description?: React.ReactNode;\n /**\n * An optional icon to display\n */\n icon?: React.ReactNode;\n /**\n * Whether the alert can be dismissed\n */\n dismissible?: boolean;\n /**\n * Callback function called when the alert is dismissed\n */\n onDismiss?: () => void;\n}\n\nconst Alert = React.forwardRef<HTMLDivElement, AlertProps>(\n ({ className, variant, animate = true, title, description, icon, dismissible, onDismiss, children, ...props }, ref) => {\n const isCompound = !title && !description && !icon;\n const [isOpen, setIsOpen] = React.useState(true);\n\n if (!isOpen) return null;\n\n const content = isCompound ? (\n children\n ) : (\n <>\n {icon && <div className=\"absolute left-4 top-4\">{icon}</div>}\n <div className={cn(icon ? \"pl-7\" : \"\")}>\n {title && <AlertTitle>{title}</AlertTitle>}\n {description && <AlertDescription>{description}</AlertDescription>}\n {!title && !description && children}\n </div>\n {dismissible && (\n <button\n onClick={() => {\n setIsOpen(false);\n onDismiss?.();\n }}\n className=\"absolute right-4 top-4 opacity-70 hover:opacity-100 transition-opacity\"\n aria-label=\"Dismiss\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"><path d=\"M18 6 6 18\"/><path d=\"m6 6 12 12\"/></svg>\n </button>\n )}\n </>\n );\n\n if (animate) {\n return (\n <motion.div\n ref={ref}\n role=\"alert\"\n initial={{ opacity: 0, y: 10 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 10 }}\n transition={{ duration: 0.3 }}\n className={cn(alertVariants({ variant }), className)}\n {...(props as unknown as HTMLMotionProps<\"div\">)}\n >\n {content}\n </motion.div>\n );\n }\n\n return (\n <div\n ref={ref}\n role=\"alert\"\n className={cn(alertVariants({ variant }), className)}\n {...props}\n >\n {content}\n </div>\n );\n }\n)\nAlert.displayName = \"Alert\"\n\nconst AlertTitle = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h5\n ref={ref}\n className={cn(\"mb-1 font-semibold leading-none tracking-tight text-base\", className)}\n {...props}\n />\n))\nAlertTitle.displayName = \"AlertTitle\"\n\nconst AlertDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\"text-sm opacity-90 [&_p]:leading-relaxed\", className)}\n {...props}\n />\n))\nAlertDescription.displayName = \"AlertDescription\"\n\nexport { Alert, AlertTitle, AlertDescription }\n`\n};\n","export const badge = {\n name: \"badge\",\n dependencies: [\n \"class-variance-authority\",\n \"clsx\",\n \"tailwind-merge\",\n \"framer-motion\"\n ],\n fileName: \"badge.tsx\",\n content: `'use client';\n\nimport * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { cn } from \"../utils/cn\"\nimport { motion } from \"framer-motion\"\n\nconst badgeVariants = cva(\n \"inline-flex items-center gap-1 rounded-full border font-semibold transition-all focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 cursor-default\",\n {\n variants: {\n variant: {\n default: \"border-transparent bg-primary text-primary-foreground hover:bg-primary/80\",\n secondary: \"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n destructive: \"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80\",\n outline: \"text-foreground border-border hover:bg-accent\",\n // New WOW Variants\n gradient: \"border-transparent bg-gradient-to-r from-violet-500 to-pink-500 text-white shadow-sm\",\n neon: \"border-primary/50 bg-primary/10 text-primary shadow-[0_0_10px_rgba(var(--primary-rgb),0.3)]\",\n success: \"border-transparent bg-emerald-500/20 text-emerald-600 dark:text-emerald-400\",\n },\n size: {\n default: \"px-2.5 py-0.5 text-xs\",\n sm: \"px-1.5 py-0.5 text-[10px]\",\n lg: \"px-3 py-1 text-sm\",\n }\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nexport interface BadgeProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof badgeVariants> {\n /**\n * Whether to show a pulse animation on the dot\n * @default false\n */\n pulse?: boolean;\n /**\n * Whether to show a dot indicator\n * @default false\n */\n dot?: boolean;\n}\n\nfunction Badge({ className, variant, size, pulse = false, dot = false, children, ...props }: BadgeProps) {\n const showDot = dot || pulse;\n \n return (\n <div className={cn(badgeVariants({ variant, size }), className)} {...props}>\n {showDot && (\n <span className=\"relative flex h-2 w-2 mr-1\">\n {pulse && (\n <span className=\"animate-ping absolute inline-flex h-full w-full rounded-full bg-current opacity-75\"></span>\n )}\n <span className=\"relative inline-flex rounded-full h-2 w-2 bg-current\"></span>\n </span>\n )}\n {children}\n </div>\n )\n}\n\nexport { Badge, badgeVariants }\n`\n};\n","import { button } from './button';\nimport { modal } from './modal';\nimport { card } from './card';\nimport { alert } from './alert';\nimport { badge } from './badge';\n\nexport interface RegistryItem {\n name: string;\n dependencies: string[];\n componentsDependencies?: string[];\n fileName: string;\n content: string;\n}\n\nexport const registry: Record<string, RegistryItem> = {\n button,\n modal,\n card,\n alert,\n badge,\n};\n","import * as fs from 'fs';\nimport * as path from 'path';\n\ninterface ProjectInfo {\n framework: string;\n componentsDir: string;\n}\n\nexport function detectProject(): ProjectInfo {\n const cwd = process.cwd();\n\n // Check for Next.js (app router)\n if (fs.existsSync(path.join(cwd, 'next.config.ts')) || fs.existsSync(path.join(cwd, 'next.config.js')) || fs.existsSync(path.join(cwd, 'next.config.mjs'))) {\n // app/ directory = App Router\n if (fs.existsSync(path.join(cwd, 'app'))) {\n return { framework: 'Next.js (App Router)', componentsDir: 'app/components/ui' };\n }\n // src/app/ directory\n if (fs.existsSync(path.join(cwd, 'src', 'app'))) {\n return { framework: 'Next.js (App Router)', componentsDir: 'src/app/components/ui' };\n }\n // pages/ directory = Pages Router\n return { framework: 'Next.js (Pages Router)', componentsDir: 'components/ui' };\n }\n\n // Check for Vite\n if (fs.existsSync(path.join(cwd, 'vite.config.ts')) || fs.existsSync(path.join(cwd, 'vite.config.js'))) {\n if (fs.existsSync(path.join(cwd, 'src'))) {\n return { framework: 'Vite', componentsDir: 'src/components/ui' };\n }\n return { framework: 'Vite', componentsDir: 'components/ui' };\n }\n\n // Check for src directory (generic React)\n if (fs.existsSync(path.join(cwd, 'src'))) {\n return { framework: 'React', componentsDir: 'src/components/ui' };\n }\n\n // Fallback\n return { framework: 'Unknown', componentsDir: 'components/ui' };\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport type { RegistryItem } from '../registry/index.js';\n\nexport function copyComponent(name: string, entry: RegistryItem, outputDir: string) {\n const filePath = path.join(outputDir, entry.fileName);\n const dir = path.dirname(filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(filePath, entry.content, 'utf-8');\n}\n","import { registry } from '../registry/index.js';\n\nexport function listCommand() {\n const names = Object.keys(registry);\n console.log(`\\n\\x1b[34m\\x1b[1mNexoreUI — Available Components\\x1b[0m\\n`);\n names.forEach((name) => {\n const entry = registry[name];\n console.log(` \\x1b[32m${name.padEnd(15)}\\x1b[0m → ${entry.fileName}`);\n });\n console.log(`\\n\\x1b[90mTotal: ${names.length} components\\x1b[0m`);\n console.log(`Usage: \\x1b[36mnpx nexoreui add ${names[0]}\\x1b[0m\\n`);\n}\n","import { addCommand } from './commands/add.js';\nimport { listCommand } from './commands/list.js';\n\nasync function main() {\n const args = process.argv.slice(2);\n const command = args[0];\n\n if (!command || command === '-h' || command === '--help') {\n printHelp();\n return;\n }\n\n if (command === 'list') {\n listCommand();\n } else if (command === 'add') {\n const components: string[] = [];\n let yes = false;\n\n for (let i = 1; i < args.length; i++) {\n const arg = args[i];\n if (arg === '-y' || arg === '--yes') {\n yes = true;\n } else if (!arg.startsWith('-')) {\n components.push(arg);\n }\n }\n\n await addCommand(components, { yes });\n } else {\n console.error(`\\x1b[31mUnknown command: ${command}\\x1b[0m`);\n printHelp();\n }\n}\n\nfunction printHelp() {\n console.log(`\n\\x1b[34m\\x1b[1mNexoreUI CLI\\x1b[0m\nUsage:\n npx nexoreui [command] [options]\n\nCommands:\n \\x1b[32madd [components...]\\x1b[0m Add components to your project (e.g., button, modal, card, alert, badge)\n \\x1b[32mlist\\x1b[0m List all available components\n\nOptions:\n \\x1b[33m-y, --yes\\x1b[0m Skip prompts and use default paths\n \\x1b[33m-h, --help\\x1b[0m Show help information\n `);\n}\n\nmain().catch((err) => {\n console.error('\\x1b[31mAn unexpected error occurred:\\x1b[0m', err);\n process.exit(1);\n});\n"],"mappings":"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","names":["fs","path","fs","path"]}
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "nexoreui-cli",
3
+ "version": "0.1.0",
4
+ "description": "CLI to install NexoreUI components individually",
5
+ "bin": {
6
+ "nexoreui": "./dist/index.js"
7
+ },
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "main": "./dist/index.js",
12
+ "scripts": {
13
+ "build": "tsup",
14
+ "dev": "tsup --watch"
15
+ },
16
+ "devDependencies": {
17
+ "tsup": "^8.0.2",
18
+ "typescript": "^5.4.5",
19
+ "@types/node": "^20.17.6"
20
+ }
21
+ }