Turma Card
Em andamentoCartão de uma turma: cidade (ou "Online"), estado da turma, preço em parcelas, previsão, local, horário, modalidade, matrícula e inscrição, aviso de poucas vagas e o indicador de escolha. Dentro de um TurmaCardGroup, é um botão de opção de um grupo de rádio (E69). Recebe os dados de um SisCourseDTO.
- Função
- Cursos e matrícula
- Também chamado de
- turma, cartão de turma, oferta, escolha de turma
- Mora em
- app/components/molecules/TurmaCard.tsx
- Última mudança
- 2026-10-01
Prévia
A peça ao vivo, vinda da ficha, na largura escolhida. Em larguras fixas, ela roda num quadro do tamanho de uma tela de verdade.
Na largura da página: 0px
Variantes na ficha
Lidas da ficha no build, na ordem do palco. Cada uma abre sozinha, sem o styleguide em volta — é o endereço que o palco carrega.
Quando usar
Na página de um curso, lado a lado, para a pessoa comparar as turmas e escolher uma — sempre dentro do `TurmaCardGroup`.
Faça
- Enquanto os dados chegam, mostre o
TurmaCardEsqueleto(E157) — um por cartão esperado, dentro de umEsqueletoGrupo rotulo="Carregando turmas"—, e troque o grupo inteiro pelos cartões quando chegarem. - Ponha os cartões num
TurmaCardGroupcomvalueeonChange: é ele que faz a escolha funcionar pelo teclado e pelo clique. - Troque o
labeldo grupo quando "Escolha a turma" não disser o bastante. - Mande
vagasRestantesdo serviço: sem o dado, o aviso de poucas vagas não aparece (E69.3).
Evite
- Um TurmaCard solto esperando que ele selecione: fora do grupo ele só mostra o estado (
isSelected). - Controle dentro do cartão: o cartão inteiro já é a opção.
Quando não usar. Para o curso em si, no catálogo, use o CourseCard. Para uma linha do tempo de datas, o TimelineItem.
Anatomia
As partes, na ordem em que o olho — e o teclado — passam.
- Destaque — Tag `aviso` "Destaque" no canto, quando a turma é destaque no site.
- Local — Cidade e UF (ou "Online"), com ícone — o começo do nome da opção.
- Estado — Badge (estado do objeto, E64): "Turma confirmada" (`success`, com visto), "Inscrições abertas" (`default`), "Em formação" (`warning`, com alerta) ou o estado cru (`outline`).
- Preço — Parcelas em destaque ("12x R$ …") ou "Consulte valores" — no nome da opção, depois do local e da situação.
- Detalhes — Uma lista de definição (`dl`): Previsão, Local, Horário, Modalidade, Matrícula e Inscrição — rótulo e valor ligados para quem ouve.
- Vagas — "Últimas N vagas!" com 10 ou menos `vagasRestantes`.
- Indicador — Rodapé com o desenho do Button (E127): `tonal` (verde claro) com o anel de seleção e "Escolher esta turma", ou `secondary` (verde cheio) com o visto e "Turma selecionada" — decorativo (`aria-hidden`): o estado vai em `aria-checked`.
Estados
Os estados que a peça tem no código, e o que muda em cada um.
| Estado | O que muda |
|---|---|
| Carregando | O TurmaCardEsqueleto (E157): a mesma superfície e proporção, com as linhas e a imagem em esqueleto, decorativo (aria-hidden); o grupo diz "Carregando turmas" uma vez. Medido na ficha: a mesma largura e menos de 20% de diferença de altura. |
| Não escolhida | Borda --border; rodapé verde claro com o anel de seleção vazio (E127) — antes era cinza com um círculo fino, que parecia desabilitado. |
| Escolhida | Borda --secondary, sombra, rodapé em verde cheio com o visto (E127) — estado por cor e ícone e texto. |
| Foco | O anel de foco no cartão, só no teclado. |
| Poucas vagas | Com vagasRestantes de 1 a 10: "Últimas N vagas!" (ou "Última vaga!") em amarelo escuro. |
| Hover (no grupo) | Borda de controle e sombra maior. |
Comportamento
| Situação | O que acontece |
|---|---|
| Clique num cartão do grupo | Chama onChange com o sigId — conferido no teste da ficha. |
| Vagas | Pelas vagas livres (vagasRestantes), e não pela capacidade: 9 livres de 10 dizem "Últimas 9 vagas!", 2 de 40 dizem "Últimas 2", sem o dado não diz nada — conferido no teste da ficha. |
| Sem cronograma | Usa as informações adicionais de data, se houver. |
| Sem data | "A definir". |
| Matrícula zero | Não mostra a linha de matrícula. |
Relacionados
Como usar no código
A importação e o menor uso, lidos do arquivo. O … marca as props obrigatórias.
import TurmaCard from '@/app/components/molecules/TurmaCard';
<TurmaCard turma={…}>…</TurmaCard>Propriedades
Lidas do código da peça no build — não escritas à mão.
| Prop | Tipo | Padrão | Obrigatória | Descrição |
|---|---|---|---|---|
turma | SisCourseDTO | — | sim | — |
isSelected | boolean | false | não | Fora de um TurmaCardGroup, só mostra o estado. Dentro, quem manda é o grupo. |
Aceita também: Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect'>.
Tokens de cor
Os tokens semânticos que o código da peça usa, com o valor de hoje em app/globals.css.
| Token | Valor | Usado como |
|---|---|---|
--border | #E5E5E5 | border-border |
--border-interactive | #8C8C8C | border-border-interactive |
--card | #FFFFFF | bg-card |
--foreground | #1A1A1A | text-ink |
--muted-foreground | #595959 | text-muted-foreground |
--primary | #D42B2B | text-primary |
--secondary | #0B8434 | border-secondary |
--warning-strong | #945201 | text-warning-strong |
Teclado
| Tecla | Faz |
|---|---|
| Tab | Entra no grupo pela turma escolhida (ou pela primeira) e sai no próximo Tab — uma parada só. Conferido no teste da ficha. |
| →↓←↑ | Vai à turma seguinte ou anterior e a escolhe, dando a volta — conferido no teste da ficha. |
| HomeEnd | Vai à primeira ou à última e a escolhe. |
| EspaçoEnter | Escolhe a turma em foco. |
Leitor de tela
O que é anunciado, e por quê.
- O grupo é
role="radiogroup"("Escolha a turma"); cada cartão,role="radio"comaria-checked— conferido no teste da ficha. Até a E69 o cartão não recebia foco, e a faixa "Selecione…" não selecionava nada. - O nome da opção é o conteúdo do cartão, na ordem de leitura — local, situação, preço, detalhes, vagas e o texto do indicador ("Escolher esta turma" ou "Turma selecionada"), como num rádio nativo com o
<label>em volta. Era só o local e o preço, e o indicador ficava fora: quem usa comando de voz dizia o que via e nada respondia (SC 2.5.3, E140) — testado na ficha, e o axe da ficha roda com a regralabel-content-name-mismatchligada.
O que sustenta o estado
Esta peça usa estatico. O estado dela é o de quem já foi ouvido com leitor de tela nesses padrões — e não uma passada sobre esta peça em específico.
Falta ouvir: estatico — ver docs/a11y-screen-reader-checklist.md.
Status e recursos
| Tipo | Recurso | Status |
|---|---|---|
| Código | app/components/molecules/TurmaCard.tsx | Disponível |
| Ficha | Storybook (abre em outra aba) | Disponível |
| Teste de acessibilidade | axe em npm run test | No gate de todo commit |
| Leitor de tela | Passada da E33 | Falta ouvir |
| Design | Figma | Desativado até a Fase 2 |
Histórico
Os últimos commits que tocaram o arquivo, lidos do git no build.
bf159c02026-10-01E161b: os dois testes que o CI do PR #15 reprovou no Linux251416b2026-10-01E159: Testimonials — o vídeo toca dentro do cartão, YouTube e Vimeo
O histórico completo está no GitHub (abre em outra aba).