De acordo com a Wikipedia , um menu de contexto (também chamado de menu do botão direito) é um menu em uma interface gráfica do usuário (GUI) que aparece na interação do usuário, como uma operação do botão direito do mouse. Um menu de contexto oferece um conjunto limitado de opções que estão disponíveis no estado atual, ou contexto, do sistema operacional ou aplicativo ao qual o menu pertence.

Se você clicar com o botão direito do mouse em seu navegador ao visitar um site, você pode ver o menu de contexto nativo do seu sistema operacional. Você pode salvar, imprimir, criar um código QR para a página e muito mais. Você também deve ver opções diferentes dependendo de onde está clicando na página; se você realçar o texto, poderá ver opções como copiar, colar e recortar.

Você também pode ver alguns menus de contexto personalizados, como aplicativos de e-mail ou lista, e aplicativos de colaboração como Trello e Notion. Esses menus de clique com o botão direito oferecem aos usuários mais opções enquanto usam o aplicativo.

Nesta postagem, exploraremos como você pode criar um menu de clique com o botão direito no React, atalhos para ativar menus de clique com o botão direito, como criar um gancho de menu de contexto personalizado e alguns pacotes se você não quiser implementá-los.

Você pode ver a demonstração do projeto abaixo e verificar o código completo no Github ou no site implantado .

Criando um menu de atalho personalizado

Para criar um menu de atalho, precisamos usar o evento contextmenu ouvinte. Este evento é disparado quando o usuário tenta abrir um menu de contexto. Normalmente, é acionado clicando com o botão direito do mouse ou pressionando o atalho de teclado do menu de contexto.

Criando um atalho de teclado para um menu de contexto

O atalho de teclado para um menu de contexto em O Windows é Shift + F10 . No Mac, você pode usar Ctrl + clique ou botão direito + clique ; não parece haver um atalho apenas de teclado.

Para criar um atalho de teclado para um menu de contexto em um Mac, vá primeiro para Preferências do sistema Acessibilidade Controle de ponteiro Métodos de controle alternativos Ativar ações alternativas do apontador . Para usar o atalho, use F12. Se você não sabe como ver as teclas de função porque seu Mac tem uma barra de toque, verifique este rápido guia .

Construindo um menu de contexto

Para desativar o menu do botão direito padrão, precisamos usar event.preventDefault ():

document.addEventListener (“contextmenu”, (evento)=> {event.preventDefault ()});

A seguir, precisamos capturar as coordenadas xey do clique e mostrar o menu onde o usuário clica na página. Podemos obter as propriedades pageX e pageY do objeto de evento e aplicar coordenadas às propriedades superior e esquerda em CSS:

const [anchorPoint, setAnchorPoint]=useState ({x: 0, y: 0}); document.addEventListener (“contextmenu”, (evento)=> {event.preventDefault () setAnchorPoint ({x: event.pageX, y: event.pageY});});

Estamos usando o gancho useState para gerenciará os pontos de ancoragem e os atualizará quando o usuário clicar com o botão direito do mouse na página.

Personalizando o menu de contexto

Agora, precisamos mostrar o menu do botão direito para o usuário. O valor padrão do menu é falso, portanto, o estaremos ocultando. Quando o usuário clica com o botão direito, defina setShow como true:

const [anchorPoint, setAnchorPoint]=useState ({x: 0, y: 0}); const [mostrar, setShow]=useState (false); document.addEventListener (“contextmenu”, (evento)=> {event.preventDefault () setAnchorPoint ({x: event.pageX, y: event.pageY}); setShow (true);});

Também precisamos usar o gancho useCallback; isso retornará uma versão memoized do callback que só muda se uma das dependências mudou. Isso evita renderizações desnecessárias. O React manterá apenas uma cópia de nossa função.

Para isso, precisamos envolver tudo dentro de uma função useCallback e passar as dependências dentro de um array:

const [anchorPoint, setAnchorPoint]=useState ( {x: 0, y: 0}); const [mostrar, setShow]=useState (false); document.addEventListener (“contextmenu”, useCallback ((event)=> {event.preventDefault (); setAnchorPoint ({x: event.pageX, y: event.pageY}); setShow (true);}, [setAnchorPoint, setShow ]));

Utilizando useEffect

A última coisa a cuidar é o gancho useEffect quando estamos disparando eventos no DOM. Este gancho é usado para efeitos colaterais, incluindo chamadas de API e manipulação de DOM. Quando ouvimos eventos, também precisamos adicionar uma função de limpeza.

Quando executamos o código, ele limpará o estado antigo primeiro e, em seguida, executará o estado atualizado. Isso removerá o comportamento desnecessário e evitará problemas de vazamento de memória.

Podemos fazer isso passando uma função de retorno:

const handleContextMenu=useCallback ((event)=> {event.preventDefault (); setAnchorPoint ({x: event.pageX, y: event.pageY}); setShow (true);}, [setAnchorPoint, setShow]); useEffect (()=> {document.addEventListener (“contextmenu”, handleContextMenu);} return ()=> {document.removeEventListener (“contextmenu”, handleContextMenu);});

Posicionando o menu de contexto

Para mostrar o menu, precisamos alterar as posições superior e esquerda de acordo com suas coordenadas xey. Vamos colocá-los em nosso componente App.js.

Aqui está o código CSS para o menu:

.menu {font-size: 14px; cor de fundo: #fff; raio da borda: 2px; preenchimento: 5px 0 5px 0; largura: 150px; altura: automático; margem: 0;/* usar posicionamento absoluto */posição: absoluto; estilo de lista: nenhum; sombra da caixa: 0 0 20px 0 #ccc; opacidade: 1; transição: opacidade 0,5s linear; }

Para alterar as posições superior e esquerda do menu, atualizaremos dinamicamente sua posição de acordo com onde o usuário clicou na página da web. Para isso, adicione estilo embutido à classe de menu e só mostre o menu quando tivermos show definido como true; caso contrário, não mostre nada:

//função App.js App () {const [anchorPoint, setAnchorPoint]=useState ({x: 0, y: 0}); const [mostrar, setShow]=useState (false); const handleContextMenu=useCallback ((event)=> {event.preventDefault (); setAnchorPoint ({x: event.pageX, y: event.pageY}); setShow (true);}, [setAnchorPoint, setShow]); useEffect (()=> {document.addEventListener (“contextmenu”, handleContextMenu); return ()=> {document.removeEventListener (“contextmenu”, handleContextMenu);};}); return (

Clique com o botão direito em algum lugar da página..

{show? (

  • Compartilhar em..
  • Cortar
  • Copiar
  • Colar

  • Atualizar
  • Sair

): (<> )}

); } exportar aplicativo padrão;

Também precisamos ocultar o menu quando o usuário clica em qualquer item do menu ou tenta clicar fora dele. Para isso, teremos uma verificação condicional: se o menu for mostrado, alterne o estado setShow para false e oculte o menu, caso contrário não faça nada. Esta função só é atualizada sempre que o estado de exibição muda com o gancho useCallback.

Como vimos com o evento contextmenu, estamos novamente lidando com o DOM, desta vez com o evento click.

Adicione isso dentro do gancho useEffect e remova o ouvinte de evento na função de retorno:

const handleClick=useCallback (()=> (show? setShow (false): null), [show]); useEffect (()=> {document.addEventListener (“click”, handleClick); return ()=> {document.removeEventListener (“click”, handleClick);};});

É isso! Aqui está o código completo:

import”./styles.css”; import {useCallback, useEffect, useState} de”react”; função App () {const [anchorPoint, setAnchorPoint]=useState ({x: 0, y: 0}); const [mostrar, setShow]=useState (false);//ocultar menu const handleContextMenu=useCallback ((event)=> {event.preventDefault (); setAnchorPoint ({x: event.pageX, y: event.pageY}); setShow (true);}, [setAnchorPoint]); const handleClick=useCallback (()=> (show? setShow (false): null), [show]); useEffect (()=> {document.addEventListener (“click”, handleClick); document.addEventListener (“contextmenu”, handleContextMenu); return ()=> {document.removeEventListener (“click”, handleClick); document.removeEventListener (“contextmenu”, handleContextMenu);};}); return (

Clique com o botão direito em algum lugar da página..

{show? (

  • Compartilhar em..
  • Cortar
  • Copiar
  • Colar

  • Atualizar
  • Sair

): (<> )}

); } exportar aplicativo padrão;

Criando um gancho de menu de contexto personalizado

Até agora, colocamos todo o nosso código dentro do App.js. No entanto, React é construído em cima de componentes, o que significa que podemos manter nosso código mais modular.

Vamos criar alguns componentes. Para o nosso menu de contexto personalizado, criaremos um gancho personalizado e faremos uso dele dentro do componente Menu. Chamarei o gancho personalizado de useContextMenu.js e retornarei show e anchorPoint a partir dele.

A parte mais importante de nosso gancho personalizado é a instrução return. Aqui, retornamos tudo o que queremos que outro componente tenha acesso. Podemos retornar um array ou um objeto.

Se você retornar um array, podemos nomear os valores retornados como quisermos fora do arquivo. Não precisamos manter o mesmo nome que retornamos:

//useContextMenu.js import {useEffect, useCallback, useState} de”react”; const useContextMenu=()=> {const [anchorPoint, setAnchorPoint]=useState ({x: 0, y: 0}); const [mostrar, setShow]=useState (false); const handleContextMenu=useCallback ((event)=> {event.preventDefault (); setAnchorPoint ({x: event.pageX, y: event.pageY}); setShow (true);}, [setShow, setAnchorPoint]); const handleClick=useCallback (()=> (show? setShow (false): null), [show]); useEffect (()=> {document.addEventListener (“click”, handleClick); document.addEventListener (“contextmenu”, handleContextMenu); return ()=> {document.removeEventListener (“click”, handleClick); document.removeEventListener (“contextmenu”, handleContextMenu);};}); return {anchorPoint, show}; }; export usar como padrão usarContextMenu;

Iremos acessar nosso gancho personalizado dentro do componente Menu e passar o componente Menu dentro do arquivo App.js:

//Menu.js import useContextMenu from”./useContextMenu”; const Menu=()=> {const {anchorPoint, show}=useContextMenu (); if (mostrar) {return (

  • Compartilhar para..
  • Cortar
  • Copiar
  • Colar

  • Atualizar
  • Sair

); } return <> ; }; exportar Menu padrão;

Agora, nosso App.js está renderizando um componente Menu e parece muito mais simples:

//App.js import”./styles.css”; importar Menu de”./Menu”; function App () {return (

Clique com o botão direito em algum lugar da página..

); } exportar aplicativo padrão;

Adicionando ícones Feather ao menu

Finalmente, usei o pacote react-feather para adicionar ícones Feather ao projeto.

Tudo que você precisa é importar o pacote com npm instale o react-feather. Importe-o no topo do seu projeto com import * as Icon from”react-feather”; e acesse os ícones como este:
.

Conclusão e considerações

Existem ainda outras opções se você não deseja implementar você mesmo um menu de contexto personalizado. Um deles é Material UI. Material UI é uma estrutura React UI e permite que você crie diferentes tipos de menus junto com menus de contexto.

Outra opção é o react-menu pacote. Oferece níveis ilimitados de submenus, suporta itens de menu de rádio e caixa de seleção, suporta menus de contexto e segue Práticas de criação WAI-ARIA .

Se você estiver criando seu próprio menu de contexto personalizado, pense na interação móvel. Os usuários podem não conseguir clicar com o botão direito do mouse se estiverem usando um telefone celular. É por isso que você pode precisar pensar duas vezes sobre por que realmente precisa de um menu de contexto personalizado. Isso pode causar algumas experiências ruins se o usuário quiser apenas ver o menu padrão.