@snow-labs/brutal-ui 0.1.1 → 0.2.1
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/components/brutal/cta-section.d.ts +7 -2
- package/dist/components/brutal/cta-section.js +136 -32
- package/dist/components/brutal/cta-section.js.map +1 -1
- package/dist/components/brutal/faq.d.ts +16 -0
- package/dist/components/brutal/faq.js +163 -0
- package/dist/components/brutal/faq.js.map +1 -0
- package/dist/components/brutal/feature-grid.d.ts +6 -2
- package/dist/components/brutal/feature-grid.js +73 -10
- package/dist/components/brutal/feature-grid.js.map +1 -1
- package/dist/components/brutal/footer.d.ts +14 -1
- package/dist/components/brutal/footer.js +181 -18
- package/dist/components/brutal/footer.js.map +1 -1
- package/dist/components/brutal/hero.d.ts +9 -2
- package/dist/components/brutal/hero.js +67 -22
- package/dist/components/brutal/hero.js.map +1 -1
- package/dist/components/brutal/index.d.ts +7 -2
- package/dist/components/brutal/index.js +1035 -128
- package/dist/components/brutal/index.js.map +1 -1
- package/dist/components/brutal/integration-grid.d.ts +1 -1
- package/dist/components/brutal/integration-grid.js +13 -5
- package/dist/components/brutal/integration-grid.js.map +1 -1
- package/dist/components/brutal/logo-cloud.d.ts +17 -0
- package/dist/components/brutal/logo-cloud.js +93 -0
- package/dist/components/brutal/logo-cloud.js.map +1 -0
- package/dist/components/brutal/nav.d.ts +3 -1
- package/dist/components/brutal/nav.js +166 -9
- package/dist/components/brutal/nav.js.map +1 -1
- package/dist/components/brutal/newsletter.d.ts +14 -0
- package/dist/components/brutal/newsletter.js +169 -0
- package/dist/components/brutal/newsletter.js.map +1 -0
- package/dist/components/brutal/pricing-table.d.ts +27 -0
- package/dist/components/brutal/pricing-table.js +251 -0
- package/dist/components/brutal/pricing-table.js.map +1 -0
- package/dist/components/brutal/section-divider.d.ts +14 -0
- package/dist/components/brutal/section-divider.js +70 -0
- package/dist/components/brutal/section-divider.js.map +1 -0
- package/dist/components/brutal/section.d.ts +7 -3
- package/dist/components/brutal/section.js +13 -5
- package/dist/components/brutal/section.js.map +1 -1
- package/dist/components/brutal/stats-bar.d.ts +16 -0
- package/dist/components/brutal/stats-bar.js +127 -0
- package/dist/components/brutal/stats-bar.js.map +1 -0
- package/dist/components/brutal/testimonials.d.ts +11 -3
- package/dist/components/brutal/testimonials.js +126 -33
- package/dist/components/brutal/testimonials.js.map +1 -1
- package/dist/components/brutal/wave-divider.d.ts +2 -12
- package/dist/components/brutal/wave-divider.js +54 -26
- package/dist/components/brutal/wave-divider.js.map +1 -1
- package/dist/components/dashboard/activity-feed.d.ts +18 -0
- package/dist/components/dashboard/activity-feed.js +105 -0
- package/dist/components/dashboard/activity-feed.js.map +1 -0
- package/dist/components/dashboard/app-shell.d.ts +19 -0
- package/dist/components/dashboard/app-shell.js +206 -0
- package/dist/components/dashboard/app-shell.js.map +1 -0
- package/dist/components/dashboard/empty-state.d.ts +14 -0
- package/dist/components/dashboard/empty-state.js +96 -0
- package/dist/components/dashboard/empty-state.js.map +1 -0
- package/dist/components/dashboard/file-upload.d.ts +12 -0
- package/dist/components/dashboard/file-upload.js +86 -0
- package/dist/components/dashboard/file-upload.js.map +1 -0
- package/dist/components/dashboard/index.d.ts +10 -0
- package/dist/components/dashboard/index.js +755 -0
- package/dist/components/dashboard/index.js.map +1 -0
- package/dist/components/dashboard/search-bar.d.ts +12 -0
- package/dist/components/dashboard/search-bar.js +49 -0
- package/dist/components/dashboard/search-bar.js.map +1 -0
- package/dist/components/dashboard/sidebar.d.ts +23 -0
- package/dist/components/dashboard/sidebar.js +113 -0
- package/dist/components/dashboard/sidebar.js.map +1 -0
- package/dist/components/dashboard/stat-card.d.ts +13 -0
- package/dist/components/dashboard/stat-card.js +55 -0
- package/dist/components/dashboard/stat-card.js.map +1 -0
- package/dist/components/dashboard/user-menu.d.ts +16 -0
- package/dist/components/dashboard/user-menu.js +179 -0
- package/dist/components/dashboard/user-menu.js.map +1 -0
- package/dist/components/dashboard/view-switcher.d.ts +12 -0
- package/dist/components/dashboard/view-switcher.js +130 -0
- package/dist/components/dashboard/view-switcher.js.map +1 -0
- package/dist/components/views/calendar-view.d.ts +17 -0
- package/dist/components/views/calendar-view.js +182 -0
- package/dist/components/views/calendar-view.js.map +1 -0
- package/dist/components/views/data-table.d.ts +15 -0
- package/dist/components/views/data-table.js +204 -0
- package/dist/components/views/data-table.js.map +1 -0
- package/dist/components/views/grid-view.d.ts +11 -0
- package/dist/components/views/grid-view.js +31 -0
- package/dist/components/views/grid-view.js.map +1 -0
- package/dist/components/views/index.d.ts +7 -0
- package/dist/components/views/index.js +542 -0
- package/dist/components/views/index.js.map +1 -0
- package/dist/components/views/kanban-board.d.ts +21 -0
- package/dist/components/views/kanban-board.js +153 -0
- package/dist/components/views/kanban-board.js.map +1 -0
- package/dist/components/views/list-view.d.ts +19 -0
- package/dist/components/views/list-view.js +96 -0
- package/dist/components/views/list-view.js.map +1 -0
- package/dist/index.d.ts +27 -3
- package/dist/index.js +1881 -142
- package/dist/index.js.map +1 -1
- package/dist/lib/animations.d.ts +68 -0
- package/dist/lib/animations.js +44 -0
- package/dist/lib/animations.js.map +1 -0
- package/dist/templates/dashboard.d.ts +40 -0
- package/dist/templates/dashboard.js +658 -0
- package/dist/templates/dashboard.js.map +1 -0
- package/dist/templates/index.d.ts +4 -0
- package/dist/templates/index.js +2001 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/templates/saas-launch.d.ts +113 -0
- package/dist/templates/saas-launch.js +1394 -0
- package/dist/templates/saas-launch.js.map +1 -0
- package/dist/templates/studio.d.ts +72 -0
- package/dist/templates/studio.js +1099 -0
- package/dist/templates/studio.js.map +1 -0
- package/dist/theme.css +58 -15
- package/package.json +48 -2
|
@@ -4,14 +4,16 @@ interface NavLink {
|
|
|
4
4
|
label: string;
|
|
5
5
|
href: string;
|
|
6
6
|
badge?: string;
|
|
7
|
+
active?: boolean;
|
|
7
8
|
}
|
|
8
9
|
interface BrutalNavProps {
|
|
9
10
|
logo: React.ReactNode;
|
|
10
11
|
links: NavLink[];
|
|
11
12
|
ctaText?: string;
|
|
12
13
|
ctaHref?: string;
|
|
14
|
+
variant?: "solid" | "transparent" | "floating-pill";
|
|
13
15
|
className?: string;
|
|
14
16
|
}
|
|
15
|
-
declare function BrutalNav({ logo, links, ctaText, ctaHref, className, }: BrutalNavProps): react_jsx_runtime.JSX.Element;
|
|
17
|
+
declare function BrutalNav({ logo, links, ctaText, ctaHref, variant, className, }: BrutalNavProps): react_jsx_runtime.JSX.Element;
|
|
16
18
|
|
|
17
19
|
export { BrutalNav };
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { useState, useEffect } from 'react';
|
|
2
3
|
import { clsx } from 'clsx';
|
|
3
4
|
import { twMerge } from 'tailwind-merge';
|
|
4
5
|
import { Button as Button$1 } from '@base-ui/react/button';
|
|
5
6
|
import { cva } from 'class-variance-authority';
|
|
6
7
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
8
|
+
import { Dialog } from '@base-ui/react/dialog';
|
|
9
|
+
import { Menu, XIcon } from 'lucide-react';
|
|
7
10
|
|
|
8
11
|
function cn(...inputs) {
|
|
9
12
|
return twMerge(clsx(inputs));
|
|
@@ -64,27 +67,127 @@ function Button({
|
|
|
64
67
|
}
|
|
65
68
|
);
|
|
66
69
|
}
|
|
70
|
+
function Sheet({ ...props }) {
|
|
71
|
+
return /* @__PURE__ */ jsx(Dialog.Root, { "data-slot": "sheet", ...props });
|
|
72
|
+
}
|
|
73
|
+
function SheetTrigger({ ...props }) {
|
|
74
|
+
return /* @__PURE__ */ jsx(Dialog.Trigger, { "data-slot": "sheet-trigger", ...props });
|
|
75
|
+
}
|
|
76
|
+
function SheetPortal({ ...props }) {
|
|
77
|
+
return /* @__PURE__ */ jsx(Dialog.Portal, { "data-slot": "sheet-portal", ...props });
|
|
78
|
+
}
|
|
79
|
+
function SheetOverlay({ className, ...props }) {
|
|
80
|
+
return /* @__PURE__ */ jsx(
|
|
81
|
+
Dialog.Backdrop,
|
|
82
|
+
{
|
|
83
|
+
"data-slot": "sheet-overlay",
|
|
84
|
+
className: cn(
|
|
85
|
+
"fixed inset-0 z-50 bg-black/60 transition-opacity duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0",
|
|
86
|
+
className
|
|
87
|
+
),
|
|
88
|
+
...props
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
function SheetContent({
|
|
93
|
+
className,
|
|
94
|
+
children,
|
|
95
|
+
side = "right",
|
|
96
|
+
showCloseButton = true,
|
|
97
|
+
...props
|
|
98
|
+
}) {
|
|
99
|
+
return /* @__PURE__ */ jsxs(SheetPortal, { children: [
|
|
100
|
+
/* @__PURE__ */ jsx(SheetOverlay, {}),
|
|
101
|
+
/* @__PURE__ */ jsxs(
|
|
102
|
+
Dialog.Popup,
|
|
103
|
+
{
|
|
104
|
+
"data-slot": "sheet-content",
|
|
105
|
+
"data-side": side,
|
|
106
|
+
className: cn(
|
|
107
|
+
"fixed z-50 flex flex-col gap-4 border-brutal border-foreground bg-background bg-clip-padding text-sm shadow-brutal-lg transition duration-200 ease-in-out data-ending-style:opacity-0 data-starting-style:opacity-0 data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:data-ending-style:translate-y-[2.5rem] data-[side=bottom]:data-starting-style:translate-y-[2.5rem] data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:data-ending-style:translate-x-[-2.5rem] data-[side=left]:data-starting-style:translate-x-[-2.5rem] data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:data-ending-style:translate-x-[2.5rem] data-[side=right]:data-starting-style:translate-x-[2.5rem] data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:data-ending-style:translate-y-[-2.5rem] data-[side=top]:data-starting-style:translate-y-[-2.5rem] data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm",
|
|
108
|
+
className
|
|
109
|
+
),
|
|
110
|
+
...props,
|
|
111
|
+
children: [
|
|
112
|
+
children,
|
|
113
|
+
showCloseButton && /* @__PURE__ */ jsxs(
|
|
114
|
+
Dialog.Close,
|
|
115
|
+
{
|
|
116
|
+
"data-slot": "sheet-close",
|
|
117
|
+
render: /* @__PURE__ */ jsx(
|
|
118
|
+
Button,
|
|
119
|
+
{
|
|
120
|
+
variant: "ghost",
|
|
121
|
+
className: "absolute top-3 right-3",
|
|
122
|
+
size: "icon-sm"
|
|
123
|
+
}
|
|
124
|
+
),
|
|
125
|
+
children: [
|
|
126
|
+
/* @__PURE__ */ jsx(
|
|
127
|
+
XIcon,
|
|
128
|
+
{}
|
|
129
|
+
),
|
|
130
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
|
|
131
|
+
]
|
|
132
|
+
}
|
|
133
|
+
)
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
)
|
|
137
|
+
] });
|
|
138
|
+
}
|
|
139
|
+
function SheetTitle({ className, ...props }) {
|
|
140
|
+
return /* @__PURE__ */ jsx(
|
|
141
|
+
Dialog.Title,
|
|
142
|
+
{
|
|
143
|
+
"data-slot": "sheet-title",
|
|
144
|
+
className: cn("text-base font-bold text-foreground", className),
|
|
145
|
+
...props
|
|
146
|
+
}
|
|
147
|
+
);
|
|
148
|
+
}
|
|
67
149
|
function BrutalNav({
|
|
68
150
|
logo,
|
|
69
151
|
links,
|
|
70
152
|
ctaText = "Sign In",
|
|
71
153
|
ctaHref = "/admin",
|
|
154
|
+
variant = "solid",
|
|
72
155
|
className
|
|
73
156
|
}) {
|
|
74
|
-
|
|
75
|
-
|
|
157
|
+
const [mobileOpen, setMobileOpen] = useState(false);
|
|
158
|
+
const [isScrolled, setIsScrolled] = useState(false);
|
|
159
|
+
useEffect(() => {
|
|
160
|
+
if (variant !== "transparent") return;
|
|
161
|
+
const onScroll = () => setIsScrolled(window.scrollY > 20);
|
|
162
|
+
onScroll();
|
|
163
|
+
window.addEventListener("scroll", onScroll, { passive: true });
|
|
164
|
+
return () => window.removeEventListener("scroll", onScroll);
|
|
165
|
+
}, [variant]);
|
|
166
|
+
const variantStyles = {
|
|
167
|
+
solid: "sticky top-0 z-50 w-full border-b-brutal border-foreground bg-brand",
|
|
168
|
+
transparent: cn(
|
|
169
|
+
"fixed top-0 left-0 right-0 z-50 w-full transition-all duration-200",
|
|
170
|
+
isScrolled ? "bg-background/80 text-foreground backdrop-blur-md border-b border-foreground/10" : "bg-transparent text-white"
|
|
171
|
+
),
|
|
172
|
+
"floating-pill": "fixed top-0 left-0 right-0 z-50 mx-4 mt-4 rounded-full border-brutal border-foreground bg-background shadow-brutal"
|
|
173
|
+
};
|
|
174
|
+
return /* @__PURE__ */ jsx("header", { className: cn(variantStyles[variant], className), children: /* @__PURE__ */ jsxs(
|
|
175
|
+
"div",
|
|
76
176
|
{
|
|
77
177
|
className: cn(
|
|
78
|
-
"
|
|
79
|
-
|
|
178
|
+
"flex h-14 items-center justify-between px-6",
|
|
179
|
+
variant === "floating-pill" ? "mx-auto max-w-7xl" : "brutal-container"
|
|
80
180
|
),
|
|
81
|
-
children:
|
|
181
|
+
children: [
|
|
82
182
|
/* @__PURE__ */ jsx("a", { href: "/", className: "flex items-center gap-2 text-lg font-black", children: logo }),
|
|
83
183
|
/* @__PURE__ */ jsx("nav", { className: "hidden items-center gap-1 md:flex", children: links.map((link) => /* @__PURE__ */ jsxs(
|
|
84
184
|
"a",
|
|
85
185
|
{
|
|
86
186
|
href: link.href,
|
|
87
|
-
className:
|
|
187
|
+
className: cn(
|
|
188
|
+
"relative rounded-md px-3 py-1.5 text-sm font-bold transition-colors hover:opacity-70",
|
|
189
|
+
link.active && "bg-foreground/10"
|
|
190
|
+
),
|
|
88
191
|
children: [
|
|
89
192
|
link.label,
|
|
90
193
|
link.badge && /* @__PURE__ */ jsx("span", { className: "absolute -top-1 -right-1 border border-foreground bg-background px-1 font-mono text-[9px] font-bold uppercase text-foreground", children: link.badge })
|
|
@@ -92,10 +195,64 @@ function BrutalNav({
|
|
|
92
195
|
},
|
|
93
196
|
link.href
|
|
94
197
|
)) }),
|
|
95
|
-
/* @__PURE__ */
|
|
96
|
-
|
|
198
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
199
|
+
/* @__PURE__ */ jsx(
|
|
200
|
+
Button,
|
|
201
|
+
{
|
|
202
|
+
variant: "nav",
|
|
203
|
+
size: "sm",
|
|
204
|
+
render: /* @__PURE__ */ jsx("a", { href: ctaHref }),
|
|
205
|
+
className: "hidden md:inline-flex",
|
|
206
|
+
children: ctaText
|
|
207
|
+
}
|
|
208
|
+
),
|
|
209
|
+
/* @__PURE__ */ jsxs(Sheet, { open: mobileOpen, onOpenChange: setMobileOpen, children: [
|
|
210
|
+
/* @__PURE__ */ jsxs(
|
|
211
|
+
SheetTrigger,
|
|
212
|
+
{
|
|
213
|
+
render: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon-sm", className: "md:hidden" }),
|
|
214
|
+
children: [
|
|
215
|
+
/* @__PURE__ */ jsx(Menu, { className: "size-5" }),
|
|
216
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Menu" })
|
|
217
|
+
]
|
|
218
|
+
}
|
|
219
|
+
),
|
|
220
|
+
/* @__PURE__ */ jsxs(SheetContent, { side: "right", showCloseButton: true, children: [
|
|
221
|
+
/* @__PURE__ */ jsx(SheetTitle, { children: "Navigation" }),
|
|
222
|
+
/* @__PURE__ */ jsxs("nav", { className: "flex flex-col gap-1 px-2 pt-4", children: [
|
|
223
|
+
links.map((link) => /* @__PURE__ */ jsxs(
|
|
224
|
+
"a",
|
|
225
|
+
{
|
|
226
|
+
href: link.href,
|
|
227
|
+
onClick: () => setMobileOpen(false),
|
|
228
|
+
className: cn(
|
|
229
|
+
"flex items-center gap-2 rounded-md px-3 py-2.5 text-sm font-bold transition-colors hover:bg-foreground/5",
|
|
230
|
+
link.active && "bg-foreground/10"
|
|
231
|
+
),
|
|
232
|
+
children: [
|
|
233
|
+
link.label,
|
|
234
|
+
link.badge && /* @__PURE__ */ jsx("span", { className: "border border-foreground bg-background px-1 font-mono text-[9px] font-bold uppercase text-foreground", children: link.badge })
|
|
235
|
+
]
|
|
236
|
+
},
|
|
237
|
+
link.href
|
|
238
|
+
)),
|
|
239
|
+
/* @__PURE__ */ jsx("div", { className: "mt-4 border-t border-foreground/10 pt-4", children: /* @__PURE__ */ jsx(
|
|
240
|
+
Button,
|
|
241
|
+
{
|
|
242
|
+
variant: "default",
|
|
243
|
+
size: "default",
|
|
244
|
+
render: /* @__PURE__ */ jsx("a", { href: ctaHref }),
|
|
245
|
+
className: "w-full",
|
|
246
|
+
children: ctaText
|
|
247
|
+
}
|
|
248
|
+
) })
|
|
249
|
+
] })
|
|
250
|
+
] })
|
|
251
|
+
] })
|
|
252
|
+
] })
|
|
253
|
+
]
|
|
97
254
|
}
|
|
98
|
-
);
|
|
255
|
+
) });
|
|
99
256
|
}
|
|
100
257
|
|
|
101
258
|
export { BrutalNav };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/ui/button.tsx","../../../src/components/brutal/nav.tsx"],"names":["ButtonPrimitive","jsx"],"mappings":"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","file":"nav.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","\"use client\";\n\nimport { Button as ButtonPrimitive } from \"@base-ui/react/button\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst buttonVariants = cva(\n \"group/button inline-flex shrink-0 items-center justify-center rounded-lg whitespace-nowrap font-bold transition-all duration-150 select-none outline-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n // Primary: Black bg, white text, offset shadow\n default:\n \"border-brutal border-foreground bg-primary text-primary-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm\",\n // CTA: Mint green bg — the Bannerbear signature\n cta: \"border-brutal border-foreground bg-cta text-cta-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm\",\n // Brand: Dynamic brand color bg\n brand:\n \"border-brutal border-foreground bg-brand text-brand-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm\",\n // Outline: White bg, black border, offset shadow\n outline:\n \"border-brutal border-foreground bg-background text-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm\",\n // Secondary: Light bg, border, smaller shadow\n secondary:\n \"border-brutal border-foreground bg-secondary text-secondary-foreground shadow-brutal-sm hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal active:translate-x-px active:translate-y-px active:shadow-none\",\n // Ghost: No border/shadow, subtle hover\n ghost: \"hover:bg-secondary hover:text-foreground\",\n // Link: Text only\n link: \"text-foreground underline-offset-4 hover:underline\",\n // Destructive\n destructive:\n \"border-brutal border-destructive bg-destructive text-destructive-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm\",\n // Nav: Thin border, no shadow (for nav Sign In buttons)\n nav: \"border border-foreground bg-background text-foreground hover:bg-foreground hover:text-background\",\n },\n size: {\n xs: \"h-7 gap-1 px-2.5 text-xs\",\n sm: \"h-8 gap-1.5 px-3 text-sm\",\n default: \"h-10 gap-2 px-5 text-sm\",\n lg: \"h-12 gap-2 px-7 text-base\",\n xl: \"h-14 gap-2.5 px-9 text-lg\",\n icon: \"size-10\",\n \"icon-sm\": \"size-8\",\n \"icon-lg\": \"size-12\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n);\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n ...props\n}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {\n return (\n <ButtonPrimitive\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nexport { Button, buttonVariants };\n","\"use client\";\n\nimport { cn } from \"../../lib/utils\";\nimport { Button } from \"../ui/button\";\n\ninterface NavLink {\n label: string;\n href: string;\n badge?: string;\n}\n\ninterface BrutalNavProps {\n logo: React.ReactNode;\n links: NavLink[];\n ctaText?: string;\n ctaHref?: string;\n className?: string;\n}\n\nexport function BrutalNav({\n logo,\n links,\n ctaText = \"Sign In\",\n ctaHref = \"/admin\",\n className,\n}: BrutalNavProps) {\n return (\n <header\n className={cn(\n \"sticky top-0 z-50 w-full border-b-brutal border-foreground bg-brand\",\n className\n )}\n >\n <div className=\"brutal-container flex h-14 items-center justify-between px-6\">\n {/* Logo */}\n <a href=\"/\" className=\"flex items-center gap-2 text-lg font-black\">\n {logo}\n </a>\n\n {/* Center links (desktop) */}\n <nav className=\"hidden items-center gap-1 md:flex\">\n {links.map((link) => (\n <a\n key={link.href}\n href={link.href}\n className=\"relative px-3 py-1.5 text-sm font-bold transition-colors hover:opacity-70\"\n >\n {link.label}\n {link.badge && (\n <span className=\"absolute -top-1 -right-1 border border-foreground bg-background px-1 font-mono text-[9px] font-bold uppercase text-foreground\">\n {link.badge}\n </span>\n )}\n </a>\n ))}\n </nav>\n\n {/* CTA */}\n <Button variant=\"nav\" size=\"sm\" render={<a href={ctaHref} />}>\n {ctaText}\n </Button>\n </div>\n </header>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/ui/button.tsx","../../../src/components/ui/sheet.tsx","../../../src/components/brutal/nav.tsx"],"names":["ButtonPrimitive","jsx","SheetPrimitive","jsxs"],"mappings":"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","file":"nav.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","\"use client\";\n\nimport { Button as ButtonPrimitive } from \"@base-ui/react/button\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst buttonVariants = cva(\n \"group/button inline-flex shrink-0 items-center justify-center rounded-lg whitespace-nowrap font-bold transition-all duration-150 select-none outline-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n // Primary: Black bg, white text, offset shadow\n default:\n \"border-brutal border-foreground bg-primary text-primary-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm\",\n // CTA: Mint green bg — the Bannerbear signature\n cta: \"border-brutal border-foreground bg-cta text-cta-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm\",\n // Brand: Dynamic brand color bg\n brand:\n \"border-brutal border-foreground bg-brand text-brand-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm\",\n // Outline: White bg, black border, offset shadow\n outline:\n \"border-brutal border-foreground bg-background text-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm\",\n // Secondary: Light bg, border, smaller shadow\n secondary:\n \"border-brutal border-foreground bg-secondary text-secondary-foreground shadow-brutal-sm hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal active:translate-x-px active:translate-y-px active:shadow-none\",\n // Ghost: No border/shadow, subtle hover\n ghost: \"hover:bg-secondary hover:text-foreground\",\n // Link: Text only\n link: \"text-foreground underline-offset-4 hover:underline\",\n // Destructive\n destructive:\n \"border-brutal border-destructive bg-destructive text-destructive-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm\",\n // Nav: Thin border, no shadow (for nav Sign In buttons)\n nav: \"border border-foreground bg-background text-foreground hover:bg-foreground hover:text-background\",\n },\n size: {\n xs: \"h-7 gap-1 px-2.5 text-xs\",\n sm: \"h-8 gap-1.5 px-3 text-sm\",\n default: \"h-10 gap-2 px-5 text-sm\",\n lg: \"h-12 gap-2 px-7 text-base\",\n xl: \"h-14 gap-2.5 px-9 text-lg\",\n icon: \"size-10\",\n \"icon-sm\": \"size-8\",\n \"icon-lg\": \"size-12\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n);\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n ...props\n}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {\n return (\n <ButtonPrimitive\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nexport { Button, buttonVariants };\n","\"use client\"\n\nimport * as React from \"react\"\nimport { Dialog as SheetPrimitive } from \"@base-ui/react/dialog\"\n\nimport { cn } from \"../../lib/utils\"\nimport { Button } from \"./button\"\nimport { XIcon } from \"lucide-react\"\n\nfunction Sheet({ ...props }: SheetPrimitive.Root.Props) {\n return <SheetPrimitive.Root data-slot=\"sheet\" {...props} />\n}\n\nfunction SheetTrigger({ ...props }: SheetPrimitive.Trigger.Props) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />\n}\n\nfunction SheetClose({ ...props }: SheetPrimitive.Close.Props) {\n return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />\n}\n\nfunction SheetPortal({ ...props }: SheetPrimitive.Portal.Props) {\n return <SheetPrimitive.Portal data-slot=\"sheet-portal\" {...props} />\n}\n\nfunction SheetOverlay({ className, ...props }: SheetPrimitive.Backdrop.Props) {\n return (\n <SheetPrimitive.Backdrop\n data-slot=\"sheet-overlay\"\n className={cn(\n \"fixed inset-0 z-50 bg-black/60 transition-opacity duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SheetContent({\n className,\n children,\n side = \"right\",\n showCloseButton = true,\n ...props\n}: SheetPrimitive.Popup.Props & {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n showCloseButton?: boolean\n}) {\n return (\n <SheetPortal>\n <SheetOverlay />\n <SheetPrimitive.Popup\n data-slot=\"sheet-content\"\n data-side={side}\n className={cn(\n \"fixed z-50 flex flex-col gap-4 border-brutal border-foreground bg-background bg-clip-padding text-sm shadow-brutal-lg transition duration-200 ease-in-out data-ending-style:opacity-0 data-starting-style:opacity-0 data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:data-ending-style:translate-y-[2.5rem] data-[side=bottom]:data-starting-style:translate-y-[2.5rem] data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:data-ending-style:translate-x-[-2.5rem] data-[side=left]:data-starting-style:translate-x-[-2.5rem] data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:data-ending-style:translate-x-[2.5rem] data-[side=right]:data-starting-style:translate-x-[2.5rem] data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:data-ending-style:translate-y-[-2.5rem] data-[side=top]:data-starting-style:translate-y-[-2.5rem] data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm\",\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <SheetPrimitive.Close\n data-slot=\"sheet-close\"\n render={\n <Button\n variant=\"ghost\"\n className=\"absolute top-3 right-3\"\n size=\"icon-sm\"\n />\n }\n >\n <XIcon\n />\n <span className=\"sr-only\">Close</span>\n </SheetPrimitive.Close>\n )}\n </SheetPrimitive.Popup>\n </SheetPortal>\n )\n}\n\nfunction SheetHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn(\"flex flex-col gap-0.5 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-footer\"\n className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetTitle({ className, ...props }: SheetPrimitive.Title.Props) {\n return (\n <SheetPrimitive.Title\n data-slot=\"sheet-title\"\n className={cn(\"text-base font-bold text-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetDescription({\n className,\n ...props\n}: SheetPrimitive.Description.Props) {\n return (\n <SheetPrimitive.Description\n data-slot=\"sheet-description\"\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n}\n","\"use client\";\n\nimport { useState, useEffect } from \"react\";\nimport { cn } from \"../../lib/utils\";\nimport { Button } from \"../ui/button\";\nimport {\n Sheet,\n SheetContent,\n SheetTrigger,\n SheetTitle,\n} from \"../ui/sheet\";\nimport { Menu } from \"lucide-react\";\n\ninterface NavLink {\n label: string;\n href: string;\n badge?: string;\n active?: boolean;\n}\n\ninterface BrutalNavProps {\n logo: React.ReactNode;\n links: NavLink[];\n ctaText?: string;\n ctaHref?: string;\n variant?: \"solid\" | \"transparent\" | \"floating-pill\";\n className?: string;\n}\n\nexport function BrutalNav({\n logo,\n links,\n ctaText = \"Sign In\",\n ctaHref = \"/admin\",\n variant = \"solid\",\n className,\n}: BrutalNavProps) {\n const [mobileOpen, setMobileOpen] = useState(false);\n const [isScrolled, setIsScrolled] = useState(false);\n\n useEffect(() => {\n if (variant !== \"transparent\") return;\n const onScroll = () => setIsScrolled(window.scrollY > 20);\n onScroll(); // check on mount\n window.addEventListener(\"scroll\", onScroll, { passive: true });\n return () => window.removeEventListener(\"scroll\", onScroll);\n }, [variant]);\n\n const variantStyles = {\n solid: \"sticky top-0 z-50 w-full border-b-brutal border-foreground bg-brand\",\n transparent: cn(\n \"fixed top-0 left-0 right-0 z-50 w-full transition-all duration-200\",\n isScrolled\n ? \"bg-background/80 text-foreground backdrop-blur-md border-b border-foreground/10\"\n : \"bg-transparent text-white\"\n ),\n \"floating-pill\":\n \"fixed top-0 left-0 right-0 z-50 mx-4 mt-4 rounded-full border-brutal border-foreground bg-background shadow-brutal\",\n };\n\n return (\n <header className={cn(variantStyles[variant], className)}>\n <div\n className={cn(\n \"flex h-14 items-center justify-between px-6\",\n variant === \"floating-pill\" ? \"mx-auto max-w-7xl\" : \"brutal-container\"\n )}\n >\n {/* Logo */}\n <a href=\"/\" className=\"flex items-center gap-2 text-lg font-black\">\n {logo}\n </a>\n\n {/* Center links (desktop) */}\n <nav className=\"hidden items-center gap-1 md:flex\">\n {links.map((link) => (\n <a\n key={link.href}\n href={link.href}\n className={cn(\n \"relative rounded-md px-3 py-1.5 text-sm font-bold transition-colors hover:opacity-70\",\n link.active && \"bg-foreground/10\"\n )}\n >\n {link.label}\n {link.badge && (\n <span className=\"absolute -top-1 -right-1 border border-foreground bg-background px-1 font-mono text-[9px] font-bold uppercase text-foreground\">\n {link.badge}\n </span>\n )}\n </a>\n ))}\n </nav>\n\n {/* Right side: CTA + Hamburger */}\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"nav\"\n size=\"sm\"\n render={<a href={ctaHref} />}\n className=\"hidden md:inline-flex\"\n >\n {ctaText}\n </Button>\n\n {/* Mobile hamburger */}\n <Sheet open={mobileOpen} onOpenChange={setMobileOpen}>\n <SheetTrigger\n render={\n <Button variant=\"ghost\" size=\"icon-sm\" className=\"md:hidden\" />\n }\n >\n <Menu className=\"size-5\" />\n <span className=\"sr-only\">Menu</span>\n </SheetTrigger>\n <SheetContent side=\"right\" showCloseButton>\n <SheetTitle>Navigation</SheetTitle>\n <nav className=\"flex flex-col gap-1 px-2 pt-4\">\n {links.map((link) => (\n <a\n key={link.href}\n href={link.href}\n onClick={() => setMobileOpen(false)}\n className={cn(\n \"flex items-center gap-2 rounded-md px-3 py-2.5 text-sm font-bold transition-colors hover:bg-foreground/5\",\n link.active && \"bg-foreground/10\"\n )}\n >\n {link.label}\n {link.badge && (\n <span className=\"border border-foreground bg-background px-1 font-mono text-[9px] font-bold uppercase text-foreground\">\n {link.badge}\n </span>\n )}\n </a>\n ))}\n <div className=\"mt-4 border-t border-foreground/10 pt-4\">\n <Button\n variant=\"default\"\n size=\"default\"\n render={<a href={ctaHref} />}\n className=\"w-full\"\n >\n {ctaText}\n </Button>\n </div>\n </nav>\n </SheetContent>\n </Sheet>\n </div>\n </div>\n </header>\n );\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
interface NewsletterProps {
|
|
4
|
+
headline?: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
placeholder?: string;
|
|
7
|
+
buttonText?: string;
|
|
8
|
+
onSubmit?: (email: string) => void;
|
|
9
|
+
color?: "white" | "brand" | "black";
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
declare function Newsletter({ headline, description, placeholder, buttonText, onSubmit, color, className, }: NewsletterProps): react_jsx_runtime.JSX.Element;
|
|
13
|
+
|
|
14
|
+
export { Newsletter };
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Button as Button$1 } from '@base-ui/react/button';
|
|
3
|
+
import { cva } from 'class-variance-authority';
|
|
4
|
+
import { clsx } from 'clsx';
|
|
5
|
+
import { twMerge } from 'tailwind-merge';
|
|
6
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
7
|
+
import { Input as Input$1 } from '@base-ui/react/input';
|
|
8
|
+
|
|
9
|
+
// src/components/ui/button.tsx
|
|
10
|
+
function cn(...inputs) {
|
|
11
|
+
return twMerge(clsx(inputs));
|
|
12
|
+
}
|
|
13
|
+
var buttonVariants = cva(
|
|
14
|
+
"group/button inline-flex shrink-0 items-center justify-center rounded-lg whitespace-nowrap font-bold transition-all duration-150 select-none outline-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
15
|
+
{
|
|
16
|
+
variants: {
|
|
17
|
+
variant: {
|
|
18
|
+
// Primary: Black bg, white text, offset shadow
|
|
19
|
+
default: "border-brutal border-foreground bg-primary text-primary-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm",
|
|
20
|
+
// CTA: Mint green bg — the Bannerbear signature
|
|
21
|
+
cta: "border-brutal border-foreground bg-cta text-cta-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm",
|
|
22
|
+
// Brand: Dynamic brand color bg
|
|
23
|
+
brand: "border-brutal border-foreground bg-brand text-brand-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm",
|
|
24
|
+
// Outline: White bg, black border, offset shadow
|
|
25
|
+
outline: "border-brutal border-foreground bg-background text-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm",
|
|
26
|
+
// Secondary: Light bg, border, smaller shadow
|
|
27
|
+
secondary: "border-brutal border-foreground bg-secondary text-secondary-foreground shadow-brutal-sm hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal active:translate-x-px active:translate-y-px active:shadow-none",
|
|
28
|
+
// Ghost: No border/shadow, subtle hover
|
|
29
|
+
ghost: "hover:bg-secondary hover:text-foreground",
|
|
30
|
+
// Link: Text only
|
|
31
|
+
link: "text-foreground underline-offset-4 hover:underline",
|
|
32
|
+
// Destructive
|
|
33
|
+
destructive: "border-brutal border-destructive bg-destructive text-destructive-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm",
|
|
34
|
+
// Nav: Thin border, no shadow (for nav Sign In buttons)
|
|
35
|
+
nav: "border border-foreground bg-background text-foreground hover:bg-foreground hover:text-background"
|
|
36
|
+
},
|
|
37
|
+
size: {
|
|
38
|
+
xs: "h-7 gap-1 px-2.5 text-xs",
|
|
39
|
+
sm: "h-8 gap-1.5 px-3 text-sm",
|
|
40
|
+
default: "h-10 gap-2 px-5 text-sm",
|
|
41
|
+
lg: "h-12 gap-2 px-7 text-base",
|
|
42
|
+
xl: "h-14 gap-2.5 px-9 text-lg",
|
|
43
|
+
icon: "size-10",
|
|
44
|
+
"icon-sm": "size-8",
|
|
45
|
+
"icon-lg": "size-12"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
defaultVariants: {
|
|
49
|
+
variant: "default",
|
|
50
|
+
size: "default"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
function Button({
|
|
55
|
+
className,
|
|
56
|
+
variant = "default",
|
|
57
|
+
size = "default",
|
|
58
|
+
...props
|
|
59
|
+
}) {
|
|
60
|
+
return /* @__PURE__ */ jsx(
|
|
61
|
+
Button$1,
|
|
62
|
+
{
|
|
63
|
+
"data-slot": "button",
|
|
64
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
65
|
+
...props
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
function Input({ className, type, ...props }) {
|
|
70
|
+
return /* @__PURE__ */ jsx(
|
|
71
|
+
Input$1,
|
|
72
|
+
{
|
|
73
|
+
type,
|
|
74
|
+
"data-slot": "input",
|
|
75
|
+
className: cn(
|
|
76
|
+
"h-10 w-full min-w-0 rounded-lg border-brutal border-foreground bg-background px-3 py-2 text-base font-medium shadow-brutal-sm transition-all outline-none placeholder:text-muted-foreground focus:shadow-brutal focus:-translate-x-0.5 focus:-translate-y-0.5 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive md:text-sm",
|
|
77
|
+
className
|
|
78
|
+
),
|
|
79
|
+
...props
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
var colorMap = {
|
|
84
|
+
white: "bg-background text-foreground",
|
|
85
|
+
brand: "bg-brand",
|
|
86
|
+
"brand-muted": "bg-brand-muted text-foreground",
|
|
87
|
+
black: "bg-foreground text-background",
|
|
88
|
+
cta: "bg-cta"
|
|
89
|
+
};
|
|
90
|
+
var containerMap = {
|
|
91
|
+
sm: "brutal-container-sm",
|
|
92
|
+
default: "brutal-container",
|
|
93
|
+
lg: "brutal-container-lg"
|
|
94
|
+
};
|
|
95
|
+
var paddingMap = {
|
|
96
|
+
sm: "brutal-section-sm",
|
|
97
|
+
default: "brutal-section",
|
|
98
|
+
lg: "brutal-section py-28 sm:py-36 md:py-44"
|
|
99
|
+
};
|
|
100
|
+
var patternMap = {
|
|
101
|
+
dots: "brutal-dots",
|
|
102
|
+
stripes: "brutal-stripes",
|
|
103
|
+
noise: "brutal-noise",
|
|
104
|
+
grain: "brutal-grain",
|
|
105
|
+
crosshatch: "brutal-crosshatch",
|
|
106
|
+
"grid-dots": "brutal-grid-dots",
|
|
107
|
+
"gradient-mesh": "brutal-gradient-mesh",
|
|
108
|
+
none: ""
|
|
109
|
+
};
|
|
110
|
+
function BrutalSection({
|
|
111
|
+
children,
|
|
112
|
+
color = "white",
|
|
113
|
+
className,
|
|
114
|
+
containerSize = "default",
|
|
115
|
+
padding = "default",
|
|
116
|
+
pattern,
|
|
117
|
+
dots = false,
|
|
118
|
+
stripes = false,
|
|
119
|
+
id
|
|
120
|
+
}) {
|
|
121
|
+
const resolvedPattern = pattern ?? (dots ? "dots" : void 0) ?? (stripes ? "stripes" : void 0) ?? "none";
|
|
122
|
+
return /* @__PURE__ */ jsx(
|
|
123
|
+
"section",
|
|
124
|
+
{
|
|
125
|
+
id,
|
|
126
|
+
className: cn(
|
|
127
|
+
paddingMap[padding],
|
|
128
|
+
colorMap[color],
|
|
129
|
+
patternMap[resolvedPattern],
|
|
130
|
+
className
|
|
131
|
+
),
|
|
132
|
+
children: /* @__PURE__ */ jsx("div", { className: containerMap[containerSize], children })
|
|
133
|
+
}
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
function Newsletter({
|
|
137
|
+
headline = "Stay in the loop",
|
|
138
|
+
description,
|
|
139
|
+
placeholder = "you@example.com",
|
|
140
|
+
buttonText = "Subscribe",
|
|
141
|
+
onSubmit,
|
|
142
|
+
color = "white",
|
|
143
|
+
className
|
|
144
|
+
}) {
|
|
145
|
+
return /* @__PURE__ */ jsx(BrutalSection, { color, padding: "sm", className, children: /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-md border-brutal border-foreground bg-background p-8 text-foreground shadow-brutal-lg", children: [
|
|
146
|
+
/* @__PURE__ */ jsx("h3", { className: "brutal-h3 mb-2", children: headline }),
|
|
147
|
+
description && /* @__PURE__ */ jsx("p", { className: "brutal-body mb-6 text-muted-foreground", children: description }),
|
|
148
|
+
/* @__PURE__ */ jsxs(
|
|
149
|
+
"form",
|
|
150
|
+
{
|
|
151
|
+
onSubmit: (e) => {
|
|
152
|
+
e.preventDefault();
|
|
153
|
+
const form = e.target;
|
|
154
|
+
const email = new FormData(form).get("email");
|
|
155
|
+
onSubmit?.(email);
|
|
156
|
+
},
|
|
157
|
+
className: "flex gap-3",
|
|
158
|
+
children: [
|
|
159
|
+
/* @__PURE__ */ jsx(Input, { type: "email", name: "email", placeholder, required: true, className: "flex-1" }),
|
|
160
|
+
/* @__PURE__ */ jsx(Button, { type: "submit", variant: "cta", children: buttonText })
|
|
161
|
+
]
|
|
162
|
+
}
|
|
163
|
+
)
|
|
164
|
+
] }) });
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export { Newsletter };
|
|
168
|
+
//# sourceMappingURL=newsletter.js.map
|
|
169
|
+
//# sourceMappingURL=newsletter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/ui/button.tsx","../../../src/components/ui/input.tsx","../../../src/components/brutal/section.tsx","../../../src/components/brutal/newsletter.tsx"],"names":["ButtonPrimitive","jsx","InputPrimitive"],"mappings":";;;;;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACEA,IAAM,cAAA,GAAiB,GAAA;AAAA,EACrB,8RAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA;AAAA,QAEP,OAAA,EACE,2NAAA;AAAA;AAAA,QAEF,GAAA,EAAK,mNAAA;AAAA;AAAA,QAEL,KAAA,EACE,uNAAA;AAAA;AAAA,QAEF,OAAA,EACE,sNAAA;AAAA;AAAA,QAEF,SAAA,EACE,0NAAA;AAAA;AAAA,QAEF,KAAA,EAAO,0CAAA;AAAA;AAAA,QAEP,IAAA,EAAM,oDAAA;AAAA;AAAA,QAEN,WAAA,EACE,oOAAA;AAAA;AAAA,QAEF,GAAA,EAAK;AAAA,OACP;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,EAAA,EAAI,0BAAA;AAAA,QACJ,EAAA,EAAI,0BAAA;AAAA,QACJ,OAAA,EAAS,yBAAA;AAAA,QACT,EAAA,EAAI,2BAAA;AAAA,QACJ,EAAA,EAAI,2BAAA;AAAA,QACJ,IAAA,EAAM,SAAA;AAAA,QACN,SAAA,EAAW,QAAA;AAAA,QACX,SAAA,EAAW;AAAA;AACb,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS,SAAA;AAAA,MACT,IAAA,EAAM;AAAA;AACR;AAEJ,CAAA;AAEA,SAAS,MAAA,CAAO;AAAA,EACd,SAAA;AAAA,EACA,OAAA,GAAU,SAAA;AAAA,EACV,IAAA,GAAO,SAAA;AAAA,EACP,GAAG;AACL,CAAA,EAAgE;AAC9D,EAAA,uBACE,GAAA;AAAA,IAACA,QAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,QAAA;AAAA,MACV,SAAA,EAAW,GAAG,cAAA,CAAe,EAAE,SAAS,IAAA,EAAM,SAAA,EAAW,CAAC,CAAA;AAAA,MACzD,GAAG;AAAA;AAAA,GACN;AAEJ;AC9DA,SAAS,MAAM,EAAE,SAAA,EAAW,IAAA,EAAM,GAAG,OAAM,EAAkC;AAC3E,EAAA,uBACEC,GAAAA;AAAA,IAACC,OAAA;AAAA,IAAA;AAAA,MACC,IAAA;AAAA,MACA,WAAA,EAAU,OAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,2VAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;ACgBA,IAAM,QAAA,GAAyC;AAAA,EAC7C,KAAA,EAAO,+BAAA;AAAA,EACP,KAAA,EAAO,UAAA;AAAA,EACP,aAAA,EAAe,gCAAA;AAAA,EACf,KAAA,EAAO,+BAAA;AAAA,EACP,GAAA,EAAK;AACP,CAAA;AAEA,IAAM,YAAA,GAAe;AAAA,EACnB,EAAA,EAAI,qBAAA;AAAA,EACJ,OAAA,EAAS,kBAAA;AAAA,EACT,EAAA,EAAI;AACN,CAAA;AAEA,IAAM,UAAA,GAAa;AAAA,EACjB,EAAA,EAAI,mBAAA;AAAA,EACJ,OAAA,EAAS,gBAAA;AAAA,EACT,EAAA,EAAI;AACN,CAAA;AAEA,IAAM,UAAA,GAA6C;AAAA,EACjD,IAAA,EAAM,aAAA;AAAA,EACN,OAAA,EAAS,gBAAA;AAAA,EACT,KAAA,EAAO,cAAA;AAAA,EACP,KAAA,EAAO,cAAA;AAAA,EACP,UAAA,EAAY,mBAAA;AAAA,EACZ,WAAA,EAAa,kBAAA;AAAA,EACb,eAAA,EAAiB,sBAAA;AAAA,EACjB,IAAA,EAAM;AACR,CAAA;AAEO,SAAS,aAAA,CAAc;AAAA,EAC5B,QAAA;AAAA,EACA,KAAA,GAAQ,OAAA;AAAA,EACR,SAAA;AAAA,EACA,aAAA,GAAgB,SAAA;AAAA,EAChB,OAAA,GAAU,SAAA;AAAA,EACV,OAAA;AAAA,EACA,IAAA,GAAO,KAAA;AAAA,EACP,OAAA,GAAU,KAAA;AAAA,EACV;AACF,CAAA,EAAuB;AACrB,EAAA,MAAM,kBAAkB,OAAA,KAClB,IAAA,GAAO,SAAS,MAAA,CAAA,KAChB,OAAA,GAAU,YAAY,MAAA,CAAA,IACvB,MAAA;AAEL,EAAA,uBACED,GAAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,EAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,WAAW,OAAO,CAAA;AAAA,QAClB,SAAS,KAAK,CAAA;AAAA,QACd,WAAW,eAAe,CAAA;AAAA,QAC1B;AAAA,OACF;AAAA,MAEA,0BAAAA,GAAAA,CAAC,KAAA,EAAA,EAAI,WAAW,YAAA,CAAa,aAAa,GAAI,QAAA,EAAS;AAAA;AAAA,GACzD;AAEJ;AC/EO,SAAS,UAAA,CAAW;AAAA,EACzB,QAAA,GAAW,kBAAA;AAAA,EACX,WAAA;AAAA,EACA,WAAA,GAAc,iBAAA;AAAA,EACd,UAAA,GAAa,WAAA;AAAA,EACb,QAAA;AAAA,EACA,KAAA,GAAQ,OAAA;AAAA,EACR;AACF,CAAA,EAAoB;AAClB,EAAA,uBACEA,GAAAA,CAAC,aAAA,EAAA,EAAc,KAAA,EAAc,OAAA,EAAQ,MAAK,SAAA,EACxC,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qGAAA,EACb,QAAA,EAAA;AAAA,oBAAAA,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,gBAAA,EAAkB,QAAA,EAAA,QAAA,EAAS,CAAA;AAAA,IACxC,+BACCA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,0CAA0C,QAAA,EAAA,WAAA,EAAY,CAAA;AAAA,oBAErE,IAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,QAAA,EAAU,CAAC,CAAA,KAAM;AACf,UAAA,CAAA,CAAE,cAAA,EAAe;AACjB,UAAA,MAAM,OAAO,CAAA,CAAE,MAAA;AACf,UAAA,MAAM,QAAQ,IAAI,QAAA,CAAS,IAAI,CAAA,CAAE,IAAI,OAAO,CAAA;AAC5C,UAAA,QAAA,GAAW,KAAK,CAAA;AAAA,QAClB,CAAA;AAAA,QACA,SAAA,EAAU,YAAA;AAAA,QAEV,QAAA,EAAA;AAAA,0BAAAA,GAAAA,CAAC,KAAA,EAAA,EAAM,IAAA,EAAK,OAAA,EAAQ,IAAA,EAAK,SAAQ,WAAA,EAA0B,QAAA,EAAQ,IAAA,EAAC,SAAA,EAAU,QAAA,EAAS,CAAA;AAAA,0BACvFA,GAAAA,CAAC,MAAA,EAAA,EAAO,MAAK,QAAA,EAAS,OAAA,EAAQ,OAAO,QAAA,EAAA,UAAA,EAAW;AAAA;AAAA;AAAA;AAClD,GAAA,EACF,CAAA,EACF,CAAA;AAEJ","file":"newsletter.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","\"use client\";\n\nimport { Button as ButtonPrimitive } from \"@base-ui/react/button\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"../../lib/utils\";\n\nconst buttonVariants = cva(\n \"group/button inline-flex shrink-0 items-center justify-center rounded-lg whitespace-nowrap font-bold transition-all duration-150 select-none outline-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n // Primary: Black bg, white text, offset shadow\n default:\n \"border-brutal border-foreground bg-primary text-primary-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm\",\n // CTA: Mint green bg — the Bannerbear signature\n cta: \"border-brutal border-foreground bg-cta text-cta-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm\",\n // Brand: Dynamic brand color bg\n brand:\n \"border-brutal border-foreground bg-brand text-brand-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm\",\n // Outline: White bg, black border, offset shadow\n outline:\n \"border-brutal border-foreground bg-background text-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm\",\n // Secondary: Light bg, border, smaller shadow\n secondary:\n \"border-brutal border-foreground bg-secondary text-secondary-foreground shadow-brutal-sm hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal active:translate-x-px active:translate-y-px active:shadow-none\",\n // Ghost: No border/shadow, subtle hover\n ghost: \"hover:bg-secondary hover:text-foreground\",\n // Link: Text only\n link: \"text-foreground underline-offset-4 hover:underline\",\n // Destructive\n destructive:\n \"border-brutal border-destructive bg-destructive text-destructive-foreground shadow-brutal hover:-translate-x-0.5 hover:-translate-y-0.5 hover:shadow-brutal-lg active:translate-x-px active:translate-y-px active:shadow-brutal-sm\",\n // Nav: Thin border, no shadow (for nav Sign In buttons)\n nav: \"border border-foreground bg-background text-foreground hover:bg-foreground hover:text-background\",\n },\n size: {\n xs: \"h-7 gap-1 px-2.5 text-xs\",\n sm: \"h-8 gap-1.5 px-3 text-sm\",\n default: \"h-10 gap-2 px-5 text-sm\",\n lg: \"h-12 gap-2 px-7 text-base\",\n xl: \"h-14 gap-2.5 px-9 text-lg\",\n icon: \"size-10\",\n \"icon-sm\": \"size-8\",\n \"icon-lg\": \"size-12\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n);\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n ...props\n}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {\n return (\n <ButtonPrimitive\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nexport { Button, buttonVariants };\n","import * as React from \"react\";\nimport { Input as InputPrimitive } from \"@base-ui/react/input\";\n\nimport { cn } from \"../../lib/utils\";\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n return (\n <InputPrimitive\n type={type}\n data-slot=\"input\"\n className={cn(\n \"h-10 w-full min-w-0 rounded-lg border-brutal border-foreground bg-background px-3 py-2 text-base font-medium shadow-brutal-sm transition-all outline-none placeholder:text-muted-foreground focus:shadow-brutal focus:-translate-x-0.5 focus:-translate-y-0.5 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive md:text-sm\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport { Input };\n","import { cn } from \"../../lib/utils\";\n\nexport type SectionColor =\n | \"white\"\n | \"brand\"\n | \"brand-muted\"\n | \"black\"\n | \"cta\";\n\nexport type SectionPattern =\n | \"dots\"\n | \"stripes\"\n | \"noise\"\n | \"grain\"\n | \"crosshatch\"\n | \"grid-dots\"\n | \"gradient-mesh\"\n | \"none\";\n\ninterface BrutalSectionProps {\n children: React.ReactNode;\n color?: SectionColor;\n className?: string;\n containerSize?: \"sm\" | \"default\" | \"lg\";\n padding?: \"sm\" | \"default\" | \"lg\";\n pattern?: SectionPattern;\n /** @deprecated Use pattern=\"dots\" instead */\n dots?: boolean;\n /** @deprecated Use pattern=\"stripes\" instead */\n stripes?: boolean;\n id?: string;\n}\n\nconst colorMap: Record<SectionColor, string> = {\n white: \"bg-background text-foreground\",\n brand: \"bg-brand\",\n \"brand-muted\": \"bg-brand-muted text-foreground\",\n black: \"bg-foreground text-background\",\n cta: \"bg-cta\",\n};\n\nconst containerMap = {\n sm: \"brutal-container-sm\",\n default: \"brutal-container\",\n lg: \"brutal-container-lg\",\n};\n\nconst paddingMap = {\n sm: \"brutal-section-sm\",\n default: \"brutal-section\",\n lg: \"brutal-section py-28 sm:py-36 md:py-44\",\n};\n\nconst patternMap: Record<SectionPattern, string> = {\n dots: \"brutal-dots\",\n stripes: \"brutal-stripes\",\n noise: \"brutal-noise\",\n grain: \"brutal-grain\",\n crosshatch: \"brutal-crosshatch\",\n \"grid-dots\": \"brutal-grid-dots\",\n \"gradient-mesh\": \"brutal-gradient-mesh\",\n none: \"\",\n};\n\nexport function BrutalSection({\n children,\n color = \"white\",\n className,\n containerSize = \"default\",\n padding = \"default\",\n pattern,\n dots = false,\n stripes = false,\n id,\n}: BrutalSectionProps) {\n const resolvedPattern = pattern\n ?? (dots ? \"dots\" : undefined)\n ?? (stripes ? \"stripes\" : undefined)\n ?? \"none\";\n\n return (\n <section\n id={id}\n className={cn(\n paddingMap[padding],\n colorMap[color],\n patternMap[resolvedPattern],\n className\n )}\n >\n <div className={containerMap[containerSize]}>{children}</div>\n </section>\n );\n}\n","import { Button } from \"../ui/button\";\nimport { Input } from \"../ui/input\";\nimport { BrutalSection } from \"./section\";\n\ninterface NewsletterProps {\n headline?: string;\n description?: string;\n placeholder?: string;\n buttonText?: string;\n onSubmit?: (email: string) => void;\n color?: \"white\" | \"brand\" | \"black\";\n className?: string;\n}\n\nexport function Newsletter({\n headline = \"Stay in the loop\",\n description,\n placeholder = \"you@example.com\",\n buttonText = \"Subscribe\",\n onSubmit,\n color = \"white\",\n className,\n}: NewsletterProps) {\n return (\n <BrutalSection color={color} padding=\"sm\" className={className}>\n <div className=\"mx-auto max-w-md border-brutal border-foreground bg-background p-8 text-foreground shadow-brutal-lg\">\n <h3 className=\"brutal-h3 mb-2\">{headline}</h3>\n {description && (\n <p className=\"brutal-body mb-6 text-muted-foreground\">{description}</p>\n )}\n <form\n onSubmit={(e) => {\n e.preventDefault();\n const form = e.target as HTMLFormElement;\n const email = new FormData(form).get(\"email\") as string;\n onSubmit?.(email);\n }}\n className=\"flex gap-3\"\n >\n <Input type=\"email\" name=\"email\" placeholder={placeholder} required className=\"flex-1\" />\n <Button type=\"submit\" variant=\"cta\">{buttonText}</Button>\n </form>\n </div>\n </BrutalSection>\n );\n}\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
interface PricingTier {
|
|
4
|
+
name: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
price: {
|
|
7
|
+
monthly: number | string;
|
|
8
|
+
annual: number | string;
|
|
9
|
+
};
|
|
10
|
+
features: string[];
|
|
11
|
+
ctaText: string;
|
|
12
|
+
ctaHref?: string;
|
|
13
|
+
ctaVariant?: "cta" | "brand" | "default" | "outline";
|
|
14
|
+
}
|
|
15
|
+
interface PricingTableProps {
|
|
16
|
+
badge?: string;
|
|
17
|
+
headline?: string;
|
|
18
|
+
description?: string;
|
|
19
|
+
tiers: PricingTier[];
|
|
20
|
+
popularIndex?: number;
|
|
21
|
+
billingToggle?: boolean;
|
|
22
|
+
color?: "white" | "black";
|
|
23
|
+
className?: string;
|
|
24
|
+
}
|
|
25
|
+
declare function PricingTable({ badge, headline, description, tiers, popularIndex, billingToggle, color, className, }: PricingTableProps): react_jsx_runtime.JSX.Element;
|
|
26
|
+
|
|
27
|
+
export { PricingTable };
|