nexoreui-cli 0.1.1 → 1.6.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 CHANGED
@@ -146,20 +146,20 @@ const buttonVariants = cva(
146
146
  {
147
147
  variants: {
148
148
  variant: {
149
- default: "bg-gradient-to-br from-primary to-primary/80 text-primary-foreground shadow-lg shadow-primary/10 hover:shadow-xl hover:shadow-primary/20",
149
+ default: "bg-primary text-primary-foreground shadow-sm hover:bg-primary/90",
150
150
  secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 border border-border/50",
151
- destructive: "bg-gradient-to-br from-destructive to-destructive/80 text-destructive-foreground shadow-lg shadow-destructive/10 hover:shadow-xl hover:shadow-destructive/20",
152
- outline: "border-2 border-input bg-background hover:bg-accent hover:text-accent-foreground hover:border-accent",
151
+ destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90 shadow-sm",
152
+ outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
153
153
  ghost: "hover:bg-accent hover:text-accent-foreground",
154
154
  link: "text-primary underline-offset-4 hover:underline",
155
155
  // Premium variants
156
156
  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",
157
- neon: "bg-background border-2 border-primary text-foreground shadow-[0_0_15px_rgba(var(--primary-rgb),0.3)] hover:shadow-[0_0_25px_rgba(var(--primary-rgb),0.5)]",
158
- 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",
157
+ neon: "bg-background border-2 border-primary text-foreground shadow-[0_0_var(--glow-radius)_rgba(var(--glow-color),var(--glow-strength))] hover:shadow-[0_0_calc(var(--glow-radius)*1.5)_rgba(var(--glow-color),calc(var(--glow-strength)*1.5))]",
158
+ glass: "backdrop-blur-md bg-zinc-900/10 dark:bg-zinc-100/10 border border-zinc-900/20 dark:border-zinc-100/20 text-zinc-900 dark:text-zinc-50 hover:bg-zinc-900/20 dark:hover:bg-zinc-100/20 shadow-md",
159
159
  shimmer: "relative overflow-hidden bg-slate-900 text-white dark:bg-white dark:text-black",
160
160
  // New requested variants
161
- gradient: "bg-gradient-to-r from-indigo-500 via-purple-500 to-violet-600 text-white shadow-lg shadow-indigo-500/20 hover:shadow-xl hover:shadow-indigo-500/30 hover:opacity-95",
162
- glow: "bg-primary text-primary-foreground shadow-[0_0_12px_rgba(var(--primary-rgb),0.3)] hover:shadow-[0_0_24px_rgba(var(--primary-rgb),0.6)] border border-primary/20",
161
+ gradient: "bg-gradient-to-r from-indigo-600 via-purple-600 to-violet-600 dark:from-indigo-500 dark:via-purple-500 dark:to-violet-500 text-white shadow-lg shadow-indigo-500/20 hover:shadow-xl hover:shadow-indigo-500/30 hover:opacity-95",
162
+ glow: "bg-primary text-primary-foreground shadow-[0_0_var(--glow-radius)_rgba(var(--glow-color),var(--glow-strength))] hover:shadow-[0_0_calc(var(--glow-radius)*1.5)_rgba(var(--glow-color),calc(var(--glow-strength)*1.5))] border border-primary/20",
163
163
  magnetic: "bg-gradient-to-br from-violet-600 to-indigo-600 text-white shadow-md hover:shadow-lg",
164
164
  loading: "bg-primary/80 text-primary-foreground/80 pointer-events-none cursor-wait",
165
165
  },
@@ -277,7 +277,7 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
277
277
  const resolvedClassName = cn(
278
278
  buttonVariants({ variant: activeVariant, size, className }),
279
279
  isShimmer && "relative overflow-hidden",
280
- isGlow && "shadow-[0_0_15px_rgba(var(--primary-rgb),0.4)]"
280
+ isGlow && "shadow-[0_0_var(--glow-radius)_rgba(var(--glow-color),var(--glow-strength))]"
281
281
  );
282
282
 
283
283
  if (!animate) {
@@ -304,7 +304,7 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
304
304
  whileHover={{
305
305
  scale: isMagnetic ? 1.02 : 1.03,
306
306
  y: isMagnetic ? 0 : -1.5,
307
- shadow: isGlow ? "0 0 25px rgba(var(--primary-rgb), 0.7)" : undefined,
307
+ shadow: isGlow ? "0 0 calc(var(--glow-radius)*1.5) rgba(var(--glow-color), calc(var(--glow-strength)*1.5))" : undefined,
308
308
  }}
309
309
  whileTap={{ scale: 0.97 }}
310
310
  transition={{
@@ -325,9 +325,12 @@ Button.displayName = "Button";
325
325
  export { Button, buttonVariants };
326
326
 
327
327
  // ----------------------------------------------------
328
- // Merged button components for backward compatibility
328
+ // Deprecated button wrappers for backward compatibility
329
329
  // ----------------------------------------------------
330
330
 
331
+ /**
332
+ * @deprecated Use the unified \`<Button variant="neon">\` instead.
333
+ */
331
334
  export const NeonButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
332
335
  ({ children, ...props }, ref) => (
333
336
  <Button ref={ref} variant="neon" glow={true} {...props}>
@@ -337,6 +340,9 @@ export const NeonButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
337
340
  );
338
341
  NeonButton.displayName = "NeonButton";
339
342
 
343
+ /**
344
+ * @deprecated Use custom styles or class variance utilities on the unified \`<Button>\` instead.
345
+ */
340
346
  export const ThreeDButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
341
347
  ({ children, className, ...props }, ref) => (
342
348
  <Button
@@ -353,6 +359,9 @@ export const ThreeDButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
353
359
  );
354
360
  ThreeDButton.displayName = "ThreeDButton";
355
361
 
362
+ /**
363
+ * @deprecated Use custom ripple animations on the unified \`<Button>\` instead.
364
+ */
356
365
  export const RippleButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
357
366
  ({ children, className, ...props }, ref) => (
358
367
  <Button
@@ -370,6 +379,9 @@ export const RippleButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
370
379
  );
371
380
  RippleButton.displayName = "RippleButton";
372
381
 
382
+ /**
383
+ * @deprecated Use standard utility classes on the unified \`<Button>\` instead.
384
+ */
373
385
  export const CyberpunkButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
374
386
  ({ children, className, ...props }, ref) => (
375
387
  <Button
@@ -386,6 +398,9 @@ export const CyberpunkButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
386
398
  );
387
399
  CyberpunkButton.displayName = "CyberpunkButton";
388
400
 
401
+ /**
402
+ * @deprecated Use the unified \`<Button variant="magnetic">\` instead.
403
+ */
389
404
  export const MagneticButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
390
405
  ({ children, ...props }, ref) => (
391
406
  <Button ref={ref} variant="magnetic" {...props}>
@@ -395,6 +410,9 @@ export const MagneticButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
395
410
  );
396
411
  MagneticButton.displayName = "MagneticButton";
397
412
 
413
+ /**
414
+ * @deprecated Use the unified \`<Button variant="shimmer">\` instead.
415
+ */
398
416
  export const ShimmerButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
399
417
  ({ children, ...props }, ref) => (
400
418
  <Button ref={ref} variant="shimmer" shimmer={true} {...props}>
@@ -404,6 +422,9 @@ export const ShimmerButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
404
422
  );
405
423
  ShimmerButton.displayName = "ShimmerButton";
406
424
 
425
+ /**
426
+ * @deprecated Use a custom hover effect on the unified \`<Button>\` instead.
427
+ */
407
428
  export const BorderBeamButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
408
429
  ({ children, className, ...props }, ref) => (
409
430
  <Button
@@ -423,6 +444,9 @@ export const BorderBeamButton = React.forwardRef<HTMLButtonElement, ButtonProps>
423
444
  );
424
445
  BorderBeamButton.displayName = "BorderBeamButton";
425
446
 
447
+ /**
448
+ * @deprecated Use the unified \`<Button isLoading={...}>\` instead.
449
+ */
426
450
  export const LoadingButton = React.forwardRef<HTMLButtonElement, ButtonProps & { isLoading?: boolean }>(
427
451
  ({ children, isLoading = true, ...props }, ref) => (
428
452
  <Button ref={ref} isLoading={isLoading} {...props}>
@@ -432,6 +456,9 @@ export const LoadingButton = React.forwardRef<HTMLButtonElement, ButtonProps & {
432
456
  );
433
457
  LoadingButton.displayName = "LoadingButton";
434
458
 
459
+ /**
460
+ * @deprecated Use the unified \`<Button variant="destructive" glow>\` instead.
461
+ */
435
462
  export const DestructiveGlowButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
436
463
  ({ children, ...props }, ref) => (
437
464
  <Button ref={ref} variant="destructive" glow={true} {...props}>
@@ -441,6 +468,9 @@ export const DestructiveGlowButton = React.forwardRef<HTMLButtonElement, ButtonP
441
468
  );
442
469
  DestructiveGlowButton.displayName = "DestructiveGlowButton";
443
470
 
471
+ /**
472
+ * @deprecated Use the unified \`<Button variant="outline">\` instead.
473
+ */
444
474
  export const GhostOutlineButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
445
475
  ({ children, ...props }, ref) => (
446
476
  <Button ref={ref} variant="outline" {...props}>
@@ -450,6 +480,9 @@ export const GhostOutlineButton = React.forwardRef<HTMLButtonElement, ButtonProp
450
480
  );
451
481
  GhostOutlineButton.displayName = "GhostOutlineButton";
452
482
 
483
+ /**
484
+ * @deprecated Use the unified \`<Button variant="glow">\` instead.
485
+ */
453
486
  export const GlowButton = React.forwardRef<HTMLButtonElement, ButtonProps & { glowColor?: string }>(
454
487
  ({ children, glowColor = "rgba(139, 92, 246, 0.15)", className, ...props }, ref) => (
455
488
  <div className="relative group inline-block">
@@ -465,6 +498,9 @@ export const GlowButton = React.forwardRef<HTMLButtonElement, ButtonProps & { gl
465
498
  );
466
499
  GlowButton.displayName = "GlowButton";
467
500
 
501
+ /**
502
+ * @deprecated Use the unified \`<Button shimmer>\` instead.
503
+ */
468
504
  export const ShinyButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
469
505
  ({ children, ...props }, ref) => (
470
506
  <Button ref={ref} shimmer={true} {...props}>
@@ -474,6 +510,9 @@ export const ShinyButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
474
510
  );
475
511
  ShinyButton.displayName = "ShinyButton";
476
512
 
513
+ /**
514
+ * @deprecated Use the unified \`<Button variant="gradient">\` instead.
515
+ */
477
516
  export const GradientButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
478
517
  ({ children, ...props }, ref) => (
479
518
  <Button ref={ref} variant="gradient" {...props}>
@@ -483,6 +522,9 @@ export const GradientButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
483
522
  );
484
523
  GradientButton.displayName = "GradientButton";
485
524
 
525
+ /**
526
+ * @deprecated Use the unified \`<Button variant="glass">\` instead.
527
+ */
486
528
  export const GlassButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
487
529
  ({ children, ...props }, ref) => (
488
530
  <Button ref={ref} variant="glass" {...props}>
@@ -515,8 +557,8 @@ var modal = {
515
557
  import * as React from "react"
516
558
  import * as DialogPrimitive from "@radix-ui/react-dialog"
517
559
  import { X, AlertTriangle, CheckCircle, Star } from "lucide-react"
560
+ import { cva, type VariantProps } from "class-variance-authority"
518
561
  import { cn } from "../utils/cn"
519
- import { Button } from "./button"
520
562
 
521
563
  const Dialog = DialogPrimitive.Root
522
564
 
@@ -541,18 +583,52 @@ const DialogOverlay = React.forwardRef<
541
583
  ))
542
584
  DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
543
585
 
586
+ const dialogContentVariants = cva(
587
+ "fixed left-[50%] top-[50%] z-50 grid w-full translate-x-[-50%] translate-y-[-50%] gap-4 border 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",
588
+ {
589
+ variants: {
590
+ variant: {
591
+ default: "border-border/50",
592
+ glass: "bg-white/10 backdrop-blur-xl border-white/20 shadow-2xl",
593
+ destructive: "border-destructive/20",
594
+ success: "border-green-500/20",
595
+ fullscreen: "max-w-full h-screen rounded-none",
596
+ drawer: "sm:max-w-full sm:h-[50vh] sm:rounded-b-none sm:rounded-t-[20px] fixed bottom-0 top-auto translate-y-0 data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
597
+ },
598
+ size: {
599
+ sm: "max-w-sm",
600
+ md: "max-w-md",
601
+ lg: "max-w-lg",
602
+ xl: "max-w-xl",
603
+ "2xl": "max-w-2xl",
604
+ full: "max-w-[95vw] md:max-w-[90vw]",
605
+ },
606
+ scrollable: {
607
+ true: "max-h-[80vh] overflow-y-auto",
608
+ false: "",
609
+ }
610
+ },
611
+ defaultVariants: {
612
+ variant: "default",
613
+ size: "lg",
614
+ scrollable: false,
615
+ },
616
+ }
617
+ )
618
+
619
+ export interface DialogContentProps
620
+ extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>,
621
+ VariantProps<typeof dialogContentVariants> {}
622
+
544
623
  const DialogContent = React.forwardRef<
545
624
  React.ElementRef<typeof DialogPrimitive.Content>,
546
- React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
547
- >(({ className, children, ...props }, ref) => (
625
+ DialogContentProps
626
+ >(({ className, variant, size, scrollable, children, ...props }, ref) => (
548
627
  <DialogPortal>
549
628
  <DialogOverlay />
550
629
  <DialogPrimitive.Content
551
630
  ref={ref}
552
- className={cn(
553
- "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",
554
- className
555
- )}
631
+ className={cn(dialogContentVariants({ variant, size, scrollable, className }))}
556
632
  {...props}
557
633
  >
558
634
  {children}
@@ -632,437 +708,6 @@ export {
632
708
  DialogTitle,
633
709
  DialogDescription,
634
710
  }
635
-
636
- export interface ModalProps {
637
- /**
638
- * The title of the modal
639
- */
640
- title?: React.ReactNode;
641
- /**
642
- * The description of the modal
643
- */
644
- description?: React.ReactNode;
645
- /**
646
- * The content of the modal
647
- */
648
- children?: React.ReactNode;
649
- /**
650
- * The trigger element to open the modal
651
- */
652
- trigger?: React.ReactNode;
653
- /**
654
- * Callback function called when the confirm button is clicked
655
- */
656
- onConfirm?: () => void;
657
- /**
658
- * Callback function called when the cancel button is clicked
659
- */
660
- onCancel?: () => void;
661
- /**
662
- * The text for the confirm button
663
- * @default "Confirm"
664
- */
665
- confirmText?: string;
666
- /**
667
- * The text for the cancel button
668
- * @default "Cancel"
669
- */
670
- cancelText?: string;
671
- /**
672
- * Whether the modal is open
673
- */
674
- isOpen?: boolean;
675
- /**
676
- * Callback function called when the open state changes
677
- */
678
- onOpenChange?: (open: boolean) => void;
679
- /**
680
- * The variant of the modal
681
- * @default "default"
682
- */
683
- variant?: "default" | "glass" | "destructive" | "success" | "fullscreen" | "drawer";
684
- /**
685
- * Whether the content is scrollable
686
- * @default false
687
- */
688
- scrollable?: boolean;
689
- /**
690
- * Additional className for the dialog content
691
- */
692
- className?: string;
693
- }
694
-
695
- export function Modal({
696
- title,
697
- description,
698
- children,
699
- trigger,
700
- onConfirm,
701
- onCancel,
702
- confirmText = "Confirm",
703
- cancelText = "Cancel",
704
- isOpen,
705
- onOpenChange,
706
- variant = "default",
707
- scrollable = false,
708
- className,
709
- }: ModalProps) {
710
- const variantClasses = {
711
- default: "",
712
- glass: "bg-white/10 backdrop-blur-xl border-white/20 shadow-2xl",
713
- destructive: "border-destructive/20",
714
- success: "border-green-500/20",
715
- fullscreen: "max-w-full h-screen rounded-none",
716
- drawer: "sm:max-w-full sm:h-[50vh] sm:rounded-b-none sm:rounded-t-[20px] fixed bottom-0 top-auto translate-y-0",
717
- }
718
-
719
- const isDestructive = variant === "destructive";
720
- const isSuccess = variant === "success";
721
-
722
- return (
723
- <Dialog open={isOpen} onOpenChange={onOpenChange}>
724
- {trigger && <DialogTrigger asChild>{trigger}</DialogTrigger>}
725
- <DialogContent className={cn(variantClasses[variant], scrollable ? "max-h-[80vh] overflow-y-auto" : "", className)}>
726
- {(title || description || isDestructive || isSuccess) && (
727
- <DialogHeader className={cn((isDestructive || isSuccess) ? "flex flex-col items-center text-center sm:text-center" : "")}>
728
- {isDestructive && (
729
- <div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-destructive/10 mb-4">
730
- <AlertTriangle className="h-6 w-6 text-destructive" />
731
- </div>
732
- )}
733
- {isSuccess && (
734
- <div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-500/10 mb-4">
735
- <CheckCircle className="h-6 w-6 text-green-500" />
736
- </div>
737
- )}
738
- {title && <DialogTitle className={cn((isDestructive || isSuccess) ? "text-xl" : "")}>{title}</DialogTitle>}
739
- {description && <DialogDescription>{description}</DialogDescription>}
740
- </DialogHeader>
741
- )}
742
- <div className="py-4">{children}</div>
743
- {(onConfirm || onCancel || isDestructive || isSuccess) && (
744
- <DialogFooter className={cn((isDestructive || isSuccess) ? "sm:justify-center flex-col sm:flex-row gap-2" : "")}>
745
- {onCancel && (
746
- <DialogPrimitive.Close asChild>
747
- <Button variant="outline" className={cn((isDestructive || isSuccess) ? "w-full sm:w-auto" : "")} onClick={onCancel}>{cancelText}</Button>
748
- </DialogPrimitive.Close>
749
- )}
750
- {onConfirm && (
751
- <Button
752
- variant={isDestructive ? "destructive" : "default"}
753
- className={cn((isDestructive || isSuccess) ? "w-full sm:w-auto" : "", isSuccess ? "bg-green-500 hover:bg-green-600" : "")}
754
- onClick={onConfirm}
755
- >
756
- {confirmText}
757
- </Button>
758
- )}
759
- </DialogFooter>
760
- )}
761
- </DialogContent>
762
- </Dialog>
763
- )
764
- }
765
-
766
- // ============================================
767
- // Backward compatibility wrappers & variants
768
- // ============================================
769
-
770
- export interface BasicModalProps {
771
- isOpen?: boolean;
772
- onOpenChange?: (open: boolean) => void;
773
- trigger?: React.ReactNode;
774
- title?: string;
775
- description?: string;
776
- children?: React.ReactNode;
777
- confirmText?: string;
778
- cancelText?: string;
779
- onConfirm?: () => void;
780
- onCancel?: () => void;
781
- className?: string;
782
- }
783
-
784
- export const BasicModal = ({
785
- isOpen,
786
- onOpenChange,
787
- trigger,
788
- title = "Basic Modal",
789
- description = "This is a simple modal dialog that can be used for various purposes.",
790
- children,
791
- confirmText = "Confirm",
792
- cancelText = "Cancel",
793
- onConfirm,
794
- onCancel,
795
- className = ""
796
- }: BasicModalProps) => {
797
- return (
798
- <Modal
799
- isOpen={isOpen}
800
- onOpenChange={onOpenChange}
801
- trigger={trigger}
802
- title={title}
803
- description={description}
804
- confirmText={confirmText}
805
- cancelText={cancelText}
806
- onConfirm={onConfirm}
807
- onCancel={onCancel}
808
- className={className}
809
- variant="default"
810
- >
811
- {children}
812
- </Modal>
813
- )
814
- }
815
-
816
- export interface InteractiveGlassModalProps {
817
- isOpen?: boolean;
818
- onOpenChange?: (open: boolean) => void;
819
- trigger?: React.ReactNode;
820
- icon?: React.ReactNode;
821
- title?: string;
822
- description?: string;
823
- children?: React.ReactNode;
824
- confirmText?: string;
825
- cancelText?: string;
826
- onConfirm?: () => void;
827
- onCancel?: () => void;
828
- className?: string;
829
- }
830
-
831
- export const InteractiveGlassModal = ({
832
- isOpen,
833
- onOpenChange,
834
- trigger,
835
- icon = <Star className="w-6 h-6 text-yellow-300" />,
836
- title = "Premium Glass Effect",
837
- description = "This modal uses full glassmorphism for a stunning visual effect.",
838
- children,
839
- confirmText = "Upgrade Now",
840
- cancelText = "Maybe Later",
841
- onConfirm,
842
- onCancel,
843
- className = ""
844
- }: InteractiveGlassModalProps) => {
845
- return (
846
- <Modal
847
- isOpen={isOpen}
848
- onOpenChange={onOpenChange}
849
- trigger={trigger}
850
- title={<span className="flex items-center gap-2">{icon} {title}</span>}
851
- description={description}
852
- confirmText={confirmText}
853
- cancelText={cancelText}
854
- onConfirm={onConfirm}
855
- onCancel={onCancel}
856
- className={className}
857
- variant="glass"
858
- >
859
- {children}
860
- </Modal>
861
- )
862
- }
863
-
864
- export interface DangerModalProps {
865
- isOpen?: boolean;
866
- onOpenChange?: (open: boolean) => void;
867
- trigger?: React.ReactNode;
868
- icon?: React.ReactNode;
869
- title?: string;
870
- description?: string;
871
- children?: React.ReactNode;
872
- confirmText?: string;
873
- cancelText?: string;
874
- onConfirm?: () => void;
875
- onCancel?: () => void;
876
- className?: string;
877
- }
878
-
879
- export const DangerModal = ({
880
- isOpen,
881
- onOpenChange,
882
- trigger,
883
- icon = <X className="w-8 h-8" />,
884
- title = "Are you absolutely sure?",
885
- description = "This action cannot be undone. This will permanently delete your account and remove your data from our servers.",
886
- children,
887
- confirmText = "Delete",
888
- cancelText = "Cancel",
889
- onConfirm,
890
- onCancel,
891
- className = ""
892
- }: DangerModalProps) => {
893
- return (
894
- <Modal
895
- isOpen={isOpen}
896
- onOpenChange={onOpenChange}
897
- trigger={trigger}
898
- title={title}
899
- description={description}
900
- confirmText={confirmText}
901
- cancelText={cancelText}
902
- onConfirm={onConfirm}
903
- onCancel={onCancel}
904
- className={className}
905
- variant="destructive"
906
- >
907
- {children}
908
- </Modal>
909
- )
910
- }
911
-
912
- export interface GlassModalProps {
913
- trigger?: React.ReactNode
914
- title?: React.ReactNode
915
- description?: React.ReactNode
916
- children?: React.ReactNode
917
- open?: boolean
918
- onOpenChange?: (open: boolean) => void
919
- }
920
-
921
- export function GlassModal({ trigger, title = "Glass Modal", description, children, open, onOpenChange }: GlassModalProps) {
922
- return (
923
- <Modal
924
- isOpen={open}
925
- onOpenChange={onOpenChange}
926
- trigger={trigger}
927
- title={title}
928
- description={description}
929
- variant="glass"
930
- >
931
- {children}
932
- </Modal>
933
- )
934
- }
935
-
936
- export interface AlertModalProps {
937
- trigger?: React.ReactNode
938
- title?: string
939
- description?: string
940
- onConfirm?: () => void
941
- onCancel?: () => void
942
- confirmText?: string
943
- cancelText?: string
944
- children?: React.ReactNode
945
- open?: boolean
946
- onOpenChange?: (open: boolean) => void
947
- }
948
-
949
- export function AlertModal({
950
- trigger,
951
- title = "Are you absolutely sure?",
952
- description,
953
- onConfirm,
954
- onCancel,
955
- confirmText = "Confirm",
956
- cancelText = "Cancel",
957
- children,
958
- open,
959
- onOpenChange
960
- }: AlertModalProps) {
961
- return (
962
- <Modal
963
- isOpen={open}
964
- onOpenChange={onOpenChange}
965
- trigger={trigger}
966
- title={title}
967
- description={description}
968
- confirmText={confirmText}
969
- cancelText={cancelText}
970
- onConfirm={onConfirm}
971
- onCancel={onCancel}
972
- variant="destructive"
973
- >
974
- {children}
975
- </Modal>
976
- )
977
- }
978
-
979
- export interface SuccessModalProps {
980
- trigger?: React.ReactNode
981
- title?: string
982
- description?: string
983
- children?: React.ReactNode
984
- open?: boolean
985
- onOpenChange?: (open: boolean) => void
986
- confirmText?: string
987
- onConfirm?: () => void
988
- }
989
-
990
- export function SuccessModal({
991
- trigger,
992
- title = "Success!",
993
- description,
994
- children,
995
- open,
996
- onOpenChange,
997
- confirmText = "Awesome",
998
- onConfirm
999
- }: SuccessModalProps) {
1000
- return (
1001
- <Modal
1002
- isOpen={open}
1003
- onOpenChange={onOpenChange}
1004
- trigger={trigger}
1005
- title={title}
1006
- description={description}
1007
- confirmText={confirmText}
1008
- onConfirm={onConfirm}
1009
- variant="success"
1010
- >
1011
- {children}
1012
- </Modal>
1013
- )
1014
- }
1015
-
1016
- export interface CommandPaletteModalProps {
1017
- trigger: React.ReactNode
1018
- open?: boolean
1019
- onOpenChange?: (open: boolean) => void
1020
- }
1021
-
1022
- export function CommandPaletteModal({ trigger, open, onOpenChange }: CommandPaletteModalProps) {
1023
- return (
1024
- <Dialog open={open} onOpenChange={onOpenChange}>
1025
- <DialogTrigger asChild>{trigger}</DialogTrigger>
1026
- <DialogContent className="p-0 overflow-hidden sm:max-w-[600px] gap-0">
1027
- <div className="flex items-center border-b px-3">
1028
- <svg className="mr-2 h-4 w-4 shrink-0 opacity-50" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
1029
- <input className="flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50" placeholder="Type a command or search..." />
1030
- </div>
1031
- <div className="max-h-[300px] overflow-y-auto p-2">
1032
- <div className="px-2 py-1.5 text-xs font-medium text-muted-foreground">Suggestions</div>
1033
- <div className="flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground hover:bg-accent/50">
1034
- Calendar
1035
- </div>
1036
- <div className="flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground hover:bg-accent/50">
1037
- Search Emoji
1038
- </div>
1039
- <div className="flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground hover:bg-accent/50">
1040
- Calculator
1041
- </div>
1042
- </div>
1043
- </DialogContent>
1044
- </Dialog>
1045
- )
1046
- }
1047
-
1048
- export interface BottomSheetSimulatedProps {
1049
- trigger: React.ReactNode
1050
- children?: React.ReactNode
1051
- open?: boolean
1052
- onOpenChange?: (open: boolean) => void
1053
- }
1054
-
1055
- export function BottomSheetSimulated({ trigger, children, open, onOpenChange }: BottomSheetSimulatedProps) {
1056
- return (
1057
- <Dialog open={open} onOpenChange={onOpenChange}>
1058
- <DialogTrigger asChild>{trigger}</DialogTrigger>
1059
- <DialogContent className="sm:max-w-full sm:h-[50vh] sm:rounded-b-none sm:rounded-t-[10px] fixed bottom-0 top-auto translate-y-0 data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom">
1060
- <div className="mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted" />
1061
- {children}
1062
- </DialogContent>
1063
- </Dialog>
1064
- )
1065
- }
1066
711
  `
1067
712
  };
1068
713
 
@@ -1124,26 +769,6 @@ export interface CardProps
1124
769
  * @default true
1125
770
  */
1126
771
  animate?: boolean;
1127
- /**
1128
- * The main title of the card
1129
- */
1130
- title?: React.ReactNode;
1131
- /**
1132
- * The subtitle or description of the card
1133
- */
1134
- description?: React.ReactNode;
1135
- /**
1136
- * Content to render in the card footer area
1137
- */
1138
- footer?: React.ReactNode;
1139
- /**
1140
- * An optional image URL to display at the top of the card
1141
- */
1142
- image?: string;
1143
- /**
1144
- * HTML alternative text for the image
1145
- */
1146
- imageAlt?: string;
1147
772
  /**
1148
773
  * Back content displayed when using the \`flip\` variant on hover
1149
774
  */
@@ -1162,11 +787,6 @@ const Card = React.forwardRef<HTMLDivElement, CardProps>(
1162
787
  variant,
1163
788
  hover,
1164
789
  animate = true,
1165
- title,
1166
- description,
1167
- footer,
1168
- image,
1169
- imageAlt,
1170
790
  backContent,
1171
791
  spotlightColor = "rgba(139, 92, 246, 0.15)",
1172
792
  children,
@@ -1174,8 +794,6 @@ const Card = React.forwardRef<HTMLDivElement, CardProps>(
1174
794
  },
1175
795
  ref
1176
796
  ) => {
1177
- const isCompound = !title && !description && !footer && !image;
1178
-
1179
797
  // Feature toggles based on variants
1180
798
  const isSpotlight = variant === "spotlight";
1181
799
  const isFlip = variant === "flip";
@@ -1212,26 +830,6 @@ const Card = React.forwardRef<HTMLDivElement, CardProps>(
1212
830
  // Flip card hover state
1213
831
  const [isFlipped, setIsFlipped] = React.useState(false);
1214
832
 
1215
- const baseContent = isCompound ? (
1216
- children
1217
- ) : (
1218
- <>
1219
- {image && (
1220
- <div className="relative w-full h-48 overflow-hidden rounded-t-2xl">
1221
- <img src={image} alt={imageAlt || (typeof title === 'string' ? title : 'Card image')} className="object-cover w-full h-full transition-transform duration-300 hover:scale-105" />
1222
- </div>
1223
- )}
1224
- {(title || description) && (
1225
- <CardHeader>
1226
- {title && <CardTitle>{title}</CardTitle>}
1227
- {description && <CardDescription>{description}</CardDescription>}
1228
- </CardHeader>
1229
- )}
1230
- {children && <CardContent>{children as React.ReactNode}</CardContent>}
1231
- {footer && <CardFooter>{footer}</CardFooter>}
1232
- </>
1233
- );
1234
-
1235
833
  // Destructure custom props to avoid DOM validation warnings
1236
834
  const { ...htmlProps } = props;
1237
835
 
@@ -1252,7 +850,7 @@ const Card = React.forwardRef<HTMLDivElement, CardProps>(
1252
850
  >
1253
851
  {/* Front Face */}
1254
852
  <div className="absolute inset-0 backface-hidden border bg-card text-card-foreground rounded-2xl shadow-sm flex flex-col justify-between overflow-hidden">
1255
- {baseContent}
853
+ {children}
1256
854
  </div>
1257
855
 
1258
856
  {/* Back Face */}
@@ -1303,7 +901,7 @@ const Card = React.forwardRef<HTMLDivElement, CardProps>(
1303
901
  {...(htmlProps as any)}
1304
902
  >
1305
903
  {spotlightEffect}
1306
- {baseContent}
904
+ {children}
1307
905
  </motion.div>
1308
906
  );
1309
907
  }
@@ -1314,7 +912,7 @@ const Card = React.forwardRef<HTMLDivElement, CardProps>(
1314
912
  className={cardClass}
1315
913
  {...(htmlProps as React.HTMLAttributes<HTMLDivElement>)}
1316
914
  >
1317
- {baseContent}
915
+ {children}
1318
916
  </div>
1319
917
  );
1320
918
  }
@@ -1424,144 +1022,7 @@ export const SpotlightCard = React.forwardRef<HTMLDivElement, CardProps>(
1424
1022
  );
1425
1023
  SpotlightCard.displayName = "SpotlightCard";
1426
1024
 
1427
- // ============================================
1428
- // Consolidated Legacy/Special Cards for Compatibility
1429
- // ============================================
1430
-
1431
- export const ImageCard = ({ src, title, subtitle, imageUrl, description }: any) => {
1432
- const finalSrc = src || imageUrl;
1433
- const finalTitle = title;
1434
- const finalSubtitle = subtitle || description;
1435
- return (
1436
- <div className="group relative overflow-hidden rounded-xl border bg-card text-card-foreground">
1437
- <div className="aspect-[4/3] w-full bg-muted overflow-hidden">
1438
- {finalSrc ? (
1439
- <img
1440
- src={finalSrc}
1441
- className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
1442
- alt={typeof finalTitle === "string" ? finalTitle : "Image"}
1443
- />
1444
- ) : (
1445
- <div className="w-full h-full bg-muted-foreground/20" />
1446
- )}
1447
- </div>
1448
- <div className="p-4">
1449
- <h3 className="font-semibold text-lg">{finalTitle}</h3>
1450
- <p className="text-sm text-muted-foreground">{finalSubtitle}</p>
1451
- </div>
1452
- </div>
1453
- );
1454
- };
1455
-
1456
- export const ProfileCard = ({ name, role, avatar }: any) => (
1457
- <div className="flex flex-col items-center p-6 text-center rounded-xl border bg-card shadow-sm">
1458
- <div className="w-24 h-24 rounded-full bg-muted mb-4 overflow-hidden border-4 border-background shadow-md">
1459
- {avatar && <img src={avatar} className="w-full h-full object-cover" alt={name} />}
1460
- </div>
1461
- <h3 className="text-xl font-bold">{name}</h3>
1462
- <p className="text-sm text-muted-foreground mb-4">{role}</p>
1463
- <button className="px-6 py-2 bg-primary text-primary-foreground rounded-full font-medium w-full hover:bg-primary/90 transition-colors">Follow</button>
1464
- </div>
1465
- )
1466
-
1467
- export const ProductCard = ({ title, price, category, src }: any) => (
1468
- <div className="rounded-xl border bg-card p-4 flex flex-col gap-3 group">
1469
- <div className="aspect-square w-full rounded-lg bg-muted overflow-hidden relative">
1470
- {src && <img src={src} className="w-full h-full object-cover" alt={title} />}
1471
- <button className="absolute top-2 right-2 p-2 bg-background/50 backdrop-blur rounded-full hover:bg-background transition-colors"><Heart className="w-4 h-4" /></button>
1472
- </div>
1473
- <div>
1474
- <p className="text-xs text-muted-foreground mb-1">{category}</p>
1475
- <h3 className="font-medium truncate">{title}</h3>
1476
- <p className="font-bold text-lg mt-1">\${price}</p>
1477
- </div>
1478
- </div>
1479
- )
1480
-
1481
- export const ArticleCard = ({ title, excerpt, date }: any) => (
1482
- <div className="p-6 rounded-xl border bg-card flex flex-col gap-4 hover:shadow-md transition-shadow cursor-pointer">
1483
- <span className="text-xs font-medium text-primary">{date}</span>
1484
- <h3 className="text-xl font-bold leading-tight">{title}</h3>
1485
- <p className="text-muted-foreground line-clamp-3">{excerpt}</p>
1486
- <div className="mt-auto pt-4 border-t flex items-center justify-between text-sm">
1487
- <span className="font-medium">Read more \u2192</span>
1488
- <button><Share2 className="w-4 h-4 text-muted-foreground hover:text-foreground" /></button>
1489
- </div>
1490
- </div>
1491
- )
1492
-
1493
- export const StatCardSimple = ({ label, value, trend }: any) => (
1494
- <div className="p-5 rounded-xl border bg-card">
1495
- <p className="text-sm font-medium text-muted-foreground mb-2">{label}</p>
1496
- <div className="flex items-end justify-between">
1497
- <h4 className="text-3xl font-bold">{value}</h4>
1498
- <span className={\`text-sm font-medium \${trend?.startsWith('+') ? 'text-green-500' : 'text-red-500'}\`}>{trend}</span>
1499
- </div>
1500
- </div>
1501
- )
1502
-
1503
- export const PricingCardBasic = ({ name, price, features }: any) => (
1504
- <div className="p-6 rounded-xl border bg-card flex flex-col items-center text-center">
1505
- <h3 className="text-xl font-medium mb-2">{name}</h3>
1506
- <div className="mb-6"><span className="text-4xl font-bold">\${price}</span><span className="text-muted-foreground">/mo</span></div>
1507
- <ul className="space-y-3 w-full mb-8 text-sm">
1508
- {features?.map((f: string, i: number) => <li key={i} className="text-muted-foreground border-b pb-2 last:border-0">{f}</li>)}
1509
- </ul>
1510
- <button className="w-full py-2 bg-primary text-primary-foreground rounded-lg font-medium mt-auto">Subscribe</button>
1511
- </div>
1512
- )
1513
-
1514
- export const WeatherCard = ({ city, temp, condition }: any) => (
1515
- <div className="p-6 rounded-xl border bg-gradient-to-br from-blue-500 to-cyan-400 text-white shadow-lg">
1516
- <div className="flex justify-between items-start mb-8">
1517
- <div>
1518
- <h3 className="text-2xl font-bold">{city}</h3>
1519
- <p className="opacity-80">{condition}</p>
1520
- </div>
1521
- <div className="text-5xl font-light">{temp}\xB0</div>
1522
- </div>
1523
- <div className="flex gap-4 opacity-90 text-sm">
1524
- <span>H: {temp + 4}\xB0</span>
1525
- <span>L: {temp - 3}\xB0</span>
1526
- </div>
1527
- </div>
1528
- )
1529
-
1530
- export const EventCard = ({ title, date, location }: any) => (
1531
- <div className="flex p-4 rounded-xl border bg-card gap-4">
1532
- <div className="flex flex-col items-center justify-center bg-primary/10 text-primary rounded-lg px-4 py-2 min-w-[70px]">
1533
- <span className="text-xs uppercase font-bold">{date?.split(' ')[0]}</span>
1534
- <span className="text-2xl font-black">{date?.split(' ')[1]}</span>
1535
- </div>
1536
- <div className="flex flex-col justify-center">
1537
- <h3 className="font-bold text-lg leading-tight mb-1">{title}</h3>
1538
- <div className="flex items-center text-sm text-muted-foreground gap-1">
1539
- <MapPin className="w-3 h-3" /> {location}
1540
- </div>
1541
- </div>
1542
- </div>
1543
- )
1544
-
1545
- export const TestimonialCardBasic = ({ text, author }: any) => (
1546
- <div className="p-6 rounded-xl border bg-muted/30 italic relative">
1547
- <span className="absolute top-4 left-4 text-4xl text-primary/20 font-serif">"</span>
1548
- <p className="relative z-10 text-muted-foreground mb-4 pt-4">{text}</p>
1549
- <div className="flex items-center gap-2">
1550
- <div className="w-8 h-8 rounded-full bg-primary/20" />
1551
- <span className="font-semibold text-sm not-italic">{author}</span>
1552
- </div>
1553
- </div>
1554
- )
1555
1025
 
1556
- export const InteractiveCard = ({ title, description }: any) => (
1557
- <div className="group p-6 rounded-xl border bg-card hover:bg-primary hover:text-primary-foreground transition-all duration-300 cursor-pointer">
1558
- <div className="w-12 h-12 rounded-lg bg-primary/10 text-primary group-hover:bg-primary-foreground/20 group-hover:text-primary-foreground flex items-center justify-center mb-4 transition-colors">
1559
- <Star className="w-6 h-6" />
1560
- </div>
1561
- <h3 className="text-xl font-bold mb-2">{title}</h3>
1562
- <p className="text-muted-foreground group-hover:text-primary-foreground/80 transition-colors">{description}</p>
1563
- </div>
1564
- )
1565
1026
 
1566
1027
 
1567
1028
  `
@@ -1614,13 +1075,45 @@ const alertVariants = cva(
1614
1075
  export interface AlertProps
1615
1076
  extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'>,
1616
1077
  VariantProps<typeof alertVariants> {
1078
+ /**
1079
+ * \u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0434\u043B\u044F animate
1080
+ * @default undefined
1081
+ */
1617
1082
  animate?: boolean;
1083
+ /**
1084
+ * \u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0434\u043B\u044F title
1085
+ * @default undefined
1086
+ */
1618
1087
  title?: React.ReactNode;
1088
+ /**
1089
+ * \u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0434\u043B\u044F description
1090
+ * @default undefined
1091
+ */
1619
1092
  description?: React.ReactNode;
1093
+ /**
1094
+ * \u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0434\u043B\u044F icon
1095
+ * @default undefined
1096
+ */
1620
1097
  icon?: React.ReactNode;
1098
+ /**
1099
+ * \u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0434\u043B\u044F dismissible
1100
+ * @default undefined
1101
+ */
1621
1102
  dismissible?: boolean;
1103
+ /**
1104
+ * \u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0434\u043B\u044F onDismiss
1105
+ * @default undefined
1106
+ */
1622
1107
  onDismiss?: () => void;
1108
+ /**
1109
+ * \u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0434\u043B\u044F actionText
1110
+ * @default undefined
1111
+ */
1623
1112
  actionText?: string;
1113
+ /**
1114
+ * \u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0434\u043B\u044F onAction
1115
+ * @default undefined
1116
+ */
1624
1117
  onAction?: () => void;
1625
1118
  }
1626
1119
 
@@ -1649,10 +1142,19 @@ const Alert = React.forwardRef<HTMLDivElement, AlertProps>(
1649
1142
  const isMinimal = variant === "minimal";
1650
1143
  const isBanner = variant === "banner";
1651
1144
 
1145
+ const defaultIcon = icon || (
1146
+ variant === "destructive" ? <XCircle className="h-4 w-4" /> :
1147
+ variant === "success" ? <CheckCircle2 className="h-4 w-4" /> :
1148
+ variant === "warning" ? <AlertTriangle className="h-4 w-4" /> :
1149
+ variant === "info" ? <Info className="h-4 w-4" /> :
1150
+ variant === "default" ? <AlertCircle className="h-4 w-4" /> :
1151
+ null
1152
+ );
1153
+
1652
1154
  const content = (
1653
1155
  <>
1654
- {icon && <div className={cn("absolute left-4", isMinimal ? "top-3" : "top-4")}>{icon}</div>}
1655
- <div className={cn(icon ? "pl-7" : "", "pr-8")}>
1156
+ {defaultIcon && <div className={cn("absolute left-4", isMinimal ? "top-3" : "top-4")}>{defaultIcon}</div>}
1157
+ <div className={cn(defaultIcon ? "pl-7" : "", "pr-8")}>
1656
1158
  {title && <AlertTitle>{title}</AlertTitle>}
1657
1159
  {description && <AlertDescription>{description}</AlertDescription>}
1658
1160
  {!title && !description && children}
@@ -1810,19 +1312,38 @@ export const RateLimitAlert = () => (
1810
1312
 
1811
1313
  // Re-export original/merged components
1812
1314
  export { Alert, AlertTitle, AlertDescription }
1813
- export const CyberAlert = ({ title, description, variant, ...props }: any) => (
1315
+ /**
1316
+ * @deprecated Use the unified \`<Alert variant="cyberpunk">\` instead.
1317
+ */
1318
+ export const CyberAlert = ({ title, description, variant = "default", ...props }: any) => (
1814
1319
  <Alert variant="cyberpunk" title={title} description={description} {...props} />
1815
1320
  )
1816
- export const SoftAlert = ({ title, description, variant, ...props }: any) => (
1321
+
1322
+ /**
1323
+ * @deprecated Use \`<Alert variant="success">\` or \`<Alert variant="info">\` instead.
1324
+ */
1325
+ export const SoftAlert = ({ title, description, variant = "default", ...props }: any) => (
1817
1326
  <Alert variant={variant === "success" ? "success" : "info"} title={title} description={description} {...props} />
1818
1327
  )
1819
- export const MinimalAlert = ({ title, description, variant, ...props }: any) => (
1328
+
1329
+ /**
1330
+ * @deprecated Use \`<Alert variant="minimal">\` instead.
1331
+ */
1332
+ export const MinimalAlert = ({ title, description, variant = "default", ...props }: any) => (
1820
1333
  <Alert variant="minimal" title={title} description={description} {...props} />
1821
1334
  )
1822
- export const LeftBorderAlert = ({ title, description, variant, ...props }: any) => (
1335
+
1336
+ /**
1337
+ * @deprecated Use \`<Alert className="border-l-4 ...">\` instead.
1338
+ */
1339
+ export const LeftBorderAlert = ({ title, description, variant = "default", ...props }: any) => (
1823
1340
  <Alert variant={variant === "warning" ? "warning" : "default"} className="border-l-4 border-l-primary" title={title} description={description} {...props} />
1824
1341
  )
1825
- export const IconTopAlert = ({ title, description, variant, ...props }: any) => (
1342
+
1343
+ /**
1344
+ * @deprecated Use custom styled layouts or standard elements instead.
1345
+ */
1346
+ export const IconTopAlert = ({ title, description, variant = "default", ...props }: any) => (
1826
1347
  <div className="flex flex-col items-center text-center p-6 bg-card border rounded-2xl" {...props}>
1827
1348
  <div className="h-12 w-12 rounded-full bg-destructive/10 text-destructive flex items-center justify-center mb-4">
1828
1349
  <AlertCircle className="h-6 w-6" />
@@ -1831,7 +1352,11 @@ export const IconTopAlert = ({ title, description, variant, ...props }: any) =>
1831
1352
  <p className="text-sm text-muted-foreground">{description}</p>
1832
1353
  </div>
1833
1354
  )
1834
- export const SolidAlert = ({ title, description, variant, ...props }: any) => {
1355
+
1356
+ /**
1357
+ * @deprecated Use standard tailwind background colors on unified \`<Alert>\` instead.
1358
+ */
1359
+ export const SolidAlert = ({ title, description, variant = "default", ...props }: any) => {
1835
1360
  const bgClasses: Record<string, string> = {
1836
1361
  error: "bg-red-600 text-white border-0",
1837
1362
  success: "bg-emerald-600 text-white border-0",
@@ -1849,16 +1374,32 @@ export const SolidAlert = ({ title, description, variant, ...props }: any) => {
1849
1374
  </div>
1850
1375
  )
1851
1376
  }
1852
- export const BannerAlert = ({ message, variant, ...props }: any) => (
1377
+
1378
+ /**
1379
+ * @deprecated Use \`<Alert variant="banner">\` instead.
1380
+ */
1381
+ export const BannerAlert = ({ message, variant = "default", ...props }: any) => (
1853
1382
  <Alert variant="banner" title={message} {...props} />
1854
1383
  )
1855
- export const NeonAlert = ({ title, description, variant, ...props }: any) => (
1384
+
1385
+ /**
1386
+ * @deprecated Use \`<Alert variant="neon">\` instead.
1387
+ */
1388
+ export const NeonAlert = ({ title, description, variant = "default", ...props }: any) => (
1856
1389
  <Alert variant="neon" title={title} description={description} {...props} />
1857
1390
  )
1858
- export const GlassAlert = ({ title, description, variant, ...props }: any) => (
1391
+
1392
+ /**
1393
+ * @deprecated Use \`<Alert variant="glass">\` instead.
1394
+ */
1395
+ export const GlassAlert = ({ title, description, variant = "default", ...props }: any) => (
1859
1396
  <Alert variant="glass" title={title} description={description} {...props} />
1860
1397
  )
1861
- export const DismissibleAlert = ({ variant, title, description, ...props }: any) => (
1398
+
1399
+ /**
1400
+ * @deprecated Use \`<Alert dismissible={true}>\` instead.
1401
+ */
1402
+ export const DismissibleAlert = ({ variant = "default", title, description, ...props }: any) => (
1862
1403
  <Alert variant={variant} title={title || "Attention"} description={description || "Action required"} dismissible={true} {...props} />
1863
1404
  )
1864
1405
 
@@ -1881,7 +1422,6 @@ var badge = {
1881
1422
  import * as React from "react"
1882
1423
  import { cva, type VariantProps } from "class-variance-authority"
1883
1424
  import { cn } from "../utils/cn"
1884
- import { Star } from "lucide-react"
1885
1425
 
1886
1426
  const badgeVariants = cva(
1887
1427
  "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",
@@ -1892,9 +1432,11 @@ const badgeVariants = cva(
1892
1432
  secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
1893
1433
  destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
1894
1434
  outline: "text-foreground border-border hover:bg-accent",
1895
- gradient: "border-transparent bg-gradient-to-r from-violet-500 to-pink-500 text-white shadow-sm",
1896
- neon: "border-purple-500/50 bg-purple-500/10 text-purple-400 shadow-[0_0_10px_rgba(168,85,247,0.3)]",
1435
+ gradient: "border-transparent bg-gradient-to-r from-violet-600 to-pink-600 dark:from-violet-500 dark:to-pink-500 text-white shadow-sm",
1436
+ neon: "border-primary/50 bg-primary/10 text-primary shadow-[0_0_10px_rgba(var(--primary-rgb),0.3)]",
1897
1437
  success: "border-transparent bg-emerald-500/20 text-emerald-600 dark:text-emerald-400",
1438
+ warning: "border-transparent bg-amber-500/20 text-amber-600 dark:text-amber-400",
1439
+ info: "border-transparent bg-blue-500/20 text-blue-600 dark:text-blue-400",
1898
1440
  },
1899
1441
  size: {
1900
1442
  default: "px-2.5 py-0.5 text-xs",
@@ -1912,8 +1454,20 @@ const badgeVariants = cva(
1912
1454
  export interface BadgeProps
1913
1455
  extends React.HTMLAttributes<HTMLDivElement>,
1914
1456
  VariantProps<typeof badgeVariants> {
1457
+ /**
1458
+ * \u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0434\u043B\u044F pulse
1459
+ * @default undefined
1460
+ */
1915
1461
  pulse?: boolean;
1462
+ /**
1463
+ * \u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0434\u043B\u044F dot
1464
+ * @default undefined
1465
+ */
1916
1466
  dot?: boolean;
1467
+ /**
1468
+ * \u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0434\u043B\u044F text
1469
+ * @default undefined
1470
+ */
1917
1471
  text?: string;
1918
1472
  }
1919
1473
 
@@ -1936,179 +1490,1226 @@ function Badge({ className, variant, size, pulse = false, dot = false, children,
1936
1490
  }
1937
1491
 
1938
1492
  export { Badge, badgeVariants }
1493
+ `
1494
+ };
1939
1495
 
1940
- // ----------------------------------------------------
1941
- // Consolidated Badge Components
1942
- // ----------------------------------------------------
1496
+ // src/registry/morphing-geometry.ts
1497
+ var morphingGeometry = {
1498
+ name: "morphing-geometry",
1499
+ dependencies: [
1500
+ "clsx",
1501
+ "tailwind-merge",
1502
+ "framer-motion",
1503
+ "lucide-react"
1504
+ ],
1505
+ fileName: "morphing-geometry.tsx",
1506
+ content: `'use client';
1943
1507
 
1944
- export const GlowBadge = ({ children, className, ...props }: BadgeProps) => (
1945
- <Badge variant="neon" className={className} {...props}>{children}</Badge>
1946
- )
1508
+ import * as React from 'react';
1509
+ import { motion, HTMLMotionProps } from 'framer-motion';
1510
+ import { Sparkles } from 'lucide-react';
1511
+ import { cn } from '../utils/cn';
1947
1512
 
1948
- export const GlassBadge = ({ children, className, ...props }: BadgeProps) => (
1949
- <Badge variant="outline" className={cn("backdrop-blur-md bg-white/10 dark:bg-black/20 border-white/20 dark:border-white/10", className)} {...props}>{children}</Badge>
1950
- )
1513
+ export type MorphingShape = 'pill' | 'circle' | 'square' | 'squircle' | 'custom';
1514
+ export type MorphingVariant = 'gradient' | 'aurora' | 'neon' | 'glass' | 'outline' | 'subtle';
1515
+ export type MorphingColor = 'violet' | 'cyan' | 'emerald' | 'rose' | 'amber' | 'rainbow' | 'mono';
1516
+ export type MorphingSize = 'sm' | 'md' | 'lg' | 'xl' | 'custom';
1517
+
1518
+ export interface MorphingGeometryProps extends Omit<HTMLMotionProps<'div'>, 'children'> {
1519
+ shape?: MorphingShape;
1520
+ radius?: number | string;
1521
+ variant?: MorphingVariant;
1522
+ color?: MorphingColor;
1523
+ size?: MorphingSize;
1524
+ dimension?: number;
1525
+ spin?: boolean;
1526
+ spinDuration?: number;
1527
+ interactive?: boolean;
1528
+ glow?: boolean;
1529
+ icon?: React.ReactNode;
1530
+ children?: React.ReactNode;
1531
+ }
1951
1532
 
1952
- export const DotBadge = ({ children, className, ...props }: BadgeProps) => (
1953
- <Badge dot={true} className={className} {...props}>{children}</Badge>
1954
- )
1533
+ export const MorphingGeometry = React.forwardRef<HTMLDivElement, MorphingGeometryProps>(
1534
+ (
1535
+ {
1536
+ shape = 'squircle',
1537
+ radius,
1538
+ variant = 'gradient',
1539
+ color = 'violet',
1540
+ size = 'md',
1541
+ dimension,
1542
+ spin = false,
1543
+ spinDuration = 6,
1544
+ interactive = false,
1545
+ glow = true,
1546
+ icon,
1547
+ children,
1548
+ className,
1549
+ style,
1550
+ onClick,
1551
+ ...props
1552
+ },
1553
+ ref
1554
+ ) => {
1555
+ return (
1556
+ <motion.div
1557
+ ref={ref}
1558
+ animate={spin ? { rotate: [0, 90, 180, 270, 360] } : { rotate: 0 }}
1559
+ transition={{ rotate: { duration: spinDuration, repeat: Infinity, ease: 'linear' }, borderRadius: { duration: 0.4 } }}
1560
+ className={cn('relative flex items-center justify-center select-none overflow-hidden transition-all duration-300 w-24 h-24', className)}
1561
+ style={{ borderRadius: radius || '24%', ...style }}
1562
+ {...props}
1563
+ >
1564
+ <div className="relative z-10 flex flex-col items-center justify-center p-2 text-center">
1565
+ {icon || children || <Sparkles className="w-6 h-6 text-white" />}
1566
+ </div>
1567
+ </motion.div>
1568
+ );
1569
+ }
1570
+ );
1955
1571
 
1956
- export const GradientBadge = ({ children, className, ...props }: BadgeProps) => (
1957
- <Badge variant="gradient" className={className} {...props}>{children}</Badge>
1958
- )
1572
+ MorphingGeometry.displayName = 'MorphingGeometry';
1573
+ export default MorphingGeometry;
1574
+ `
1575
+ };
1959
1576
 
1960
- export const OutlineGlowBadge = ({ children, className, ...props }: BadgeProps) => (
1961
- <Badge variant="neon" className={cn("bg-transparent border border-purple-500/50", className)} {...props}>{children}</Badge>
1962
- )
1577
+ // src/registry/aurora-border-fx.ts
1578
+ var auroraBorderFX = {
1579
+ name: "aurora-border-fx",
1580
+ dependencies: [
1581
+ "clsx",
1582
+ "tailwind-merge",
1583
+ "framer-motion",
1584
+ "lucide-react"
1585
+ ],
1586
+ fileName: "aurora-border-fx.tsx",
1587
+ content: `'use client';
1963
1588
 
1964
- export const PulseBadge = ({ children, className, ...props }: BadgeProps) => (
1965
- <Badge pulse={true} className={className} {...props}>{children}</Badge>
1966
- )
1589
+ import * as React from 'react';
1590
+ import { motion, useReducedMotion } from 'framer-motion';
1591
+ import { Sparkles } from 'lucide-react';
1592
+ import { cn } from '../utils/cn';
1967
1593
 
1968
- export const SoftBadge = ({ children, className, ...props }: BadgeProps) => (
1969
- <Badge variant="secondary" className={className} {...props}>{children}</Badge>
1970
- )
1594
+ export type AuroraFXColor = 'violet' | 'cyan' | 'emerald' | 'rose' | 'amber' | string;
1595
+ export type AuroraFXGlow = 'none' | 'subtle' | 'medium' | 'strong';
1596
+ export type AuroraFXRadius = 'sm' | 'md' | 'lg' | 'xl' | 'full';
1971
1597
 
1972
- export const TagBadge = ({ children, className, ...props }: BadgeProps) => (
1973
- <Badge className={cn("rounded-md", className)} {...props}>{children}</Badge>
1974
- )
1598
+ export interface AuroraColorOption {
1599
+ name: string;
1600
+ hex: string;
1601
+ }
1975
1602
 
1976
- export const PremiumBadge = ({ children, className, ...props }: BadgeProps) => (
1977
- <Badge variant="gradient" className={cn("bg-gradient-to-r from-yellow-500 via-amber-500 to-orange-500", className)} {...props}>{children}</Badge>
1978
- )
1603
+ export const defaultAuroraColors: AuroraColorOption[] = [
1604
+ { name: 'Violet', hex: '#8b5cf6' },
1605
+ { name: 'Cyan', hex: '#06b6d4' },
1606
+ { name: 'Emerald', hex: '#10b981' },
1607
+ { name: 'Rose', hex: '#f43f5e' },
1608
+ { name: 'Amber', hex: '#f59e0b' },
1609
+ ];
1610
+
1611
+ const colorPresetMap: Record<string, string> = {
1612
+ violet: '#8b5cf6',
1613
+ cyan: '#06b6d4',
1614
+ emerald: '#10b981',
1615
+ rose: '#f43f5e',
1616
+ amber: '#f59e0b',
1617
+ };
1979
1618
 
1980
- export const MinimalBadge = ({ children, className, ...props }: BadgeProps) => (
1981
- <Badge size="sm" variant="outline" className={className} {...props}>{children}</Badge>
1982
- )
1619
+ const radiusMap: Record<AuroraFXRadius, { outer: string; inner: string }> = {
1620
+ sm: { outer: 'rounded-lg', inner: 'rounded-[calc(0.5rem-1px)]' },
1621
+ md: { outer: 'rounded-xl', inner: 'rounded-[calc(0.75rem-1px)]' },
1622
+ lg: { outer: 'rounded-2xl', inner: 'rounded-[calc(1rem-1px)]' },
1623
+ xl: { outer: 'rounded-3xl', inner: 'rounded-[calc(1.5rem-1.5px)]' },
1624
+ full: { outer: 'rounded-full', inner: 'rounded-full' },
1625
+ };
1983
1626
 
1984
- export const NotificationBadge = ({ count, className }: { count: number; className?: string }) => (
1985
- <div className={cn("flex h-5 min-w-[20px] px-1 items-center justify-center rounded-full bg-destructive text-[10px] font-bold text-destructive-foreground shadow-sm", className)}>
1986
- {count}
1987
- </div>
1988
- )
1627
+ const glowOpacityMap: Record<AuroraFXGlow, number> = {
1628
+ none: 0,
1629
+ subtle: 0.25,
1630
+ medium: 0.45,
1631
+ strong: 0.75,
1632
+ };
1989
1633
 
1990
- export const RibbonBadge = ({ children, text, className }: { children?: React.ReactNode; text?: string; className?: string }) => (
1991
- <div className={cn("absolute top-0 right-0 bg-primary text-primary-foreground text-[10px] font-bold px-3 py-1 rounded-bl-xl uppercase tracking-wider", className)}>
1992
- {children || text}
1993
- </div>
1994
- )
1634
+ export interface AuroraBorderFXProps extends React.HTMLAttributes<HTMLDivElement> {
1635
+ color?: AuroraFXColor;
1636
+ glow?: AuroraFXGlow;
1637
+ radius?: AuroraFXRadius;
1638
+ badgeText?: string;
1639
+ badgeIcon?: React.ReactNode;
1640
+ title?: string;
1641
+ description?: string;
1642
+ showColorPicker?: boolean;
1643
+ colors?: AuroraColorOption[];
1644
+ activeColor?: string;
1645
+ onColorChange?: (colorHex: string) => void;
1646
+ previewSlot?: React.ReactNode;
1647
+ footerSlot?: React.ReactNode;
1648
+ children?: React.ReactNode;
1649
+ }
1995
1650
 
1996
- export interface OutlineDotBadgeProps extends React.HTMLAttributes<HTMLDivElement> {
1997
- status?: string;
1998
- text?: string;
1651
+ export const AuroraBorderFX = React.forwardRef<HTMLDivElement, AuroraBorderFXProps>(
1652
+ (
1653
+ {
1654
+ color = 'violet',
1655
+ glow = 'medium',
1656
+ radius = 'lg',
1657
+ badgeText = 'Aurora Border FX',
1658
+ badgeIcon = <Sparkles className="w-3 h-3" />,
1659
+ title = 'Reactive Aurora Borders',
1660
+ description = 'Smooth multi-color conic gradients that dynamically track and react with zero JavaScript canvas lag.',
1661
+ showColorPicker = true,
1662
+ colors = defaultAuroraColors,
1663
+ activeColor: controlledColor,
1664
+ onColorChange,
1665
+ previewSlot,
1666
+ footerSlot,
1667
+ className,
1668
+ children,
1669
+ ...props
1670
+ },
1671
+ ref
1672
+ ) => {
1673
+ const resolvedInitialColor = colorPresetMap[color] || color || '#8b5cf6';
1674
+ const [internalColor, setInternalColor] = React.useState<string>(resolvedInitialColor);
1675
+
1676
+ React.useEffect(() => {
1677
+ if (colorPresetMap[color]) {
1678
+ setInternalColor(colorPresetMap[color]);
1679
+ } else if (color) {
1680
+ setInternalColor(color);
1681
+ }
1682
+ }, [color]);
1683
+
1684
+ const currentColor = controlledColor !== undefined ? controlledColor : internalColor;
1685
+ const radiusConfig = radiusMap[radius] || radiusMap.lg;
1686
+ const glowOpacity = glowOpacityMap[glow] ?? 0.45;
1687
+
1688
+ const handleSelectColor = (hex: string) => {
1689
+ if (controlledColor === undefined) {
1690
+ setInternalColor(hex);
1691
+ }
1692
+ onColorChange?.(hex);
1693
+ };
1694
+
1695
+ return (
1696
+ <div
1697
+ ref={ref}
1698
+ className={cn(
1699
+ 'relative isolate p-5 sm:p-6 overflow-hidden flex flex-col justify-between group transition-all duration-300',
1700
+ 'border border-border/80 bg-card/60 backdrop-blur-xl shadow-xl',
1701
+ radiusConfig.outer,
1702
+ className
1703
+ )}
1704
+ {...props}
1705
+ >
1706
+ {glow !== 'none' && (
1707
+ <div
1708
+ className="absolute -top-12 -right-12 w-48 h-48 rounded-full blur-[85px] pointer-events-none transition-colors duration-500 -z-10"
1709
+ style={{
1710
+ backgroundColor: currentColor,
1711
+ opacity: glowOpacity,
1712
+ }}
1713
+ />
1714
+ )}
1715
+
1716
+ {glow !== 'none' && glow !== 'subtle' && (
1717
+ <div
1718
+ className="absolute -bottom-10 -left-10 w-40 h-40 rounded-full blur-[90px] pointer-events-none transition-colors duration-700 -z-10"
1719
+ style={{
1720
+ backgroundColor: currentColor,
1721
+ opacity: glowOpacity * 0.4,
1722
+ }}
1723
+ />
1724
+ )}
1725
+
1726
+ {children ? (
1727
+ <div className="relative z-10 w-full h-full">{children}</div>
1728
+ ) : (
1729
+ <div className="relative z-10 flex flex-col justify-between h-full space-y-5">
1730
+ <div className="space-y-3">
1731
+ <div className="flex items-center justify-between gap-3">
1732
+ {badgeText && (
1733
+ <div
1734
+ className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-[11px] font-semibold border transition-all duration-300 shadow-xs"
1735
+ style={{
1736
+ backgroundColor: \`\${currentColor}18\`,
1737
+ borderColor: \`\${currentColor}40\`,
1738
+ color: currentColor,
1739
+ }}
1740
+ >
1741
+ {badgeIcon}
1742
+ <span>{badgeText}</span>
1743
+ </div>
1744
+ )}
1745
+
1746
+ {showColorPicker && colors && colors.length > 0 && (
1747
+ <div className="flex items-center gap-1.5 bg-muted/60 dark:bg-muted/40 p-1 rounded-full border border-border/60 backdrop-blur-md">
1748
+ {colors.map((c) => {
1749
+ const isActive = currentColor.toLowerCase() === c.hex.toLowerCase();
1750
+ return (
1751
+ <button
1752
+ key={c.name}
1753
+ type="button"
1754
+ onClick={() => handleSelectColor(c.hex)}
1755
+ className={cn(
1756
+ 'w-3.5 h-3.5 rounded-full transition-all duration-200 cursor-pointer',
1757
+ isActive
1758
+ ? 'scale-125 ring-2 ring-foreground/40 shadow-xs'
1759
+ : 'hover:scale-110 opacity-70 hover:opacity-100'
1760
+ )}
1761
+ style={{ backgroundColor: c.hex }}
1762
+ title={\`Switch to \${c.name}\`}
1763
+ aria-label={\`Switch glow to \${c.name}\`}
1764
+ />
1765
+ );
1766
+ })}
1767
+ </div>
1768
+ )}
1769
+ </div>
1770
+
1771
+ <div>
1772
+ {title && (
1773
+ <h3 className="text-base sm:text-lg font-bold tracking-tight text-foreground">
1774
+ {title}
1775
+ </h3>
1776
+ )}
1777
+ {description && (
1778
+ <p className="text-xs sm:text-sm text-muted-foreground leading-relaxed mt-1">
1779
+ {description}
1780
+ </p>
1781
+ )}
1782
+ </div>
1783
+ </div>
1784
+
1785
+ <div className="pt-2 flex items-center justify-center">
1786
+ {previewSlot ? (
1787
+ previewSlot
1788
+ ) : (
1789
+ <div
1790
+ className={cn(
1791
+ 'relative p-[1.5px] overflow-hidden transition-all duration-300 w-full max-w-[280px]',
1792
+ radiusConfig.inner
1793
+ )}
1794
+ style={{
1795
+ background: \`linear-gradient(135deg, \${currentColor}, transparent 60%, \${currentColor}90)\`,
1796
+ }}
1797
+ >
1798
+ <div
1799
+ className={cn(
1800
+ 'bg-card/90 dark:bg-card/80 px-4 py-3 flex items-center justify-between backdrop-blur-md shadow-inner',
1801
+ radiusConfig.inner
1802
+ )}
1803
+ >
1804
+ <div className="flex items-center gap-2.5">
1805
+ <div
1806
+ className="w-2.5 h-2.5 rounded-full animate-pulse shrink-0"
1807
+ style={{ backgroundColor: currentColor }}
1808
+ />
1809
+ <span className="text-xs font-mono font-semibold text-foreground">
1810
+ Interactive Aurora Pill
1811
+ </span>
1812
+ </div>
1813
+ <span
1814
+ className="text-[10px] font-mono px-2 py-0.5 rounded-md font-medium border"
1815
+ style={{
1816
+ backgroundColor: \`\${currentColor}12\`,
1817
+ borderColor: \`\${currentColor}30\`,
1818
+ color: currentColor,
1819
+ }}
1820
+ >
1821
+ {currentColor.toUpperCase()}
1822
+ </span>
1823
+ </div>
1824
+ </div>
1825
+ )}
1826
+ </div>
1827
+
1828
+ {footerSlot && <div className="pt-2 border-t border-border/50">{footerSlot}</div>}
1829
+ </div>
1830
+ )}
1831
+ </div>
1832
+ );
1833
+ }
1834
+ );
1835
+
1836
+ AuroraBorderFX.displayName = 'AuroraBorderFX';
1837
+ `
1838
+ };
1839
+
1840
+ // src/registry/aurora-search-pill.ts
1841
+ var auroraSearchPill = {
1842
+ name: "auroraSearchPill",
1843
+ dependencies: [
1844
+ "clsx",
1845
+ "tailwind-merge",
1846
+ "framer-motion",
1847
+ "lucide-react"
1848
+ ],
1849
+ fileName: "aurora-search-pill.tsx",
1850
+ content: `'use client';
1851
+
1852
+ import * as React from 'react';
1853
+ import { Globe, Sparkles } from 'lucide-react';
1854
+ import { cn } from '../utils/cn';
1855
+
1856
+ // Register hardware angle property once for conic gradient rotation
1857
+ if (typeof window !== 'undefined' && typeof (window as any).CSS !== 'undefined' && 'registerProperty' in (window as any).CSS) {
1858
+ try {
1859
+ (window as any).CSS.registerProperty({
1860
+ name: '--aurora-deg',
1861
+ syntax: '<angle>',
1862
+ inherits: false,
1863
+ initialValue: '0deg',
1864
+ });
1865
+ } catch {}
1866
+ }
1867
+
1868
+ export interface AuroraSearchSource {
1869
+ /** Unique key for the source badge */
1870
+ id: string;
1871
+ /** Label or tooltip text for the source */
1872
+ label?: string;
1873
+ /** Direct avatar image URL (e.g. favicon, PNG, SVG) */
1874
+ avatarUrl?: string;
1875
+ /** Custom icon or element */
1876
+ icon?: React.ReactNode;
1877
+ /** Text initials to display inside badge */
1878
+ initials?: string;
1879
+ /** Built-in preset type or custom */
1880
+ type?: 'globe' | 'gradient' | 'github' | 'claude' | 'chatgpt' | 'perplexity' | 'custom';
1881
+ /** Custom background CSS string or hex */
1882
+ bg?: string;
1883
+ }
1884
+
1885
+ export type AuroraSearchPillSize = 'sm' | 'md' | 'lg';
1886
+ export type AuroraSearchPillSpeed = 'slow' | 'normal' | 'fast';
1887
+ export type AuroraSearchPillTheme = 'light' | 'dark' | 'auto';
1888
+ export type AuroraSearchPillGlow = 'subtle' | 'medium' | 'strong' | 'none';
1889
+ export type AuroraSpinMode = 'always' | 'searching' | 'hover' | 'never';
1890
+
1891
+ export interface AuroraSearchPillProps
1892
+ extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onToggle'> {
1893
+ /** Controlled searching state */
1894
+ isSearching?: boolean;
1895
+ /** Uncontrolled default searching state */
1896
+ defaultSearching?: boolean;
1897
+ /** Callback fired when searching state toggles */
1898
+ onToggle?: (searching: boolean) => void;
1899
+ /** Main search title text shown when active (default: "Search...") */
1900
+ searchLabel?: string;
1901
+ /** List of badge sources to render in the active state */
1902
+ sources?: AuroraSearchSource[];
1903
+ /** Shortcut array of avatar image URLs */
1904
+ sourceAvatars?: string[];
1905
+ /** Color theme for the pill body: light, dark, or auto (follows dark mode) */
1906
+ theme?: AuroraSearchPillTheme;
1907
+ /** Size scale of the pill */
1908
+ size?: AuroraSearchPillSize;
1909
+ /** Glow intensity of the surrounding ambient aurora */
1910
+ glowIntensity?: AuroraSearchPillGlow;
1911
+ /** Speed of the rotating aurora beam */
1912
+ speed?: AuroraSearchPillSpeed;
1913
+ /**
1914
+ * When the aurora beam should rotate:
1915
+ * - 'always' (default): continuously rotates the aurora light wave all the time
1916
+ * - 'searching': only spins while searching/active, remains calm when idle
1917
+ * - 'hover': spins on cursor hover / focus
1918
+ * - 'never': static gradient, no rotation
1919
+ */
1920
+ spinMode?: AuroraSpinMode;
1921
+ /** Manually override spinning state */
1922
+ isSpinning?: boolean;
1923
+ /** Automatically toggle searching state at a set interval (demo mode) */
1924
+ autoCycle?: boolean;
1925
+ /** Interval in ms for autoCycle (default: 2400) */
1926
+ cycleInterval?: number;
1999
1927
  }
2000
1928
 
2001
- export const OutlineDotBadge = ({ children, className, status, text, ...props }: OutlineDotBadgeProps) => {
2002
- const statusColors: Record<string, string> = {
2003
- online: "bg-emerald-500",
2004
- offline: "bg-muted-foreground/50",
2005
- away: "bg-amber-500",
2006
- busy: "bg-red-500",
1929
+ const DEFAULT_SOURCES: AuroraSearchSource[] = [
1930
+ { id: 'web', type: 'globe', label: 'Web' },
1931
+ { id: 'gradient', type: 'gradient', label: 'Neural Index' },
1932
+ { id: 'github', type: 'github', label: 'GitHub' },
1933
+ ];
1934
+
1935
+ const SPEED_MAP: Record<AuroraSearchPillSpeed, string> = {
1936
+ slow: '5s',
1937
+ normal: '3.2s',
1938
+ fast: '1.8s',
1939
+ };
1940
+
1941
+ const GLOW_OPACITY: Record<AuroraSearchPillGlow, number> = {
1942
+ none: 0,
1943
+ subtle: 0.45,
1944
+ medium: 0.75,
1945
+ strong: 0.95,
1946
+ };
1947
+
1948
+ const SIZE_CONFIG: Record<
1949
+ AuroraSearchPillSize,
1950
+ {
1951
+ height: string;
1952
+ paddingDots: string;
1953
+ paddingSearch: string;
1954
+ dotSize: string;
1955
+ dotGap: string;
1956
+ fontSize: string;
1957
+ badgeSize: string;
1958
+ badgeMargin: string;
1959
+ minWidthSearch: string;
2007
1960
  }
2008
- const dotColor = status ? statusColors[status] || "bg-emerald-500" : "bg-primary"
1961
+ > = {
1962
+ sm: {
1963
+ height: 'h-10',
1964
+ paddingDots: 'px-4',
1965
+ paddingSearch: 'px-4',
1966
+ dotSize: 'w-1.5 h-1.5',
1967
+ dotGap: 'gap-1.5',
1968
+ fontSize: 'text-xs',
1969
+ badgeSize: 'w-4 h-4',
1970
+ badgeMargin: '-ml-1',
1971
+ minWidthSearch: 'min-w-[160px]',
1972
+ },
1973
+ md: {
1974
+ height: 'h-12',
1975
+ paddingDots: 'px-5',
1976
+ paddingSearch: 'px-5',
1977
+ dotSize: 'w-[6.5px] h-[6.5px]',
1978
+ dotGap: 'gap-[7px]',
1979
+ fontSize: 'text-sm sm:text-base',
1980
+ badgeSize: 'w-[22px] h-[22px]',
1981
+ badgeMargin: '-ml-1.5',
1982
+ minWidthSearch: 'min-w-[190px]',
1983
+ },
1984
+ lg: {
1985
+ height: 'h-14',
1986
+ paddingDots: 'px-6',
1987
+ paddingSearch: 'px-6',
1988
+ dotSize: 'w-2 h-2',
1989
+ dotGap: 'gap-2',
1990
+ fontSize: 'text-base sm:text-lg',
1991
+ badgeSize: 'w-6 h-6',
1992
+ badgeMargin: '-ml-2',
1993
+ minWidthSearch: 'min-w-[220px]',
1994
+ },
1995
+ };
1996
+
1997
+ /**
1998
+ * AuroraSearchPill Component
1999
+ *
2000
+ * An ultra-premium AI search pill with an ambient rotating aurora conic glow,
2001
+ * 1.5px illuminated border track, and smooth transition between pulsing dots and
2002
+ * active search query with source badges.
2003
+ */
2004
+ export const AuroraSearchPill = React.forwardRef<HTMLDivElement, AuroraSearchPillProps>(
2005
+ (
2006
+ {
2007
+ isSearching: controlledSearching,
2008
+ defaultSearching = false,
2009
+ onToggle,
2010
+ searchLabel = 'Search...',
2011
+ sources = DEFAULT_SOURCES,
2012
+ sourceAvatars,
2013
+ theme = 'auto',
2014
+ size = 'md',
2015
+ glowIntensity = 'medium',
2016
+ speed = 'normal',
2017
+ spinMode = 'always',
2018
+ isSpinning: controlledSpinning,
2019
+ autoCycle = false,
2020
+ cycleInterval = 2400,
2021
+ className,
2022
+ onClick,
2023
+ onMouseEnter,
2024
+ onMouseLeave,
2025
+ ...props
2026
+ },
2027
+ ref
2028
+ ) => {
2029
+ const isControlled = controlledSearching !== undefined;
2030
+ const [uncontrolledSearching, setUncontrolledSearching] = React.useState(defaultSearching);
2031
+ const active = isControlled ? controlledSearching : uncontrolledSearching;
2032
+
2033
+ const [isHovered, setIsHovered] = React.useState(false);
2034
+
2035
+ // Unique style injection ID for CSS custom property and keyframes
2036
+ const instanceId = React.useId().replace(/:/g, '');
2037
+
2038
+ // Resolve active sources list (support direct sourceAvatars list)
2039
+ const activeSources = React.useMemo<AuroraSearchSource[]>(() => {
2040
+ if (sourceAvatars && sourceAvatars.length > 0) {
2041
+ return sourceAvatars.map((url, i): AuroraSearchSource => ({
2042
+ id: \`avatar-\${i}\`,
2043
+ avatarUrl: url,
2044
+ label: \`Source \${i + 1}\`,
2045
+ type: 'custom',
2046
+ }));
2047
+ }
2048
+ return sources;
2049
+ }, [sourceAvatars, sources]);
2050
+
2051
+ // Determine whether the aurora beam should actively rotate (default: always on)
2052
+ const shouldSpin = React.useMemo(() => {
2053
+ if (controlledSpinning !== undefined) return controlledSpinning;
2054
+ if (spinMode === 'never') return false;
2055
+ if (spinMode === 'searching') return active;
2056
+ if (spinMode === 'hover') return isHovered;
2057
+ // Default: 'always' -> continuously rotates in both idle (dots) and searching states
2058
+ return true;
2059
+ }, [controlledSpinning, spinMode, isHovered, active]);
2060
+
2061
+ // Auto demo cycling
2062
+ React.useEffect(() => {
2063
+ if (!autoCycle) return;
2064
+ const interval = setInterval(() => {
2065
+ if (isControlled) {
2066
+ onToggle?.(!active);
2067
+ } else {
2068
+ setUncontrolledSearching((prev) => {
2069
+ const next = !prev;
2070
+ onToggle?.(next);
2071
+ return next;
2072
+ });
2073
+ }
2074
+ }, cycleInterval);
2075
+
2076
+ return () => clearInterval(interval);
2077
+ }, [autoCycle, cycleInterval, active, isControlled, onToggle]);
2078
+
2079
+ const handleToggle = (e: React.MouseEvent<HTMLDivElement>) => {
2080
+ onClick?.(e);
2081
+ if (!isControlled) {
2082
+ setUncontrolledSearching(!active);
2083
+ }
2084
+ onToggle?.(!active);
2085
+ };
2086
+
2087
+ const sizeStyle = SIZE_CONFIG[size] || SIZE_CONFIG.md;
2088
+ const animationDuration = SPEED_MAP[speed] || SPEED_MAP.normal;
2089
+ const glowAlpha = GLOW_OPACITY[glowIntensity] ?? GLOW_OPACITY.medium;
2090
+
2091
+ // Theme resolution for pill body
2092
+ const bodyThemeClass =
2093
+ theme === 'light'
2094
+ ? 'bg-white text-slate-900 border-white/60 shadow-sm'
2095
+ : theme === 'dark'
2096
+ ? 'bg-[#090d16] text-white border-white/10 shadow-lg shadow-black/40'
2097
+ : 'bg-white text-slate-900 dark:bg-[#090d16] dark:text-white border-white/60 dark:border-white/10 shadow-sm dark:shadow-black/40';
2098
+
2099
+ const dotsColorClass =
2100
+ theme === 'light'
2101
+ ? 'bg-slate-900'
2102
+ : theme === 'dark'
2103
+ ? 'bg-white'
2104
+ : 'bg-slate-900 dark:bg-white';
2105
+
2106
+ return (
2107
+ <div
2108
+ ref={ref}
2109
+ onClick={handleToggle}
2110
+ onMouseEnter={(e) => {
2111
+ setIsHovered(true);
2112
+ onMouseEnter?.(e);
2113
+ }}
2114
+ onMouseLeave={(e) => {
2115
+ setIsHovered(false);
2116
+ onMouseLeave?.(e);
2117
+ }}
2118
+ role="button"
2119
+ tabIndex={0}
2120
+ aria-pressed={active}
2121
+ aria-label={active ? \`Searching: \${searchLabel}\` : 'Activate AI Search'}
2122
+ onKeyDown={(e) => {
2123
+ if (e.key === 'Enter' || e.key === ' ') {
2124
+ e.preventDefault();
2125
+ handleToggle(e as unknown as React.MouseEvent<HTMLDivElement>);
2126
+ }
2127
+ }}
2128
+ className={cn(
2129
+ 'relative inline-flex items-center justify-center cursor-pointer select-none isolate outline-none group',
2130
+ 'transition-transform duration-200 ease-out active:scale-[0.96] focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2',
2131
+ className
2132
+ )}
2133
+ {...props}
2134
+ >
2135
+ {/* Scoped CSS for hardware accelerated conic rotation and pulse */}
2136
+ <style dangerouslySetInnerHTML={{
2137
+ __html: \`
2138
+ @property --aurora-deg {
2139
+ syntax: '<angle>';
2140
+ initial-value: 0deg;
2141
+ inherits: false;
2142
+ }
2143
+ @keyframes spinAurora {
2144
+ from {
2145
+ --aurora-deg: 0deg;
2146
+ }
2147
+ to {
2148
+ --aurora-deg: 360deg;
2149
+ }
2150
+ }
2151
+ @keyframes dotPulse {
2152
+ 0%, 80%, 100% {
2153
+ opacity: 0.35;
2154
+ transform: scale(0.75);
2155
+ }
2156
+ 40% {
2157
+ opacity: 1;
2158
+ transform: scale(1.15);
2159
+ }
2160
+ }
2161
+ \`,
2162
+ }} />
2163
+
2164
+ {/* 1. Ambient Volumetric Glow (Aurora Ambient Glow) */}
2165
+ {glowIntensity !== 'none' && (
2166
+ <div
2167
+ className="absolute -inset-1.5 rounded-full pointer-events-none blur-md z-0 transition-opacity duration-300"
2168
+ style={{
2169
+ opacity: glowAlpha,
2170
+ background: \`conic-gradient(
2171
+ from var(--aurora-deg, 0deg) at 50% 50%,
2172
+ transparent 0deg,
2173
+ rgba(59, 130, 246, 0.75) 60deg,
2174
+ rgba(139, 92, 246, 0.9) 110deg,
2175
+ rgba(236, 72, 153, 0.95) 160deg,
2176
+ rgba(244, 63, 94, 0.8) 200deg,
2177
+ transparent 250deg,
2178
+ transparent 360deg
2179
+ )\`,
2180
+ animation: shouldSpin
2181
+ ? \`spinAurora \${animationDuration} linear infinite\`
2182
+ : undefined,
2183
+ }}
2184
+ />
2185
+ )}
2186
+
2187
+ {/* 2. Sharp 1.5px Conic Border Track */}
2188
+ <div
2189
+ className="relative z-10 p-[1.5px] rounded-full transition-shadow duration-300 shadow-sm"
2190
+ style={{
2191
+ background: \`conic-gradient(
2192
+ from var(--aurora-deg, 0deg) at 50% 50%,
2193
+ rgba(226, 232, 240, 0.8) 0deg,
2194
+ rgba(59, 130, 246, 0.85) 60deg,
2195
+ rgba(139, 92, 246, 1) 110deg,
2196
+ rgba(236, 72, 153, 1) 160deg,
2197
+ rgba(244, 63, 94, 0.85) 200deg,
2198
+ rgba(226, 232, 240, 0.6) 260deg,
2199
+ rgba(226, 232, 240, 0.8) 360deg
2200
+ )\`,
2201
+ animation: shouldSpin
2202
+ ? \`spinAurora \${animationDuration} linear infinite\`
2203
+ : undefined,
2204
+ }}
2205
+ >
2206
+ {/* 3. Center Pill Body */}
2207
+ <div
2208
+ className={cn(
2209
+ 'relative z-20 rounded-full flex items-center justify-center overflow-hidden border',
2210
+ sizeStyle.height,
2211
+ active ? cn(sizeStyle.paddingSearch, sizeStyle.minWidthSearch) : sizeStyle.paddingDots,
2212
+ bodyThemeClass,
2213
+ 'transition-all duration-500 [transition-timing-function:cubic-bezier(0.16,1,0.3,1)]'
2214
+ )}
2215
+ >
2216
+ {/* STATE 1: Pulsing Dots (Idle/Listening) */}
2217
+ <div
2218
+ className={cn(
2219
+ 'flex items-center',
2220
+ sizeStyle.dotGap,
2221
+ 'transition-all duration-400 [transition-timing-function:cubic-bezier(0.16,1,0.3,1)]',
2222
+ active
2223
+ ? 'opacity-0 scale-50 -translate-y-2 pointer-events-none absolute'
2224
+ : 'opacity-100 scale-100 translate-y-0'
2225
+ )}
2226
+ >
2227
+ {[0, 1, 2].map((idx) => (
2228
+ <span
2229
+ key={idx}
2230
+ className={cn('rounded-full inline-block', sizeStyle.dotSize, dotsColorClass)}
2231
+ style={{
2232
+ animation: \`dotPulse 1.4s ease-in-out infinite both\`,
2233
+ animationDelay: \`\${idx === 0 ? -0.32 : idx === 1 ? -0.16 : 0}s\`,
2234
+ }}
2235
+ />
2236
+ ))}
2237
+ </div>
2238
+
2239
+ {/* STATE 2: Active Search Label + Overlapping Sources */}
2240
+ <div
2241
+ className={cn(
2242
+ 'flex items-center gap-2.5 whitespace-nowrap',
2243
+ 'transition-all duration-400 [transition-timing-function:cubic-bezier(0.16,1,0.3,1)]',
2244
+ active
2245
+ ? 'opacity-100 scale-100 translate-y-0'
2246
+ : 'opacity-0 scale-90 translate-y-2 pointer-events-none absolute'
2247
+ )}
2248
+ >
2249
+ {/* Search Title */}
2250
+ <span className={cn('font-medium tracking-tight', sizeStyle.fontSize)}>
2251
+ {searchLabel}
2252
+ </span>
2253
+
2254
+ {/* Overlapping Sources Row */}
2255
+ {activeSources && activeSources.length > 0 && (
2256
+ <div className="inline-flex items-center pl-0.5">
2257
+ {activeSources.map((src, i) => {
2258
+ const isFirst = i === 0;
2259
+
2260
+ return (
2261
+ <div
2262
+ key={src.id || i}
2263
+ title={src.label || src.id}
2264
+ className={cn(
2265
+ 'rounded-full border-[1.5px] border-white dark:border-zinc-900 flex items-center justify-center shrink-0 shadow-xs overflow-hidden',
2266
+ sizeStyle.badgeSize,
2267
+ !isFirst && sizeStyle.badgeMargin
2268
+ )}
2269
+ style={{
2270
+ backgroundColor:
2271
+ src.type === 'globe'
2272
+ ? '#0b1120'
2273
+ : src.type === 'github'
2274
+ ? '#ffffff'
2275
+ : src.type === 'claude'
2276
+ ? '#d97757'
2277
+ : src.type === 'chatgpt'
2278
+ ? '#10a37f'
2279
+ : src.type === 'perplexity'
2280
+ ? '#1fb8cd'
2281
+ : src.type === 'custom' && src.bg
2282
+ ? src.bg
2283
+ : undefined,
2284
+ background:
2285
+ src.type === 'gradient'
2286
+ ? 'linear-gradient(135deg, #06b6d4 45%, #3b82f6 55%)'
2287
+ : undefined,
2288
+ }}
2289
+ >
2290
+ {src.avatarUrl ? (
2291
+ <img
2292
+ src={src.avatarUrl}
2293
+ alt={src.label || src.id}
2294
+ className="w-full h-full object-cover"
2295
+ />
2296
+ ) : src.icon ? (
2297
+ src.icon
2298
+ ) : src.type === 'globe' ? (
2299
+ <Globe className="w-3 h-3 text-sky-400 stroke-[2.5]" />
2300
+ ) : src.type === 'github' ? (
2301
+ <svg className="w-3.5 h-3.5 fill-[#181717]" viewBox="0 0 24 24">
2302
+ <path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12z" />
2303
+ </svg>
2304
+ ) : src.type === 'claude' ? (
2305
+ <Sparkles className="w-2.5 h-2.5 text-white" />
2306
+ ) : src.type === 'chatgpt' ? (
2307
+ <div className="w-2 h-2 rounded-full bg-white" />
2308
+ ) : src.type === 'perplexity' ? (
2309
+ <Sparkles className="w-2.5 h-2.5 text-white" />
2310
+ ) : src.initials ? (
2311
+ <span className="text-[8px] font-bold text-white uppercase">
2312
+ {src.initials}
2313
+ </span>
2314
+ ) : null}
2315
+ </div>
2316
+ );
2317
+ })}
2318
+ </div>
2319
+ )}
2320
+ </div>
2321
+ </div>
2322
+ </div>
2323
+ </div>
2324
+ );
2325
+ }
2326
+ );
2327
+
2328
+ AuroraSearchPill.displayName = 'AuroraSearchPill';
2329
+ `
2330
+ };
2331
+
2332
+ // src/registry/template-ai-startup.ts
2333
+ var templateAiStartup = {
2334
+ name: "template-ai-startup",
2335
+ dependencies: ["framer-motion", "lucide-react"],
2336
+ fileName: "template-ai-startup.tsx",
2337
+ content: `"use client";
2338
+
2339
+ import React, { useState } from "react";
2340
+ import { motion, AnimatePresence } from "framer-motion";
2341
+ import {
2342
+ Sparkles,
2343
+ ArrowRight,
2344
+ Cpu,
2345
+ Zap,
2346
+ Shield,
2347
+ Check,
2348
+ ChevronRight,
2349
+ Send,
2350
+ Terminal,
2351
+ Activity,
2352
+ } from "lucide-react";
2353
+
2354
+ export default function AiStartupTemplate() {
2355
+ const [selectedModel, setSelectedModel] = useState<"DeepSeek-R1" | "Claude-3.5" | "GPT-4o">("DeepSeek-R1");
2356
+ const [promptText, setPromptText] = useState("Synthesize an edge-routed vector indexing service");
2357
+ const [isGenerating, setIsGenerating] = useState(false);
2358
+ const [generatedOutput, setGeneratedOutput] = useState<string | null>(
2359
+ "\u2713 Tensor graph compiled. 4 regions provisioned. TTFT: 14ms. Throughput: 142 tok/s."
2360
+ );
2361
+ const [billingCycle, setBillingCycle] = useState<"monthly" | "annual">("annual");
2362
+
2363
+ const handleSynthesize = (e: React.FormEvent) => {
2364
+ e.preventDefault();
2365
+ if (!promptText.trim()) return;
2366
+ setIsGenerating(true);
2367
+ setGeneratedOutput(null);
2368
+ setTimeout(() => {
2369
+ setIsGenerating(false);
2370
+ setGeneratedOutput(
2371
+ \`\u2713 [\${selectedModel}] execution complete. 2,140 tokens streamed with zero-copy serialization. Latency: 1.1ms.\`
2372
+ );
2373
+ }, 900);
2374
+ };
2375
+
2009
2376
  return (
2010
- <Badge variant="outline" className={className} {...props}>
2011
- <span className={cn("h-1.5 w-1.5 rounded-full mr-1.5", dotColor)} />
2012
- {children || text}
2013
- </Badge>
2014
- )
2377
+ <div className="min-h-screen bg-[#08090d] text-zinc-100 font-sans selection:bg-indigo-500/30">
2378
+ <header className="sticky top-0 z-30 backdrop-blur-xl border-b border-white/10 bg-[#08090d]/80">
2379
+ <div className="max-w-6xl mx-auto px-4 sm:px-6 h-14 flex items-center justify-between">
2380
+ <div className="flex items-center gap-2">
2381
+ <div className="h-7 w-7 rounded-lg bg-indigo-600 flex items-center justify-center text-white">
2382
+ <Sparkles className="h-4 w-4" />
2383
+ </div>
2384
+ <span className="font-bold text-sm">Synthetix AI</span>
2385
+ </div>
2386
+ <button className="text-xs font-semibold px-3.5 py-1.5 rounded-lg bg-indigo-600 text-white hover:bg-indigo-500">
2387
+ Get API Key
2388
+ </button>
2389
+ </div>
2390
+ </header>
2391
+
2392
+ <section className="pt-20 pb-16 px-4 sm:px-6 max-w-5xl mx-auto text-center">
2393
+ <div className="inline-flex items-center gap-2 px-3 py-1 rounded-full border border-indigo-500/30 bg-indigo-500/10 text-indigo-400 text-xs font-mono mb-6">
2394
+ <Cpu className="h-3 w-3" />
2395
+ <span>Next-Gen Autonomous Inference Engine</span>
2396
+ </div>
2397
+
2398
+ <h1 className="text-4xl sm:text-6xl font-extrabold tracking-tight mb-5 leading-tight">
2399
+ Zero Latency. Real Autonomous Intelligence.
2400
+ </h1>
2401
+
2402
+ <p className="text-sm sm:text-base text-zinc-400 max-w-2xl mx-auto mb-10">
2403
+ Stream deep reasoning tokens directly to edge clients. Synthesize complex backend architectures,
2404
+ fine-tune proprietary weights, and run microsecond telemetry without cold starts.
2405
+ </p>
2406
+
2407
+ <form
2408
+ onSubmit={handleSynthesize}
2409
+ className="max-w-2xl mx-auto p-2 rounded-2xl bg-zinc-900 border border-white/10 flex flex-col sm:flex-row gap-2 shadow-2xl"
2410
+ >
2411
+ <input
2412
+ type="text"
2413
+ value={promptText}
2414
+ onChange={(e) => setPromptText(e.target.value)}
2415
+ className="flex-1 bg-transparent px-3 py-2 text-xs text-white focus:outline-none"
2416
+ />
2417
+ <button
2418
+ type="submit"
2419
+ disabled={isGenerating}
2420
+ className="px-4 py-2 rounded-xl bg-indigo-600 text-white text-xs font-semibold shrink-0"
2421
+ >
2422
+ {isGenerating ? "Synthesizing..." : "Execute"}
2423
+ </button>
2424
+ </form>
2425
+
2426
+ <AnimatePresence>
2427
+ {generatedOutput && (
2428
+ <motion.div
2429
+ initial={{ opacity: 0, y: 8 }}
2430
+ animate={{ opacity: 1, y: 0 }}
2431
+ className="mt-4 p-3.5 rounded-xl border border-indigo-500/30 bg-indigo-950/20 text-xs font-mono text-indigo-300 max-w-2xl mx-auto text-left"
2432
+ >
2433
+ {generatedOutput}
2434
+ </motion.div>
2435
+ )}
2436
+ </AnimatePresence>
2437
+ </section>
2438
+ </div>
2439
+ );
2015
2440
  }
2441
+ `
2442
+ };
2016
2443
 
2017
- export interface GradientOutlineBadgeProps extends React.HTMLAttributes<HTMLDivElement> {
2018
- text?: string;
2444
+ // src/registry/template-modern-saas.ts
2445
+ var templateModernSaas = {
2446
+ name: "template-modern-saas",
2447
+ dependencies: ["framer-motion", "lucide-react"],
2448
+ fileName: "template-modern-saas.tsx",
2449
+ content: `"use client";
2450
+
2451
+ import React, { useState } from "react";
2452
+ import { motion } from "framer-motion";
2453
+ import { Command, Search, GitBranch, CheckCircle2, ArrowUpRight, ChevronRight, Zap } from "lucide-react";
2454
+
2455
+ export default function ModernSaasTemplate() {
2456
+ const [activeTab, setActiveTab] = useState<"branch" | "edge" | "telemetry">("branch");
2457
+
2458
+ return (
2459
+ <div className="min-h-screen bg-[#090b10] text-zinc-100 font-sans">
2460
+ <header className="sticky top-0 z-30 border-b border-white/10 bg-[#090b10]/80 backdrop-blur-xl">
2461
+ <div className="max-w-6xl mx-auto px-4 sm:px-6 h-14 flex items-center justify-between">
2462
+ <span className="font-bold text-sm">Aura Cloud</span>
2463
+ <button className="text-xs px-3 py-1.5 rounded-lg bg-white/10 hover:bg-white/20 text-white font-medium">
2464
+ Console
2465
+ </button>
2466
+ </div>
2467
+ </header>
2468
+
2469
+ <section className="pt-20 pb-16 px-4 sm:px-6 max-w-5xl mx-auto text-center">
2470
+ <div className="inline-flex items-center gap-2 px-3 py-1 rounded-full border border-blue-500/30 bg-blue-500/10 text-blue-400 text-xs font-mono mb-5">
2471
+ <GitBranch className="h-3 w-3" />
2472
+ <span>Continuous Edge Infrastructure</span>
2473
+ </div>
2474
+
2475
+ <h1 className="text-4xl sm:text-6xl font-extrabold tracking-tight mb-5 leading-tight">
2476
+ The Developer Cloud for Ultra-Fast Teams.
2477
+ </h1>
2478
+
2479
+ <p className="text-sm sm:text-base text-zinc-400 max-w-xl mx-auto mb-10">
2480
+ Push code, spawn instant ephemeral preview environments, and deploy across 300 global edge locations
2481
+ with zero configuration.
2482
+ </p>
2483
+ </section>
2484
+ </div>
2485
+ );
2019
2486
  }
2487
+ `
2488
+ };
2020
2489
 
2021
- export const GradientOutlineBadge = ({ children, text, className, ...props }: GradientOutlineBadgeProps) => (
2022
- <Badge className={cn("p-[1px] bg-gradient-to-r from-violet-500 to-pink-500 rounded-full border-0", className)} {...props}>
2023
- <div className="bg-background text-foreground rounded-full px-2.5 py-0.5 text-xs font-semibold">
2024
- {children || text}
2490
+ // src/registry/template-analytics-dashboard.ts
2491
+ var templateAnalyticsDashboard = {
2492
+ name: "template-analytics-dashboard",
2493
+ dependencies: ["framer-motion", "lucide-react"],
2494
+ fileName: "template-analytics-dashboard.tsx",
2495
+ content: `"use client";
2496
+
2497
+ import React, { useState } from "react";
2498
+ import { BarChart3, TrendingUp, Users, CreditCard, ArrowUpRight, Download } from "lucide-react";
2499
+
2500
+ export default function AnalyticsDashboardTemplate() {
2501
+ const [dateRange, setDateRange] = useState("30D");
2502
+
2503
+ return (
2504
+ <div className="min-h-screen bg-[#08090d] text-zinc-100 flex flex-col md:flex-row font-sans">
2505
+ <aside className="w-full md:w-56 border-r border-white/10 p-4 shrink-0 bg-[#08090d]">
2506
+ <div className="font-bold text-sm mb-6">Prism Analytics</div>
2507
+ <nav className="space-y-1 text-xs">
2508
+ <button className="w-full text-left px-3 py-2 rounded-lg bg-emerald-600 text-white font-semibold">
2509
+ Overview
2510
+ </button>
2511
+ <button className="w-full text-left px-3 py-2 rounded-lg text-zinc-400 hover:text-white">
2512
+ Inflows
2513
+ </button>
2514
+ </nav>
2515
+ </aside>
2516
+ <main className="flex-1 p-6">
2517
+ <h1 className="text-2xl font-bold mb-4">Executive Telemetry</h1>
2518
+ </main>
2025
2519
  </div>
2026
- </Badge>
2027
- )
2520
+ );
2521
+ }
2522
+ `
2523
+ };
2028
2524
 
2029
- export interface IconBadgeProps extends React.HTMLAttributes<HTMLDivElement> {
2030
- icon?: React.ReactNode;
2031
- text?: string;
2525
+ // src/registry/template-devtools-cli.ts
2526
+ var templateDevtoolsCli = {
2527
+ name: "template-devtools-cli",
2528
+ dependencies: ["framer-motion", "lucide-react"],
2529
+ fileName: "template-devtools-cli.tsx",
2530
+ content: `"use client";
2531
+
2532
+ import React, { useState } from "react";
2533
+ import { Terminal, Copy, Check, Star } from "lucide-react";
2534
+
2535
+ export default function DevtoolsCliTemplate() {
2536
+ const [copied, setCopied] = useState(false);
2537
+
2538
+ return (
2539
+ <div className="min-h-screen bg-[#090a10] text-zinc-100 font-mono p-6">
2540
+ <header className="flex justify-between items-center mb-12">
2541
+ <span className="font-bold text-sm">HyperTerminal</span>
2542
+ </header>
2543
+ </div>
2544
+ );
2032
2545
  }
2546
+ `
2547
+ };
2033
2548
 
2034
- export const IconBadge = ({ children, icon, text, className, ...props }: IconBadgeProps) => {
2035
- const renderIcon = () => {
2036
- if (!icon) return null;
2037
- if (typeof icon === "string") {
2038
- if (icon.toLowerCase() === "star") {
2039
- return <Star className="h-3 w-3 mr-1" />
2040
- }
2041
- return <span className="mr-1">{icon}</span>
2042
- }
2043
- return <span className="mr-1">{icon}</span>
2044
- }
2549
+ // src/registry/template-creative-portfolio.ts
2550
+ var templateCreativePortfolio = {
2551
+ name: "template-creative-portfolio",
2552
+ dependencies: ["framer-motion", "lucide-react"],
2553
+ fileName: "template-creative-portfolio.tsx",
2554
+ content: `"use client";
2555
+
2556
+ import React from "react";
2557
+ import { ArrowUpRight, Award, X } from "lucide-react";
2045
2558
 
2559
+ export default function CreativePortfolioTemplate() {
2046
2560
  return (
2047
- <Badge className={cn("inline-flex items-center gap-1", className)} {...props}>
2048
- {renderIcon()}
2049
- {children || text}
2050
- </Badge>
2051
- )
2561
+ <div className="min-h-screen bg-[#09090b] text-zinc-100 font-serif p-8">
2562
+ <header className="flex justify-between items-center mb-16 font-sans">
2563
+ <span className="font-bold uppercase tracking-tight">Studio Monolith</span>
2564
+ </header>
2565
+ <h1 className="text-5xl font-light leading-tight mb-12">
2566
+ Sculpting singular digital experiences for luxury institutions.
2567
+ </h1>
2568
+ </div>
2569
+ );
2052
2570
  }
2571
+ `
2572
+ };
2053
2573
 
2054
- export interface FloatingBadgeProps extends React.HTMLAttributes<HTMLDivElement> {
2055
- text?: string;
2574
+ // src/registry/template-fintech-app.ts
2575
+ var templateFintechApp = {
2576
+ name: "template-fintech-app",
2577
+ dependencies: ["framer-motion", "lucide-react"],
2578
+ fileName: "template-fintech-app.tsx",
2579
+ content: `"use client";
2580
+
2581
+ import React, { useState } from "react";
2582
+ import { CreditCard, Send, Lock, Unlock, ShieldCheck } from "lucide-react";
2583
+
2584
+ export default function FintechAppTemplate() {
2585
+ const [frozen, setFrozen] = useState(false);
2586
+
2587
+ return (
2588
+ <div className="min-h-screen bg-[#08090d] text-zinc-100 font-sans p-6">
2589
+ <h1 className="text-2xl font-bold mb-4">Apex Treasury</h1>
2590
+ </div>
2591
+ );
2056
2592
  }
2593
+ `
2594
+ };
2057
2595
 
2058
- export const FloatingBadge = ({ children, text, className, ...props }: FloatingBadgeProps) => (
2059
- <Badge className={cn("absolute -top-2 -right-2 z-10 animate-[bounce_3s_infinite]", className)} {...props}>
2060
- {children || text}
2061
- </Badge>
2062
- )
2596
+ // src/registry/template-ecommerce-store.ts
2597
+ var templateEcommerceStore = {
2598
+ name: "template-ecommerce-store",
2599
+ dependencies: ["framer-motion", "lucide-react"],
2600
+ fileName: "template-ecommerce-store.tsx",
2601
+ content: `"use client";
2063
2602
 
2064
- export interface ProgressBadgeProps extends React.HTMLAttributes<HTMLDivElement> {
2065
- progress?: number;
2066
- text?: string;
2603
+ import React from "react";
2604
+ import { ShoppingBag, Heart, Truck, RotateCcw } from "lucide-react";
2605
+
2606
+ export default function EcommerceStoreTemplate() {
2607
+ return (
2608
+ <div className="min-h-screen bg-[#0c0d12] text-zinc-100 p-8">
2609
+ <h1 className="text-3xl font-bold">Atelier Objects</h1>
2610
+ </div>
2611
+ );
2067
2612
  }
2613
+ `
2614
+ };
2068
2615
 
2069
- export const ProgressBadge = ({ children, progress = 50, text, className, ...props }: ProgressBadgeProps) => (
2070
- <Badge variant="outline" className={cn("relative overflow-hidden", className)} {...props}>
2071
- <div className="absolute inset-y-0 left-0 bg-primary/10 transition-all duration-300" style={{ width: \`\${progress}%\` }} />
2072
- <span className="relative z-10">{children || (text ? \`\${text} (\${progress}%)\` : \`\${progress}%\`)}</span>
2073
- </Badge>
2074
- )
2616
+ // src/registry/template-agency-creative.ts
2617
+ var templateAgencyCreative = {
2618
+ name: "template-agency-creative",
2619
+ dependencies: ["framer-motion", "lucide-react"],
2620
+ fileName: "template-agency-creative.tsx",
2621
+ content: `"use client";
2075
2622
 
2076
- export interface StatusRingBadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
2077
- status?: "success" | "error" | "warning" | "active" | string;
2623
+ import React from "react";
2624
+ import { ArrowUpRight, Sparkles } from "lucide-react";
2625
+
2626
+ export default function AgencyCreativeTemplate() {
2627
+ return (
2628
+ <div className="min-h-screen bg-[#08090d] text-zinc-100 p-8 font-sans">
2629
+ <h1 className="text-6xl font-black uppercase">Vanguard Digital</h1>
2630
+ </div>
2631
+ );
2078
2632
  }
2633
+ `
2634
+ };
2079
2635
 
2080
- export const StatusRingBadge = ({ status = "success", children, className, ...props }: StatusRingBadgeProps) => {
2081
- const ringColors: Record<string, string> = {
2082
- success: "border-emerald-500/30 ring-emerald-500/20 bg-emerald-500",
2083
- active: "border-emerald-500/30 ring-emerald-500/20 bg-emerald-500",
2084
- error: "border-red-500/30 ring-red-500/20 bg-red-500",
2085
- warning: "border-amber-500/30 ring-amber-500/20 bg-amber-500",
2086
- }
2087
- const colorClass = ringColors[status] || ringColors.success;
2636
+ // src/registry/template-ai-chat.ts
2637
+ var templateAiChat = {
2638
+ name: "template-ai-chat",
2639
+ dependencies: ["framer-motion", "lucide-react"],
2640
+ fileName: "template-ai-chat.tsx",
2641
+ content: `"use client";
2642
+
2643
+ import React, { useState } from "react";
2644
+ import { Send, Cpu, Copy, Check } from "lucide-react";
2645
+
2646
+ export default function AiChatTemplate() {
2088
2647
  return (
2089
- <span className={cn("relative flex h-2.5 w-2.5 rounded-full ring-4 border-2 border-transparent", colorClass, className)} {...props} />
2090
- )
2648
+ <div className="min-h-screen bg-[#08090d] text-zinc-100 flex p-4 font-sans">
2649
+ <div className="flex-1">Cortex AI Assistant</div>
2650
+ </div>
2651
+ );
2091
2652
  }
2653
+ `
2654
+ };
2092
2655
 
2093
- export interface NeonOutlineBadgeProps extends React.HTMLAttributes<HTMLDivElement> {
2094
- text?: string;
2656
+ // src/registry/template-project-management.ts
2657
+ var templateProjectManagement = {
2658
+ name: "template-project-management",
2659
+ dependencies: ["framer-motion", "lucide-react"],
2660
+ fileName: "template-project-management.tsx",
2661
+ content: `"use client";
2662
+
2663
+ import React, { useState } from "react";
2664
+ import { Plus, Kanban } from "lucide-react";
2665
+
2666
+ export default function ProjectManagementTemplate() {
2667
+ return (
2668
+ <div className="min-h-screen bg-[#08090d] text-zinc-100 p-6 font-sans">
2669
+ <h1 className="text-xl font-bold">Orbit Flow</h1>
2670
+ </div>
2671
+ );
2095
2672
  }
2673
+ `
2674
+ };
2096
2675
 
2097
- export const NeonOutlineBadge = ({ children, text, className, ...props }: NeonOutlineBadgeProps) => (
2098
- <Badge variant="outline" className={cn("border-2 border-primary text-primary shadow-[0_0_10px_rgba(var(--primary-rgb),0.4)] bg-transparent", className)} {...props}>
2099
- {children || text}
2100
- </Badge>
2101
- )
2676
+ // src/registry/template-startup-waitlist.ts
2677
+ var templateStartupWaitlist = {
2678
+ name: "template-startup-waitlist",
2679
+ dependencies: ["framer-motion", "lucide-react"],
2680
+ fileName: "template-startup-waitlist.tsx",
2681
+ content: `"use client";
2102
2682
 
2103
- export interface TagLabelProps extends React.HTMLAttributes<HTMLSpanElement> {
2104
- text?: string;
2683
+ import React, { useState } from "react";
2684
+ import { ArrowRight, Clock, Users } from "lucide-react";
2685
+
2686
+ export default function StartupWaitlistTemplate() {
2687
+ return (
2688
+ <div className="min-h-screen bg-[#08090d] text-zinc-100 p-8 text-center flex flex-col justify-center">
2689
+ <h1 className="text-5xl font-extrabold mb-4">Genesis Stealth</h1>
2690
+ </div>
2691
+ );
2105
2692
  }
2693
+ `
2694
+ };
2106
2695
 
2107
- export const TagLabel = ({ children, text, className, ...props }: TagLabelProps) => (
2108
- <span className={cn("px-2 py-1 bg-muted text-muted-foreground rounded-md text-xs font-medium text-muted-foreground hover:bg-muted/80 hover:text-foreground cursor-pointer transition-colors before:content-['#'] before:mr-0.5 before:opacity-50", className)} {...props}>
2109
- {children || text}
2110
- </span>
2111
- )
2696
+ // src/registry/template-docs-platform.ts
2697
+ var templateDocsPlatform = {
2698
+ name: "template-docs-platform",
2699
+ dependencies: ["framer-motion", "lucide-react"],
2700
+ fileName: "template-docs-platform.tsx",
2701
+ content: `"use client";
2702
+
2703
+ import React, { useState } from "react";
2704
+ import { Search, Code2, Send } from "lucide-react";
2705
+
2706
+ export default function DocsPlatformTemplate() {
2707
+ return (
2708
+ <div className="min-h-screen bg-[#08090d] text-zinc-100 p-6">
2709
+ <h1 className="text-3xl font-bold">Codex Documentation</h1>
2710
+ </div>
2711
+ );
2712
+ }
2112
2713
  `
2113
2714
  };
2114
2715
 
@@ -2118,7 +2719,22 @@ var registry = {
2118
2719
  modal,
2119
2720
  card,
2120
2721
  alert,
2121
- badge
2722
+ badge,
2723
+ "morphing-geometry": morphingGeometry,
2724
+ "aurora-border-fx": auroraBorderFX,
2725
+ "aurora-search-pill": auroraSearchPill,
2726
+ "template-ai-startup": templateAiStartup,
2727
+ "template-modern-saas": templateModernSaas,
2728
+ "template-analytics-dashboard": templateAnalyticsDashboard,
2729
+ "template-devtools-cli": templateDevtoolsCli,
2730
+ "template-creative-portfolio": templateCreativePortfolio,
2731
+ "template-fintech-app": templateFintechApp,
2732
+ "template-ecommerce-store": templateEcommerceStore,
2733
+ "template-agency-creative": templateAgencyCreative,
2734
+ "template-ai-chat": templateAiChat,
2735
+ "template-project-management": templateProjectManagement,
2736
+ "template-startup-waitlist": templateStartupWaitlist,
2737
+ "template-docs-platform": templateDocsPlatform
2122
2738
  };
2123
2739
 
2124
2740
  // src/commands/add.ts
@@ -2128,16 +2744,23 @@ function askQuestion(query) {
2128
2744
  output: process.stdout
2129
2745
  });
2130
2746
  return new Promise(
2131
- (resolve2) => rl.question(query, (ans) => {
2747
+ (resolve4) => rl.question(query, (ans) => {
2132
2748
  rl.close();
2133
- resolve2(ans);
2749
+ resolve4(ans);
2134
2750
  })
2135
2751
  );
2136
2752
  }
2137
- async function addCommand(components, options) {
2138
- if (components.length === 0) {
2139
- console.error("\x1B[31mError: Please specify components to add.\x1B[0m");
2140
- console.log("Example: npx nexoreui add button modal");
2753
+ async function addCommand(components, options = {}) {
2754
+ const allRegistryKeys = Object.keys(registry);
2755
+ let targetComponents = [...components];
2756
+ if (options.all || targetComponents.includes("--all")) {
2757
+ targetComponents = allRegistryKeys;
2758
+ console.log(`
2759
+ \x1B[36m\u26A1 Adding all ${targetComponents.length} components from NexoreUI registry...\x1B[0m`);
2760
+ }
2761
+ if (targetComponents.length === 0) {
2762
+ console.error("\x1B[31mError: Please specify components to add or use --all.\x1B[0m");
2763
+ console.log("Example: npx nexoreui add button modal table --all");
2141
2764
  return;
2142
2765
  }
2143
2766
  const project = detectProject(process.cwd());
@@ -2145,9 +2768,25 @@ async function addCommand(components, options) {
2145
2768
  \x1B[34mDetected project type:\x1B[0m ${project.projectType.toUpperCase()}`);
2146
2769
  console.log(`\x1B[34mDetected package manager:\x1B[0m ${project.packageManager}
2147
2770
  `);
2771
+ let customComponentsDir;
2772
+ let customUtilsFile;
2773
+ try {
2774
+ const configPath = path3.join(project.baseDir, "nexore.json");
2775
+ if (fs3.existsSync(configPath)) {
2776
+ const cfg = JSON.parse(fs3.readFileSync(configPath, "utf8"));
2777
+ if (cfg.aliases?.components) {
2778
+ customComponentsDir = cfg.aliases.components.replace(/^@\//, project.hasSrcDir ? "src/" : "");
2779
+ }
2780
+ if (cfg.aliases?.utils) {
2781
+ const utilBase = cfg.aliases.utils.replace(/^@\//, project.hasSrcDir ? "src/" : "");
2782
+ customUtilsFile = utilBase.endsWith(".ts") || utilBase.endsWith(".js") ? utilBase : `${utilBase}.ts`;
2783
+ }
2784
+ }
2785
+ } catch {
2786
+ }
2148
2787
  const componentsToInstall = /* @__PURE__ */ new Set();
2149
2788
  const invalidComponents = [];
2150
- const queue = [...components];
2789
+ const queue = [...targetComponents.filter((c) => c !== "--all")];
2151
2790
  while (queue.length > 0) {
2152
2791
  const compName = queue.shift();
2153
2792
  const registryItem = registry[compName];
@@ -2169,14 +2808,11 @@ async function addCommand(components, options) {
2169
2808
  console.log("Run \x1B[32mnpx nexoreui list\x1B[0m to see all available components.");
2170
2809
  return;
2171
2810
  }
2172
- const defaultComponentsDir = project.hasSrcDir ? "src/components/ui" : "components/ui";
2173
- const defaultUtilsFile = project.hasSrcDir ? "src/lib/utils.ts" : "lib/utils.ts";
2174
- let componentsDirInput = "";
2175
- let utilsFileInput = "";
2176
- if (options.yes) {
2177
- componentsDirInput = defaultComponentsDir;
2178
- utilsFileInput = defaultUtilsFile;
2179
- } else {
2811
+ const defaultComponentsDir = customComponentsDir || (project.hasSrcDir ? "src/components/ui" : "components/ui");
2812
+ const defaultUtilsFile = customUtilsFile || (project.hasSrcDir ? "src/lib/utils.ts" : "lib/utils.ts");
2813
+ let componentsDirInput = defaultComponentsDir;
2814
+ let utilsFileInput = defaultUtilsFile;
2815
+ if (!options.yes && !customComponentsDir) {
2180
2816
  const compPrompt = await askQuestion(`Where would you like to install the components? (default: ${defaultComponentsDir}): `);
2181
2817
  componentsDirInput = compPrompt.trim() || defaultComponentsDir;
2182
2818
  const utilsPrompt = await askQuestion(`Where should we create the utilities file (cn helper)? (default: ${defaultUtilsFile}): `);
@@ -2184,25 +2820,24 @@ async function addCommand(components, options) {
2184
2820
  }
2185
2821
  const absoluteComponentsDir = path3.resolve(project.baseDir, componentsDirInput);
2186
2822
  const absoluteUtilsFile = path3.resolve(project.baseDir, utilsFileInput);
2187
- console.log(`
2188
- \x1B[33mInstalling components to:\x1B[0m ${absoluteComponentsDir}`);
2823
+ console.log(`\x1B[33mInstalling components to:\x1B[0m ${absoluteComponentsDir}`);
2189
2824
  console.log(`\x1B[33mUsing cn helper from:\x1B[0m ${absoluteUtilsFile}
2190
2825
  `);
2191
2826
  ensureDir(absoluteComponentsDir);
2192
2827
  const didCreateCn = ensureCnUtil(absoluteUtilsFile);
2193
2828
  if (didCreateCn) {
2194
- console.log(`\x1B[32mCreated utilities file (cn helper) at:\x1B[0m ${utilsFileInput}`);
2195
- } else {
2196
- console.log(`\x1B[90mUtilities file already exists at:\x1B[0m ${utilsFileInput}`);
2829
+ console.log(`\x1B[32m\u2714 Created utilities file (cn helper) at:\x1B[0m ${utilsFileInput}`);
2197
2830
  }
2198
2831
  const npmDependencies = /* @__PURE__ */ new Set();
2199
2832
  npmDependencies.add("clsx");
2200
2833
  npmDependencies.add("tailwind-merge");
2834
+ npmDependencies.add("lucide-react");
2835
+ npmDependencies.add("framer-motion");
2201
2836
  for (const compName of componentsToInstall) {
2202
2837
  const registryItem = registry[compName];
2203
2838
  const targetPath = path3.join(absoluteComponentsDir, registryItem.fileName);
2204
2839
  copyComponentFile(registryItem.content, targetPath, absoluteUtilsFile);
2205
- console.log(`\x1B[32mAdded component:\x1B[0m ${compName} -> ${path3.join(componentsDirInput, registryItem.fileName)}`);
2840
+ console.log(`\x1B[32m\u2714 Added component:\x1B[0m ${compName} -> ${path3.join(componentsDirInput, registryItem.fileName)}`);
2206
2841
  registryItem.dependencies.forEach((dep) => npmDependencies.add(dep));
2207
2842
  }
2208
2843
  const depsArray = Array.from(npmDependencies);
@@ -2214,33 +2849,29 @@ async function addCommand(components, options) {
2214
2849
  const existingDeps = { ...packageJson.dependencies, ...packageJson.devDependencies };
2215
2850
  depsToInstall = depsArray.filter((dep) => !existingDeps[dep]);
2216
2851
  }
2217
- } catch (e) {
2852
+ } catch {
2218
2853
  }
2219
2854
  if (depsToInstall.length > 0) {
2220
2855
  console.log(`
2221
2856
  \x1B[33mInstalling external dependencies:\x1B[0m ${depsToInstall.join(", ")}...`);
2222
2857
  let installCmd = "npm install";
2223
- if (project.packageManager === "pnpm") {
2224
- installCmd = "pnpm add";
2225
- } else if (project.packageManager === "yarn") {
2226
- installCmd = "yarn add";
2227
- } else if (project.packageManager === "bun") {
2228
- installCmd = "bun add";
2229
- }
2858
+ if (project.packageManager === "pnpm") installCmd = "pnpm add";
2859
+ else if (project.packageManager === "yarn") installCmd = "yarn add";
2860
+ else if (project.packageManager === "bun") installCmd = "bun add";
2230
2861
  try {
2231
2862
  (0, import_child_process.execSync)(`${installCmd} ${depsToInstall.join(" ")}`, {
2232
2863
  stdio: "inherit",
2233
2864
  cwd: project.baseDir
2234
2865
  });
2235
- console.log("\x1B[32mDependencies installed successfully!\x1B[0m");
2236
- } catch (err) {
2237
- console.error("\x1B[31mFailed to install dependencies. Please run the command manually:\x1B[0m");
2866
+ console.log("\x1B[32m\u2714 Dependencies installed successfully!\x1B[0m");
2867
+ } catch {
2868
+ console.error("\x1B[31mFailed to install dependencies automatically. Please run:\x1B[0m");
2238
2869
  console.log(` ${installCmd} ${depsToInstall.join(" ")}`);
2239
2870
  }
2240
- } else {
2241
- console.log("\n\x1B[90mAll external dependencies are already installed.\x1B[0m");
2242
2871
  }
2243
- console.log("\n\x1B[32m\x1B[1mDone! NexoreUI components are ready to use.\x1B[0m\n");
2872
+ console.log(`
2873
+ \x1B[32m\x1B[1m\u{1F389} Done! ${componentsToInstall.size} NexoreUI component(s) ready to use.\x1B[0m
2874
+ `);
2244
2875
  }
2245
2876
 
2246
2877
  // src/commands/list.ts
@@ -2259,6 +2890,299 @@ function listCommand() {
2259
2890
  });
2260
2891
  }
2261
2892
 
2893
+ // src/commands/init.ts
2894
+ var fs5 = __toESM(require("fs"));
2895
+ var path5 = __toESM(require("path"));
2896
+ var readline2 = __toESM(require("readline"));
2897
+
2898
+ // src/utils/config.ts
2899
+ var fs4 = __toESM(require("fs"));
2900
+ var path4 = __toESM(require("path"));
2901
+ var import_child_process2 = require("child_process");
2902
+ var THEME_PALETTES = {
2903
+ indigo: { light: "hsl(250 85% 50%)", dark: "hsl(250 85% 65%)", rgb: "99 60 220" },
2904
+ violet: { light: "hsl(262.1 83.3% 57.8%)", dark: "hsl(263.4 70% 50.4%)", rgb: "139 92 246" },
2905
+ emerald: { light: "hsl(142.1 76.2% 36.3%)", dark: "hsl(142.1 70.6% 45.3%)", rgb: "16 185 129" },
2906
+ rose: { light: "hsl(346.8 77.2% 49.8%)", dark: "hsl(346.8 77.2% 55%)", rgb: "244 63 94" },
2907
+ amber: { light: "hsl(37.7 92.1% 50.2%)", dark: "hsl(37.7 92.1% 55%)", rgb: "245 158 11" },
2908
+ cyan: { light: "hsl(190.4 95% 39%)", dark: "hsl(188.7 94.5% 42.7%)", rgb: "6 182 212" },
2909
+ slate: { light: "hsl(240 5.9% 10%)", dark: "hsl(0 0% 98%)", rgb: "244 244 245" },
2910
+ neon: { light: "hsl(173 80% 40%)", dark: "hsl(173 100% 50%)", rgb: "0 255 220" }
2911
+ };
2912
+ function ensurePathAlias(baseDir, projectType, hasSrcDir) {
2913
+ let updated = false;
2914
+ const tsConfigPath = path4.join(baseDir, "tsconfig.json");
2915
+ const jsConfigPath = path4.join(baseDir, "jsconfig.json");
2916
+ const targetConfig = fs4.existsSync(tsConfigPath) ? tsConfigPath : fs4.existsSync(jsConfigPath) ? jsConfigPath : null;
2917
+ if (targetConfig) {
2918
+ try {
2919
+ const content = fs4.readFileSync(targetConfig, "utf8");
2920
+ const parsed = JSON.parse(content);
2921
+ parsed.compilerOptions = parsed.compilerOptions || {};
2922
+ parsed.compilerOptions.baseUrl = parsed.compilerOptions.baseUrl || ".";
2923
+ parsed.compilerOptions.paths = parsed.compilerOptions.paths || {};
2924
+ const aliasTarget = hasSrcDir ? ["./src/*"] : ["./*"];
2925
+ if (!parsed.compilerOptions.paths["@/*"]) {
2926
+ parsed.compilerOptions.paths["@/*"] = aliasTarget;
2927
+ fs4.writeFileSync(targetConfig, JSON.stringify(parsed, null, 2), "utf8");
2928
+ updated = true;
2929
+ }
2930
+ } catch {
2931
+ }
2932
+ }
2933
+ if (projectType === "vite") {
2934
+ const viteConfigFiles = ["vite.config.ts", "vite.config.js", "vite.config.mjs"];
2935
+ for (const fileName of viteConfigFiles) {
2936
+ const vitePath = path4.join(baseDir, fileName);
2937
+ if (fs4.existsSync(vitePath)) {
2938
+ let viteContent = fs4.readFileSync(vitePath, "utf8");
2939
+ if (!viteContent.includes("alias") && !viteContent.includes("'@'")) {
2940
+ const hasPathImport = viteContent.includes("from 'path'") || viteContent.includes('from "path"');
2941
+ let headerAdditions = "";
2942
+ if (!hasPathImport) {
2943
+ headerAdditions += `import path from 'path'
2944
+ import { fileURLToPath } from 'url'
2945
+ const __dirname = path.dirname(fileURLToPath(import.meta.url))
2946
+ `;
2947
+ }
2948
+ if (viteContent.includes("defineConfig({")) {
2949
+ viteContent = headerAdditions + viteContent.replace(
2950
+ "defineConfig({",
2951
+ `defineConfig({
2952
+ resolve: {
2953
+ alias: {
2954
+ '@': path.resolve(__dirname, './${hasSrcDir ? "src" : "."}'),
2955
+ },
2956
+ },`
2957
+ );
2958
+ fs4.writeFileSync(vitePath, viteContent, "utf8");
2959
+ updated = true;
2960
+ }
2961
+ }
2962
+ break;
2963
+ }
2964
+ }
2965
+ }
2966
+ return updated;
2967
+ }
2968
+ function injectThemeCss(baseDir, cssRelativePath, themeName, radiusValue) {
2969
+ const cssAbsolutePath = path4.join(baseDir, cssRelativePath);
2970
+ const palette = THEME_PALETTES[themeName] || THEME_PALETTES.cyan;
2971
+ const radius = typeof radiusValue === "number" ? radiusValue : parseFloat(radiusValue) || 1;
2972
+ const themeBlock = `
2973
+ @source "../node_modules/nexoreui/dist/**/*.{js,mjs}";
2974
+
2975
+ @theme {
2976
+ --color-background: var(--background);
2977
+ --color-foreground: var(--foreground);
2978
+ --color-card: var(--card);
2979
+ --color-card-foreground: var(--card-foreground);
2980
+ --color-primary: var(--primary);
2981
+ --color-primary-foreground: var(--primary-foreground);
2982
+ --color-border: var(--border);
2983
+ --radius-lg: var(--radius);
2984
+ --radius-md: calc(var(--radius) - 2px);
2985
+ --radius-sm: calc(var(--radius) - 4px);
2986
+ --font-sans: system-ui, -apple-system, sans-serif;
2987
+ }
2988
+
2989
+ :root {
2990
+ --background: hsl(0 0% 100%);
2991
+ --foreground: hsl(240 10% 3.9%);
2992
+ --card: hsl(0 0% 100%);
2993
+ --card-foreground: hsl(240 10% 3.9%);
2994
+ --primary: ${palette.light};
2995
+ --primary-foreground: hsl(0 0% 100%);
2996
+ --border: hsl(240 5.9% 90%);
2997
+ --radius: ${radius}rem;
2998
+ }
2999
+
3000
+ .dark {
3001
+ --background: hsl(240 10% 3.9%);
3002
+ --foreground: hsl(0 0% 98%);
3003
+ --card: hsl(240 10% 3.9%);
3004
+ --card-foreground: hsl(0 0% 98%);
3005
+ --primary: ${palette.dark};
3006
+ --primary-foreground: hsl(0 0% 100%);
3007
+ --border: hsl(240 3.7% 15.9%);
3008
+ --radius: ${radius}rem;
3009
+ }
3010
+ `;
3011
+ if (fs4.existsSync(cssAbsolutePath)) {
3012
+ const existingContent = fs4.readFileSync(cssAbsolutePath, "utf8");
3013
+ if (!existingContent.includes("--color-primary") && !existingContent.includes("nexoreui/dist")) {
3014
+ fs4.writeFileSync(cssAbsolutePath, existingContent.trim() + "\n" + themeBlock, "utf8");
3015
+ return true;
3016
+ }
3017
+ } else {
3018
+ const cssDir = path4.dirname(cssAbsolutePath);
3019
+ if (!fs4.existsSync(cssDir)) fs4.mkdirSync(cssDir, { recursive: true });
3020
+ fs4.writeFileSync(cssAbsolutePath, `@import "tailwindcss";
3021
+ ` + themeBlock, "utf8");
3022
+ return true;
3023
+ }
3024
+ return false;
3025
+ }
3026
+ function installPeerDependencies(baseDir, packageManager, dependencies = ["clsx", "tailwind-merge", "lucide-react", "framer-motion"]) {
3027
+ try {
3028
+ const packageJsonPath = path4.join(baseDir, "package.json");
3029
+ let missingDeps = [...dependencies];
3030
+ if (fs4.existsSync(packageJsonPath)) {
3031
+ const pkg = JSON.parse(fs4.readFileSync(packageJsonPath, "utf8"));
3032
+ const installed = { ...pkg.dependencies, ...pkg.devDependencies };
3033
+ missingDeps = dependencies.filter((dep) => !installed[dep]);
3034
+ }
3035
+ if (missingDeps.length === 0) return true;
3036
+ let installCmd = "npm install";
3037
+ if (packageManager === "pnpm") installCmd = "pnpm add";
3038
+ else if (packageManager === "yarn") installCmd = "yarn add";
3039
+ else if (packageManager === "bun") installCmd = "bun add";
3040
+ console.log(`
3041
+ \x1B[33m\u26A1 Installing peer dependencies:\x1B[0m ${missingDeps.join(", ")}...`);
3042
+ (0, import_child_process2.execSync)(`${installCmd} ${missingDeps.join(" ")}`, {
3043
+ stdio: "inherit",
3044
+ cwd: baseDir
3045
+ });
3046
+ return true;
3047
+ } catch (err) {
3048
+ console.warn("\x1B[33mWarning: Automatic peer dependency installation skipped.\x1B[0m");
3049
+ return false;
3050
+ }
3051
+ }
3052
+
3053
+ // src/commands/init.ts
3054
+ function askQuestion2(query) {
3055
+ const rl = readline2.createInterface({
3056
+ input: process.stdin,
3057
+ output: process.stdout
3058
+ });
3059
+ return new Promise(
3060
+ (resolve4) => rl.question(query, (ans) => {
3061
+ rl.close();
3062
+ resolve4(ans);
3063
+ })
3064
+ );
3065
+ }
3066
+ async function initCommand(options = {}) {
3067
+ console.log(`
3068
+ \x1B[36m\x1B[1m=== Initializing NexoreUI in your project ===\x1B[0m
3069
+ `);
3070
+ const project = detectProject(process.cwd());
3071
+ console.log(`\x1B[32m\u2714 Detected Project:\x1B[0m ${project.projectType.toUpperCase()} (${project.packageManager})`);
3072
+ let theme = options.theme || "cyan";
3073
+ let radius = options.radius || "1.0";
3074
+ const defaultComponentsDir = project.hasSrcDir ? "src/components/ui" : "components/ui";
3075
+ const defaultUtilsFile = project.hasSrcDir ? "src/lib/utils.ts" : "lib/utils.ts";
3076
+ const defaultCssFile = project.projectType === "next" ? project.hasSrcDir ? "src/app/globals.css" : "app/globals.css" : project.hasSrcDir ? "src/index.css" : "src/index.css";
3077
+ let componentsDir = defaultComponentsDir;
3078
+ let utilsFile = defaultUtilsFile;
3079
+ if (!options.yes) {
3080
+ if (!options.theme) {
3081
+ const themeAns = await askQuestion2(`Which color theme would you like to use? (cyan, indigo, violet, emerald, rose, amber, slate, neon) [default: cyan]: `);
3082
+ if (themeAns.trim() && THEME_PALETTES[themeAns.trim().toLowerCase()]) {
3083
+ theme = themeAns.trim().toLowerCase();
3084
+ }
3085
+ }
3086
+ if (!options.radius) {
3087
+ const radiusAns = await askQuestion2(`Which radius value would you like to use? (0, 0.3, 0.5, 0.75, 1.0) [default: 1.0]: `);
3088
+ if (radiusAns.trim()) {
3089
+ radius = radiusAns.trim();
3090
+ }
3091
+ }
3092
+ const compAns = await askQuestion2(`Where should UI components be created? (default: ${defaultComponentsDir}): `);
3093
+ if (compAns.trim()) componentsDir = compAns.trim();
3094
+ const utilsAns = await askQuestion2(`Where should utility functions (cn helper) be placed? (default: ${defaultUtilsFile}): `);
3095
+ if (utilsAns.trim()) utilsFile = utilsAns.trim();
3096
+ }
3097
+ const absoluteComponentsDir = path5.resolve(project.baseDir, componentsDir);
3098
+ const absoluteUtilsFile = path5.resolve(project.baseDir, utilsFile);
3099
+ ensureDir(absoluteComponentsDir);
3100
+ ensureCnUtil(absoluteUtilsFile);
3101
+ const didUpdateAlias = ensurePathAlias(project.baseDir, project.projectType, project.hasSrcDir);
3102
+ if (didUpdateAlias) {
3103
+ console.log(`\x1B[32m\u2714\x1B[0m Configured path alias \x1B[1m'@/*'\x1B[0m in project config`);
3104
+ }
3105
+ const didInjectCss = injectThemeCss(project.baseDir, defaultCssFile, theme, radius);
3106
+ if (didInjectCss) {
3107
+ console.log(`\x1B[32m\u2714\x1B[0m Injected Tailwind CSS v4 @theme tokens into \x1B[1m${defaultCssFile}\x1B[0m`);
3108
+ }
3109
+ installPeerDependencies(project.baseDir, project.packageManager);
3110
+ const config = {
3111
+ $schema: "https://nexoreui.site/schema.json",
3112
+ style: "default",
3113
+ theme,
3114
+ radius: Number(radius),
3115
+ framework: project.projectType,
3116
+ packageManager: project.packageManager,
3117
+ font: "system",
3118
+ density: "default",
3119
+ animation: "energetic",
3120
+ defaultMode: "light",
3121
+ tailwind: {
3122
+ config: "tailwind.config.js",
3123
+ css: defaultCssFile,
3124
+ baseColor: "zinc",
3125
+ cssVariables: true
3126
+ },
3127
+ aliases: {
3128
+ components: `@/${componentsDir.replace(/^src\//, "")}`,
3129
+ utils: `@/${utilsFile.replace(/^src\//, "").replace(/\.(ts|js)$/, "")}`
3130
+ }
3131
+ };
3132
+ const configPath = path5.join(project.baseDir, "nexore.json");
3133
+ fs5.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf8");
3134
+ console.log(`\x1B[32m\u2714\x1B[0m Generated \x1B[1mnexore.json\x1B[0m (Theme: ${theme}, Radius: ${radius}rem)`);
3135
+ console.log(`\x1B[32m\u2714\x1B[0m Utilities ready at \x1B[1m${utilsFile}\x1B[0m`);
3136
+ console.log(`\x1B[32m\u2714\x1B[0m Components directory ready at \x1B[1m${componentsDir}\x1B[0m`);
3137
+ console.log(`
3138
+ \x1B[32m\x1B[1m\u{1F389} NexoreUI initialized successfully! You can now add components:\x1B[0m`);
3139
+ console.log(` \x1B[36mnpx nexoreui add button card modal table --all\x1B[0m
3140
+ `);
3141
+ }
3142
+
3143
+ // src/commands/create.ts
3144
+ var fs6 = __toESM(require("fs"));
3145
+ var path6 = __toESM(require("path"));
3146
+ var import_child_process3 = require("child_process");
3147
+ async function createCommand(projectName, options = {}) {
3148
+ const name = projectName || "my-nexore-app";
3149
+ const targetDir = path6.resolve(process.cwd(), name);
3150
+ console.log(`
3151
+ \x1B[36m\x1B[1m\u{1F680} Creating a new NexoreUI Project:\x1B[0m \x1B[32m${name}\x1B[0m
3152
+ `);
3153
+ if (fs6.existsSync(targetDir) && fs6.readdirSync(targetDir).length > 0) {
3154
+ console.error(`\x1B[31mError: Target directory ${name} already exists and is not empty.\x1B[0m`);
3155
+ return;
3156
+ }
3157
+ console.log(`\x1B[33m\u26A1 Scaffolding React + Vite + Tailwind CSS template...\x1B[0m`);
3158
+ try {
3159
+ (0, import_child_process3.execSync)(`npm create vite@latest ${name} -- --template react-ts`, { stdio: "inherit" });
3160
+ } catch (err) {
3161
+ console.error(`\x1B[31mFailed to scaffold Vite project.\x1B[0m`);
3162
+ return;
3163
+ }
3164
+ process.chdir(targetDir);
3165
+ console.log(`
3166
+ \x1B[33m\u{1F4E6} Installing NexoreUI, Tailwind CSS, and core packages...\x1B[0m`);
3167
+ (0, import_child_process3.execSync)(`npm install nexoreui lucide-react clsx tailwind-merge framer-motion @tailwindcss/vite tailwindcss`, {
3168
+ stdio: "inherit"
3169
+ });
3170
+ await initCommand({
3171
+ yes: true,
3172
+ theme: options.theme || "cyan",
3173
+ radius: options.radius || "1.0"
3174
+ });
3175
+ console.log(`
3176
+ \x1B[32m\x1B[1m\u2728 Project ${name} is ready!\x1B[0m`);
3177
+ console.log(`
3178
+ To get started:
3179
+ `);
3180
+ console.log(` \x1B[36mcd ${name}\x1B[0m`);
3181
+ console.log(` \x1B[36mnpx nexoreui add button card modal table --all\x1B[0m`);
3182
+ console.log(` \x1B[36mnpm run dev\x1B[0m
3183
+ `);
3184
+ }
3185
+
2262
3186
  // src/index.ts
2263
3187
  async function main() {
2264
3188
  const args = process.argv.slice(2);
@@ -2267,20 +3191,59 @@ async function main() {
2267
3191
  printHelp();
2268
3192
  return;
2269
3193
  }
2270
- if (command === "list") {
3194
+ if (command === "create") {
3195
+ const projectName = args[1] && !args[1].startsWith("-") ? args[1] : void 0;
3196
+ let theme;
3197
+ let radius;
3198
+ for (let i = 1; i < args.length; i++) {
3199
+ const arg = args[i];
3200
+ if (arg === "--theme" && args[i + 1]) {
3201
+ theme = args[++i];
3202
+ } else if (arg.startsWith("--theme=")) {
3203
+ theme = arg.split("=")[1];
3204
+ } else if (arg === "--radius" && args[i + 1]) {
3205
+ radius = args[++i];
3206
+ } else if (arg.startsWith("--radius=")) {
3207
+ radius = arg.split("=")[1];
3208
+ }
3209
+ }
3210
+ await createCommand(projectName, { theme, radius });
3211
+ } else if (command === "init") {
3212
+ let yes = false;
3213
+ let theme;
3214
+ let radius;
3215
+ for (let i = 1; i < args.length; i++) {
3216
+ const arg = args[i];
3217
+ if (arg === "-y" || arg === "--yes") {
3218
+ yes = true;
3219
+ } else if (arg === "--theme" && args[i + 1]) {
3220
+ theme = args[++i];
3221
+ } else if (arg.startsWith("--theme=")) {
3222
+ theme = arg.split("=")[1];
3223
+ } else if (arg === "--radius" && args[i + 1]) {
3224
+ radius = args[++i];
3225
+ } else if (arg.startsWith("--radius=")) {
3226
+ radius = arg.split("=")[1];
3227
+ }
3228
+ }
3229
+ await initCommand({ yes, theme, radius });
3230
+ } else if (command === "list") {
2271
3231
  listCommand();
2272
3232
  } else if (command === "add") {
2273
3233
  const components = [];
2274
3234
  let yes = false;
3235
+ let all = false;
2275
3236
  for (let i = 1; i < args.length; i++) {
2276
3237
  const arg = args[i];
2277
3238
  if (arg === "-y" || arg === "--yes") {
2278
3239
  yes = true;
3240
+ } else if (arg === "--all" || arg === "-a") {
3241
+ all = true;
2279
3242
  } else if (!arg.startsWith("-")) {
2280
3243
  components.push(arg);
2281
3244
  }
2282
3245
  }
2283
- await addCommand(components, { yes });
3246
+ await addCommand(components, { yes, all });
2284
3247
  } else {
2285
3248
  console.error(`\x1B[31mUnknown command: ${command}\x1B[0m`);
2286
3249
  printHelp();
@@ -2288,16 +3251,23 @@ async function main() {
2288
3251
  }
2289
3252
  function printHelp() {
2290
3253
  console.log(`
2291
- \x1B[34m\x1B[1mNexoreUI CLI\x1B[0m
3254
+ \x1B[36m\x1B[1mNexoreUI CLI\x1B[0m
3255
+ \x1B[90mModern, animated, production-ready React components with Tailwind CSS v4\x1B[0m
3256
+
2292
3257
  Usage:
2293
3258
  npx nexoreui [command] [options]
2294
3259
 
2295
3260
  Commands:
2296
- \x1B[32madd [components...]\x1B[0m Add components to your project (e.g., button, modal, card, alert, badge)
2297
- \x1B[32mlist\x1B[0m List all available components
3261
+ \x1B[32mcreate [name]\x1B[0m Create a new fully configured NexoreUI starter project
3262
+ \x1B[32minit\x1B[0m Initialize NexoreUI in your project (configure theme, aliases, and CSS)
3263
+ \x1B[32madd [components...]\x1B[0m Add components to your project (use --all to install all 40+ components)
3264
+ \x1B[32mlist\x1B[0m List all available components in registry
2298
3265
 
2299
3266
  Options:
2300
- \x1B[33m-y, --yes\x1B[0m Skip prompts and use default paths
3267
+ \x1B[33m--theme <name>\x1B[0m Set color palette (cyan, indigo, violet, emerald, rose, amber, slate, neon)
3268
+ \x1B[33m--radius <val>\x1B[0m Set border radius (0, 0.3, 0.5, 0.75, 1.0)
3269
+ \x1B[33m--all, -a\x1B[0m Install all available components at once
3270
+ \x1B[33m-y, --yes\x1B[0m Skip prompts and use defaults automatically
2301
3271
  \x1B[33m-h, --help\x1B[0m Show help information
2302
3272
  `);
2303
3273
  }