Radio Group
optics/radio-groupFreeComponent
A set of checkable buttons—known as radio buttons.
See it running
Open the demo on optics
optics.agusmayol.com.ar/components/radio-groupInstall it
npx shadcn@latest add https://optics.agusmayol.com.ar/r/radio-group.jsonSource
1"use client";23import { Radio as RadioPrimitive } from "@base-ui/react/radio";4import { RadioGroup as RadioGroupPrimitive } from "@base-ui/react/radio-group";5import { buttonVariants } from "@/registry/optics/button";6import { cn } from "@/lib/utils";7import { CircleIcon } from "lucide-react";8import * as React from "react";910function RadioGroup({ className = "", ...props }) {11 return (12 <RadioGroupPrimitive13 data-slot="radio-group"14 className={cn("grid gap-3 w-full", className)}15 {...props}16 />17 );18}1920function RadioGroupItem({ className = "", ...props }) {21 const [isChecked, setIsChecked] = React.useState(false);22 const ref = React.useRef(null);2324 // Detectar cambios en el estado del radio usando MutationObserver25 React.useEffect(() => {26 const element = ref.current;27 if (!element) return;2829 // Función para verificar el estado30 const checkState = () => {31 const checked =32 element.hasAttribute("data-checked") ||33 element.getAttribute("aria-checked") === "true";34 setIsChecked(checked);35 };3637 // Verificar estado inicial38 checkState();3940 // Observar cambios en atributos41 const observer = new MutationObserver(checkState);42 observer.observe(element, {43 attributes: true,44 attributeFilter: ["data-checked", "aria-checked"],45 });4647 return () => {48 observer.disconnect();49 };50 }, []);5152 return (53 <RadioPrimitive.Root54 ref={ref}55 data-slot="radio-group-item"56 className={cn(57 "border-input text-primary dark:bg-input/30 focus-visible:border-ring focus-visible:ring-ring/30 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 data-checked:bg-primary data-checked:border-primary flex size-4 rounded-full squircle-none transition-none focus-visible:ring-[2px] aria-invalid:ring-[2px] group/radio-group-item peer relative aspect-square shrink-0 border outline-none after:absolute after:-inset-x-3 after:-inset-y-2 disabled:cursor-not-allowed disabled:opacity-50",58 buttonVariants({59 variant: isChecked ? "default" : "outline",60 size: "icon-xs",61 className: "rounded-full squircle-none",62 }),63 className,64 )}65 {...props}66 >67 <RadioPrimitive.Indicator68 data-slot="radio-group-indicator"69 className={cn(70 "group-aria-invalid/radio-group-item:text-destructive flex size-4 p-4 items-center justify-center text-white",71 )}72 >73// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from optics
All 79 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | optics | Components | Free | 5 deps | |
| Alertalert | optics | Components | Free | 4 deps | |
| Alert Dialogalert-dialog | optics | Components | Free | 4 deps | |
| Aspect Ratioaspect-ratio | optics | Components | Free | 2 deps | |
| Auto Heightauto-height | optics | Components | Free | 3 deps | |
| Avataravatar | optics | Components | Free | 3 deps | |
| Badgebadge | optics | Components | Free | 4 deps | |
| Breadcrumbbreadcrumb | optics | Components | Free | 4 deps |
