1"use client";
2
3import type { Toggle as TogglePrimitive } from "@base-ui/react/toggle";
4import { ToggleGroup as ToggleGroupPrimitive } from "@base-ui/react/toggle-group";
5import type { VariantProps } from "class-variance-authority";
6import * as React from "react";
7
8import { cn } from "~/lib/utils";
9import { Toggle as ToggleComponent, type toggleVariants } from "~/components/ui/toggle";
10
11const ToggleGroupContext = React.createContext<VariantProps<typeof toggleVariants>>({
12 size: "default",
13 variant: "default",
14});
15
16function ToggleGroup({
17 className,
18 variant = "segmented",
19 size = variant === "segmented" ? "segmented" : "default",
20 orientation = "horizontal",
21 children,
22 ...props
23}: ToggleGroupPrimitive.Props & VariantProps<typeof toggleVariants>) {
24 const value = React.useMemo(() => ({ size, variant }), [size, variant]);
25 return (
26 <ToggleGroupPrimitive
27 className={cn(
28 "flex w-fit *:focus-visible:z-10 dark:*:[[data-slot=separator]:has(+[data-slot=toggle]:hover)]:before:bg-input/64 dark:*:[[data-slot=separator]:has(+[data-slot=toggle][data-pressed])]:before:bg-input dark:*:[[data-slot=toggle]:hover+[data-slot=separator]]:before:bg-input/64 dark:*:[[data-slot=toggle][data-pressed]+[data-slot=separator]]:before:bg-input",
29 orientation === "horizontal"
30 ? "*:pointer-coarse:after:min-w-auto"
31 : "*:pointer-coarse:after:min-h-auto",
32 variant === "segmented"
33 ? "gap-0.5 rounded-lg bg-input/40 p-0.5"
34 : variant === "default"
35 ? "gap-0.5"
36 : orientation === "horizontal"
37 ? "*:not-first:not-data-[slot=separator]:before:-start-[0.5px] *:not-last:not-data-[slot=separator]:before:-end-[0.5px] *:not-first:rounded-s-none *:not-last:rounded-e-none *:not-first:border-s-0 *:not-last:border-e-0 *:not-first:before:rounded-s-none *:not-last:before:rounded-e-none"
38 : "*:not-first:not-data-[slot=separator]:before:-top-[0.5px] *:not-last:not-data-[slot=separator]:before:-bottom-[0.5px] flex-col *:not-first:rounded-t-none *:not-last:rounded-b-none *:not-first:border-t-0 *:not-last:border-b-0 *:not-first:before:rounded-t-none *:not-last:before:rounded-b-none *:data-[slot=toggle]:not-last:before:hidden dark:*:last:before:hidden dark:*:first:before:block",
39 className,
40 )}
41 data-size={size}
42 data-slot="toggle-group"
43 data-variant={variant}
44 orientation={orientation}
45 {...props}
46 >
47 <ToggleGroupContext value={value}>{children}</ToggleGroupContext>
48 </ToggleGroupPrimitive>
49 );
50}
51
52function Toggle({
53 className,
54 children,
55 variant,
56 size,
57 ...props
58}: TogglePrimitive.Props & VariantProps<typeof toggleVariants>) {
59 const context = React.use(ToggleGroupContext);
60
61 const resolvedVariant = variant ?? context.variant;
62 const resolvedSize = size ?? context.size;
63
64 return (
65 <ToggleComponent
66 className={className}
67 data-size={resolvedSize}
68 data-variant={resolvedVariant}
69 size={resolvedSize}
70 variant={resolvedVariant}
71 {...props}
72 >
73 {children}
74 </ToggleComponent>
75 );
76}
77
78export { ToggleGroup, Toggle, Toggle as ToggleGroupItem };