Makuco UI
ComponentesNavigation

Menu

Superfície de menu dropdown (`mk-menu`, `mk-menu-item`, `mk-menu-group`, `mk-menu-header`, `mk-menu-divider`, `mk-menu-trigger`) ancorada a um gatilho externo por id.

O mk-menu é a superfície de menu dropdown do Makuco. Ele se ancora a um gatilho externo pelo id (prop anchor) — o gatilho pode ser qualquer elemento (mk-menu-trigger, mk-button, mk-icon-button ou um <button> nativo). O menu injeta aria-haspopup, aria-expanded e aria-controls no gatilho e anexa os listeners, sem envolvê-lo em um wrapper. Compõe-se de mk-menu (painel), mk-menu-item (item com título e descrição), mk-menu-header (caption de seção), mk-menu-divider (separador) e mk-menu-trigger (pill de conveniência).

Padrão

O mk-menu-trigger recebe um id e o mk-menu aponta para ele via anchor.

import { MkMenu, MkMenuItem, MkMenuTrigger } from '@db1/makuco-ui-react';

<MkMenuTrigger id="menu-default" label="Menu item" />
<MkMenu anchor="menu-default" onMkSelect={(e) => console.log(e.detail.value)}>
  <MkMenuItem value="overview" label="Overview" description="Start here for a quick tour" />
  <MkMenuItem value="features" label="Features" description="See everything we offer" />
  <MkMenuItem value="changelog" label="Changelog" description="Latest updates and releases" />
</MkMenu>
<mk-menu-trigger id="menu-default" label="Menu item"></mk-menu-trigger>
<mk-menu anchor="menu-default" (mkSelect)="onSelect($event)">
  <mk-menu-item value="overview" label="Overview" description="Start here for a quick tour"></mk-menu-item>
  <mk-menu-item value="features" label="Features" description="See everything we offer"></mk-menu-item>
  <mk-menu-item value="changelog" label="Changelog" description="Latest updates and releases"></mk-menu-item>
</mk-menu>

Gatilho customizado

A customização é realmente necessária?

Utilize somente com gatilhos customizados quando não for possível usar mk-menu-trigger. O mk-menu-trigger já implementa o comportamento de acessibilidade e foco esperado, além de fornecer um pill estilizado pronto para uso.

Qualquer elemento com um id pode ser o gatilho. O menu não precisa de mk-menu-trigger — um mk-button, um <button> nativo ou qualquer outro elemento funcionam igualmente, pois o mk-menu injeta aria-haspopup, aria-expanded, aria-controls e os listeners diretamente nele.

import { MkMenu, MkMenuItem, MkButton } from '@db1/makuco-ui-react';

<MkButton id="menu-actions" variant="outlined">Ações</MkButton>
<MkMenu anchor="menu-actions">
  <MkMenuItem value="edit" label="Editar" />
  <MkMenuItem value="copy" label="Copiar" />
</MkMenu>
<mk-button id="menu-actions" variant="outlined">Ações</mk-button>
<mk-menu anchor="menu-actions">
  <mk-menu-item value="edit" label="Editar"></mk-menu-item>
  <mk-menu-item value="copy" label="Copiar"></mk-menu-item>
</mk-menu>

Também funciona com um <button> HTML puro, sem nenhum componente Makuco:

import { MkMenu, MkMenuItem } from '@db1/makuco-ui-react';

<button id="menu-native">Ações</button>
<MkMenu anchor="menu-native">
  <MkMenuItem value="edit" label="Editar" />
  <MkMenuItem value="copy" label="Copiar" />
</MkMenu>
<button id="menu-native">Ações</button>
<mk-menu anchor="menu-native">
  <mk-menu-item value="edit" label="Editar"></mk-menu-item>
  <mk-menu-item value="copy" label="Copiar"></mk-menu-item>
</mk-menu>

Ícones e descrição

Use icon para um ícone leading e description para um texto secundário abaixo do título.

import { MkMenu, MkMenuItem, MkMenuTrigger } from '@db1/makuco-ui-react';

<MkMenuTrigger id="menu-icons" label="Ações" />
<MkMenu anchor="menu-icons">
  <MkMenuItem value="edit" icon="pencil" label="Editar" description="Altere o conteúdo" />
  <MkMenuItem value="copy" icon="copy" label="Copiar" description="Duplique o item" />
  <MkMenuItem value="share" icon="share-2" label="Compartilhar" description="Envie um link" />
</MkMenu>
<mk-menu-trigger id="menu-icons" label="Ações"></mk-menu-trigger>
<mk-menu anchor="menu-icons">
  <mk-menu-item
    value="edit"
    icon="pencil"
    label="Editar"
    description="Altere o conteúdo"
  ></mk-menu-item>
  <mk-menu-item
    value="copy"
    icon="copy"
    label="Copiar"
    description="Duplique o item"
  ></mk-menu-item>
  <mk-menu-item
    value="share"
    icon="share-2"
    label="Compartilhar"
    description="Envie um link"
  ></mk-menu-item>
</mk-menu>

Cabeçalho e separador

Use mk-menu-header para rotular uma seção (caption + divisor sutil abaixo) e mk-menu-divider para um separador autônomo entre grupos.

import { MkMenu, MkMenuItem, MkMenuHeader, MkMenuDivider, MkMenuTrigger } from '@db1/makuco-ui-react';

<MkMenuTrigger id="menu-header" label="Navegação" />
<MkMenu anchor="menu-header">
  <MkMenuHeader label="Navigation" />
  <MkMenuItem value="overview" label="Overview" description="Start here for a quick tour" />
  <MkMenuItem value="features" label="Features" description="See everything we offer" />
  <MkMenuDivider />
  <MkMenuItem value="changelog" label="Changelog" description="Latest updates and releases" />
</MkMenu>
<mk-menu-trigger id="menu-header" label="Navegação"></mk-menu-trigger>
<mk-menu anchor="menu-header">
  <mk-menu-header label="Navigation"></mk-menu-header>
  <mk-menu-item value="overview" label="Overview" description="Start here for a quick tour"></mk-menu-item>
  <mk-menu-item value="features" label="Features" description="See everything we offer"></mk-menu-item>
  <mk-menu-divider></mk-menu-divider>
  <mk-menu-item value="changelog" label="Changelog" description="Latest updates and releases"></mk-menu-item>
</mk-menu>

Agrupamento

mk-menu-group agrupa itens num role="group" com nome acessível (label). É só semântica: não há rótulo visível, divisor nem mudança de layout, e os itens do grupo continuam na navegação por teclado do menu. Use para nomear um conjunto de itens; para um título visível entre seções, use mk-menu-header.

<MkMenu anchor="menu-grouped">
  <MkMenuItem value="open" label="Abrir" />
  <MkMenuGroup label="Exportar">
    <MkMenuItem value="pdf" label="PDF" />
    <MkMenuItem value="csv" label="CSV" />
  </MkMenuGroup>
</MkMenu>
<mk-menu anchor="menu-grouped">
  <mk-menu-item value="open" label="Abrir"></mk-menu-item>
  <mk-menu-group label="Exportar">
    <mk-menu-item value="pdf" label="PDF"></mk-menu-item>
    <mk-menu-item value="csv" label="CSV"></mk-menu-item>
  </mk-menu-group>
</mk-menu>

Seleção

selectionMode no mk-menu define como os itens marcam uma escolha: "none" (padrão) mantém o comportamento de ação; "single" faz dos itens opções excludentes (menuitemradio); "multiple" faz deles opções independentes (menuitemcheckbox). O menu repassa o modo aos itens, e o item marcado mostra um tique à direita, no lugar do chevron, com a largura sempre reservada, de modo que o texto não se desloca.

O estado marcado é a prop selected do item e fica com quem usa o menu: alterne selected no evento mkSelect. O menu não marca nem desmarca sozinho. Com selectionMode="multiple" o menu não fecha ao selecionar, independentemente de closeOnSelect, e o foco permanece no item ativado. Em single e none, closeOnSelect vale como sempre. Itens com triggerFor (submenu) não participam da seleção.

Envolva as opções em mk-menu-group com label: o padrão ARIA pede que os itens menuitemradio fiquem num grupo com nome.

const [visible, setVisible] = useState(['name', 'role']);
const toggle = (value: string) =>
  setVisible((current) =>
    current.includes(value) ? current.filter((v) => v !== value) : [...current, value]);

<MkMenuTrigger id="menu-columns" label="Colunas" />
<MkMenu anchor="menu-columns" selectionMode="multiple" onMkSelect={(e) => toggle(e.detail.value)}>
  <MkMenuGroup label="Colunas visíveis">
    <MkMenuItem value="name" label="Nome" selected={visible.includes('name')} />
    <MkMenuItem value="role" label="Cargo" selected={visible.includes('role')} />
    <MkMenuItem value="status" label="Status" selected={visible.includes('status')} />
  </MkMenuGroup>
</MkMenu>
<mk-menu-trigger id="menu-columns" label="Colunas"></mk-menu-trigger>
<mk-menu anchor="menu-columns" selectionMode="multiple" (mkSelect)="toggle($event.detail.value)">
  <mk-menu-group label="Colunas visíveis">
    <mk-menu-item value="name" label="Nome" [selected]="visible.includes('name')"></mk-menu-item>
    <mk-menu-item value="role" label="Cargo" [selected]="visible.includes('role')"></mk-menu-item>
    <mk-menu-item value="status" label="Status" [selected]="visible.includes('status')"></mk-menu-item>
  </mk-menu-group>
</mk-menu>

Tamanhos

O painel tem três larguras: sm (200px), md (280px, padrão) e lg (360px).

import { MkMenu, MkMenuItem, MkMenuTrigger } from '@db1/makuco-ui-react';

<MkMenuTrigger id="menu-sm" label="sm" />
<MkMenu anchor="menu-sm" size="sm">
  <MkMenuItem value="edit" label="Editar" />
  <MkMenuItem value="copy" label="Copiar" />
</MkMenu>

<MkMenuTrigger id="menu-md" label="md" />
<MkMenu anchor="menu-md" size="md">
  <MkMenuItem value="edit" label="Editar" />
  <MkMenuItem value="copy" label="Copiar" />
</MkMenu>

<MkMenuTrigger id="menu-lg" label="lg" />
<MkMenu anchor="menu-lg" size="lg">
  <MkMenuItem value="edit" label="Editar" />
  <MkMenuItem value="copy" label="Copiar" />
</MkMenu>
<mk-menu-trigger id="menu-sm" label="sm"></mk-menu-trigger>
<mk-menu anchor="menu-sm" size="sm">
  <mk-menu-item value="edit" label="Editar"></mk-menu-item>
  <mk-menu-item value="copy" label="Copiar"></mk-menu-item>
</mk-menu>

<mk-menu-trigger id="menu-md" label="md"></mk-menu-trigger>
<mk-menu anchor="menu-md" size="md">
  <mk-menu-item value="edit" label="Editar"></mk-menu-item>
  <mk-menu-item value="copy" label="Copiar"></mk-menu-item>
</mk-menu>

<mk-menu-trigger id="menu-lg" label="lg"></mk-menu-trigger>
<mk-menu anchor="menu-lg" size="lg">
  <mk-menu-item value="edit" label="Editar"></mk-menu-item>
  <mk-menu-item value="copy" label="Copiar"></mk-menu-item>
</mk-menu>

Intenção do item

kind aceita default, error, success, warning, info e brand. Use error para ações destrutivas/irreversíveis. O valor danger é um alias de error mantido por compatibilidade e será removido em uma versão futura.

import { MkMenu, MkMenuItem, MkMenuDivider, MkMenuTrigger } from '@db1/makuco-ui-react';

<MkMenuTrigger id="menu-kinds" label="Mais opções" />
<MkMenu anchor="menu-kinds">
  <MkMenuItem value="edit" icon="pencil" label="Editar" />
  <MkMenuItem value="approve" icon="circle-check" label="Aprovar" kind="success" />
  <MkMenuItem value="review" icon="triangle-alert" label="Revisar" kind="warning" />
  <MkMenuItem value="details" icon="info" label="Ver detalhes" kind="info" />
  <MkMenuItem value="upgrade" icon="sparkles" label="Fazer upgrade" kind="brand" />
  <MkMenuDivider />
  <MkMenuItem value="delete" icon="trash-2" kind="error" label="Excluir permanentemente" />
</MkMenu>
<mk-menu-trigger id="menu-kinds" label="Mais opções"></mk-menu-trigger>
<mk-menu anchor="menu-kinds">
  <mk-menu-item value="edit" icon="pencil" label="Editar"></mk-menu-item>
  <mk-menu-item value="approve" icon="circle-check" label="Aprovar" kind="success"></mk-menu-item>
  <mk-menu-item value="review" icon="triangle-alert" label="Revisar" kind="warning"></mk-menu-item>
  <mk-menu-item value="details" icon="info" label="Ver detalhes" kind="info"></mk-menu-item>
  <mk-menu-item value="upgrade" icon="sparkles" label="Fazer upgrade" kind="brand"></mk-menu-item>
  <mk-menu-divider></mk-menu-divider>
  <mk-menu-item
    value="delete"
    icon="trash-2"
    kind="error"
    label="Excluir permanentemente"
  ></mk-menu-item>
</mk-menu>

Abertura por hover

Defina open-on="hover" para abrir ao passar o mouse. Há uma ponte de intenção entre gatilho e painel para evitar fechamentos acidentais; em dispositivos sem hover a interação degrada para clique, e o teclado sempre abre o menu.

import { MkMenu, MkMenuItem, MkMenuTrigger } from '@db1/makuco-ui-react';

<MkMenuTrigger id="menu-hover" label="Passe o mouse" />
<MkMenu anchor="menu-hover" openOn="hover">
  <MkMenuItem value="edit" label="Editar" description="Altere o conteúdo" />
  <MkMenuItem value="copy" label="Copiar" description="Duplique o item" />
</MkMenu>
<mk-menu-trigger id="menu-hover" label="Passe o mouse"></mk-menu-trigger>
<mk-menu anchor="menu-hover" open-on="hover">
  <mk-menu-item value="edit" label="Editar" description="Altere o conteúdo"></mk-menu-item>
  <mk-menu-item value="copy" label="Copiar" description="Duplique o item"></mk-menu-item>
</mk-menu>

Aponte um mk-menu-item para outro mk-menu com trigger-for (id). O item exibe um chevron à direita e abre o submenu ao ser ativado ou com ArrowRight.

import { MkMenu, MkMenuItem, MkMenuDivider, MkMenuTrigger } from '@db1/makuco-ui-react';

<MkMenuTrigger id="menu-sub" label="Ações" />
<MkMenu anchor="menu-sub">
  <MkMenuItem value="edit" label="Editar" icon="pencil" />
  <MkMenuItem value="copy" label="Copiar" icon="copy" />
  <MkMenuItem label="Mover para" icon="folder-open" triggerFor="submenu-move" />
  <MkMenuDivider />
  <MkMenuItem value="delete" label="Excluir" icon="trash-2" kind="error" />
</MkMenu>

<MkMenu id="submenu-move" size="sm" placement="right">
  <MkMenuItem value="folder-a" label="Pasta A" icon="folder" />
  <MkMenuItem value="folder-b" label="Pasta B" icon="folder" />
</MkMenu>
<mk-menu-trigger id="menu-sub" label="Ações"></mk-menu-trigger>
<mk-menu anchor="menu-sub">
  <mk-menu-item value="edit" label="Editar" icon="pencil"></mk-menu-item>
  <mk-menu-item value="copy" label="Copiar" icon="copy"></mk-menu-item>
  <mk-menu-item label="Mover para" icon="folder-open" trigger-for="submenu-move"></mk-menu-item>
  <mk-menu-divider></mk-menu-divider>
  <mk-menu-item value="delete" label="Excluir" icon="trash-2" kind="error"></mk-menu-item>
</mk-menu>

<mk-menu id="submenu-move" size="sm" placement="right">
  <mk-menu-item value="folder-a" label="Pasta A" icon="folder"></mk-menu-item>
  <mk-menu-item value="folder-b" label="Pasta B" icon="folder"></mk-menu-item>
</mk-menu>

Defina href em mk-menu-item para renderizar como <a>.

import { MkMenu, MkMenuItem, MkMenuTrigger } from '@db1/makuco-ui-react';

<MkMenuTrigger id="menu-link" label="Navegar" />
<MkMenu anchor="menu-link">
  <MkMenuItem value="home" icon="house" label="Início" href="#home" />
  <MkMenuItem value="docs" icon="book-open" label="Documentação" href="/docs" />
  <MkMenuItem value="settings" icon="settings" label="Configurações" href="#settings" />
</MkMenu>
<mk-menu-trigger id="menu-link" label="Navegar"></mk-menu-trigger>
<mk-menu anchor="menu-link">
  <mk-menu-item value="home" icon="house" label="Início" href="#home"></mk-menu-item>
  <mk-menu-item value="docs" icon="book-open" label="Documentação" href="/docs"></mk-menu-item>
  <mk-menu-item value="settings" icon="settings" label="Configurações" href="#settings"></mk-menu-item>
</mk-menu>

Props — mk-menu

PropTipoPadrãoDescrição
anchorstring—

Id do elemento gatilho. Resolvido via getRootNode(), funcionando dentro de shadow roots.

openbooleanfalseControla a visibilidade. Refletido como atributo; ativa o modo controlado.
openOn"click" | "hover""click"Gatilho de abertura. Em hover, degrada para clique em telas sem hover.
size"sm" | "md" | "lg""md"Largura do painel: 200 / 280 / 360 px.
placement"bottom-start" | "bottom-end" | "top-start" | "top-end" | "left" | "right""bottom-start"Posicionamento do painel em relação ao gatilho.
selectionMode"none" | "single" | "multiple""none"Modo de seleção dos itens. "single" e "multiple" fazem dos itens menuitemradio e menuitemcheckbox, com tique à direita no item selected. Com "multiple" o menu não fecha ao selecionar.
closeOnSelectbooleantrueFecha o menu ao selecionar um item.
disabledbooleanfalseImpede a abertura do menu.

Props — mk-menu-item

PropTipoPadrãoDescrição
valuestring—Valor emitido em mkClick e no mkSelect do menu pai.
labelstring—Título do item. Alternativa ao slot padrão.
descriptionstring—Texto secundário exibido abaixo do título.
iconIconName—Ícone leading.
kind"default" | "error" | "success" | "warning" | "info" | "brand" | "danger""default"

Intenção visual. Use "error" para ações destrutivas/irreversíveis. "danger" é um alias de "error" mantido por compatibilidade e será removido em uma versão futura.

hrefstring—Quando preenchido, renderiza o item como <a>.
selectedbooleanfalseMarca o item como selecionado visualmente. Fora de um mk-menu com selectionMode, vira aria-current="true"; dentro de um, é o estado marcado (aria-checked, com tique à direita), controlado por quem usa o menu.
disabledbooleanfalseDesabilita o item.
triggerForstring—Id de um mk-menu aberto como submenu. Exibe um chevron à direita.

Props — mk-menu-trigger

PropTipoPadrãoDescrição
labelstring—Texto do gatilho. Alternativa ao slot padrão.
selectedbooleanfalseRefletido pelo mk-menu quando aberto — gira o chevron.
disabledbooleanfalseDesabilita o gatilho, impedindo a abertura.

Props — mk-menu-group

PropTipoPadrãoDescrição
labelstring—Nome acessível do grupo (aria-label). Recomendado: sem ele o grupo é anunciado sem nome.

Props — mk-menu-header

PropTipoPadrãoDescrição
labelstring—Rótulo da seção (caption). Alternativa ao slot padrão.

Eventos

EventoComponentePayloadDescrição
mkOpenmk-menuvoidEmitido quando o menu abre.
mkClosemk-menuvoidEmitido quando o menu fecha.
mkSelectmk-menu{ value: string }Emitido quando um item é selecionado.
mkClickmk-menu-item{ value: string }Emitido quando o item é ativado diretamente.

Slots

ComponenteSlotDescrição
mk-menu(default)Itens do menu: mk-menu-item, mk-menu-group, mk-menu-header, mk-menu-divider.
mk-menu-group(default)Itens (mk-menu-item) do grupo.
mk-menu-item(default)Conteúdo do título quando label não é fornecido.
mk-menu-header(default)Conteúdo do rótulo quando label não é fornecido.
mk-menu-trigger(default)Conteúdo do gatilho quando label não é fornecido.

Acessibilidade

  • O painel tem role="menu"; cada item tem role="menuitem" e aria-disabled quando desabilitado.
  • mk-menu-divider usa role="separator".
  • mk-menu-group usa role="group", com o nome vindo de label (aria-label).
  • Com selectionMode single ou multiple, os itens usam role="menuitemradio" ou "menuitemcheckbox" com aria-checked; fora da seleção, o item com selected usa aria-current="true". O tique é decorativo (aria-hidden), e o estado marcado é anunciado por aria-checked.
  • O gatilho recebe aria-haspopup="menu", aria-controls e aria-expanded automaticamente, sincronizados com o estado aberto.
  • O foco real fica no item atual; ao fechar, retorna ao gatilho.
  • Com o foco no gatilho e o menu aberto, setas, Home, End, Escape e Tab seguem a navegação do menu.
  • O teclado sempre abre o menu, mesmo com open-on="hover".
TeclaComportamento
Enter / SpaceNo gatilho, abre o menu e leva o foco ao primeiro item. No item em foco, ativa o item.
ArrowDown / ArrowUpNavega entre os itens habilitados. No gatilho com o menu fechado, ArrowDown abre no primeiro item e ArrowUp no último.
ArrowRightAbre o submenu do item em foco (quando há trigger-for).
Home / EndMove o foco para o primeiro/último item.
EscapeFecha o menu e devolve o foco ao gatilho.
TabFecha o menu e segue o fluxo de foco normal.
Caractere

Typeahead: move o foco para o próximo item cujo título começa com o caractere digitado.

On this page