VsDropdownCustom

src/components/vs-dropdown/ (dropdown.vue · dropdown-menu.vue · dropdown-item.vue)
Navigation Medium 84 usos

Grupo de 3 componentes que reimplementam e estendem o vs-dropdown do Vuesax com posicionamento dinâmico inteligente (detecta espaço disponível acima/abaixo e ajusta a posição), suporte a vsCustomContent (conteúdo livre no menu sem lista ul), trigger por click ou hover, suporte a contextmenu, alinhamento esquerda/direita, e fix de comportamento em iPhone/iOS. É o dropdown mais usado no admin (84 arquivos).

Trigger por Click (com vs-dropdown-item)

Padrão com vs-trigger-click — abre e fecha por click, não hover. Usa vs-dropdown-item para listar opções. Cada item fecha o dropdown automaticamente ao ser clicado. Usado no seletor de cor de tag de cliente.

Trigger (fechado)
Menu aberto (abaixo)
Vermelho
Verde
Azul
Laranja
Real src/components/group-of-customer/Tag.vue:3
<vs-dropdown vs-trigger-click class="cursor-pointer">
  <div class="d-flex">
    <vs-icon
      v-for="(color, index) in takeTwoColors"
      :key="index"
      :color="color"
      icon="label"
    />
  </div>

  <vs-dropdown-menu>
    <vs-dropdown-item v-for="(group, index) in groups" :key="index">
      <vs-icon icon="label" :color="group.color_tag" />
      <div class="group-name ml-4">{{ group.name }}</div>
    </vs-dropdown-item>
  </vs-dropdown-menu>
</vs-dropdown>

Conteúdo Customizado (avatar trigger)

vs-custom-content + vs-trigger-click — o menu contém HTML livre (ul/li próprio) em vez de vs-dropdown-item. Padrão dominante no admin para dropdowns complexos (user menu, notificações). O menu é inserido no document.body para evitar overflow:hidden do pai.

Trigger (avatar)
D
Daniel A.
admin
Menu aberto (vsCustomContent)
D

Configurações
Logout
Real src/layouts/components/navbar/components/UserDropDown.vue:2
<vs-dropdown
  vs-custom-content
  vs-trigger-click
  class="user-dropdown-component cursor-pointer"
>
  <div class="con-img">
    <img
      :src="activeUserInfo.image"
      alt="user-img"
      width="40"
      height="40"
      class="rounded-full shadow-md cursor-pointer block"
    />
  </div>

  <vs-dropdown-menu class="vx-navbar-dropdown">
    <ul style="min-width: 9rem">
      <li
        class="flex py-2 px-4 cursor-pointer hover:bg-primary hover:text-white"
        @click="$router.push('/user-settings').catch(() => {})"
      >
        <feather-icon icon="UserIcon" svgClasses="w-4 h-4" />
        <span class="ml-2">Configurações</span>
      </li>
      <vs-divider class="m-1" />
      <li
        class="flex py-2 px-4 cursor-pointer hover:bg-primary hover:text-white"
        @click="logout"
      >
        <feather-icon icon="LogOutIcon" svgClasses="w-4 h-4" />
        <span class="ml-2">Logout</span>
      </li>
    </ul>
  </vs-dropdown-menu>
</vs-dropdown>

Conteúdo Rico com Scroll (Notificações)

vs-custom-content com VuePerfectScrollbar dentro do menu — padrão do dropdown de notificações. O menu pode ter header colorido, lista com scroll e rodapé fixo. O trigger é um feather-icon com badge de contagem.

Trigger (ícone + badge)
3
Menu aberto (com scroll)

Notificações

3 não lidas

Novo pedido recebido — Farmácia Central
há 5 minutos
Tempo de espera alto — Fila de atendimento
há 12 minutos
Integração ativa — WhatsApp conectado
há 1 hora
Real src/layouts/components/navbar/components/NotificationDropDown.vue:6
<vs-dropdown
  vs-custom-content
  vs-trigger-click
  class="cursor-pointer"
>
  <feather-icon
    icon="BellIcon"
    class="cursor-pointer"
    :badge="unreadNotificationsBadge"
  />

  <vs-dropdown-menu class="notification-dropdown dropdown-custom vx-navbar-dropdown">
    <div class="notification-top text-center p-5 bg-primary text-white">
      <h3 class="text-white">Notificações</h3>
    </div>

    <VuePerfectScrollbar
      class="scroll-area--nofications-dropdown p-0"
      :settings="settings"
    >
      <ul class="bordered-items" v-if="unreadNotifications.length > 0">
        <!-- itens de notificação -->
      </ul>
    </VuePerfectScrollbar>
  </vs-dropdown-menu>
</vs-dropdown>

Trigger por Hover (padrão)

Modo default — sem vs-trigger-click. Abre ao passar o mouse no trigger e fecha ao sair do menu. Nota: todos os 84 usos reais no admin adicionam vs-trigger-click — o hover puro nunca foi encontrado no codebase real.

Trigger + menu (hover)
Ação 1
Ação 2
Nota
Nunca usado no admin real.
Todos os 84 usos adicionam vs-trigger-click. Use sempre vs-trigger-click para comportamento consistente.
Sintético synthetic
<!-- Exemplo sintético — todos os usos reais usam vs-trigger-click -->
<vs-dropdown class="cursor-pointer">
  <span>Opções</span>

  <vs-dropdown-menu>
    <vs-dropdown-item>Ação 1</vs-dropdown-item>
    <vs-dropdown-item>Ação 2</vs-dropdown-item>
  </vs-dropdown-menu>
</vs-dropdown>

Trigger por Botão Direito

vs-trigger-contextmenu — menu abre com right-click. Previne o menu nativo do browser. Útil para menus de contexto em células de tabela ou áreas de conteúdo.

Área de right-click + menu
Clique com botão direito aqui
Copiar
Colar

Excluir
Sintético synthetic
<!-- Exemplo sintético — sem uso real encontrado no admin -->
<vs-dropdown vs-trigger-contextmenu class="cursor-pointer">
  <div class="w-full h-32 bg-grey-light flex items-center justify-center">
    Clique com botão direito aqui
  </div>

  <vs-dropdown-menu>
    <vs-dropdown-item>Copiar</vs-dropdown-item>
    <vs-dropdown-item>Colar</vs-dropdown-item>
    <vs-dropdown-item :divider="true" />
    <vs-dropdown-item>Excluir</vs-dropdown-item>
  </vs-dropdown-menu>
</vs-dropdown>

Com Divider e Item Desabilitado

VsDropdownItem com :divider="true" adiciona linha separadora entre grupos. :disabled="true" impede o clique e não fecha o menu. Útil para separar ações destrutivas de operações normais.

Menu com divider e item desabilitado
Visualizar
Editar

Excluir (sem permissão)
Sintético synthetic
<!-- Exemplo sintético — VsDropdownItem.divider/.disabled sem uso real encontrado -->
<vs-dropdown vs-trigger-click class="cursor-pointer">
  <span>Ações</span>

  <vs-dropdown-menu>
    <vs-dropdown-item>Visualizar</vs-dropdown-item>
    <vs-dropdown-item>Editar</vs-dropdown-item>
    <vs-dropdown-item :divider="true" />
    <vs-dropdown-item :disabled="true">Excluir (sem permissão)</vs-dropdown-item>
  </vs-dropdown-menu>
</vs-dropdown>

Posicionamento Dinâmico

O VsDropdown detecta automaticamente o espaço disponível e abre o menu para cima quando não há espaço abaixo. O vsDropRight abre o menu para a direita do trigger; vsAlignLeft alinha pela borda esquerda.

Open below (default)
Ação
Open above (automático)
Ação
Drop right
Ação
Sintético synthetic
<!-- Posicionamento calculado automaticamente pelo VsDropdown -->

<!-- Open above: automático quando não há espaço abaixo -->
<vs-dropdown vs-trigger-click class="cursor-pointer"> ... </vs-dropdown>

<!-- Drop right -->
<vs-dropdown vs-trigger-click vs-drop-right class="cursor-pointer"> ... </vs-dropdown>

<!-- Align left (default alinha pela borda direita) -->
<vs-dropdown vs-trigger-click vs-align-left class="cursor-pointer"> ... </vs-dropdown>

API

<!-- VsDropdown: vs-trigger-click (ou hover), vs-custom-content (menu livre), vs-drop-right, vs-align-left -->
<!-- VsDropdownItem: :to (router-link), :divider (separador), :disabled (não clicável) -->
<vs-dropdown
  vs-trigger-click
  vs-custom-content
  color="primary"
  class="cursor-pointer"
>
  <!-- Trigger: qualquer elemento -->
  <feather-icon icon="MoreVerticalIcon" />

  <vs-dropdown-menu>
    <!-- vsCustomContent=true: conteúdo livre -->
    <ul>
      <li @click="editItem">Editar</li>
      <li @click="deleteItem">Excluir</li>
    </ul>

    <!-- sem vsCustomContent: usar vs-dropdown-item -->
    <!-- <vs-dropdown-item :to="'/rota'">Link</vs-dropdown-item> -->
    <!-- <vs-dropdown-item :disabled="true">Inativo</vs-dropdown-item> -->
    <!-- <vs-dropdown-item :divider="true" /> -->
  </vs-dropdown-menu>
</vs-dropdown>

Props — VsDropdown

Nome (HTML)TipoDefaultObrig.Descrição
vs-trigger-click Boolean false Não Abre/fecha apenas por click. Sem este attr: hover. Fecha ao clicar fora (document click listener).
vs-trigger-contextmenu Boolean false Não Abre com botão direito. Previne menu nativo do browser.
color String "primary" Não Cor do hover nos VsDropdownItem filhos. Propagada via $children traversal.
vs-custom-content Boolean false Não Menu renderiza <div class="vs-dropdown--custom"> em vez de <ul>. Permite qualquer conteúdo.
vs-drop-right Boolean false Não Menu abre para a direita do trigger. Calcula leftx adicionando a largura do menu.
vs-align-left Boolean false Não Alinha o menu pela borda esquerda do trigger. Ignorado quando vsDropRight=true ou quando o menu ultrapassa a borda esquerda da viewport.

Props — VsDropdownItem

NomeTipoDefaultObrig.Descrição
to Any null Não Rota para router-link. Quando definido, renderiza <router-link :to="to">. Sem este prop: renderiza <a>.
disabled Boolean false Não Desabilita o item — classe .disabled e impede o fechamento do menu ao clicar.
divider Boolean false Não Linha separadora entre grupos — classe .divider no <li>.

Slots

ComponenteSlotDescrição
VsDropdown default Conteúdo do botão trigger — texto, ícone, avatar, qualquer elemento. Wrapper é um <button type="button">.
VsDropdownMenu default Conteúdo do menu. Sem vsCustomContent: deve conter VsDropdownItem. Com: conteúdo livre.
VsDropdownItem default Conteúdo do item — texto, ícone + texto. Renderizado dentro do router-link ou a.

Eventos — VsDropdown

EventoPayloadDescrição
@click Emitido quando o trigger é clicado diretamente. Útil para detectar click no botão.
@focus Emitido quando o dropdown é aberto (vsDropdownVisible = true).
@blur Emitido quando o dropdown é fechado (vsDropdownVisible = false).

Arquitetura dos Componentes

ComponenteArquivoResponsabilidade
VsDropdown dropdown.vue Botão trigger. Gerencia abertura/fechamento e calcula posição do menu.
VsDropdownMenu dropdown-menu.vue Menu flutuante. Inserido no document.body via insertBody() no mounted — evita overflow:hidden do pai.
VsDropdownItem dropdown-item.vue Item da lista. Fecha o dropdown ao clicar navegando via $parent recursivo até encontrar .parent-dropdown.

Cuidados Importantes

Comunicação via $children direta: VsDropdown e VsDropdownMenu comunicam-se via $children traversal, não via props. VsDropdownMenu DEVE ser filho direto de VsDropdown. Inserir outros filhos entre eles quebra a comunicação.
Menu no document.body: VsDropdownMenu é teleportado para o <body> no mounted via insertBody(). Isso significa que ele não está no DOM do componente pai — estilos com escopo (scoped) não atingem o menu.
vs-trigger-click sempre: Todos os 84 usos reais adicionam vs-trigger-click. O modo hover puro (default do componente) nunca é usado no admin. Use sempre vs-trigger-click.
vs-custom-content é o padrão real: O admin usa vs-custom-content + HTML/ul/li próprio na maioria dos casos. O vs-dropdown-item aparece em poucos casos (tag color picker). Para dropdowns com layout customizado, prefira vs-custom-content.

Dependências

src/assets/utils/color.js (_color.rColor)

Onde é usado (84 usos)

src/layouts/components/navbar/components/UserDropDown.vue
src/layouts/components/navbar/components/NotificationDropDown.vue
src/components/ChangeTimeDurationDropdown.vue
src/components/group-of-customer/Tag.vue
src/layouts/components/navbar/components/Bookmarks.vue
+ 79 outros arquivos