Loading
Indicador giratório para estados pendentes. Herda a cor de texto atual, então se adapta a qualquer superfície. O Button já o renderiza pela prop loading, então você só precisa usá-lo diretamente fora de botões.
Exemplos
Básico
Tamanhos e cores
Use size para a largura e a altura em pixels e uma classe de cor de texto para mudar a cor do traço.
Com status acessível
Por padrão o spinner é decorativo: sai com aria-hidden="true" e os leitores de tela o ignoram. Quando ele é o único feedback na tela, envolva-o num elemento com role="status" e um texto de label (visível ou oculto com sr-only).
Carregando aulas…
Com nome acessível
Para o spinner ter nome próprio, passe aria-label: ele deixa de ter aria-hidden e recebe role="img", com o rótulo como nome. Isso não anuncia a mudança de estado; para anunciar, continue usando role="status".
API
| Propriedade | Tipo | Padrão | Descrição |
|---|---|---|---|
| size | number | 24 | Largura e altura do spinner, em pixels. |
| className | string | - | Mesclado com o animate-spin embutido. Use uma classe de cor de texto para mudar a cor do traço. |
| aria-label | string | - | Nome acessível do spinner. Sem ele, o spinner é decorativo (aria-hidden="true"); com ele, recebe role="img" e é lido com esse nome. |
| ...props | Todas as props nativas de svg, exceto width e height | - | Repassadas ao svg (ex.: style, data-*). O tamanho vem só da prop size. |
Diretrizes de uso
- Dentro de botões, use a prop
loadingdoButtonem vez de colocar oLoadingmanualmente. - Acompanhe o spinner de um texto visível ou visualmente oculto dentro de um elemento com
role="status", para que leitores de tela anunciem o estado pendente. - Para placeholders de conteúdo com formato conhecido, prefira o
Skeleton.
Loading com a marca
Para esperas que bloqueiam a tela inteira (gerar um cronograma, salvar uma prova), use o LoadingOverlay, que segue o Loading do Figma: um anel de 72px que dá uma volta a cada 1,6s, o "m" da Medway no centro, pulsando, e o texto "Carregando...". O icon troca o "m" por outro ícone, e icon={null} deixa só o anel. São três peças, com os mesmos nomes, props e valores padrão do @medway-ui/native (só muda o que é de plataforma: o label daqui é o accessibilityLabel do app, e o modalProps existe só lá): LoadingOverlaySpinner (só o anel), LoadingOverlayCard (anel e textos num card) e LoadingOverlay (o card sobre um fundo que cobre a tela). Com prefers-reduced-motion, o anel e o ícone ficam parados.
Spinner
Sozinho, o LoadingOverlaySpinner é decorativo e fica fora da árvore de acessibilidade. Quando ele for o único sinal de carregamento na tela, passe aria-label para o leitor de tela encontrá-lo como uma imagem com esse nome (ou use o LoadingOverlayCard, que já anuncia o carregamento).
Card
O anel e os textos ficam dentro de um role="status", então o leitor de tela anuncia o carregamento. O que vai em children (como um botão de cancelar) fica fora dele e continua focável. Com text={null} o rótulo some da tela, mas o leitor de tela ainda ouve "Carregando" (ou o label, se houver). Quando o text não for uma string (por exemplo, com um trecho em negrito), passe label com o texto corrido para dar nome ao status e, no LoadingOverlay, ao diálogo. Dentro do LoadingOverlay, o card não usa o role="status": o carregamento é anunciado só pelo nome do diálogo, para o leitor de tela não ler o mesmo texto duas vezes.
Overlay
O LoadingOverlay abre o card no centro da tela, sobre o fundo backdrop. Enquanto ele está visível, o conteúdo por trás fica bloqueado para o mouse, para o teclado e para o leitor de tela, e o Escape não fecha: ele só chama onRequestClose, para você decidir o que fazer. Controle a visibilidade com visible. Ao fechar, o foco volta para o elemento que estava focado quando o overlay abriu.
API do LoadingOverlaySpinner
| Propriedade | Tipo | Padrão | Descrição |
|---|---|---|---|
| icon | React.ReactNode | "m" da Medway | Ícone no centro do anel (ex.: de @medway-ui/icons). Sem a prop, mostra o "m" da Medway; null deixa só o anel. |
| size | number | 72 | Diâmetro do anel, em pixels. |
| trackWidth | number | 2.16 | Espessura do traço, em pixels. |
| colorToken | string | "gray-stroke" | Token de cor do arco, sem o prefixo --color-. |
| color | string | - | Cor CSS do arco. Tem prioridade sobre colorToken. |
| pulse | boolean | true | Faz o ícone do centro pulsar, de 20% a 100% de opacidade a cada 400ms. |
| ...props | React.ComponentProps<"div"> | - | Repassadas ao div que envolve o anel (ex.: className). Com aria-label ou aria-labelledby, o spinner ganha role="img"; sem eles, fica com aria-hidden. |
API do LoadingOverlayCard
Aceita todas as props do LoadingOverlaySpinner (exceto as de div, que vão para o card) e mais:
| Propriedade | Tipo | Padrão | Descrição |
|---|---|---|---|
| text | React.ReactNode | "Carregando..." | Rótulo principal. null ou "" esconde o rótulo da tela. |
| description | React.ReactNode | - | Texto secundário abaixo do rótulo. |
| label | string | - | Nome acessível do carregamento, equivalente ao accessibilityLabel do native. No LoadingOverlayCard usado sozinho, vira o nome do role="status"; no LoadingOverlay, vira o título do diálogo, que é o único anúncio. Sem ele, o título junta text e description quando são strings e cai em "Carregando". |
| children | React.ReactNode | - | Conteúdo abaixo dos textos, fora do status (ex.: um botão de cancelar). |
| textClassName | string | - | Classes do rótulo. |
| descriptionClassName | string | - | Classes da descrição. |
| ...props | React.ComponentProps<"div"> | - | Repassadas ao card (ex.: className). |
API do LoadingOverlay
Aceita todas as props do LoadingOverlayCard e mais:
| Propriedade | Tipo | Padrão | Descrição |
|---|---|---|---|
| visible | boolean | true | Mostra ou esconde o overlay. |
| onRequestClose | () => void | - | Chamada no Escape. O overlay não fecha sozinho; quem decide é você, pelo visible. |
| overlayColorToken | string | "backdrop" | Token de cor do fundo, sem o prefixo --color-. |
| overlayClassName | string | - | Classes do fundo. Para mudar a cor, use overlayColorToken. |
| containerClassName | string | - | Classes do invólucro que limita a largura do card (w-[90%] max-w-[320px]). |