nextworks 0.2.0-alpha.2 → 0.2.0-alpha.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/README.md +280 -228
  2. package/dist/cli_manifests/blocks_manifest.json +193 -194
  3. package/dist/commands/blocks.d.ts +3 -0
  4. package/dist/commands/blocks.d.ts.map +1 -1
  5. package/dist/commands/blocks.js +128 -19
  6. package/dist/commands/blocks.js.map +1 -1
  7. package/dist/commands/doctor.d.ts +136 -0
  8. package/dist/commands/doctor.d.ts.map +1 -0
  9. package/dist/commands/doctor.js +696 -0
  10. package/dist/commands/doctor.js.map +1 -0
  11. package/dist/commands/remove-blocks.d.ts +4 -1
  12. package/dist/commands/remove-blocks.d.ts.map +1 -1
  13. package/dist/commands/remove-blocks.js +24 -6
  14. package/dist/commands/remove-blocks.js.map +1 -1
  15. package/dist/index.js +125 -4
  16. package/dist/index.js.map +1 -1
  17. package/dist/kits/blocks/.nextworks/docs/BLOCKS_QUICKSTART.md +104 -194
  18. package/dist/kits/blocks/.nextworks/docs/BLOCKS_README.md +115 -75
  19. package/dist/kits/blocks/.nextworks/docs/THEME_GUIDE.md +269 -251
  20. package/dist/kits/blocks/app/templates/digitalagency/PresetThemeVars.tsx +80 -80
  21. package/dist/kits/blocks/app/templates/digitalagency/README.md +42 -36
  22. package/dist/kits/blocks/app/templates/digitalagency/components/About.tsx +71 -99
  23. package/dist/kits/blocks/app/templates/digitalagency/components/CTA.tsx +40 -74
  24. package/dist/kits/blocks/app/templates/digitalagency/components/Contact.tsx +123 -227
  25. package/dist/kits/blocks/app/templates/digitalagency/components/Footer.tsx +89 -89
  26. package/dist/kits/blocks/app/templates/digitalagency/components/Hero.tsx +83 -90
  27. package/dist/kits/blocks/app/templates/digitalagency/components/Navbar.tsx +121 -168
  28. package/dist/kits/blocks/app/templates/digitalagency/components/NetworkPattern.tsx +288 -297
  29. package/dist/kits/blocks/app/templates/digitalagency/components/Portfolio.tsx +157 -157
  30. package/dist/kits/blocks/app/templates/digitalagency/components/Pricing.tsx +114 -114
  31. package/dist/kits/blocks/app/templates/digitalagency/components/Process.tsx +59 -59
  32. package/dist/kits/blocks/app/templates/digitalagency/components/Services.tsx +55 -55
  33. package/dist/kits/blocks/app/templates/digitalagency/components/Team.tsx +28 -28
  34. package/dist/kits/blocks/app/templates/digitalagency/components/Testimonials.tsx +65 -65
  35. package/dist/kits/blocks/app/templates/digitalagency/page.tsx +38 -38
  36. package/dist/kits/blocks/app/templates/gallery/PresetThemeVars.tsx +130 -85
  37. package/dist/kits/blocks/app/templates/gallery/page.tsx +357 -303
  38. package/dist/kits/blocks/app/templates/productlaunch/PresetThemeVars.tsx +75 -74
  39. package/dist/kits/blocks/app/templates/productlaunch/README.md +62 -55
  40. package/dist/kits/blocks/app/templates/productlaunch/components/About.tsx +84 -178
  41. package/dist/kits/blocks/app/templates/productlaunch/components/CTA.tsx +50 -93
  42. package/dist/kits/blocks/app/templates/productlaunch/components/Contact.tsx +231 -231
  43. package/dist/kits/blocks/app/templates/productlaunch/components/FAQ.tsx +86 -93
  44. package/dist/kits/blocks/app/templates/productlaunch/components/Features.tsx +83 -84
  45. package/dist/kits/blocks/app/templates/productlaunch/components/Footer.tsx +132 -132
  46. package/dist/kits/blocks/app/templates/productlaunch/components/Hero.tsx +88 -89
  47. package/dist/kits/blocks/app/templates/productlaunch/components/Navbar.tsx +116 -162
  48. package/dist/kits/blocks/app/templates/productlaunch/components/Pricing.tsx +106 -106
  49. package/dist/kits/blocks/app/templates/productlaunch/components/ProcessTimeline.tsx +110 -110
  50. package/dist/kits/blocks/app/templates/productlaunch/components/ServicesGrid.tsx +68 -68
  51. package/dist/kits/blocks/app/templates/productlaunch/components/Team.tsx +104 -104
  52. package/dist/kits/blocks/app/templates/productlaunch/components/Testimonials.tsx +90 -89
  53. package/dist/kits/blocks/app/templates/productlaunch/components/TrustBadges.tsx +76 -76
  54. package/dist/kits/blocks/app/templates/productlaunch/page.tsx +43 -43
  55. package/dist/kits/blocks/app/templates/saasdashboard/PresetThemeVars.tsx +80 -80
  56. package/dist/kits/blocks/app/templates/saasdashboard/README.md +44 -38
  57. package/dist/kits/blocks/app/templates/saasdashboard/components/Contact.tsx +129 -176
  58. package/dist/kits/blocks/app/templates/saasdashboard/components/Dashboard.tsx +293 -293
  59. package/dist/kits/blocks/app/templates/saasdashboard/components/FAQ.tsx +55 -55
  60. package/dist/kits/blocks/app/templates/saasdashboard/components/Features.tsx +90 -91
  61. package/dist/kits/blocks/app/templates/saasdashboard/components/Footer.tsx +77 -77
  62. package/dist/kits/blocks/app/templates/saasdashboard/components/Hero.tsx +104 -105
  63. package/dist/kits/blocks/app/templates/saasdashboard/components/Hero_mask.tsx +126 -127
  64. package/dist/kits/blocks/app/templates/saasdashboard/components/Navbar.tsx +117 -159
  65. package/dist/kits/blocks/app/templates/saasdashboard/components/Pricing.tsx +90 -90
  66. package/dist/kits/blocks/app/templates/saasdashboard/components/SmoothScroll.tsx +96 -97
  67. package/dist/kits/blocks/app/templates/saasdashboard/components/Testimonials.tsx +72 -72
  68. package/dist/kits/blocks/app/templates/saasdashboard/components/TrustBadges.tsx +53 -53
  69. package/dist/kits/blocks/app/templates/saasdashboard/page.tsx +39 -39
  70. package/dist/kits/blocks/components/enhanced-theme-provider.tsx +195 -183
  71. package/dist/kits/blocks/components/providers/BlocksAppProviders.tsx +27 -27
  72. package/dist/kits/blocks/components/sections/About.tsx +291 -291
  73. package/dist/kits/blocks/components/sections/CTA.tsx +257 -258
  74. package/dist/kits/blocks/components/sections/CommandShowcase.tsx +517 -0
  75. package/dist/kits/blocks/components/sections/Contact.tsx +267 -267
  76. package/dist/kits/blocks/components/sections/FAQ.tsx +214 -225
  77. package/dist/kits/blocks/components/sections/FeaturedProjectShowcase.tsx +687 -0
  78. package/dist/kits/blocks/components/sections/Features.tsx +268 -270
  79. package/dist/kits/blocks/components/sections/Footer.tsx +302 -302
  80. package/dist/kits/blocks/components/sections/HeroMotion.tsx +308 -308
  81. package/dist/kits/blocks/components/sections/HeroOverlay.tsx +358 -358
  82. package/dist/kits/blocks/components/sections/HeroProductDemo.tsx +246 -0
  83. package/dist/kits/blocks/components/sections/HeroSplit.tsx +352 -352
  84. package/dist/kits/blocks/components/sections/HeroWithVideo.tsx +495 -0
  85. package/dist/kits/blocks/components/sections/Navbar.tsx +352 -353
  86. package/dist/kits/blocks/components/sections/PortfolioSimple.tsx +549 -550
  87. package/dist/kits/blocks/components/sections/Pricing.tsx +264 -264
  88. package/dist/kits/blocks/components/sections/ProcessTimeline.tsx +325 -325
  89. package/dist/kits/blocks/components/sections/ProjectDeepDive.tsx +805 -0
  90. package/dist/kits/blocks/components/sections/SelectedWorkRail.tsx +485 -0
  91. package/dist/kits/blocks/components/sections/ServicesGrid.tsx +210 -210
  92. package/dist/kits/blocks/components/sections/Team.tsx +309 -309
  93. package/dist/kits/blocks/components/sections/Testimonials.tsx +158 -158
  94. package/dist/kits/blocks/components/sections/TrustBadges.tsx +162 -162
  95. package/dist/kits/blocks/components/sections/product-demo/ApprovalInboxPanel.tsx +128 -0
  96. package/dist/kits/blocks/components/sections/product-demo/DemoStage.tsx +519 -0
  97. package/dist/kits/blocks/components/sections/product-demo/DemoWindow.tsx +140 -0
  98. package/dist/kits/blocks/components/sections/product-demo/KnowledgePanel.tsx +130 -0
  99. package/dist/kits/blocks/components/sections/product-demo/RunConsolePanel.tsx +430 -0
  100. package/dist/kits/blocks/components/sections/product-demo/TaskListPanel.tsx +302 -0
  101. package/dist/kits/blocks/components/sections/product-demo/WorkflowStudioPanel.tsx +744 -0
  102. package/dist/kits/blocks/components/sections/product-demo/types.ts +262 -0
  103. package/dist/kits/blocks/components/theme-provider.tsx +1 -34
  104. package/dist/kits/blocks/components/ui/alert-dialog.tsx +134 -134
  105. package/dist/kits/blocks/components/ui/brand-node.tsx +121 -121
  106. package/dist/kits/blocks/components/ui/button.tsx +122 -122
  107. package/dist/kits/blocks/components/ui/card.tsx +95 -95
  108. package/dist/kits/blocks/components/ui/checkbox.tsx +30 -30
  109. package/dist/kits/blocks/components/ui/cta-button.tsx +125 -125
  110. package/dist/kits/blocks/components/ui/dropdown-menu.tsx +201 -201
  111. package/dist/kits/blocks/components/ui/feature-card.tsx +91 -91
  112. package/dist/kits/blocks/components/ui/input.tsx +27 -27
  113. package/dist/kits/blocks/components/ui/label.tsx +29 -29
  114. package/dist/kits/blocks/components/ui/pricing-card.tsx +120 -120
  115. package/dist/kits/blocks/components/ui/select.tsx +25 -25
  116. package/dist/kits/blocks/components/ui/skeleton.tsx +13 -13
  117. package/dist/kits/blocks/components/ui/table.tsx +98 -98
  118. package/dist/kits/blocks/components/ui/testimonial-card.tsx +108 -108
  119. package/dist/kits/blocks/components/ui/textarea.tsx +26 -26
  120. package/dist/kits/blocks/components/ui/theme-selector.tsx +243 -247
  121. package/dist/kits/blocks/components/ui/theme-toggle.tsx +74 -74
  122. package/dist/kits/blocks/components/ui/toaster.tsx +7 -7
  123. package/dist/kits/blocks/lib/themes.ts +400 -400
  124. package/dist/kits/blocks/lib/utils.ts +6 -9
  125. package/dist/kits/blocks/package-deps.json +40 -28
  126. package/dist/kits/blocks/tsconfig.json +11 -0
  127. package/dist/kits/blocks/tsconfig.tsbuildinfo +1 -0
  128. package/dist/utils/file-operations.d.ts +3 -1
  129. package/dist/utils/file-operations.d.ts.map +1 -1
  130. package/dist/utils/file-operations.js +84 -12
  131. package/dist/utils/file-operations.js.map +1 -1
  132. package/dist/utils/installation-tracker.d.ts +2 -2
  133. package/dist/utils/installation-tracker.d.ts.map +1 -1
  134. package/dist/utils/installation-tracker.js +11 -11
  135. package/dist/utils/installation-tracker.js.map +1 -1
  136. package/dist/utils/package-manager.d.ts +6 -0
  137. package/dist/utils/package-manager.d.ts.map +1 -0
  138. package/dist/utils/package-manager.js +58 -0
  139. package/dist/utils/package-manager.js.map +1 -0
  140. package/dist/utils/yarn-pnp.d.ts +6 -0
  141. package/dist/utils/yarn-pnp.d.ts.map +1 -0
  142. package/dist/utils/yarn-pnp.js +39 -0
  143. package/dist/utils/yarn-pnp.js.map +1 -0
  144. package/package.json +5 -2
  145. package/dist/kits/blocks/notes/THEME_GUIDE.md +0 -29
@@ -1,121 +1,121 @@
1
- "use client";
2
-
3
- import React from "react";
4
- import type { ComponentType } from "react";
5
- import { Sparkles } from "lucide-react";
6
- import { cn } from "@/lib/utils";
7
-
8
- export interface BrandNodeProps {
9
- /** Optional wrapper className to override size/colors (merged with defaults) */
10
- className?: string;
11
- }
12
-
13
- export interface BrandNodeIconBadgeProps extends BrandNodeProps {
14
- /** Icon component to render inside the badge */
15
- icon?: ComponentType<{ className?: string }>;
16
- /** Tailwind classes to control icon size; default `h-4 w-4` */
17
- iconClassName?: string;
18
- }
19
-
20
- export function BrandNodeIconBadge({
21
- className,
22
- icon: Icon = Sparkles,
23
- iconClassName = "h-4 w-4",
24
- }: BrandNodeIconBadgeProps) {
25
- const base = "grid h-8 w-8 place-items-center rounded-md bg-primary/10 ring-1 ring-primary/30 text-primary";
26
- return (
27
- <div className={cn(base, className)} aria-label="Brand icon badge">
28
- <Icon className={iconClassName} />
29
- </div>
30
- );
31
- }
32
-
33
- export interface BrandNodeGradientRingProps extends BrandNodeProps {
34
- /** CSS conic-gradient string; provide two or more colors */
35
- gradient?: string;
36
- /** Inner fill background (center disc) */
37
- innerBgClassName?: string;
38
- }
39
-
40
- export function BrandNodeGradientRing({
41
- className,
42
- gradient = "conic-gradient(hsl(var(--primary)), hsl(var(--accent)), hsl(var(--primary)))",
43
- innerBgClassName = "h-full w-full rounded-full bg-background",
44
- }: BrandNodeGradientRingProps) {
45
- const base = "relative h-8 w-8";
46
- return (
47
- <div className={cn(base, className)} aria-label="Brand gradient ring">
48
- <div className="absolute inset-0 rounded-full p-[2px]" style={{ background: gradient }}>
49
- <div className={innerBgClassName} />
50
- </div>
51
- </div>
52
- );
53
- }
54
-
55
- export function BrandNodeGeometricMark({ className }: BrandNodeProps) {
56
- const base = "grid h-8 w-8 place-items-center rounded-md bg-gradient-to-br from-primary/10 to-accent/10 ring-1 ring-border";
57
- return (
58
- <div className={cn(base, className)} aria-label="Brand geometric mark">
59
- <svg viewBox="0 0 24 24" className="fill-primary h-4 w-4">
60
- <path d="M12 4l8 14H4l8-14z" />
61
- </svg>
62
- </div>
63
- );
64
- }
65
-
66
- export interface BrandNodeEmojiBadgeProps extends BrandNodeProps {
67
- emoji?: string;
68
- }
69
-
70
- export function BrandNodeEmojiBadge({ className, emoji = "⚡" }: BrandNodeEmojiBadgeProps) {
71
- const base = "grid h-8 w-8 place-items-center rounded-md bg-card/60 backdrop-blur ring-1 ring-border";
72
- return (
73
- <div className={cn(base, className)} aria-label="Brand emoji badge">
74
- <span className="text-base" aria-hidden>
75
- {emoji}
76
- </span>
77
- </div>
78
- );
79
- }
80
-
81
- export interface BrandNodeDiagonalAppIconProps extends BrandNodeProps {
82
- /** Base and overlay colors */
83
- baseColorClass?: string;
84
- overlayColorClass?: string;
85
- }
86
-
87
- export function BrandNodeDiagonalAppIcon({
88
- className,
89
- baseColorClass = "bg-primary",
90
- overlayColorClass = "bg-accent",
91
- }: BrandNodeDiagonalAppIconProps) {
92
- const base = "relative h-8 w-8 overflow-hidden rounded-md ring-1 ring-black/5 dark:ring-white/10";
93
- return (
94
- <div className={cn(base, className)} aria-label="Brand diagonal app icon">
95
- <div className={cn("absolute inset-0", baseColorClass)} />
96
- <div className={cn("absolute inset-0 translate-y-1/3 -skew-y-12", overlayColorClass)} />
97
- </div>
98
- );
99
- }
100
-
101
- export function BrandNodeCubeOutline({ className }: BrandNodeProps) {
102
- const base = "grid h-8 w-8 place-items-center rounded-md bg-foreground text-background ring-1 ring-border";
103
- return (
104
- <div className={cn(base, className)} aria-label="Brand cube outline">
105
- <svg viewBox="0 0 24 24" className="h-4 w-4">
106
- <path d="M12 2l8 4.5v9L12 20 4 15.5v-9L12 2z" fill="none" stroke="currentColor" strokeWidth="1.6" />
107
- <path d="M12 20v-9M4 6l8 5 8-5" fill="none" stroke="currentColor" strokeWidth="1.6" />
108
- </svg>
109
- </div>
110
- );
111
- }
112
-
113
- /** Registry for quick swapping by name */
114
- export const BrandNodes = {
115
- IconBadge: BrandNodeIconBadge,
116
- GradientRing: BrandNodeGradientRing,
117
- GeometricMark: BrandNodeGeometricMark,
118
- EmojiBadge: BrandNodeEmojiBadge,
119
- DiagonalAppIcon: BrandNodeDiagonalAppIcon,
120
- CubeOutline: BrandNodeCubeOutline,
121
- };
1
+ "use client";
2
+
3
+ import React from "react";
4
+ import type { ComponentType } from "react";
5
+ import { Sparkles } from "lucide-react";
6
+ import { cn } from "@/lib/utils";
7
+
8
+ export interface BrandNodeProps {
9
+ /** Optional wrapper className to override size/colors (merged with defaults) */
10
+ className?: string;
11
+ }
12
+
13
+ export interface BrandNodeIconBadgeProps extends BrandNodeProps {
14
+ /** Icon component to render inside the badge */
15
+ icon?: ComponentType<{ className?: string }>;
16
+ /** Tailwind classes to control icon size; default `h-4 w-4` */
17
+ iconClassName?: string;
18
+ }
19
+
20
+ export function BrandNodeIconBadge({
21
+ className,
22
+ icon: Icon = Sparkles,
23
+ iconClassName = "h-4 w-4",
24
+ }: BrandNodeIconBadgeProps) {
25
+ const base = "grid h-8 w-8 place-items-center rounded-md bg-primary/10 ring-1 ring-primary/30 text-primary";
26
+ return (
27
+ <div className={cn(base, className)} aria-label="Brand icon badge">
28
+ <Icon className={iconClassName} />
29
+ </div>
30
+ );
31
+ }
32
+
33
+ export interface BrandNodeGradientRingProps extends BrandNodeProps {
34
+ /** CSS conic-gradient string; provide two or more colors */
35
+ gradient?: string;
36
+ /** Inner fill background (center disc) */
37
+ innerBgClassName?: string;
38
+ }
39
+
40
+ export function BrandNodeGradientRing({
41
+ className,
42
+ gradient = "conic-gradient(hsl(var(--primary)), hsl(var(--accent)), hsl(var(--primary)))",
43
+ innerBgClassName = "h-full w-full rounded-full bg-background",
44
+ }: BrandNodeGradientRingProps) {
45
+ const base = "relative h-8 w-8";
46
+ return (
47
+ <div className={cn(base, className)} aria-label="Brand gradient ring">
48
+ <div className="absolute inset-0 rounded-full p-[2px]" style={{ background: gradient }}>
49
+ <div className={innerBgClassName} />
50
+ </div>
51
+ </div>
52
+ );
53
+ }
54
+
55
+ export function BrandNodeGeometricMark({ className }: BrandNodeProps) {
56
+ const base = "grid h-8 w-8 place-items-center rounded-md bg-gradient-to-br from-primary/10 to-accent/10 ring-1 ring-border";
57
+ return (
58
+ <div className={cn(base, className)} aria-label="Brand geometric mark">
59
+ <svg viewBox="0 0 24 24" className="fill-primary h-4 w-4">
60
+ <path d="M12 4l8 14H4l8-14z" />
61
+ </svg>
62
+ </div>
63
+ );
64
+ }
65
+
66
+ export interface BrandNodeEmojiBadgeProps extends BrandNodeProps {
67
+ emoji?: string;
68
+ }
69
+
70
+ export function BrandNodeEmojiBadge({ className, emoji = "⚡" }: BrandNodeEmojiBadgeProps) {
71
+ const base = "grid h-8 w-8 place-items-center rounded-md bg-card/60 backdrop-blur ring-1 ring-border";
72
+ return (
73
+ <div className={cn(base, className)} aria-label="Brand emoji badge">
74
+ <span className="text-base" aria-hidden>
75
+ {emoji}
76
+ </span>
77
+ </div>
78
+ );
79
+ }
80
+
81
+ export interface BrandNodeDiagonalAppIconProps extends BrandNodeProps {
82
+ /** Base and overlay colors */
83
+ baseColorClass?: string;
84
+ overlayColorClass?: string;
85
+ }
86
+
87
+ export function BrandNodeDiagonalAppIcon({
88
+ className,
89
+ baseColorClass = "bg-primary",
90
+ overlayColorClass = "bg-accent",
91
+ }: BrandNodeDiagonalAppIconProps) {
92
+ const base = "relative h-8 w-8 overflow-hidden rounded-md ring-1 ring-black/5 dark:ring-white/10";
93
+ return (
94
+ <div className={cn(base, className)} aria-label="Brand diagonal app icon">
95
+ <div className={cn("absolute inset-0", baseColorClass)} />
96
+ <div className={cn("absolute inset-0 translate-y-1/3 -skew-y-12", overlayColorClass)} />
97
+ </div>
98
+ );
99
+ }
100
+
101
+ export function BrandNodeCubeOutline({ className }: BrandNodeProps) {
102
+ const base = "grid h-8 w-8 place-items-center rounded-md bg-foreground text-background ring-1 ring-border";
103
+ return (
104
+ <div className={cn(base, className)} aria-label="Brand cube outline">
105
+ <svg viewBox="0 0 24 24" className="h-4 w-4">
106
+ <path d="M12 2l8 4.5v9L12 20 4 15.5v-9L12 2z" fill="none" stroke="currentColor" strokeWidth="1.6" />
107
+ <path d="M12 20v-9M4 6l8 5 8-5" fill="none" stroke="currentColor" strokeWidth="1.6" />
108
+ </svg>
109
+ </div>
110
+ );
111
+ }
112
+
113
+ /** Registry for quick swapping by name */
114
+ export const BrandNodes = {
115
+ IconBadge: BrandNodeIconBadge,
116
+ GradientRing: BrandNodeGradientRing,
117
+ GeometricMark: BrandNodeGeometricMark,
118
+ EmojiBadge: BrandNodeEmojiBadge,
119
+ DiagonalAppIcon: BrandNodeDiagonalAppIcon,
120
+ CubeOutline: BrandNodeCubeOutline,
121
+ };
@@ -1,122 +1,122 @@
1
- import * as React from "react";
2
- import { Slot } from "@radix-ui/react-slot";
3
- import { cva, type VariantProps } from "class-variance-authority";
4
-
5
- import { cn } from "@/lib/utils";
6
-
7
- const buttonVariants = cva(
8
- "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
9
- {
10
- variants: {
11
- variant: {
12
- default:
13
- "bg-primary text-primary-foreground hover:bg-primary/90 shadow-xs",
14
- destructive:
15
- "bg-destructive text-destructive-foreground hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60 shadow-xs",
16
- outline:
17
- "bg-background hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 border shadow-xs",
18
- secondary:
19
- "bg-secondary text-secondary-foreground hover:bg-secondary/80 shadow-xs",
20
- ghost:
21
- "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
22
- link: "text-primary underline-offset-4 hover:underline",
23
- },
24
- size: {
25
- default: "h-9 px-4 py-2 has-[>svg]:px-3",
26
- sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
27
- lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
28
- icon: "size-9",
29
- },
30
- },
31
- defaultVariants: {
32
- variant: "default",
33
- size: "default",
34
- },
35
- },
36
- );
37
-
38
- type ButtonProps = React.ComponentProps<"button"> &
39
- VariantProps<typeof buttonVariants> & {
40
- asChild?: boolean;
41
- /** When true, bypasses tokenized buttonVariants so callers fully control classes */
42
- unstyled?: boolean;
43
- /** Opt-in: force inline CSS var styles for color/bg/border/ring */
44
- forceInlineVars?: boolean;
45
- };
46
-
47
- const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
48
- (
49
- {
50
- className,
51
- variant,
52
- size,
53
- asChild = false,
54
- unstyled = false,
55
- forceInlineVars = false,
56
- ...props
57
- },
58
- ref,
59
- ) => {
60
- const Comp = asChild ? Slot : "button";
61
-
62
- // Use caller-provided style; only inject inline var-driven colors when explicitly requested
63
- const incomingStyle =
64
- (props.style as React.CSSProperties | undefined) ?? undefined;
65
- const finalStyle =
66
- forceInlineVars && !unstyled
67
- ? {
68
- ...incomingStyle,
69
- color: "var(--btn-fg)",
70
- backgroundColor: "var(--btn-bg)",
71
- borderColor: "var(--btn-border)",
72
- "--tw-ring-color": "var(--btn-ring)",
73
- }
74
- : incomingStyle;
75
-
76
- // Only enable CSS variable hooks when explicitly requested via inline vars
77
- // or when the caller sets any [--btn-*] classes in className.
78
- const wantsVarHooks =
79
- !unstyled &&
80
- (forceInlineVars ||
81
- (typeof className === "string" && className.includes("[--btn-")));
82
-
83
- return (
84
- <Comp
85
- ref={ref}
86
- data-slot="button"
87
- className={
88
- unstyled
89
- ? cn(
90
- "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap disabled:pointer-events-none disabled:opacity-50",
91
- className,
92
- )
93
- : cn(
94
- buttonVariants({ variant, size }),
95
- wantsVarHooks && [
96
- // Color var hooks (apply only when CSS vars are provided)
97
- "text-[var(--btn-fg)]",
98
- "bg-[var(--btn-bg)]",
99
- "hover:bg-[var(--btn-hover-bg)]",
100
- "hover:text-[var(--btn-hover-fg)]",
101
- // explicit dark variants to compete with dark: utilities from variants like outline
102
- "dark:bg-[var(--btn-bg)]",
103
- "dark:hover:bg-[var(--btn-hover-bg)]",
104
- "dark:hover:text-[var(--btn-hover-fg)]",
105
- // Focus ring and border hooks
106
- "focus-visible:ring-[var(--btn-ring)]",
107
- "border-[var(--btn-border)]",
108
- "dark:border-[var(--btn-border)]",
109
- ],
110
- className,
111
- )
112
- }
113
- style={finalStyle}
114
- {...props}
115
- />
116
- );
117
- },
118
- );
119
-
120
- Button.displayName = "Button";
121
-
122
- export { Button, buttonVariants };
1
+ import * as React from "react";
2
+ import { Slot } from "@radix-ui/react-slot";
3
+ import { cva, type VariantProps } from "class-variance-authority";
4
+
5
+ import { cn } from "@/lib/utils";
6
+
7
+ const buttonVariants = cva(
8
+ "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default:
13
+ "bg-primary text-primary-foreground hover:bg-primary/90 shadow-xs",
14
+ destructive:
15
+ "bg-destructive text-destructive-foreground hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60 shadow-xs",
16
+ outline:
17
+ "bg-background hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 border shadow-xs",
18
+ secondary:
19
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80 shadow-xs",
20
+ ghost:
21
+ "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
22
+ link: "text-primary underline-offset-4 hover:underline",
23
+ },
24
+ size: {
25
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
26
+ sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
27
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
28
+ icon: "size-9",
29
+ },
30
+ },
31
+ defaultVariants: {
32
+ variant: "default",
33
+ size: "default",
34
+ },
35
+ },
36
+ );
37
+
38
+ type ButtonProps = React.ComponentProps<"button"> &
39
+ VariantProps<typeof buttonVariants> & {
40
+ asChild?: boolean;
41
+ /** When true, bypasses tokenized buttonVariants so callers fully control classes */
42
+ unstyled?: boolean;
43
+ /** Opt-in: force inline CSS var styles for color/bg/border/ring */
44
+ forceInlineVars?: boolean;
45
+ };
46
+
47
+ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
48
+ (
49
+ {
50
+ className,
51
+ variant,
52
+ size,
53
+ asChild = false,
54
+ unstyled = false,
55
+ forceInlineVars = false,
56
+ ...props
57
+ },
58
+ ref,
59
+ ) => {
60
+ const Comp = asChild ? Slot : "button";
61
+
62
+ // Use caller-provided style; only inject inline var-driven colors when explicitly requested
63
+ const incomingStyle =
64
+ (props.style as React.CSSProperties | undefined) ?? undefined;
65
+ const finalStyle =
66
+ forceInlineVars && !unstyled
67
+ ? {
68
+ ...incomingStyle,
69
+ color: "var(--btn-fg)",
70
+ backgroundColor: "var(--btn-bg)",
71
+ borderColor: "var(--btn-border)",
72
+ "--tw-ring-color": "var(--btn-ring)",
73
+ }
74
+ : incomingStyle;
75
+
76
+ // Only enable CSS variable hooks when explicitly requested via inline vars
77
+ // or when the caller sets any [--btn-*] classes in className.
78
+ const wantsVarHooks =
79
+ !unstyled &&
80
+ (forceInlineVars ||
81
+ (typeof className === "string" && className.includes("[--btn-")));
82
+
83
+ return (
84
+ <Comp
85
+ ref={ref}
86
+ data-slot="button"
87
+ className={
88
+ unstyled
89
+ ? cn(
90
+ "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap disabled:pointer-events-none disabled:opacity-50",
91
+ className,
92
+ )
93
+ : cn(
94
+ buttonVariants({ variant, size }),
95
+ wantsVarHooks && [
96
+ // Color var hooks (apply only when CSS vars are provided)
97
+ "text-[var(--btn-fg)]",
98
+ "bg-[var(--btn-bg)]",
99
+ "hover:bg-[var(--btn-hover-bg)]",
100
+ "hover:text-[var(--btn-hover-fg)]",
101
+ // explicit dark variants to compete with dark: utilities from variants like outline
102
+ "dark:bg-[var(--btn-bg)]",
103
+ "dark:hover:bg-[var(--btn-hover-bg)]",
104
+ "dark:hover:text-[var(--btn-hover-fg)]",
105
+ // Focus ring and border hooks
106
+ "focus-visible:ring-[var(--btn-ring)]",
107
+ "border-[var(--btn-border)]",
108
+ "dark:border-[var(--btn-border)]",
109
+ ],
110
+ className,
111
+ )
112
+ }
113
+ style={finalStyle}
114
+ {...props}
115
+ />
116
+ );
117
+ },
118
+ );
119
+
120
+ Button.displayName = "Button";
121
+
122
+ export { Button, buttonVariants };