For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to documentation URLs. Homepage markdown is available at /llms.md/content.md. An agent skill is available at /.well-known/agent-skills/site-skill.md.

Radio Card

A selectable card built on Radio Group.

Installation

$ pnpm dlx shadcn@latest add @cobalt/radio-card

Source

"use client";

import { cn } from "cn";
import * as React from "react";

import { RadioGroupItem } from "@/components/ui/radio-group";

type RadioCardProps = Omit<
  React.ComponentProps<typeof RadioGroupItem>,
  "title" | "children"
> & {
  title: React.ReactNode;
  description?: React.ReactNode;
};

function RadioCard({
  className,
  title,
  description,
  ...props
}: RadioCardProps) {
  const titleId = React.useId();
  const descriptionId = React.useId();
  const hasDescription = description !== undefined && description !== null;

  return (
    <label
      data-slot="radio-card"
      className={cn(
        "relative isolate flex w-full cursor-pointer items-center justify-between gap-3 rounded-[10px] border before:pointer-events-none before:absolute before:inset-0 before:rounded-[inherit] before:ring-inset has-data-checked:before:ring-2 border-[var(--border-subtle,var(--border))] bg-card py-3 pe-5 ps-4 shadow-[0_1px_1px_0_rgb(0_0_0/0.05)] ring-2 ring-transparent ring-inset transition-[box-shadow] duration-150 ease-[ease] select-none dark:shadow-[0_1px_1px_0_rgb(0_0_0/0.14)] has-data-checked:before:ring-primary has-data-checked:transition-none motion-reduce:transition-none hover:not-has-data-disabled:not-has-data-checked:ring-[var(--border-hover,var(--border))] has-data-disabled:cursor-not-allowed has-data-disabled:opacity-50",
        className
      )}
    >
      <span className="flex min-w-0 flex-col gap-0.5">
        <span
          id={titleId}
          className="truncate text-sm leading-5 font-medium text-foreground"
        >
          {title}
        </span>
        {hasDescription && (
          <span
            id={descriptionId}
            className="truncate text-sm leading-5 font-normal text-muted-foreground"
          >
            {description}
          </span>
        )}
      </span>
      <span className="flex shrink-0 items-center py-1">
        <RadioGroupItem
          {...props}
          aria-labelledby={titleId}
          aria-describedby={hasDescription ? descriptionId : undefined}
          className="data-disabled:opacity-100"
        />
      </span>
    </label>
  );
}

export { RadioCard };
export type { RadioCardProps };