From 151d0d511ad95f2324b150bb2bedb04561784c75 Mon Sep 17 00:00:00 2001 From: javayhu Date: Tue, 1 Apr 2025 11:51:56 +0800 Subject: [PATCH] feat: support matsu theme https://matsu-theme.vercel.app/ --- src/app/[locale]/(marketing)/(home)/page.tsx | 10 +- src/app/[locale]/layout.tsx | 16 ++ .../preview/hero-section/one/page.tsx | 8 +- src/components/layout/active-theme.tsx | 24 +- src/components/ui/accordion.tsx | 22 +- src/components/ui/badge.tsx | 2 +- src/components/ui/button.tsx | 32 +-- src/components/ui/calendar.tsx | 12 +- src/components/ui/card.tsx | 22 +- src/components/ui/checkbox.tsx | 16 +- src/components/ui/dialog.tsx | 34 +-- src/components/ui/input.tsx | 12 +- src/components/ui/navigation-menu.tsx | 4 +- src/components/ui/radio-group.tsx | 20 +- src/components/ui/scroll-area.tsx | 2 +- src/components/ui/select.tsx | 36 +-- src/components/ui/separator.tsx | 14 +- src/components/ui/sheet.tsx | 36 +-- src/components/ui/sidebar.tsx | 226 +++++++++--------- src/components/ui/slider.tsx | 20 +- src/components/ui/switch.tsx | 16 +- src/components/ui/table.tsx | 30 +-- src/components/ui/tabs.tsx | 22 +- src/components/ui/toggle-group.tsx | 24 +- src/components/ui/toggle.tsx | 22 +- src/components/ui/tooltip.tsx | 22 +- src/styles/globals.css | 119 ++++++--- 27 files changed, 441 insertions(+), 382 deletions(-) diff --git a/src/app/[locale]/(marketing)/(home)/page.tsx b/src/app/[locale]/(marketing)/(home)/page.tsx index a5508c6..0d28d21 100644 --- a/src/app/[locale]/(marketing)/(home)/page.tsx +++ b/src/app/[locale]/(marketing)/(home)/page.tsx @@ -42,7 +42,7 @@ export default async function HomePage(props: HomePageProps) { return ( <> -
+
@@ -55,17 +55,17 @@ export default async function HomePage(props: HomePageProps) {
-
+ {/*
-
+
*/}
-
+ {/*
-
+
*/}
diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx index 551fc91..9e6849b 100644 --- a/src/app/[locale]/layout.tsx +++ b/src/app/[locale]/layout.tsx @@ -9,6 +9,20 @@ import { Providers } from './providers'; import '@/styles/globals.css'; +import { Nunito } from "next/font/google"; +import { PT_Sans } from "next/font/google"; + +const nunito = Nunito({ +variable: "--font-nunito", +subsets: ["latin"], +}); + +const ptSans = PT_Sans({ +variable: "--font-pt-sans", +subsets: ["latin"], +weight: ["400", "700"], +}); + interface LocaleLayoutProps { children: ReactNode; params: Promise<{ locale: Locale }>; @@ -38,6 +52,8 @@ export default async function LocaleLayout({ suppressHydrationWarning className={cn( 'size-full antialiased', + nunito.variable, + ptSans.variable, fontNotoSans.className, fontNotoSerif.variable, fontNotoSansMono.variable, diff --git a/src/app/[locale]/preview/hero-section/one/page.tsx b/src/app/[locale]/preview/hero-section/one/page.tsx index d3741d2..cf0e6a2 100644 --- a/src/app/[locale]/preview/hero-section/one/page.tsx +++ b/src/app/[locale]/preview/hero-section/one/page.tsx @@ -87,7 +87,7 @@ export default function HeroSection() { className="hover:bg-background dark:hover:border-t-border bg-muted group mx-auto flex w-fit items-center gap-4 rounded-full border p-1 pl-4 shadow-md shadow-zinc-950/5 transition-colors duration-300 dark:border-t-white/5 dark:shadow-zinc-950" > - Introducing Support for AI Models + Introducing MkSaaS @@ -110,7 +110,7 @@ export default function HeroSection() { as="h1" className="mt-8 text-balance text-6xl md:text-7xl lg:mt-16 xl:text-[5.25rem]" > - Modern Solutions for Customer Engagement + The best SaaS boilerplate - Highly customizable components for building modern websites - and applications that look and feel the way you mean it. + The best SaaS boilerplate for building AI SaaS applications + that look and work the way you mean it. initialTheme || DEFAULT_THEME ); - useEffect(() => { - setThemeCookie(activeTheme); + // useEffect(() => { + // setThemeCookie(activeTheme); - Array.from(document.body.classList) - .filter((className) => className.startsWith("theme-")) - .forEach((className) => { - document.body.classList.remove(className); - }); - document.body.classList.add(`theme-${activeTheme}`); - if (activeTheme.endsWith("-scaled")) { - document.body.classList.add("theme-scaled"); - } - }, [activeTheme]); + // Array.from(document.body.classList) + // .filter((className) => className.startsWith("theme-")) + // .forEach((className) => { + // document.body.classList.remove(className); + // }); + // document.body.classList.add(`theme-${activeTheme}`); + // if (activeTheme.endsWith("-scaled")) { + // document.body.classList.add("theme-scaled"); + // } + // }, [activeTheme]); return ( diff --git a/src/components/ui/accordion.tsx b/src/components/ui/accordion.tsx index 4a8cca4..55a5568 100644 --- a/src/components/ui/accordion.tsx +++ b/src/components/ui/accordion.tsx @@ -1,15 +1,15 @@ -"use client" +"use client"; -import * as React from "react" -import * as AccordionPrimitive from "@radix-ui/react-accordion" -import { ChevronDownIcon } from "lucide-react" +import * as React from "react"; +import * as AccordionPrimitive from "@radix-ui/react-accordion"; +import { ChevronDownIcon } from "lucide-react"; -import { cn } from "@/lib/utils" +import { cn } from "@/lib/utils"; function Accordion({ ...props }: React.ComponentProps) { - return + return ; } function AccordionItem({ @@ -22,7 +22,7 @@ function AccordionItem({ className={cn("border-b last:border-b-0", className)} {...props} /> - ) + ); } function AccordionTrigger({ @@ -35,7 +35,7 @@ function AccordionTrigger({ svg]:rotate-180", + "focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-bold font-serif text-base transition-all outline-none hover:underline focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180", className )} {...props} @@ -44,7 +44,7 @@ function AccordionTrigger({ - ) + ); } function AccordionContent({ @@ -60,7 +60,7 @@ function AccordionContent({ >
{children}
- ) + ); } -export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }; diff --git a/src/components/ui/badge.tsx b/src/components/ui/badge.tsx index 2151ab6..0205413 100644 --- a/src/components/ui/badge.tsx +++ b/src/components/ui/badge.tsx @@ -14,7 +14,7 @@ const badgeVariants = cva( secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90", destructive: - "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/70", + "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground", }, diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx index a2df8dc..c36d75c 100644 --- a/src/components/ui/button.tsx +++ b/src/components/ui/button.tsx @@ -1,8 +1,8 @@ -import * as React from "react" -import { Slot } from "@radix-ui/react-slot" -import { cva, type VariantProps } from "class-variance-authority" +import * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { cva, type VariantProps } from "class-variance-authority"; -import { cn } from "@/lib/utils" +import { cn } from "@/lib/utils"; const buttonVariants = cva( "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", @@ -10,22 +10,22 @@ const buttonVariants = cva( variants: { variant: { default: - "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90", + "bg-primary border border-primary-border shadow-primary text-primary-foreground hover:bg-primary/90", destructive: - "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", + "bg-destructive text-white border border-destructive-border shadow-destructive-border hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", outline: - "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50", + "border bg-card shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50", secondary: - "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80", + "bg-secondary text-secondary-foreground hover:bg-secondary/80", ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", link: "text-primary underline-offset-4 hover:underline", }, size: { - default: "h-9 px-4 py-2 has-[>svg]:px-3", + default: "h-10 px-4 py-2 has-[>svg]:px-3", sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5", - lg: "h-10 rounded-md px-6 has-[>svg]:px-4", - icon: "size-9", + lg: "h-12 rounded-md px-6 has-[>svg]:px-4", + icon: "size-10", }, }, defaultVariants: { @@ -33,7 +33,7 @@ const buttonVariants = cva( size: "default", }, } -) +); function Button({ className, @@ -43,9 +43,9 @@ function Button({ ...props }: React.ComponentProps<"button"> & VariantProps & { - asChild?: boolean + asChild?: boolean; }) { - const Comp = asChild ? Slot : "button" + const Comp = asChild ? Slot : "button"; return ( - ) + ); } -export { Button, buttonVariants } +export { Button, buttonVariants }; diff --git a/src/components/ui/calendar.tsx b/src/components/ui/calendar.tsx index 5f867d5..b8df044 100644 --- a/src/components/ui/calendar.tsx +++ b/src/components/ui/calendar.tsx @@ -60,15 +60,11 @@ function Calendar({ ...classNames, }} components={{ - PreviousMonthButton: (props) => ( - + IconLeft: ({ className, ...props }) => ( + ), - NextMonthButton: (props) => ( - + IconRight: ({ className, ...props }) => ( + ), }} {...props} diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx index d05bbc6..aadfb86 100644 --- a/src/components/ui/card.tsx +++ b/src/components/ui/card.tsx @@ -1,6 +1,6 @@ -import * as React from "react" +import * as React from "react"; -import { cn } from "@/lib/utils" +import { cn } from "@/lib/utils"; function Card({ className, ...props }: React.ComponentProps<"div">) { return ( @@ -12,7 +12,7 @@ function Card({ className, ...props }: React.ComponentProps<"div">) { )} {...props} /> - ) + ); } function CardHeader({ className, ...props }: React.ComponentProps<"div">) { @@ -25,17 +25,17 @@ function CardHeader({ className, ...props }: React.ComponentProps<"div">) { )} {...props} /> - ) + ); } function CardTitle({ className, ...props }: React.ComponentProps<"div">) { return (
- ) + ); } function CardDescription({ className, ...props }: React.ComponentProps<"div">) { @@ -45,7 +45,7 @@ function CardDescription({ className, ...props }: React.ComponentProps<"div">) { className={cn("text-muted-foreground text-sm", className)} {...props} /> - ) + ); } function CardAction({ className, ...props }: React.ComponentProps<"div">) { @@ -58,7 +58,7 @@ function CardAction({ className, ...props }: React.ComponentProps<"div">) { )} {...props} /> - ) + ); } function CardContent({ className, ...props }: React.ComponentProps<"div">) { @@ -68,7 +68,7 @@ function CardContent({ className, ...props }: React.ComponentProps<"div">) { className={cn("px-6", className)} {...props} /> - ) + ); } function CardFooter({ className, ...props }: React.ComponentProps<"div">) { @@ -78,7 +78,7 @@ function CardFooter({ className, ...props }: React.ComponentProps<"div">) { className={cn("flex items-center px-6 [.border-t]:pt-6", className)} {...props} /> - ) + ); } export { @@ -89,4 +89,4 @@ export { CardAction, CardDescription, CardContent, -} +}; diff --git a/src/components/ui/checkbox.tsx b/src/components/ui/checkbox.tsx index fa0e4b5..26e43fd 100644 --- a/src/components/ui/checkbox.tsx +++ b/src/components/ui/checkbox.tsx @@ -1,10 +1,10 @@ -"use client" +"use client"; -import * as React from "react" -import * as CheckboxPrimitive from "@radix-ui/react-checkbox" -import { CheckIcon } from "lucide-react" +import * as React from "react"; +import * as CheckboxPrimitive from "@radix-ui/react-checkbox"; +import { CheckIcon } from "lucide-react"; -import { cn } from "@/lib/utils" +import { cn } from "@/lib/utils"; function Checkbox({ className, @@ -14,7 +14,7 @@ function Checkbox({ - ) + ); } -export { Checkbox } +export { Checkbox }; diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx index 7d7a9d3..1332f57 100644 --- a/src/components/ui/dialog.tsx +++ b/src/components/ui/dialog.tsx @@ -1,33 +1,33 @@ -"use client" +"use client"; -import * as React from "react" -import * as DialogPrimitive from "@radix-ui/react-dialog" -import { XIcon } from "lucide-react" +import * as React from "react"; +import * as DialogPrimitive from "@radix-ui/react-dialog"; +import { XIcon } from "lucide-react"; -import { cn } from "@/lib/utils" +import { cn } from "@/lib/utils"; function Dialog({ ...props }: React.ComponentProps) { - return + return ; } function DialogTrigger({ ...props }: React.ComponentProps) { - return + return ; } function DialogPortal({ ...props }: React.ComponentProps) { - return + return ; } function DialogClose({ ...props }: React.ComponentProps) { - return + return ; } function DialogOverlay({ @@ -43,7 +43,7 @@ function DialogOverlay({ )} {...props} /> - ) + ); } function DialogContent({ @@ -69,7 +69,7 @@ function DialogContent({ - ) + ); } function DialogHeader({ className, ...props }: React.ComponentProps<"div">) { @@ -79,7 +79,7 @@ function DialogHeader({ className, ...props }: React.ComponentProps<"div">) { className={cn("flex flex-col gap-2 text-center sm:text-left", className)} {...props} /> - ) + ); } function DialogFooter({ className, ...props }: React.ComponentProps<"div">) { @@ -92,7 +92,7 @@ function DialogFooter({ className, ...props }: React.ComponentProps<"div">) { )} {...props} /> - ) + ); } function DialogTitle({ @@ -102,10 +102,10 @@ function DialogTitle({ return ( - ) + ); } function DialogDescription({ @@ -118,7 +118,7 @@ function DialogDescription({ className={cn("text-muted-foreground text-sm", className)} {...props} /> - ) + ); } export { @@ -132,4 +132,4 @@ export { DialogPortal, DialogTitle, DialogTrigger, -} +}; diff --git a/src/components/ui/input.tsx b/src/components/ui/input.tsx index 03295ca..3f8e80e 100644 --- a/src/components/ui/input.tsx +++ b/src/components/ui/input.tsx @@ -1,6 +1,6 @@ -import * as React from "react" +import * as React from "react"; -import { cn } from "@/lib/utils" +import { cn } from "@/lib/utils"; function Input({ className, type, ...props }: React.ComponentProps<"input">) { return ( @@ -8,14 +8,14 @@ function Input({ className, type, ...props }: React.ComponentProps<"input">) { type={type} data-slot="input" className={cn( - "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", + "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-10 w-full min-w-0 rounded-md border bg-card px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-card file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]", - "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", + "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive aria-invalid:!shadow-destructive", className )} {...props} /> - ) + ); } -export { Input } +export { Input }; diff --git a/src/components/ui/navigation-menu.tsx b/src/components/ui/navigation-menu.tsx index 431e5c9..1199945 100644 --- a/src/components/ui/navigation-menu.tsx +++ b/src/components/ui/navigation-menu.tsx @@ -59,7 +59,7 @@ function NavigationMenuItem({ } const navigationMenuTriggerStyle = cva( - "group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=open]:hover:bg-accent data-[state=open]:text-accent-foreground data-[state=open]:focus:bg-accent data-[state=open]:bg-accent/50 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 transition-[color,box-shadow] focus-visible:ring-4 focus-visible:outline-1" + "group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=open]:hover:bg-accent data-[state=open]:text-accent-foreground data-[state=open]:focus:bg-accent data-[state=open]:bg-accent/50 focus-visible:ring-ring/50 outline-none transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1" ) function NavigationMenuTrigger({ @@ -129,7 +129,7 @@ function NavigationMenuLink({ - ) + ); } function RadioGroupItem({ @@ -27,7 +27,7 @@ function RadioGroupItem({ - + - ) + ); } -export { RadioGroup, RadioGroupItem } +export { RadioGroup, RadioGroupItem }; diff --git a/src/components/ui/scroll-area.tsx b/src/components/ui/scroll-area.tsx index c0c4df7..8e4fa13 100644 --- a/src/components/ui/scroll-area.tsx +++ b/src/components/ui/scroll-area.tsx @@ -18,7 +18,7 @@ function ScrollArea({ > {children} diff --git a/src/components/ui/select.tsx b/src/components/ui/select.tsx index dcbbc0c..25a6ddb 100644 --- a/src/components/ui/select.tsx +++ b/src/components/ui/select.tsx @@ -1,27 +1,27 @@ -"use client" +"use client"; -import * as React from "react" -import * as SelectPrimitive from "@radix-ui/react-select" -import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react" +import * as React from "react"; +import * as SelectPrimitive from "@radix-ui/react-select"; +import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react"; -import { cn } from "@/lib/utils" +import { cn } from "@/lib/utils"; function Select({ ...props }: React.ComponentProps) { - return + return ; } function SelectGroup({ ...props }: React.ComponentProps) { - return + return ; } function SelectValue({ ...props }: React.ComponentProps) { - return + return ; } function SelectTrigger({ @@ -30,14 +30,14 @@ function SelectTrigger({ children, ...props }: React.ComponentProps & { - size?: "sm" | "default" + size?: "sm" | "default"; }) { return ( - ) + ); } function SelectContent({ @@ -82,7 +82,7 @@ function SelectContent({ - ) + ); } function SelectLabel({ @@ -95,7 +95,7 @@ function SelectLabel({ className={cn("text-muted-foreground px-2 py-1.5 text-xs", className)} {...props} /> - ) + ); } function SelectItem({ @@ -119,7 +119,7 @@ function SelectItem({ {children} - ) + ); } function SelectSeparator({ @@ -132,7 +132,7 @@ function SelectSeparator({ className={cn("bg-border pointer-events-none -mx-1 my-1 h-px", className)} {...props} /> - ) + ); } function SelectScrollUpButton({ @@ -150,7 +150,7 @@ function SelectScrollUpButton({ > - ) + ); } function SelectScrollDownButton({ @@ -168,7 +168,7 @@ function SelectScrollDownButton({ > - ) + ); } export { @@ -182,4 +182,4 @@ export { SelectSeparator, SelectTrigger, SelectValue, -} +}; diff --git a/src/components/ui/separator.tsx b/src/components/ui/separator.tsx index 67c73e5..a213aa4 100644 --- a/src/components/ui/separator.tsx +++ b/src/components/ui/separator.tsx @@ -1,9 +1,9 @@ -"use client" +"use client"; -import * as React from "react" -import * as SeparatorPrimitive from "@radix-ui/react-separator" +import * as React from "react"; +import * as SeparatorPrimitive from "@radix-ui/react-separator"; -import { cn } from "@/lib/utils" +import { cn } from "@/lib/utils"; function Separator({ className, @@ -17,12 +17,12 @@ function Separator({ decorative={decorative} orientation={orientation} className={cn( - "bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px", + "bg-border/60 shrink-0 data-[orientation=horizontal]:h-0.5 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-0.5", className )} {...props} /> - ) + ); } -export { Separator } +export { Separator }; diff --git a/src/components/ui/sheet.tsx b/src/components/ui/sheet.tsx index 84649ad..ccd543c 100644 --- a/src/components/ui/sheet.tsx +++ b/src/components/ui/sheet.tsx @@ -1,31 +1,31 @@ -"use client" +"use client"; -import * as React from "react" -import * as SheetPrimitive from "@radix-ui/react-dialog" -import { XIcon } from "lucide-react" +import * as React from "react"; +import * as SheetPrimitive from "@radix-ui/react-dialog"; +import { XIcon } from "lucide-react"; -import { cn } from "@/lib/utils" +import { cn } from "@/lib/utils"; function Sheet({ ...props }: React.ComponentProps) { - return + return ; } function SheetTrigger({ ...props }: React.ComponentProps) { - return + return ; } function SheetClose({ ...props }: React.ComponentProps) { - return + return ; } function SheetPortal({ ...props }: React.ComponentProps) { - return + return ; } function SheetOverlay({ @@ -41,7 +41,7 @@ function SheetOverlay({ )} {...props} /> - ) + ); } function SheetContent({ @@ -50,7 +50,7 @@ function SheetContent({ side = "right", ...props }: React.ComponentProps & { - side?: "top" | "right" | "bottom" | "left" + side?: "top" | "right" | "bottom" | "left"; }) { return ( @@ -78,7 +78,7 @@ function SheetContent({ - ) + ); } function SheetHeader({ className, ...props }: React.ComponentProps<"div">) { @@ -88,7 +88,7 @@ function SheetHeader({ className, ...props }: React.ComponentProps<"div">) { className={cn("flex flex-col gap-1.5 p-4", className)} {...props} /> - ) + ); } function SheetFooter({ className, ...props }: React.ComponentProps<"div">) { @@ -98,7 +98,7 @@ function SheetFooter({ className, ...props }: React.ComponentProps<"div">) { className={cn("mt-auto flex flex-col gap-2 p-4", className)} {...props} /> - ) + ); } function SheetTitle({ @@ -108,10 +108,10 @@ function SheetTitle({ return ( - ) + ); } function SheetDescription({ @@ -124,7 +124,7 @@ function SheetDescription({ className={cn("text-muted-foreground text-sm", className)} {...props} /> - ) + ); } export { @@ -136,4 +136,4 @@ export { SheetFooter, SheetTitle, SheetDescription, -} +}; diff --git a/src/components/ui/sidebar.tsx b/src/components/ui/sidebar.tsx index 7ffbc07..60e632c 100644 --- a/src/components/ui/sidebar.tsx +++ b/src/components/ui/sidebar.tsx @@ -1,56 +1,56 @@ -"use client" +"use client"; -import * as React from "react" -import { Slot } from "@radix-ui/react-slot" -import { VariantProps, cva } from "class-variance-authority" -import { PanelLeftIcon } from "lucide-react" +import * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { VariantProps, cva } from "class-variance-authority"; +import { PanelLeftIcon } from "lucide-react"; -import { useIsMobile } from "@/hooks/use-mobile" -import { cn } from "@/lib/utils" -import { Button } from "@/components/ui/button" -import { Input } from "@/components/ui/input" -import { Separator } from "@/components/ui/separator" +import { useIsMobile } from "@/hooks/use-mobile"; +import { cn } from "@/lib/utils"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Separator } from "@/components/ui/separator"; import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, -} from "@/components/ui/sheet" -import { Skeleton } from "@/components/ui/skeleton" +} from "@/components/ui/sheet"; +import { Skeleton } from "@/components/ui/skeleton"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, -} from "@/components/ui/tooltip" +} from "@/components/ui/tooltip"; -const SIDEBAR_COOKIE_NAME = "sidebar_state" -const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7 -const SIDEBAR_WIDTH = "16rem" -const SIDEBAR_WIDTH_MOBILE = "18rem" -const SIDEBAR_WIDTH_ICON = "3rem" -const SIDEBAR_KEYBOARD_SHORTCUT = "b" +const SIDEBAR_COOKIE_NAME = "sidebar_state"; +const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7; +const SIDEBAR_WIDTH = "16rem"; +const SIDEBAR_WIDTH_MOBILE = "18rem"; +const SIDEBAR_WIDTH_ICON = "3rem"; +const SIDEBAR_KEYBOARD_SHORTCUT = "b"; type SidebarContextProps = { - state: "expanded" | "collapsed" - open: boolean - setOpen: (open: boolean) => void - openMobile: boolean - setOpenMobile: (open: boolean) => void - isMobile: boolean - toggleSidebar: () => void -} + state: "expanded" | "collapsed"; + open: boolean; + setOpen: (open: boolean) => void; + openMobile: boolean; + setOpenMobile: (open: boolean) => void; + isMobile: boolean; + toggleSidebar: () => void; +}; -const SidebarContext = React.createContext(null) +const SidebarContext = React.createContext(null); function useSidebar() { - const context = React.useContext(SidebarContext) + const context = React.useContext(SidebarContext); if (!context) { - throw new Error("useSidebar must be used within a SidebarProvider.") + throw new Error("useSidebar must be used within a SidebarProvider."); } - return context + return context; } function SidebarProvider({ @@ -62,36 +62,36 @@ function SidebarProvider({ children, ...props }: React.ComponentProps<"div"> & { - defaultOpen?: boolean - open?: boolean - onOpenChange?: (open: boolean) => void + defaultOpen?: boolean; + open?: boolean; + onOpenChange?: (open: boolean) => void; }) { - const isMobile = useIsMobile() - const [openMobile, setOpenMobile] = React.useState(false) + const isMobile = useIsMobile(); + const [openMobile, setOpenMobile] = React.useState(false); // This is the internal state of the sidebar. // We use openProp and setOpenProp for control from outside the component. - const [_open, _setOpen] = React.useState(defaultOpen) - const open = openProp ?? _open + const [_open, _setOpen] = React.useState(defaultOpen); + const open = openProp ?? _open; const setOpen = React.useCallback( (value: boolean | ((value: boolean) => boolean)) => { - const openState = typeof value === "function" ? value(open) : value + const openState = typeof value === "function" ? value(open) : value; if (setOpenProp) { - setOpenProp(openState) + setOpenProp(openState); } else { - _setOpen(openState) + _setOpen(openState); } // This sets the cookie to keep the sidebar state. - document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}` + document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`; }, [setOpenProp, open] - ) + ); // Helper to toggle the sidebar. const toggleSidebar = React.useCallback(() => { - return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open) - }, [isMobile, setOpen, setOpenMobile]) + return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open); + }, [isMobile, setOpen, setOpenMobile]); // Adds a keyboard shortcut to toggle the sidebar. React.useEffect(() => { @@ -100,18 +100,18 @@ function SidebarProvider({ event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey) ) { - event.preventDefault() - toggleSidebar() + event.preventDefault(); + toggleSidebar(); } - } + }; - window.addEventListener("keydown", handleKeyDown) - return () => window.removeEventListener("keydown", handleKeyDown) - }, [toggleSidebar]) + window.addEventListener("keydown", handleKeyDown); + return () => window.removeEventListener("keydown", handleKeyDown); + }, [toggleSidebar]); // We add a state so that we can do data-state="expanded" or "collapsed". // This makes it easier to style the sidebar with Tailwind classes. - const state = open ? "expanded" : "collapsed" + const state = open ? "expanded" : "collapsed"; const contextValue = React.useMemo( () => ({ @@ -124,7 +124,7 @@ function SidebarProvider({ toggleSidebar, }), [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar] - ) + ); return ( @@ -139,7 +139,7 @@ function SidebarProvider({ } as React.CSSProperties } className={cn( - "group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full", + "group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar-background flex min-h-svh w-full", className )} {...props} @@ -148,7 +148,7 @@ function SidebarProvider({
- ) + ); } function Sidebar({ @@ -159,11 +159,11 @@ function Sidebar({ children, ...props }: React.ComponentProps<"div"> & { - side?: "left" | "right" - variant?: "sidebar" | "floating" | "inset" - collapsible?: "offcanvas" | "icon" | "none" + side?: "left" | "right"; + variant?: "sidebar" | "floating" | "inset"; + collapsible?: "offcanvas" | "icon" | "none"; }) { - const { isMobile, state, openMobile, setOpenMobile } = useSidebar() + const { isMobile, state, openMobile, setOpenMobile } = useSidebar(); if (collapsible === "none") { return ( @@ -177,7 +177,7 @@ function Sidebar({ > {children}
- ) + ); } if (isMobile) { @@ -187,7 +187,7 @@ function Sidebar({ data-sidebar="sidebar" data-slot="sidebar" data-mobile="true" - className="bg-sidebar text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden" + className="bg-background text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden" style={ { "--sidebar-width": SIDEBAR_WIDTH_MOBILE, @@ -202,7 +202,7 @@ function Sidebar({
{children}
- ) + ); } return ( @@ -250,7 +250,7 @@ function Sidebar({
- ) + ); } function SidebarTrigger({ @@ -258,7 +258,7 @@ function SidebarTrigger({ onClick, ...props }: React.ComponentProps) { - const { toggleSidebar } = useSidebar() + const { toggleSidebar } = useSidebar(); return ( - ) + ); } function SidebarRail({ className, ...props }: React.ComponentProps<"button">) { - const { toggleSidebar } = useSidebar() + const { toggleSidebar } = useSidebar(); return (