Skip to content
Versão preliminar. Cores, componentes e layout ainda vão mudar: falta receber o padrão de interface do TJES (template-basico-vue) e o manual de identidade visual.

BaseModal e BaseConfirmModal ​

BaseModal abre uma janela sobre a tela e prende o foco nela até a pessoa terminar ou fechar. BaseConfirmModal é a confirmação pronta: pergunta o que vai acontecer, pede a justificativa quando o fluxo exige e deixa claro o botão que decide. É o modal das aprovações (devolver medição, cancelar aditivo).

Uso ​

  • Use modal só quando a pessoa precisa decidir ou informar algo antes de seguir. Para avisar, use um aviso; para editar muita coisa, use uma página.
  • O título é uma pergunta ou uma ação com o objeto: "Devolver a medição 29?", não "Atenção" nem "Tem certeza?".
  • A descrição diz o que acontece e com quem: "A medição volta para Paulo Ramos com a sua justificativa."
  • O botão que decide repete o verbo do título: "Devolver medição", nunca "Sim" ou "OK". O botão de voltar vem antes, à esquerda.
  • danger só para o que não tem volta, como excluir. Devolver para correção não é perigoso: use o botão primário e o ícone de atenção.
  • Com danger, a descrição diz com palavras que não dá para desfazer ("Não dá para desfazer."). A cor vermelha sozinha não avisa quem não enxerga cores.
  • Com require-reason, a justificativa é obrigatória e vai junto no evento confirm. O erro só aparece depois que a pessoa tenta confirmar. O modal fica persistente, para um clique fora não apagar o texto.
  • A justificativa é apagada sempre que o modal fecha, então um único BaseConfirmModal reaproveitado numa lista nunca leva o motivo de uma medição para a próxima. Para abrir com um texto pronto, preencha v-model:reason antes de abrir.
  • Se a ação remove o botão que abriu o modal (uma linha da tabela, por exemplo), passe return-focus com o elemento ou o seletor que deve receber o foco, como o título da lista. Sem ele, o foco fica no início da página.
  • Quem abre o modal também fecha: depois de confirm, salve, troque loading e feche com v-model. Assim o botão mostra o progresso enquanto a ação roda.

Fechar pelo fundo ​

Por padrão, clicar no fundo escuro fecha. Use persistent quando o modal tem um formulário que a pessoa perderia por um clique fora. Esc e o botão de fechar continuam funcionando.

Tamanhos ​

Estilo ​

PropriedadeToken
Fundo da tela atrás--tj-overlay
Fundo do modal--tj-layer-01; rodapé --tj-layer-02 com borda --tj-border-subtle-01
Sombra--tj-shadow-3
Raio--tj-radius-lg (12 px)
Título--tj-text-xl, --tj-weight-semibold, --tj-text-primary
Descrição--tj-text-secondary
Ícone--tj-support-warning-text sobre --tj-support-warning-subtle; com danger, --tj-support-error-text sobre --tj-support-error-subtle
Espaçamento--tj-space-6 nas laterais (--tj-space-4 à direita do cabeçalho, por causa do botão de fechar), --tj-space-4 entre cabeçalho e corpo
Corpo com rolagem, em foco--tj-ring por dentro da borda
Entrada--tj-duration-moderate-02 (240 ms) com --tj-easing-standard, como no protótipo; sem animação com movimento reduzido

Código ​

vue
<BaseConfirmModal
  v-model="devolverAberto"
  v-model:reason="justificativa"
  title="Devolver a medição 29?"
  description="A medição volta para Paulo Ramos com a sua justificativa."
  icon="arrow-return-left"
  confirm-label="Devolver medição"
  require-reason
  reason-helper-text="Fica no histórico da medição."
  :loading="salvando"
  @confirm="(motivo) => devolverMedicao(motivo)"
/>

<BaseModal v-model="editarAberto" title="Editar fiscal do contrato" persistent>
  <BaseField label="Fiscal" required><BaseInput v-model="fiscal" /></BaseField>
  <template #footer="{ close }">
    <BaseButton kind="secondary" @click="close">Cancelar</BaseButton>
    <BaseButton @click="salvarFiscal">Salvar fiscal</BaseButton>
  </template>
</BaseModal>

BaseModal

PropriedadeTipoPadrãoDescrição
v-modelbooleanfalseAberto ou fechado
titlestring—Título e nome acessível (obrigatório)
descriptionstring—Linha abaixo do título, lida junto com ele
size'sm' | 'md' | 'lg''md'Largura: 400, 480 ou 720 px
iconstring—Ícone do Bootstrap Icons, sem bi-, ao lado do título
dangerbooleanfalseÍcone em vermelho, para ação sem volta
persistentbooleanfalseClicar no fundo não fecha
loadingbooleanfalseAção em andamento: nada fecha o modal
closeLabelstring'Fechar'Nome do botão de fechar
role'dialog' | 'alertdialog''dialog'alertdialog para confirmações que interrompem o trabalho
returnFocusHTMLElement | string—Recebe o foco ao fechar quando o botão que abriu não existe mais (elemento ou seletor CSS)

Atributos extras, como class e data-testid, vão para o elemento do modal (role="dialog").

Slots: default (corpo) e footer, que recebe close. Eventos: update:modelValue e close (a pessoa fechou pelo Esc, pelo fundo, pelo botão de fechar ou pelo close do rodapé).

BaseConfirmModal

PropriedadeTipoPadrãoDescrição
v-modelbooleanfalseAberto ou fechado
v-model:reasonstring''Texto da justificativa
title, description, size, icon, danger, loading, closeLabel, returnFocusComo no BaseModal
persistentbooleanfalseClicar no fundo não fecha; sempre ligado com requireReason
confirmLabelstring—Verbo e objeto da decisão (obrigatório)
cancelLabelstring'Voltar'Botão que fecha sem decidir
requireReasonbooleanfalsePede a justificativa antes de confirmar
reasonLabelstring'Justificativa'Rótulo do campo
reasonHelperTextstring—Ajuda abaixo do campo
reasonInvalidTextstring'Escreva a justificativa para continuar'Erro quando a pessoa confirma sem escrever
reasonPlaceholderstring—Exemplo dentro do campo

Eventos: confirm, com a justificativa sem espaços nas pontas (vazia quando não há campo); close, quando a pessoa fecha sem decidir (voltar, Esc, fundo ou botão de fechar); update:modelValue e update:reason.

Acessibilidade ​

  • O BaseModal segue o padrão Dialog (Modal) do WAI-ARIA APG: role="dialog", aria-modal="true", aria-labelledby no título e aria-describedby na descrição.
  • O BaseConfirmModal segue o padrão Alert Dialog: role="alertdialog", com a descrição ligada por aria-describedby, para o leitor de tela anunciar a confirmação como urgente.
  • Ao abrir, o foco vai para o elemento marcado com data-autofocus; se não houver, para o primeiro campo do corpo (a justificativa, nas aprovações); depois, para o primeiro botão do rodapé (no BaseConfirmModal, o de voltar; no BaseModal, ponha a ação menos destrutiva primeiro); por fim, para o próprio modal.
  • Tab e Shift+Tab circulam só dentro do modal, seguindo as paradas reais: um grupo de rádios conta uma vez, e o que está oculto ou desativado fica de fora. Se o foco sair do modal (pela barra de endereço, por exemplo), ele volta. Esc fecha, a menos que um menu dentro do modal já tenha usado a tecla para se fechar.
  • Ao fechar, o foco volta para o botão que abriu o modal. Se ele não existe mais, vai para return-focus; sem return-focus, fica no início da página.
  • Quando o corpo tem mais texto do que cabe, ele entra na ordem do Tab como região com o nome do título, para as setas rolarem o texto.
  • A página atrás não rola enquanto o modal está aberto; modais um sobre o outro dividem a mesma trava.
  • Com loading, o botão de confirmar mostra progresso (aria-busy) sem perder o foco, e Esc, o fundo e o botão de fechar esperam a ação terminar. Se o foco estava num botão que fica desativado, ele vai para o próprio modal e não cai para fora.
  • O erro da justificativa tem ícone e texto, não só a borda vermelha, e o foco volta para o campo.
  • A animação de entrada some com prefers-reduced-motion. Em alto contraste do Windows, o modal ganha borda.
  • Todos os estados passam no axe em jsdom. Contraste e rolagem não são medidos ali, porque jsdom não desenha a tela: eles são conferidos nas páginas desta documentação.