toggle-group.tsx 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. "use client";
  2. import * as React from "react";
  3. import { type VariantProps } from "class-variance-authority";
  4. import { ToggleGroup as ToggleGroupPrimitive } from "radix-ui";
  5. import { cn } from "@/lib/utils";
  6. import { toggleVariants } from "@/components/ui/toggle";
  7. const ToggleGroupContext = React.createContext<
  8. VariantProps<typeof toggleVariants> & {
  9. spacing?: number;
  10. }
  11. >({
  12. size: "default",
  13. variant: "default",
  14. spacing: 0,
  15. });
  16. function ToggleGroup({
  17. className,
  18. variant,
  19. size,
  20. spacing = 0,
  21. children,
  22. ...props
  23. }: React.ComponentProps<typeof ToggleGroupPrimitive.Root> &
  24. VariantProps<typeof toggleVariants> & {
  25. spacing?: number;
  26. }) {
  27. return (
  28. <ToggleGroupPrimitive.Root
  29. data-slot="toggle-group"
  30. data-variant={variant}
  31. data-size={size}
  32. data-spacing={spacing}
  33. style={{ "--gap": spacing } as React.CSSProperties}
  34. className={cn(
  35. "group/toggle-group flex w-fit items-center gap-[--spacing(var(--gap))] rounded-md data-[spacing=default]:data-[variant=outline]:shadow-xs",
  36. className,
  37. )}
  38. {...props}
  39. >
  40. <ToggleGroupContext.Provider value={{ variant, size, spacing }}>
  41. {children}
  42. </ToggleGroupContext.Provider>
  43. </ToggleGroupPrimitive.Root>
  44. );
  45. }
  46. function ToggleGroupItem({
  47. className,
  48. children,
  49. variant,
  50. size,
  51. ...props
  52. }: React.ComponentProps<typeof ToggleGroupPrimitive.Item> &
  53. VariantProps<typeof toggleVariants>) {
  54. const context = React.useContext(ToggleGroupContext);
  55. return (
  56. <ToggleGroupPrimitive.Item
  57. data-slot="toggle-group-item"
  58. data-variant={context.variant || variant}
  59. data-size={context.size || size}
  60. data-spacing={context.spacing}
  61. className={cn(
  62. toggleVariants({
  63. variant: context.variant || variant,
  64. size: context.size || size,
  65. }),
  66. "w-auto min-w-0 shrink-0 px-3 focus:z-10 focus-visible:z-10",
  67. "data-[spacing=0]:rounded-none data-[spacing=0]:shadow-none data-[spacing=0]:first:rounded-l-md data-[spacing=0]:last:rounded-r-md data-[spacing=0]:data-[variant=outline]:border-l-0 data-[spacing=0]:data-[variant=outline]:first:border-l",
  68. className,
  69. )}
  70. {...props}
  71. >
  72. {children}
  73. </ToggleGroupPrimitive.Item>
  74. );
  75. }
  76. export { ToggleGroup, ToggleGroupItem };