CmChoiceCard
Cartão de escolha para quando um rádio ou um checkbox comum não deixa espaço para explicar o que está sendo escolhido. É o bloco de telas de instalação e configuração — tipo de instalação, sistema de arquivos, plano —, em que a diferença entre as opções precisa estar visível na hora de decidir, não escondida num tooltip.
Import
import { CmChoiceCard, CmChoiceCardGroup } from "cosmemilton-ui/client";Escolha única
Cartões soltos com o mesmo name — a escolha única é o rádio nativo, sem estado no React.
Grupo controlado em duas colunas
CmChoiceCardGroup com value/onChange, columns e uma opção desabilitada.
Sistema de arquivos
Formato da partição raiz. Dá para mudar até confirmar a instalação.
Valor no estado:
ext4Seleção múltipla
Com multiple, a seleção volta na ordem das opções — não na ordem dos cliques.
Marque na ordem que quiser: o array volta na ordem das opções, não na dos cliques.
["ferramentas-cli"]
API rápida
Props principais de cada peça exportada.
CmChoiceCard
CmChoiceCardGroup
CmChoiceCardOption
Notas
O estado marcado sai do CSS (:has(:checked)) e nunca de uma classe calculada em JS: com rádios nativos, marcar um cartão DESMARCA os irmãos sem disparar onChange neles — um estado espelhado no React ficaria velho justamente no caso mais comum.
O <input> continua no DOM (apenas visualmente escondido), então teclado, envio em <form> nativo e leitor de tela funcionam sem nada a mais. O anel de foco aparece no cartão inteiro, porque o input está oculto.
multiple troca o rádio por checkbox. No CmChoiceCardGroup o tipo muda junto: value é string | null com onChange(value: string) na escolha única, e string[] com onChange(values: string[]) quando multiple.
No modo múltiplo a seleção volta na ORDEM DAS OPÇÕES, não na ordem dos cliques — quem compara ou serializa a seleção (uma receita de instalação, um filtro salvo) não vê diferença onde não houve mudança.
columns define as colunas do grid e abaixo de 40rem o grupo sempre empilha. O grupo é role="radiogroup" (ou role="group" quando multiple) e usa label como nome acessível; sem label, aponte aria-labelledby.
title fica fora dos atributos da raiz de propósito: o title nativo do HTML é string e intersectaria para string & ReactNode. Aqui o título é conteúdo, não tooltip.