MenuDropdown
Visão geral
O componente LxMenuDropdown serve como um contêiner para itens de menu, permitindo que você crie menus suspensos com facilidade.
Seu funcionamento é semelhante a uma modal, sendo necessário importá-lo apenas uma vez no componente principal (uma lista, por exemplo) e definir um id para o menu, assim qualquer objeto pode ser um trigger (acionador) simplesmente inserindo o atributo 'aria-controls='id-do-dropdown-aqui'' e o componente irá automaticamente se posicionar ao lado do trigger.
O LxMenuDropdownItem é usado para definir cada item dentro do MenuDropdown. Ele permite a configuração de ações específicas para cada item, fornecendo uma interface intuitiva e responsiva para os usuários.
Esses componentes são ideais para criar menus de navegação, seletores de opções e outras funcionalidades interativas que necessitam de um menu suspenso dinâmico.
Exemplo com Tabela
| ID | Nome | Preço | Status | Ações |
|---|---|---|---|---|
| 1 | Produto A | R$ 100,00 | Ativo | |
| 2 | Produto B | R$ 250,00 | Inativo | |
| 3 | Produto C | R$ 75,00 | Ativo | |
| 4 | Produto D | R$ 320,00 | Ativo | |
| 5 | Produto E | R$ 150,00 | Inativo |
Exemplo Simples (Original)
Clique para visualizar o código
vue
<script setup>
import { LxMenuDropdownItem } from '@lde/lxcomponents';
import LxMenuDropdown from '@/components/LxMenuDropdown/LxMenuDropdown.vue';
const tableData = [
{ id: 1, nome: 'Produto A', preco: 'R$ 100,00', status: 'Ativo' },
{ id: 2, nome: 'Produto B', preco: 'R$ 250,00', status: 'Inativo' },
{ id: 3, nome: 'Produto C', preco: 'R$ 75,00', status: 'Ativo' },
{ id: 4, nome: 'Produto D', preco: 'R$ 320,00', status: 'Ativo' },
{ id: 5, nome: 'Produto E', preco: 'R$ 150,00', status: 'Inativo' }
];
const handleAction = (action, item) => {
console.log(`Ação: ${action}`, item);
};
</script>
<template>
<div class="mb-3">
<h4 class="mb-3">Exemplo com Tabela</h4>
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Nome</th>
<th>Preço</th>
<th>Status</th>
<th style="width: 100px">Ações</th>
</tr>
</thead>
<tbody>
<tr v-for="item in tableData" :key="item.id">
<td>{{ item.id }}</td>
<td>{{ item.nome }}</td>
<td>{{ item.preco }}</td>
<td>{{ item.status }}</td>
<td>
<button class="btn btn-sm btn-secondary" :aria-controls="`dropdown-${item.id}`">⋮</button>
<LxMenuDropdown :id="`dropdown-${item.id}`">
<LxMenuDropdownItem :id="`dropdown-${item.id}-edit`" @click="handleAction('editar', item)"> ✏️ Editar </LxMenuDropdownItem>
<LxMenuDropdownItem :id="`dropdown-${item.id}-duplicate`" @click="handleAction('duplicar', item)"> 📋 Duplicar </LxMenuDropdownItem>
<LxMenuDropdownItem :id="`dropdown-${item.id}-view`" @click="handleAction('visualizar', item)"> 👁️ Visualizar </LxMenuDropdownItem>
<LxMenuDropdownItem
:id="`dropdown-${item.id}-delete`"
:aria-controls="`dropdown-${item.id}`"
class="text-danger"
hasDivider
@click="handleAction('deletar', item)"
>
🗑️ Deletar
</LxMenuDropdownItem>
</LxMenuDropdown>
</td>
</tr>
</tbody>
</table>
<h4 class="mb-3 mt-5">Exemplo Simples (Original)</h4>
<button class="btn btn-secondary" aria-controls="lx-menu-dropdown-example">Abrir</button>
<LxMenuDropdown id="lx-menu-dropdown-example">
<LxMenuDropdownItem id="lx-menu-dropdown-item-1"> Primeiro item </LxMenuDropdownItem>
<LxMenuDropdownItem id="lx-menu-dropdown-item-2"> Segundo item </LxMenuDropdownItem>
<LxMenuDropdownItem id="lx-menu-dropdown-item-3" disabled> Esse não da pra clicar </LxMenuDropdownItem>
<LxMenuDropdownItem id="lx-menu-dropdown-item-4" aria-controls="lx-menu-dropdown-example"> Esse pode fechar o dropdown </LxMenuDropdownItem>
<LxMenuDropdownItem id="lx-menu-dropdown-item-5" class="text-danger" hasDivider> Aquele perigoso </LxMenuDropdownItem>
</LxMenuDropdown>
</div>
</template>
<style scoped>
.table {
background: white;
}
.table th {
background-color: #f8f9fa;
font-weight: 600;
}
.table td {
vertical-align: middle;
}
</style>Propriedades MenuDropdown
| Nome | Descrição | Tipo | Padrão |
|---|---|---|---|
| id | Seletor CSS id | String | - |
| mobileBackdrop | MOBILE: Por padrão o menu ficará na parte inferior da tela, independente da posição do botão/trigger | Boolean | true |
| maxHeight | Define uma altura máxima para o popup do dropdown | String | - |
| placement | Define a posição do dropdown em relação ao trigger. Valores: auto, auto-start, auto-end, top, top-start, top-end, right, right-start, right-end, bottom, bottom-start, bottom-end, left, left-start, left-end | String | auto |
Propriedades MenuDropdownItem
| Nome | Descrição | Tipo | Padrão |
|---|---|---|---|
| id | Seletor CSS id | String | - |
| class | Caso queira personalizar o botão/trigger | String | - |
| hasDivider | Cria uma linha acima do item | Boolean | false |
| disabled | Se o mesmo será desabilitado | Boolean | false |
Métodos e propriedades acessíveis pelo ref do MenuDropdown
| Nome | Descrição | Tipo | Padrão |
|---|---|---|---|
| toggle | Método para abrir ou fechar o menu dropdown | Function | - |
| close | Método para fechar o menu dropdown | Function | true |
| isOpen | Estado menu dropdown (se está aberto ou fechado) | Boolean | - |
Playground
| MenuDropdown | |
|---|---|
| Nome | Controle |
| MenuDropdownItem | |
Clique para exibir o código
vue
<script setup>
import { reactive } from 'vue';
import { LxMenuDropdown, LxMenuDropdownItem } from '@lde/lxcomponents';
const propsMenuDropDown = reactive({
id: 'lx-menu-dropdown',
mobileBackdrop: true,
maxHeight: '',
placement: 'auto'
});
const propsMenuDropDownItem = reactive({
disabled: false,
hasDivider: false,
class: ''
});
</script>
<template>
<div class="d-flex justify-content-between">
<button class="btn btn-secondary" :aria-controls="propsMenuDropDown.id">Abrir</button>
<button class="btn btn-default border-0" :aria-controls="propsMenuDropDown.id">Mais opções <i class="fas fa-ellipsis-v"></i></button>
</div>
<div class="row">
<div class="col-12">
<LxMenuDropdown
:id="propsMenuDropDown.id"
:mobileBackdrop="propsMenuDropDown.mobileBackdrop"
:maxHeight="propsMenuDropDown.maxHeight"
:placement="propsMenuDropDown.placement"
>
<LxMenuDropdownItem id="lx-menu-dropdown-item-1"> Primeiro item </LxMenuDropdownItem>
<LxMenuDropdownItem id="lx-menu-dropdown-item-2"> Segundo item </LxMenuDropdownItem>
<LxMenuDropdownItem
:key="'reset-' + propsMenuDropDownItem.disabled + '-' + propsMenuDropDownItem.hasDivider + '-' + propsMenuDropDownItem.class"
id="lx-menu-dropdown-item-3"
:class="propsMenuDropDownItem.class"
:disabled="propsMenuDropDownItem.disabled"
:hasDivider="propsMenuDropDownItem.hasDivider"
>
Item de teste
</LxMenuDropdownItem>
</LxMenuDropdown>
</div>
</div>
<!-- playground controls -->
<table style="max-height: 50vh">
<thead>
<tr>
<th colspan="2">MenuDropdown</th>
</tr>
<tr>
<th style="width: 140px">Nome</th>
<th class="">Controle</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<label class="form-label m-0">mobileBackdrop</label>
</td>
<td>
<input v-model="propsMenuDropDown.mobileBackdrop" class="form-check-input" type="checkbox" />
</td>
</tr>
<tr>
<td>
<label class="form-label m-0">maxHeight</label>
</td>
<td>
<input v-model="propsMenuDropDown.maxHeight" type="text" class="form-control" />
</td>
</tr>
<tr>
<td>
<label class="form-label m-0">placement</label>
</td>
<td>
<select v-model="propsMenuDropDown.placement" class="form-select">
<option value="auto">auto</option>
<option value="auto-start">auto-start</option>
<option value="auto-end">auto-end</option>
<option value="top">top</option>
<option value="top-start">top-start</option>
<option value="top-end">top-end</option>
<option value="right">right</option>
<option value="right-start">right-start</option>
<option value="right-end">right-end</option>
<option value="bottom">bottom</option>
<option value="bottom-start">bottom-start</option>
<option value="bottom-end">bottom-end</option>
<option value="left">left</option>
<option value="left-start">left-start</option>
<option value="left-end">left-end</option>
</select>
</td>
</tr>
</tbody>
<thead>
<tr>
<th colspan="2">MenuDropdownItem</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<label class="form-label m-0">disabled</label>
</td>
<td>
<input v-model="propsMenuDropDownItem.disabled" class="form-check-input" type="checkbox" />
</td>
</tr>
<tr>
<td>
<label class="form-label m-0">hasDivider</label>
</td>
<td>
<input v-model="propsMenuDropDownItem.hasDivider" class="form-check-input" type="checkbox" />
</td>
</tr>
<tr>
<td>
<label class="form-label m-0">class</label>
</td>
<td>
<input v-model="propsMenuDropDownItem.class" type="text" class="form-control" />
</td>
</tr>
</tbody>
</table>
</template>
LxComponents