Checkbox Compose
Um card de checkbox com título, descrição, imagem e ação opcionais
Código:
import { cn } from '@/lib/utils';
import * as React from 'react';
import Image, { StaticImageData } from 'next/image';
import * as CheckboxPrimitive from 'radix-ui/checkbox';
import { Button } from '../button';
import { Icon } from '../icons';
import { textVariants } from '../text';
export interface CheckboxComposeItemProps extends React.ComponentProps<typeof CheckboxPrimitive.Root> {
title: string;
description?: string;
actionName?: string;
action?: () => void;
image?: string | StaticImageData;
customNode?: React.ReactNode;
}
function CheckboxComposeItem({ title, description, actionName, image, customNode, action, ...props }: CheckboxComposeItemProps) {
return (
<>
<CheckboxPrimitive.Root
data-slot='checkbox'
className={cn(
'border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 aria-invalid:border-destructive group relative flex w-full flex-col justify-center gap-2 rounded-3xl border-2 p-4 outline-none transition-all focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50',
'data-[state=checked]:border-primary',
props.className
)}
{...props}
>
<div className='flex gap-2'>
<div className='flex w-full flex-col gap-2'>
<div className='flex items-center gap-2'>
<div
className={cn(
'border-input flex aspect-square size-6 w-max items-center justify-center rounded-[8px] border',
'group-data-[state=checked]:border-primary group-data-[state=checked]:bg-primary group-data-[state=checked]:text-primary-foreground'
)}
>
<CheckboxPrimitive.Indicator data-slot='checkbox-indicator' className='grid place-content-center transition-all'>
<Icon icon='check' className='size-4' />
</CheckboxPrimitive.Indicator>
</div>
<span className={cn(textVariants({ typography: 'subtitle-2' }))}>{title}</span>
</div>
{description && (
<p className={cn('text-emphasis-low text-left', textVariants({ typography: 'description-2' }))}>{description}</p>
)}
</div>
{image && <Image className='rounded-xl' src={image} alt='title' width={44} height={44} />}
</div>
{actionName && (
<Button className='w-full' variant='secondary' size='sm' onClick={(e) => (e.stopPropagation(), action && action())}>
{actionName}
</Button>
)}
<div>{customNode}</div>
</CheckboxPrimitive.Root>
</>
);
}
export { CheckboxComposeItem };
yarn add radix-ui
Prévia:
Item 2
Sem imagem e sem ação
Item 3
Desabilitado
Checked
Disabled
Com imagem
Com ação
Props:
| Property | Type | Default | Description |
|---|---|---|---|
title | string | - | Título exibido no item. |
description | string | - | Texto descritivo exibido abaixo do título. |
actionName | string | - | Rótulo do botão de ação, exibido quando informado. |
action | () => void | - | Função executada ao clicar no botão de ação. |
image | string | StaticImageData | - | Imagem exibida ao lado do título/descrição. |
customNode | React.ReactNode | - | Conteúdo customizado exibido abaixo do item. |
checked | boolean | - | Controla o estado marcado do checkbox. |
onCheckedChange | (checked: boolean) => void | - | Callback disparado quando o estado marcado muda. |
disabled | boolean | false | Desabilita a interação com o item. |
