first commit
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
"use client"
|
||||
|
||||
import type { LucideIcon } from "lucide-react"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
|
||||
|
||||
interface SelectableCardOption {
|
||||
value: string
|
||||
label: string
|
||||
description?: string
|
||||
icon?: LucideIcon
|
||||
}
|
||||
|
||||
interface SelectableCardGroupProps {
|
||||
options: SelectableCardOption[]
|
||||
value: string
|
||||
onValueChange: (value: string) => void
|
||||
className?: string
|
||||
columns?: 1 | 2 | 3
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
function SelectableCardGroup({
|
||||
options,
|
||||
value,
|
||||
onValueChange,
|
||||
className,
|
||||
columns = 2,
|
||||
disabled = false,
|
||||
}: SelectableCardGroupProps) {
|
||||
return (
|
||||
<RadioGroup
|
||||
value={value}
|
||||
onValueChange={(v) => onValueChange(String(v))}
|
||||
disabled={disabled}
|
||||
className={cn(
|
||||
"grid gap-3",
|
||||
columns === 1 && "grid-cols-1",
|
||||
columns === 2 && "grid-cols-1 sm:grid-cols-2",
|
||||
columns === 3 && "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
|
||||
className
|
||||
)}
|
||||
>
|
||||
{options.map((opt) => {
|
||||
const Icon = opt.icon
|
||||
return (
|
||||
<label
|
||||
key={opt.value}
|
||||
htmlFor={`selectable-card-${opt.value}`}
|
||||
className={cn(
|
||||
"flex items-start gap-3 rounded-xl border bg-card p-4 transition-colors has-data-checked:border-primary has-data-checked:bg-primary/5 has-data-checked:ring-1 has-data-checked:ring-primary/30",
|
||||
disabled ? "cursor-not-allowed opacity-70" : "cursor-pointer"
|
||||
)}
|
||||
>
|
||||
<RadioGroupItem
|
||||
id={`selectable-card-${opt.value}`}
|
||||
value={opt.value}
|
||||
className="mt-1"
|
||||
/>
|
||||
<div className="flex min-w-0 flex-col gap-1">
|
||||
<div className="flex items-center gap-2 font-medium">
|
||||
{Icon && <Icon className="size-4 text-primary" />}
|
||||
{opt.label}
|
||||
</div>
|
||||
{opt.description && (
|
||||
<p className="text-sm text-muted-foreground">{opt.description}</p>
|
||||
)}
|
||||
</div>
|
||||
</label>
|
||||
)
|
||||
})}
|
||||
</RadioGroup>
|
||||
)
|
||||
}
|
||||
|
||||
export { SelectableCardGroup }
|
||||
export type { SelectableCardOption }
|
||||
Reference in New Issue
Block a user