Provides a shared state to a series of toggle buttons.
Installation
npx shadcn@latest add @caprice/toggle-groupnpm install @caprice-ui/reactInstall the following dependencies:
npm install @base-ui/react lucide-reactAdd a cn helper
import { defineConfig, type VariantProps } from 'cva';import { twMerge } from 'tailwind-merge';export const { compose, cva, cx: cn,} = defineConfig({ hooks: { onComplete: (className: string) => twMerge(className), },});export type { VariantProps };Copy and paste the following code into your project.
'use client';import { ToggleGroup as ToggleGroupPrimitive } from '@base-ui/react/toggle-group';import * as React from 'react';import { Toggle as ToggleComponent, type toggleVariants } from '@/components/caprice-ui/toggle';import { cn, type VariantProps } from '@/lib/utils';type ToggleGroupVariants = VariantProps<typeof toggleVariants> & { /** * The spacing between the toggle buttons. * @default 0 */ spacing?: number;};const ToggleGroupContext = React.createContext<ToggleGroupVariants>({ size: 'md', variant: 'transparent', spacing: 0,});/** * Provides a shared state to a series of toggle buttons. * * Documentation: [Caprice UI Toggle Group](https://caprice-ui.com/docs/components/toggle-group) * * API Reference: [Base UI Toggle Group](https://base-ui.com/react/components/toggle-group) */export namespace Root { export type State = ToggleGroupPrimitive.State; export type Variants = ToggleGroupVariants; export type Props = React.ComponentProps<typeof ToggleGroupPrimitive> & Root.Variants; export type ChangeEventDetails = ToggleGroupPrimitive.ChangeEventDetails; export type ChangeEventReason = ToggleGroupPrimitive.ChangeEventReason;}export function Root({ className, variant, size, spacing = 0, children, ...props }: Root.Props) { return ( <ToggleGroupPrimitive className={cn( 'group/toggle-group flex w-fit items-center gap-[--spacing(var(--gap))] rounded-md data-[spacing=default]:data-[variant=outline]:shadow-xs', className )} data-size={size} data-slot="toggle-group" data-spacing={spacing} data-variant={variant} style={{ '--gap': spacing } as React.CSSProperties} {...props} > <ToggleGroupContext.Provider value={{ size, variant, spacing }}> {children} </ToggleGroupContext.Provider> </ToggleGroupPrimitive> );}/** * A toggle button that can be used within a toggle group. * Renders a `<button>` element. * * Documentation: [Caprice UI Toggle Group](https://caprice-ui.com/docs/components/toggle-group) * * API Reference: [Base UI Toggle Group](https://base-ui.com/react/components/toggle) */export function Item({ className, children, variant, size, ...props}: React.ComponentProps<typeof ToggleComponent> & VariantProps<typeof toggleVariants>) { const context = React.useContext(ToggleGroupContext); return ( <ToggleComponent className={cn( 'w-auto min-w-0 shrink-0 px-3 focus:z-10 focus-visible:z-10', 'data-[spacing=0]:data-[variant=outline]:border-l-0 data-[spacing=0]:rounded-none data-[spacing=0]:shadow-none data-[spacing=0]:last:rounded-r-md data-[spacing=0]:data-[variant=outline]:first:border-l data-[spacing=0]:first:rounded-l-md', className )} data-size={context.size || size} data-slot="toggle-group-item" data-spacing={context.spacing} data-variant={context.variant || variant} size={context.size || size} variant={context.variant || variant} {...props} > {children} </ToggleComponent> );}Update the import paths to match your project setup.
Usage
import * as ToggleGroup from "@/components/caprice-ui/togglegroup"import * as ToggleGroup from "@caprice-ui/react/togglegroup"<ToggleGroup.Root>
<ToggleGroup.Item value="a">A</ToggleGroup.Item>
<ToggleGroup.Item value="b">B</ToggleGroup.Item>
<ToggleGroup.Item value="c">C</ToggleGroup.Item>
</ToggleGroup.Root>Examples
Outline
Multiple
By default, only one item in the group can be pressed. If any item in the group becomes pressed, the others will become unpressed. You can use the multiple prop to allow multiple items to be pressed.