---
fonte: 01-canonicos/seed-componentes.md
versao_da_fonte: v1.43
secao: 54
titulo: "Botão dividido — `estável` (F7.3, 2026-08-16) · BD1–BD9 + MN9 · fecha a dívida A-P1"
sequencia: 60 de 98
bytes_do_corpo: 8112
md5_do_corpo: 078c2a6a509d413f41357cc195fca31f
gerado_por: 06-validacao/geradores/gen-camada-ia.py
nota: fatia GERADA — o corpo abaixo é byte a byte o trecho do canônico; edite o canônico, nunca esta fatia. Canônico inteiro em https://ds.seed.eng.br/01-canonicos/seed-componentes.md
---
## 54. Botão dividido — `estável` (F7.3, 2026-08-16) · BD1–BD9 + MN9 · fecha a dívida A-P1

> **Como esta seção nasceu tarde, e por que isso está escrito.** O botão dividido foi produzido em
> 2026-08-15 como artefato — os códigos `BD1–BD6` e `MN9` viviam **só** no comentário de CSS do
> `banco-navegacao.html`, e nenhum arquivo canônico os mencionava. Foi o inverso exato da ordem que
> este projeto pratica desde o marco v1.2: **decisão escrita → artefato produzido**. A leitura de
> volta da edição v8.4 do MANIFESTO mediu a lacuna (zero ocorrências de `BD1` em qualquer `.md`) e
> abriu a dívida **A-P1**. Ela fecha aqui, e fecha pelo caminho certo: **rito completo de três
> rodadas**, e não transcrição do comentário — reconstruir spec a partir do artefato é reconstrução
> de memória, que este projeto já pagou caro na v7.0. Decisão do Rafael em 2026-08-16: *"pode
> resolver logo de uma vez, vamos evitar jogar as coisas pra frente."*
>
> **Base (3 rodadas encadeadas, 2026-08-16).**
> **R1 canon — o que o padrão É.** A definição é estável e antiga: um botão com dois componentes,
> rótulo e seta, em que clicar no rótulo dispara a ação padrão e clicar na seta abre a lista das
> demais; é um híbrido entre botão e menu, que agrupa comandos relacionados e ainda oferece acesso
> de um clique à escolha padrão. A NN/g é explícita sobre o requisito visual: **a seta que sinaliza
> o menu precisa estar claramente separada do rótulo** — sem essa separação o padrão não é
> reconhecido. Vários sistemas convergem em três regras de uso: as ações do menu têm de pertencer
> **ao mesmo fluxo** da ação padrão; a variante **destrutiva não existe** para o botão dividido, e
> uma ação destrutiva, se houver, aparece **uma só vez e sempre por último** no menu; e quando não
> há ação dominante, o certo é um botão de menu simples, não um dividido — *sem ação dominante não
> há padrão que valha proteger*.
> **R2 mercado/stack — o que o padrão FAZ no teclado.** O comportamento é o do menu button do
> WAI-ARIA, e é o mesmo em React Aria, Radix e nos sistemas de referência: o gatilho leva
> `aria-haspopup`, `aria-expanded` e `aria-controls`; **Seta ↓, Espaço ou Enter abrem o menu e
> movem o foco para o PRIMEIRO item; Seta ↑ abre e vai para o ÚLTIMO**; dentro do menu as setas
> circulam, Home e End vão às pontas, letras navegam por inicial; **Esc fecha e devolve o foco ao
> gatilho**. Com o menu aberto, o gatilho não recebe foco enquanto o usuário percorre os itens.
> **R3 normas e fora do circuito — onde o padrão FALHA.** A crítica prática é dura e entrou como
> contrato: **o botão dividido não é recomendado para toque**, pelo problema do dedo grosso, e
> mesmo no desktop **as duas zonas precisam atender ao tamanho mínimo de alvo**. E há uma
> exigência de aprendizado: o padrão só funciona em aplicação de uso repetido; em fluxo de uma vez
> só, o usuário não percebe o menu secundário.

### 54.1 Os contratos

| # | Contrato | O que ele descarta, e por quê |
|---|---|---|
| **BD1** | **DOIS BOTÕES NATIVOS lado a lado**, dentro de um contêiner que dá a aparência de peça única | Um botão só com duas zonas de clique. *Um clique que faz coisas diferentes conforme ONDE caiu é o oposto de um alvo previsível*, e o leitor de tela não teria como anunciar as duas ações — há um nome acessível por elemento |
| **BD2** | **O fio separador é `border-left` do segundo botão**, nunca pseudo-elemento nem sombra | `background` e `box-shadow` são **descartados em `forced-colors`**, e ali o fio sumiria — junto com a única pista de que existem duas ações. Borda sobrevive |
| **BD3** | **O gatilho tem `min-width:44px`**: é alvo próprio, não apêndice do botão principal | Largura por conteúdo. Com 36px ele mediu **37 × 44** e reprovou o R4 da `suite-render`. *O eixo curto de um alvo pode ser qualquer um dos dois* — lição que o stepper já tinha dado na mesma fase, e que se repetiu quatro vezes |
| **BD4** | **O gatilho é menu button**: `aria-haspopup="menu"`, `aria-expanded` alternando, `aria-controls` apontando para o menu | `aria-expanded` sozinho: sem `aria-haspopup` a tecnologia assistiva não identifica o elemento como abridor de menu |
| **BD5** | **Teclado do WAI-ARIA, inteiro:** ↓/Espaço/Enter abrem e focam o **primeiro** item; ↑ abre e foca o **último**; setas circulam; Home/End vão às pontas; **Esc fecha e devolve o foco ao gatilho** | Implementar só o clique. Metade do padrão de teclado é pior que nenhum: cria expectativa e frustra |
| **BD6** | **A ação do corpo é a MAIS FREQUENTE do conjunto**, e as do menu pertencem ao mesmo fluxo | Usar o dividido quando não há ação dominante — aí o certo é botão de menu simples. Sem dominante não há padrão a proteger |
| **BD7** | **O gatilho NUNCA executa ação** — ele só abre e fecha o menu | Gatilho que dispara a ação padrão *e* abre o menu: torna o resultado do clique imprevisível |
| **BD8** | **Sem variante destrutiva.** Uma ação destrutiva, se existir, aparece **uma vez** no menu e **por último** | Agrupar duas ações destrutivas atrás de um gatilho de 44px |
| **BD9** | **Em contexto de TOQUE e no degrau estreito, o botão dividido COLAPSA**: vira botão de menu único, com a ação padrão como primeiro item | Manter as duas zonas no toque. A norma do alvo continua cumprida, mas duas zonas coladas de 44px convidam ao erro — e o padrão pressupõe uso repetido, que o toque casual não tem |
| **MN9** | **Cabeçalho de seção do menu com ação secundária à direita.** O rótulo nomeia o grupo por `aria-labelledby`; a ação é `<button>` de verdade e fica **FORA da varredura de `menuitem`** | Tratar a ação como opção da lista. Ela não é uma escolha do menu — é atalho para **gerenciar** a lista, e virar `menuitem` faria a contagem de opções mentir |

### 54.2 Anatomia

```
┌──────────────────────┬─────┐
│  Criar ordem         │  ▾  │   ← BD1: dois <button> reais
└──────────────────────┴─────┘
   ação padrão (BD6)     │ └ min-width 44px (BD3)
                         └── border-left 1px (BD2)
```

A **anatomia com BORDA** foi decidida no gate de 2026-08-15: a proposta alternativa (botão sem
contorno) foi medida, apresentada em amostra A/B e **reprovada**. Verbatim do Rafael: *"esse da
foto que mandei está melhor"*. **Não reabrir sem pedido dele.**

### 54.3 Estados e tokens

| Estado | Tratamento |
|---|---|
| Repouso | fundo `action-primary`, tinta `text-on-brand`, raio 8 nas pontas externas |
| Hover | escurecimento por sobreposição, aplicado a **cada metade em separado** — o hover diz qual metade receberá o clique |
| Foco | anel `border-focus` com `outline-offset:2px` e `z-index:1`, para o anel não ser cortado pela metade vizinha |
| Menu aberto | `aria-expanded="true"`, e o *caret* gira 180° |
| Desabilitado | `aria-disabled` nas duas metades; nunca só numa |

### 54.4 Validação

| Guarda | O que prova |
|---|---|
| `suite-navegacao.mjs` | presença estrutural, ARIA do gatilho e a regra do MN9 fora da varredura de `menuitem` |
| `render-*` R4 | as duas metades com **44px nos dois eixos** — foi esta guarda que reprovou o gatilho a 37 × 44 |
| Escala de cinza do preview | o fio sobrevive sem cor; é ele que diz que há duas ações |

### 54.5 Pendências

| # | Pendência | Por que fica aberta |
|---|---|---|
| **BD-P1** | O colapso do BD9 está escrito e **não tem gabarito** | Nenhuma tela do projeto usa botão dividido ainda; o colapso nasce junto com o primeiro uso real, medido |
| **BD-P2** | Navegação por **letra inicial** dentro do menu (parte do BD5) não é exercitada na bancada | A bancada tem três itens curtos; a navegação por inicial só é observável com lista maior |

---

