diff --git a/apps/www/components/examples/index.tsx b/apps/www/components/examples/index.tsx
index 2d3c335becf..411006cd94e 100644
--- a/apps/www/components/examples/index.tsx
+++ b/apps/www/components/examples/index.tsx
@@ -82,6 +82,12 @@ import { ToastDestructive } from "@/components/examples/toast/destructive"
import { ToastSimple } from "@/components/examples/toast/simple"
import { ToastWithAction } from "@/components/examples/toast/with-action"
import { ToastWithTitle } from "@/components/examples/toast/with-title"
+import { ToggleGroupDemo } from "@/components/examples/toggle-group/demo"
+import { ToggleGroupDisabled } from "@/components/examples/toggle-group/disabled"
+import { ToggleGroupLg } from "@/components/examples/toggle-group/lg"
+import { ToggleGroupMultiple } from "@/components/examples/toggle-group/multiple"
+import { ToggleGroupOutline } from "@/components/examples/toggle-group/outline"
+import { ToggleGroupSm } from "@/components/examples/toggle-group/sm"
import { ToggleDemo } from "@/components/examples/toggle/demo"
import { ToggleDisabled } from "@/components/examples/toggle/disabled"
import { ToggleLg } from "@/components/examples/toggle/lg"
@@ -210,4 +216,10 @@ export const examples = {
ToggleOutline,
ToggleDisabled,
ToggleWithText,
+ ToggleGroupDemo,
+ ToggleGroupSm,
+ ToggleGroupLg,
+ ToggleGroupOutline,
+ ToggleGroupMultiple,
+ ToggleGroupDisabled,
}
diff --git a/apps/www/components/examples/toggle-group/demo.tsx b/apps/www/components/examples/toggle-group/demo.tsx
new file mode 100644
index 00000000000..5d71754ebd3
--- /dev/null
+++ b/apps/www/components/examples/toggle-group/demo.tsx
@@ -0,0 +1,23 @@
+import { AlignCenter, AlignLeft, AlignRight } from "lucide-react"
+
+import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
+
+export function ToggleGroupDemo() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/www/components/examples/toggle-group/disabled.tsx b/apps/www/components/examples/toggle-group/disabled.tsx
new file mode 100644
index 00000000000..43ed19f02b0
--- /dev/null
+++ b/apps/www/components/examples/toggle-group/disabled.tsx
@@ -0,0 +1,19 @@
+import { AlignCenter, AlignLeft, AlignRight } from "lucide-react"
+
+import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
+
+export function ToggleGroupDisabled() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/www/components/examples/toggle-group/lg.tsx b/apps/www/components/examples/toggle-group/lg.tsx
new file mode 100644
index 00000000000..1cffaf3ae14
--- /dev/null
+++ b/apps/www/components/examples/toggle-group/lg.tsx
@@ -0,0 +1,24 @@
+import { AlignCenter, AlignLeft, AlignRight } from "lucide-react"
+
+import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
+
+export function ToggleGroupLg() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/www/components/examples/toggle-group/multiple.tsx b/apps/www/components/examples/toggle-group/multiple.tsx
new file mode 100644
index 00000000000..188f08c8a06
--- /dev/null
+++ b/apps/www/components/examples/toggle-group/multiple.tsx
@@ -0,0 +1,23 @@
+import { AlignCenter, AlignLeft, AlignRight } from "lucide-react"
+
+import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
+
+export function ToggleGroupMultiple() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/www/components/examples/toggle-group/outline.tsx b/apps/www/components/examples/toggle-group/outline.tsx
new file mode 100644
index 00000000000..a015f1cc78a
--- /dev/null
+++ b/apps/www/components/examples/toggle-group/outline.tsx
@@ -0,0 +1,26 @@
+import { AlignCenter, AlignLeft, AlignRight } from "lucide-react"
+
+import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
+
+export function ToggleGroupOutline() {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+ >
+ )
+}
diff --git a/apps/www/components/examples/toggle-group/sm.tsx b/apps/www/components/examples/toggle-group/sm.tsx
new file mode 100644
index 00000000000..b7213c21315
--- /dev/null
+++ b/apps/www/components/examples/toggle-group/sm.tsx
@@ -0,0 +1,24 @@
+import { AlignCenter, AlignLeft, AlignRight } from "lucide-react"
+
+import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
+
+export function ToggleGroupSm() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/www/components/ui/toggle-group.tsx b/apps/www/components/ui/toggle-group.tsx
new file mode 100644
index 00000000000..3209030b473
--- /dev/null
+++ b/apps/www/components/ui/toggle-group.tsx
@@ -0,0 +1,81 @@
+"use client"
+
+import * as React from "react"
+import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group"
+import { cva, type VariantProps } from "class-variance-authority"
+
+import { cn } from "@/lib/utils"
+
+const ToggleGroupContext = React.createContext<
+ VariantProps
+>({
+ size: "default",
+ variant: "default",
+})
+
+const toggleGroupVariants = cva(
+ "inline-flex items-center justify-center text-muted-foreground text-sm font-medium transition-colors data-[state=on]:bg-accent-foreground/5 dark:data-[state=on]:bg-accent data-[state=on]:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 ring-offset-background hover:bg-muted hover:text-muted-foreground first:rounded-l last:rounded-r",
+ {
+ variants: {
+ variant: {
+ default: "bg-transparent",
+ outline: "bg-transparent data-[state=on]:bg-muted",
+ },
+ size: {
+ default: "h-10 px-3",
+ sm: "h-9 px-2.5",
+ lg: "h-11 px-5",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ size: "default",
+ },
+ }
+)
+
+const ToggleGroup = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef &
+ VariantProps
+>(({ className, variant, size, children, ...props }, ref) => (
+
+
+ {children}
+
+
+))
+
+const ToggleGroupItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => {
+ const context = React.useContext(ToggleGroupContext)
+ return (
+
+ )
+})
+
+ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName
+ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName
+
+export { ToggleGroup, ToggleGroupItem }
diff --git a/apps/www/config/components.ts b/apps/www/config/components.ts
index 8e060c14df2..7ceb227df42 100644
--- a/apps/www/config/components.ts
+++ b/apps/www/config/components.ts
@@ -202,6 +202,12 @@ export const components = [
dependencies: ["@radix-ui/react-toggle"],
files: ["components/ui/toggle.tsx"],
},
+ {
+ component: "toggle-group",
+ name: "Toggle Group",
+ dependencies: ["@radix-ui/react-toggle-group"],
+ files: ["components/ui/toggle-group.tsx"],
+ },
{
component: "tooltip",
name: "Tooltip",
diff --git a/apps/www/config/docs.ts b/apps/www/config/docs.ts
index 95868e522f4..8223f9d0aa0 100644
--- a/apps/www/config/docs.ts
+++ b/apps/www/config/docs.ts
@@ -288,6 +288,12 @@ export const docsConfig: DocsConfig = {
href: "/docs/components/toggle",
items: [],
},
+ {
+ title: "Toggle Group",
+ href: "/docs/components/toggle-group",
+ label: "New",
+ items: [],
+ },
{
title: "Tooltip",
href: "/docs/components/tooltip",
diff --git a/apps/www/content/docs/components/toggle-group.mdx b/apps/www/content/docs/components/toggle-group.mdx
new file mode 100644
index 00000000000..6bc5af7e09e
--- /dev/null
+++ b/apps/www/content/docs/components/toggle-group.mdx
@@ -0,0 +1,111 @@
+---
+title: Toggle Group
+description: A set of two-state buttons that can be toggled on or off.
+component: true
+radix:
+ link: https://www.radix-ui.com/docs/primitives/components/toggle-group
+ api: https://www.radix-ui.com/docs/primitives/components/toggle-group#api-reference
+---
+
+
+
+
+
+## Installation
+
+```bash
+npx shadcn-ui add toggle-group
+```
+
+
+
+ Manual Installation
+
+
+1. Install the `@radix-ui/react-toggle-group` component from radix-ui:
+
+```bash
+npm install @radix-ui/react-toggle-group
+```
+
+2. Copy and paste the following code into your project.
+
+
+
+
+ This is the `` primitive. You can place it in a file at
+ `components/ui/toggle-group.tsx`.
+
+
+
+
+
+
+
+## Usage
+
+```tsx
+import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
+```
+
+```tsx
+
+
+
+
+
+
+
+
+
+
+
+```
+
+## Examples
+
+### Default
+
+
+
+
+
+---
+
+### Outline
+
+
+
+
+
+---
+
+### Small
+
+
+
+
+
+---
+
+### Large
+
+
+
+
+
+---
+
+### Multiple
+
+
+
+
+
+---
+
+### Disabled
+
+
+
+
diff --git a/apps/www/pages/api/components.json b/apps/www/pages/api/components.json
index 9fe8b0616a6..e7ffe006c1c 100644
--- a/apps/www/pages/api/components.json
+++ b/apps/www/pages/api/components.json
@@ -20,7 +20,7 @@
{
"name": "alert.tsx",
"dir": "components/ui",
- "content": "import * as React from \"react\"\nimport { VariantProps, cva } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst alertVariants = cva(\n \"relative w-full rounded-lg border p-4 [&>svg]:absolute [&>svg]:text-foreground [&>svg]:left-4 [&>svg]:top-4 [&>svg+div]:translate-y-[-3px] [&:has(svg)]:pl-11\",\n {\n variants: {\n variant: {\n default: \"bg-background text-foreground\",\n destructive:\n \"text-destructive border-destructive/50 dark:border-destructive [&>svg]:text-destructive text-destructive\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nconst Alert = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes & VariantProps\n>(({ className, variant, ...props }, ref) => (\n \n))\nAlert.displayName = \"Alert\"\n\nconst AlertTitle = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => (\n \n))\nAlertTitle.displayName = \"AlertTitle\"\n\nconst AlertDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => (\n \n))\nAlertDescription.displayName = \"AlertDescription\"\n\nexport { Alert, AlertTitle, AlertDescription }\n"
+ "content": "import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst alertVariants = cva(\n \"relative w-full rounded-lg border p-4 [&>svg]:absolute [&>svg]:text-foreground [&>svg]:left-4 [&>svg]:top-4 [&>svg+div]:translate-y-[-3px] [&:has(svg)]:pl-11\",\n {\n variants: {\n variant: {\n default: \"bg-background text-foreground\",\n destructive:\n \"text-destructive border-destructive/50 dark:border-destructive [&>svg]:text-destructive text-destructive\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nconst Alert = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes & VariantProps\n>(({ className, variant, ...props }, ref) => (\n \n))\nAlert.displayName = \"Alert\"\n\nconst AlertTitle = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => (\n \n))\nAlertTitle.displayName = \"AlertTitle\"\n\nconst AlertDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => (\n \n))\nAlertDescription.displayName = \"AlertDescription\"\n\nexport { Alert, AlertTitle, AlertDescription }\n"
}
]
},
@@ -73,7 +73,7 @@
{
"name": "badge.tsx",
"dir": "components/ui",
- "content": "import * as React from \"react\"\nimport { VariantProps, cva } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst badgeVariants = cva(\n \"inline-flex items-center border rounded-full px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary hover:bg-primary/80 border-transparent text-primary-foreground\",\n secondary:\n \"bg-secondary hover:bg-secondary/80 border-transparent text-secondary-foreground\",\n destructive:\n \"bg-destructive hover:bg-destructive/80 border-transparent text-destructive-foreground\",\n outline: \"text-foreground\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nexport interface BadgeProps\n extends React.HTMLAttributes,\n VariantProps {}\n\nfunction Badge({ className, variant, ...props }: BadgeProps) {\n return (\n \n )\n}\n\nexport { Badge, badgeVariants }\n"
+ "content": "import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst badgeVariants = cva(\n \"inline-flex items-center border rounded-full px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary hover:bg-primary/80 border-transparent text-primary-foreground\",\n secondary:\n \"bg-secondary hover:bg-secondary/80 border-transparent text-secondary-foreground\",\n destructive:\n \"bg-destructive hover:bg-destructive/80 border-transparent text-destructive-foreground\",\n outline: \"text-foreground\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nexport interface BadgeProps\n extends React.HTMLAttributes,\n VariantProps {}\n\nfunction Badge({ className, variant, ...props }: BadgeProps) {\n return (\n \n )\n}\n\nexport { Badge, badgeVariants }\n"
}
]
},
@@ -87,7 +87,7 @@
{
"name": "button.tsx",
"dir": "components/ui",
- "content": "import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { VariantProps, cva } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-destructive-foreground hover:bg-destructive/90\",\n outline:\n \"border border-input hover:bg-accent hover:text-accent-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"underline-offset-4 hover:underline text-primary\",\n },\n size: {\n default: \"h-10 py-2 px-4\",\n sm: \"h-9 px-3 rounded-md\",\n lg: \"h-11 px-8 rounded-md\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes,\n VariantProps {\n asChild?: boolean\n}\n\nconst Button = React.forwardRef(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : \"button\"\n return (\n \n )\n }\n)\nButton.displayName = \"Button\"\n\nexport { Button, buttonVariants }\n"
+ "content": "import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-destructive-foreground hover:bg-destructive/90\",\n outline:\n \"border border-input hover:bg-accent hover:text-accent-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"underline-offset-4 hover:underline text-primary\",\n },\n size: {\n default: \"h-10 py-2 px-4\",\n sm: \"h-9 px-3 rounded-md\",\n lg: \"h-11 px-8 rounded-md\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes,\n VariantProps {\n asChild?: boolean\n}\n\nconst Button = React.forwardRef(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : \"button\"\n return (\n \n )\n }\n)\nButton.displayName = \"Button\"\n\nexport { Button, buttonVariants }\n"
}
]
},
@@ -155,7 +155,7 @@
{
"name": "command.tsx",
"dir": "components/ui",
- "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { DialogProps } from \"@radix-ui/react-dialog\"\nimport { Command as CommandPrimitive } from \"cmdk\"\nimport { Search } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Dialog, DialogContent } from \"@/components/ui/dialog\"\n\nconst Command = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\nCommand.displayName = CommandPrimitive.displayName\n\ninterface CommandDialogProps extends DialogProps {}\n\nconst CommandDialog = ({ children, ...props }: CommandDialogProps) => {\n return (\n \n )\n}\n\nconst CommandInput = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n \n \n
\n))\n\nCommandInput.displayName = CommandPrimitive.Input.displayName\n\nconst CommandList = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\n\nCommandList.displayName = CommandPrimitive.List.displayName\n\nconst CommandEmpty = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>((props, ref) => (\n \n))\n\nCommandEmpty.displayName = CommandPrimitive.Empty.displayName\n\nconst CommandGroup = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\n\nCommandGroup.displayName = CommandPrimitive.Group.displayName\n\nconst CommandSeparator = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\nCommandSeparator.displayName = CommandPrimitive.Separator.displayName\n\nconst CommandItem = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\n\nCommandItem.displayName = CommandPrimitive.Item.displayName\n\nconst CommandShortcut = ({\n className,\n ...props\n}: React.HTMLAttributes) => {\n return (\n \n )\n}\nCommandShortcut.displayName = \"CommandShortcut\"\n\nexport {\n Command,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n}\n"
+ "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { DialogProps } from \"@radix-ui/react-dialog\"\nimport { Command as CommandPrimitive } from \"cmdk\"\nimport { Search } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Dialog, DialogContent } from \"@/components/ui/dialog\"\n\nconst Command = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\nCommand.displayName = CommandPrimitive.displayName\n\ninterface CommandDialogProps extends DialogProps {}\n\nconst CommandDialog = ({ children, ...props }: CommandDialogProps) => {\n return (\n \n )\n}\n\nconst CommandInput = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n \n \n
\n))\n\nCommandInput.displayName = CommandPrimitive.Input.displayName\n\nconst CommandList = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\n\nCommandList.displayName = CommandPrimitive.List.displayName\n\nconst CommandEmpty = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>((props, ref) => (\n \n))\n\nCommandEmpty.displayName = CommandPrimitive.Empty.displayName\n\nconst CommandGroup = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\n\nCommandGroup.displayName = CommandPrimitive.Group.displayName\n\nconst CommandSeparator = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\nCommandSeparator.displayName = CommandPrimitive.Separator.displayName\n\nconst CommandItem = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\n\nCommandItem.displayName = CommandPrimitive.Item.displayName\n\nconst CommandShortcut = ({\n className,\n ...props\n}: React.HTMLAttributes) => {\n return (\n \n )\n}\nCommandShortcut.displayName = \"CommandShortcut\"\n\nexport {\n Command,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n}\n"
}
]
},
@@ -236,7 +236,7 @@
{
"name": "label.tsx",
"dir": "components/ui",
- "content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as LabelPrimitive from \"@radix-ui/react-label\"\nimport { VariantProps, cva } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst labelVariants = cva(\n \"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n)\n\nconst Label = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef &\n VariantProps\n>(({ className, ...props }, ref) => (\n \n))\nLabel.displayName = LabelPrimitive.Root.displayName\n\nexport { Label }\n"
+ "content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as LabelPrimitive from \"@radix-ui/react-label\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst labelVariants = cva(\n \"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\"\n)\n\nconst Label = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef &\n VariantProps\n>(({ className, ...props }, ref) => (\n \n))\nLabel.displayName = LabelPrimitive.Root.displayName\n\nexport { Label }\n"
}
]
},
@@ -362,7 +362,7 @@
{
"name": "sheet.tsx",
"dir": "components/ui",
- "content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as SheetPrimitive from \"@radix-ui/react-dialog\"\nimport { VariantProps, cva } from \"class-variance-authority\"\nimport { X } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Sheet = SheetPrimitive.Root\n\nconst SheetTrigger = SheetPrimitive.Trigger\n\nconst SheetClose = SheetPrimitive.Close\n\nconst portalVariants = cva(\"fixed inset-0 z-50 flex\", {\n variants: {\n position: {\n top: \"items-start\",\n bottom: \"items-end\",\n left: \"justify-start\",\n right: \"justify-end\",\n },\n },\n defaultVariants: { position: \"right\" },\n})\n\ninterface SheetPortalProps\n extends SheetPrimitive.DialogPortalProps,\n VariantProps {}\n\nconst SheetPortal = ({\n position,\n className,\n children,\n ...props\n}: SheetPortalProps) => (\n \n {children}
\n \n)\nSheetPortal.displayName = SheetPrimitive.Portal.displayName\n\nconst SheetOverlay = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, children, ...props }, ref) => (\n \n))\nSheetOverlay.displayName = SheetPrimitive.Overlay.displayName\n\nconst sheetVariants = cva(\n \"fixed z-50 scale-100 gap-4 bg-background p-6 opacity-100 shadow-lg border\",\n {\n variants: {\n position: {\n top: \"animate-in slide-in-from-top w-full duration-300\",\n bottom: \"animate-in slide-in-from-bottom w-full duration-300\",\n left: \"animate-in slide-in-from-left h-full duration-300\",\n right: \"animate-in slide-in-from-right h-full duration-300\",\n },\n size: {\n content: \"\",\n default: \"\",\n sm: \"\",\n lg: \"\",\n xl: \"\",\n full: \"\",\n },\n },\n compoundVariants: [\n {\n position: [\"top\", \"bottom\"],\n size: \"content\",\n class: \"max-h-screen\",\n },\n {\n position: [\"top\", \"bottom\"],\n size: \"default\",\n class: \"h-1/3\",\n },\n {\n position: [\"top\", \"bottom\"],\n size: \"sm\",\n class: \"h-1/4\",\n },\n {\n position: [\"top\", \"bottom\"],\n size: \"lg\",\n class: \"h-1/2\",\n },\n {\n position: [\"top\", \"bottom\"],\n size: \"xl\",\n class: \"h-5/6\",\n },\n {\n position: [\"top\", \"bottom\"],\n size: \"full\",\n class: \"h-screen\",\n },\n {\n position: [\"right\", \"left\"],\n size: \"content\",\n class: \"max-w-screen\",\n },\n {\n position: [\"right\", \"left\"],\n size: \"default\",\n class: \"w-1/3\",\n },\n {\n position: [\"right\", \"left\"],\n size: \"sm\",\n class: \"w-1/4\",\n },\n {\n position: [\"right\", \"left\"],\n size: \"lg\",\n class: \"w-1/2\",\n },\n {\n position: [\"right\", \"left\"],\n size: \"xl\",\n class: \"w-5/6\",\n },\n {\n position: [\"right\", \"left\"],\n size: \"full\",\n class: \"w-screen\",\n },\n ],\n defaultVariants: {\n position: \"right\",\n size: \"default\",\n },\n }\n)\n\nexport interface DialogContentProps\n extends React.ComponentPropsWithoutRef,\n VariantProps {}\n\nconst SheetContent = React.forwardRef<\n React.ElementRef,\n DialogContentProps\n>(({ position, size, className, children, ...props }, ref) => (\n \n \n \n {children}\n \n \n Close\n \n \n \n))\nSheetContent.displayName = SheetPrimitive.Content.displayName\n\nconst SheetHeader = ({\n className,\n ...props\n}: React.HTMLAttributes) => (\n \n)\nSheetHeader.displayName = \"SheetHeader\"\n\nconst SheetFooter = ({\n className,\n ...props\n}: React.HTMLAttributes) => (\n \n)\nSheetFooter.displayName = \"SheetFooter\"\n\nconst SheetTitle = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\nSheetTitle.displayName = SheetPrimitive.Title.displayName\n\nconst SheetDescription = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\nSheetDescription.displayName = SheetPrimitive.Description.displayName\n\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n}\n"
+ "content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as SheetPrimitive from \"@radix-ui/react-dialog\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { X } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Sheet = SheetPrimitive.Root\n\nconst SheetTrigger = SheetPrimitive.Trigger\n\nconst SheetClose = SheetPrimitive.Close\n\nconst portalVariants = cva(\"fixed inset-0 z-50 flex\", {\n variants: {\n position: {\n top: \"items-start\",\n bottom: \"items-end\",\n left: \"justify-start\",\n right: \"justify-end\",\n },\n },\n defaultVariants: { position: \"right\" },\n})\n\ninterface SheetPortalProps\n extends SheetPrimitive.DialogPortalProps,\n VariantProps {}\n\nconst SheetPortal = ({\n position,\n className,\n children,\n ...props\n}: SheetPortalProps) => (\n \n {children}
\n \n)\nSheetPortal.displayName = SheetPrimitive.Portal.displayName\n\nconst SheetOverlay = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, children, ...props }, ref) => (\n \n))\nSheetOverlay.displayName = SheetPrimitive.Overlay.displayName\n\nconst sheetVariants = cva(\n \"fixed z-50 scale-100 gap-4 bg-background p-6 opacity-100 shadow-lg border\",\n {\n variants: {\n position: {\n top: \"animate-in slide-in-from-top w-full duration-300\",\n bottom: \"animate-in slide-in-from-bottom w-full duration-300\",\n left: \"animate-in slide-in-from-left h-full duration-300\",\n right: \"animate-in slide-in-from-right h-full duration-300\",\n },\n size: {\n content: \"\",\n default: \"\",\n sm: \"\",\n lg: \"\",\n xl: \"\",\n full: \"\",\n },\n },\n compoundVariants: [\n {\n position: [\"top\", \"bottom\"],\n size: \"content\",\n class: \"max-h-screen\",\n },\n {\n position: [\"top\", \"bottom\"],\n size: \"default\",\n class: \"h-1/3\",\n },\n {\n position: [\"top\", \"bottom\"],\n size: \"sm\",\n class: \"h-1/4\",\n },\n {\n position: [\"top\", \"bottom\"],\n size: \"lg\",\n class: \"h-1/2\",\n },\n {\n position: [\"top\", \"bottom\"],\n size: \"xl\",\n class: \"h-5/6\",\n },\n {\n position: [\"top\", \"bottom\"],\n size: \"full\",\n class: \"h-screen\",\n },\n {\n position: [\"right\", \"left\"],\n size: \"content\",\n class: \"max-w-screen\",\n },\n {\n position: [\"right\", \"left\"],\n size: \"default\",\n class: \"w-1/3\",\n },\n {\n position: [\"right\", \"left\"],\n size: \"sm\",\n class: \"w-1/4\",\n },\n {\n position: [\"right\", \"left\"],\n size: \"lg\",\n class: \"w-1/2\",\n },\n {\n position: [\"right\", \"left\"],\n size: \"xl\",\n class: \"w-5/6\",\n },\n {\n position: [\"right\", \"left\"],\n size: \"full\",\n class: \"w-screen\",\n },\n ],\n defaultVariants: {\n position: \"right\",\n size: \"default\",\n },\n }\n)\n\nexport interface DialogContentProps\n extends React.ComponentPropsWithoutRef,\n VariantProps {}\n\nconst SheetContent = React.forwardRef<\n React.ElementRef,\n DialogContentProps\n>(({ position, size, className, children, ...props }, ref) => (\n \n \n \n {children}\n \n \n Close\n \n \n \n))\nSheetContent.displayName = SheetPrimitive.Content.displayName\n\nconst SheetHeader = ({\n className,\n ...props\n}: React.HTMLAttributes) => (\n \n)\nSheetHeader.displayName = \"SheetHeader\"\n\nconst SheetFooter = ({\n className,\n ...props\n}: React.HTMLAttributes) => (\n \n)\nSheetFooter.displayName = \"SheetFooter\"\n\nconst SheetTitle = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\nSheetTitle.displayName = SheetPrimitive.Title.displayName\n\nconst SheetDescription = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\nSheetDescription.displayName = SheetPrimitive.Description.displayName\n\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n}\n"
}
]
},
@@ -451,12 +451,12 @@
{
"name": "toast.tsx",
"dir": "components/ui",
- "content": "import * as React from \"react\"\nimport * as ToastPrimitives from \"@radix-ui/react-toast\"\nimport { VariantProps, cva } from \"class-variance-authority\"\nimport { X } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst ToastProvider = ToastPrimitives.Provider\n\nconst ToastViewport = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\nToastViewport.displayName = ToastPrimitives.Viewport.displayName\n\nconst toastVariants = cva(\n \"data-[swipe=move]:transition-none group relative pointer-events-auto flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full data-[state=closed]:slide-out-to-right-full\",\n {\n variants: {\n variant: {\n default: \"bg-background border\",\n destructive:\n \"group destructive border-destructive bg-destructive text-destructive-foreground\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nconst Toast = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef &\n VariantProps\n>(({ className, variant, ...props }, ref) => {\n return (\n \n )\n})\nToast.displayName = ToastPrimitives.Root.displayName\n\nconst ToastAction = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\nToastAction.displayName = ToastPrimitives.Action.displayName\n\nconst ToastClose = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n \n \n))\nToastClose.displayName = ToastPrimitives.Close.displayName\n\nconst ToastTitle = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\nToastTitle.displayName = ToastPrimitives.Title.displayName\n\nconst ToastDescription = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\nToastDescription.displayName = ToastPrimitives.Description.displayName\n\ntype ToastProps = React.ComponentPropsWithoutRef\n\ntype ToastActionElement = React.ReactElement\n\nexport {\n type ToastProps,\n type ToastActionElement,\n ToastProvider,\n ToastViewport,\n Toast,\n ToastTitle,\n ToastDescription,\n ToastClose,\n ToastAction,\n}\n"
+ "content": "import * as React from \"react\"\nimport * as ToastPrimitives from \"@radix-ui/react-toast\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { X } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst ToastProvider = ToastPrimitives.Provider\n\nconst ToastViewport = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\nToastViewport.displayName = ToastPrimitives.Viewport.displayName\n\nconst toastVariants = cva(\n \"data-[swipe=move]:transition-none group relative pointer-events-auto flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full data-[state=closed]:slide-out-to-right-full\",\n {\n variants: {\n variant: {\n default: \"bg-background border\",\n destructive:\n \"group destructive border-destructive bg-destructive text-destructive-foreground\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nconst Toast = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef &\n VariantProps\n>(({ className, variant, ...props }, ref) => {\n return (\n \n )\n})\nToast.displayName = ToastPrimitives.Root.displayName\n\nconst ToastAction = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\nToastAction.displayName = ToastPrimitives.Action.displayName\n\nconst ToastClose = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n \n \n))\nToastClose.displayName = ToastPrimitives.Close.displayName\n\nconst ToastTitle = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\nToastTitle.displayName = ToastPrimitives.Title.displayName\n\nconst ToastDescription = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n))\nToastDescription.displayName = ToastPrimitives.Description.displayName\n\ntype ToastProps = React.ComponentPropsWithoutRef\n\ntype ToastActionElement = React.ReactElement\n\nexport {\n type ToastProps,\n type ToastActionElement,\n ToastProvider,\n ToastViewport,\n Toast,\n ToastTitle,\n ToastDescription,\n ToastClose,\n ToastAction,\n}\n"
},
{
"name": "use-toast.ts",
"dir": "components/ui",
- "content": "// Inspired by react-hot-toast library\nimport * as React from \"react\"\n\nimport { ToastActionElement, type ToastProps } from \"@/components/ui/toast\"\n\nconst TOAST_LIMIT = 1\nconst TOAST_REMOVE_DELAY = 1000000\n\ntype ToasterToast = ToastProps & {\n id: string\n title?: React.ReactNode\n description?: React.ReactNode\n action?: ToastActionElement\n}\n\nconst actionTypes = {\n ADD_TOAST: \"ADD_TOAST\",\n UPDATE_TOAST: \"UPDATE_TOAST\",\n DISMISS_TOAST: \"DISMISS_TOAST\",\n REMOVE_TOAST: \"REMOVE_TOAST\",\n} as const\n\nlet count = 0\n\nfunction genId() {\n count = (count + 1) % Number.MAX_VALUE\n return count.toString()\n}\n\ntype ActionType = typeof actionTypes\n\ntype Action =\n | {\n type: ActionType[\"ADD_TOAST\"]\n toast: ToasterToast\n }\n | {\n type: ActionType[\"UPDATE_TOAST\"]\n toast: Partial\n }\n | {\n type: ActionType[\"DISMISS_TOAST\"]\n toastId?: ToasterToast[\"id\"]\n }\n | {\n type: ActionType[\"REMOVE_TOAST\"]\n toastId?: ToasterToast[\"id\"]\n }\n\ninterface State {\n toasts: ToasterToast[]\n}\n\nconst toastTimeouts = new Map>()\n\nconst addToRemoveQueue = (toastId: string) => {\n if (toastTimeouts.has(toastId)) {\n return\n }\n\n const timeout = setTimeout(() => {\n toastTimeouts.delete(toastId)\n dispatch({\n type: \"REMOVE_TOAST\",\n toastId: toastId,\n })\n }, TOAST_REMOVE_DELAY)\n\n toastTimeouts.set(toastId, timeout)\n}\n\nexport const reducer = (state: State, action: Action): State => {\n switch (action.type) {\n case \"ADD_TOAST\":\n return {\n ...state,\n toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),\n }\n\n case \"UPDATE_TOAST\":\n return {\n ...state,\n toasts: state.toasts.map((t) =>\n t.id === action.toast.id ? { ...t, ...action.toast } : t\n ),\n }\n\n case \"DISMISS_TOAST\": {\n const { toastId } = action\n\n // ! Side effects ! - This could be extracted into a dismissToast() action,\n // but I'll keep it here for simplicity\n if (toastId) {\n addToRemoveQueue(toastId)\n } else {\n state.toasts.forEach((toast) => {\n addToRemoveQueue(toast.id)\n })\n }\n\n return {\n ...state,\n toasts: state.toasts.map((t) =>\n t.id === toastId || toastId === undefined\n ? {\n ...t,\n open: false,\n }\n : t\n ),\n }\n }\n case \"REMOVE_TOAST\":\n if (action.toastId === undefined) {\n return {\n ...state,\n toasts: [],\n }\n }\n return {\n ...state,\n toasts: state.toasts.filter((t) => t.id !== action.toastId),\n }\n }\n}\n\nconst listeners: Array<(state: State) => void> = []\n\nlet memoryState: State = { toasts: [] }\n\nfunction dispatch(action: Action) {\n memoryState = reducer(memoryState, action)\n listeners.forEach((listener) => {\n listener(memoryState)\n })\n}\n\ninterface Toast extends Omit {}\n\nfunction toast({ ...props }: Toast) {\n const id = genId()\n\n const update = (props: ToasterToast) =>\n dispatch({\n type: \"UPDATE_TOAST\",\n toast: { ...props, id },\n })\n const dismiss = () => dispatch({ type: \"DISMISS_TOAST\", toastId: id })\n\n dispatch({\n type: \"ADD_TOAST\",\n toast: {\n ...props,\n id,\n open: true,\n onOpenChange: (open) => {\n if (!open) dismiss()\n },\n },\n })\n\n return {\n id: id,\n dismiss,\n update,\n }\n}\n\nfunction useToast() {\n const [state, setState] = React.useState(memoryState)\n\n React.useEffect(() => {\n listeners.push(setState)\n return () => {\n const index = listeners.indexOf(setState)\n if (index > -1) {\n listeners.splice(index, 1)\n }\n }\n }, [state])\n\n return {\n ...state,\n toast,\n dismiss: (toastId?: string) => dispatch({ type: \"DISMISS_TOAST\", toastId }),\n }\n}\n\nexport { useToast, toast }\n"
+ "content": "// Inspired by react-hot-toast library\nimport * as React from \"react\"\n\nimport type { ToastActionElement, ToastProps } from \"@/components/ui/toast\"\n\nconst TOAST_LIMIT = 1\nconst TOAST_REMOVE_DELAY = 1000000\n\ntype ToasterToast = ToastProps & {\n id: string\n title?: React.ReactNode\n description?: React.ReactNode\n action?: ToastActionElement\n}\n\nconst actionTypes = {\n ADD_TOAST: \"ADD_TOAST\",\n UPDATE_TOAST: \"UPDATE_TOAST\",\n DISMISS_TOAST: \"DISMISS_TOAST\",\n REMOVE_TOAST: \"REMOVE_TOAST\",\n} as const\n\nlet count = 0\n\nfunction genId() {\n count = (count + 1) % Number.MAX_VALUE\n return count.toString()\n}\n\ntype ActionType = typeof actionTypes\n\ntype Action =\n | {\n type: ActionType[\"ADD_TOAST\"]\n toast: ToasterToast\n }\n | {\n type: ActionType[\"UPDATE_TOAST\"]\n toast: Partial\n }\n | {\n type: ActionType[\"DISMISS_TOAST\"]\n toastId?: ToasterToast[\"id\"]\n }\n | {\n type: ActionType[\"REMOVE_TOAST\"]\n toastId?: ToasterToast[\"id\"]\n }\n\ninterface State {\n toasts: ToasterToast[]\n}\n\nconst toastTimeouts = new Map>()\n\nconst addToRemoveQueue = (toastId: string) => {\n if (toastTimeouts.has(toastId)) {\n return\n }\n\n const timeout = setTimeout(() => {\n toastTimeouts.delete(toastId)\n dispatch({\n type: \"REMOVE_TOAST\",\n toastId: toastId,\n })\n }, TOAST_REMOVE_DELAY)\n\n toastTimeouts.set(toastId, timeout)\n}\n\nexport const reducer = (state: State, action: Action): State => {\n switch (action.type) {\n case \"ADD_TOAST\":\n return {\n ...state,\n toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),\n }\n\n case \"UPDATE_TOAST\":\n return {\n ...state,\n toasts: state.toasts.map((t) =>\n t.id === action.toast.id ? { ...t, ...action.toast } : t\n ),\n }\n\n case \"DISMISS_TOAST\": {\n const { toastId } = action\n\n // ! Side effects ! - This could be extracted into a dismissToast() action,\n // but I'll keep it here for simplicity\n if (toastId) {\n addToRemoveQueue(toastId)\n } else {\n state.toasts.forEach((toast) => {\n addToRemoveQueue(toast.id)\n })\n }\n\n return {\n ...state,\n toasts: state.toasts.map((t) =>\n t.id === toastId || toastId === undefined\n ? {\n ...t,\n open: false,\n }\n : t\n ),\n }\n }\n case \"REMOVE_TOAST\":\n if (action.toastId === undefined) {\n return {\n ...state,\n toasts: [],\n }\n }\n return {\n ...state,\n toasts: state.toasts.filter((t) => t.id !== action.toastId),\n }\n }\n}\n\nconst listeners: Array<(state: State) => void> = []\n\nlet memoryState: State = { toasts: [] }\n\nfunction dispatch(action: Action) {\n memoryState = reducer(memoryState, action)\n listeners.forEach((listener) => {\n listener(memoryState)\n })\n}\n\ntype Toast = Omit\n\nfunction toast({ ...props }: Toast) {\n const id = genId()\n\n const update = (props: ToasterToast) =>\n dispatch({\n type: \"UPDATE_TOAST\",\n toast: { ...props, id },\n })\n const dismiss = () => dispatch({ type: \"DISMISS_TOAST\", toastId: id })\n\n dispatch({\n type: \"ADD_TOAST\",\n toast: {\n ...props,\n id,\n open: true,\n onOpenChange: (open) => {\n if (!open) dismiss()\n },\n },\n })\n\n return {\n id: id,\n dismiss,\n update,\n }\n}\n\nfunction useToast() {\n const [state, setState] = React.useState(memoryState)\n\n React.useEffect(() => {\n listeners.push(setState)\n return () => {\n const index = listeners.indexOf(setState)\n if (index > -1) {\n listeners.splice(index, 1)\n }\n }\n }, [state])\n\n return {\n ...state,\n toast,\n dismiss: (toastId?: string) => dispatch({ type: \"DISMISS_TOAST\", toastId }),\n }\n}\n\nexport { useToast, toast }\n"
}
]
},
@@ -470,7 +470,21 @@
{
"name": "toggle.tsx",
"dir": "components/ui",
- "content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\"\nimport { VariantProps, cva } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst toggleVariants = cva(\n \"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors data-[state=on]:bg-accent data-[state=on]:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 ring-offset-background hover:bg-muted hover:text-muted-foreground\",\n {\n variants: {\n variant: {\n default: \"bg-transparent\",\n outline:\n \"bg-transparent border border-input hover:bg-accent hover:text-accent-foreground\",\n },\n size: {\n default: \"h-10 px-3\",\n sm: \"h-9 px-2.5\",\n lg: \"h-11 px-5\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nconst Toggle = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef &\n VariantProps\n>(({ className, variant, size, ...props }, ref) => (\n \n))\n\nToggle.displayName = TogglePrimitive.Root.displayName\n\nexport { Toggle, toggleVariants }\n"
+ "content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst toggleVariants = cva(\n \"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors data-[state=on]:bg-accent data-[state=on]:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 ring-offset-background hover:bg-muted hover:text-muted-foreground\",\n {\n variants: {\n variant: {\n default: \"bg-transparent\",\n outline:\n \"bg-transparent border border-input hover:bg-accent hover:text-accent-foreground\",\n },\n size: {\n default: \"h-10 px-3\",\n sm: \"h-9 px-2.5\",\n lg: \"h-11 px-5\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nconst Toggle = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef &\n VariantProps\n>(({ className, variant, size, ...props }, ref) => (\n \n))\n\nToggle.displayName = TogglePrimitive.Root.displayName\n\nexport { Toggle, toggleVariants }\n"
+ }
+ ]
+ },
+ {
+ "component": "toggle-group",
+ "name": "Toggle Group",
+ "dependencies": [
+ "@radix-ui/react-toggle-group"
+ ],
+ "files": [
+ {
+ "name": "toggle-group.tsx",
+ "dir": "components/ui",
+ "content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as ToggleGroupPrimitive from \"@radix-ui/react-toggle-group\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst ToggleGroupContext = React.createContext<\n VariantProps\n>({\n size: \"default\",\n variant: \"default\",\n})\n\nconst toggleGroupVariants = cva(\n \"inline-flex items-center justify-center text-muted-foreground text-sm font-medium transition-colors data-[state=on]:bg-accent-foreground/5 dark:data-[state=on]:bg-accent data-[state=on]:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 ring-offset-background hover:bg-muted hover:text-muted-foreground first:rounded-l last:rounded-r\",\n {\n variants: {\n variant: {\n default: \"bg-transparent\",\n outline: \"bg-transparent data-[state=on]:bg-muted\",\n },\n size: {\n default: \"h-10 px-3\",\n sm: \"h-9 px-2.5\",\n lg: \"h-11 px-5\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nconst ToggleGroup = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef &\n VariantProps\n>(({ className, variant, size, children, ...props }, ref) => (\n \n \n {children}\n \n \n))\n\nconst ToggleGroupItem = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => {\n const context = React.useContext(ToggleGroupContext)\n return (\n \n )\n})\n\nToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName\nToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName\n\nexport { ToggleGroup, ToggleGroupItem }\n"
}
]
},
@@ -488,4 +502,4 @@
}
]
}
-]
+]
\ No newline at end of file