Skip to content

Modal

Visão geral

O componente LxModal é utilizado para exibir uma janela modal com diversas opções de personalização, incluindo título, tamanho, estado de carregamento, e botões de ação. Ele também suporta slots para customização do cabeçalho, conteúdo e rodapé.

Clique para visualizar o código
vue
<script setup>
import { ref } from 'vue';
import { LxModal } from '@lde/lxcomponents';

const isModalVisible = ref(false);

const handleClose = () => {
	console.log('Modal closed');
	isModalVisible.value = false;
};

const handleConfirm = () => {
	console.log('Modal confirmed');
	isModalVisible.value = false;
};

const openModal = () => {
	isModalVisible.value = true;
};
</script>

<template>
	<div>
		<button class="btn btn-primary m-0" @click="openModal">Open Modal</button>

		<LxModal v-if="isModalVisible" title="Modal Exemplo" btnCloseLabel="Custom Fechar" btnConfirmLabel="Custom Salvar" @close="handleClose" @confirm="handleConfirm">
			<template #content>
				<h1>Aqui vai o conteúdo do modal.</h1>
			</template>
		</LxModal>
	</div>
</template>

<style scoped>
button {
	margin: 10px;
}
</style>

Propriedades

NomeDescriçãoTipoPadrão
titleTítulo do modalString''
sizeTamanho do modal ('', 'sm', 'lg', 'xl).
Nota: O valor default (empty string) é considerado md.
String""
loadingIndica se o modal está em estado de carregamentoBooleanfalse
loadingMsgMensagem exibida durante o carregamentoString'Carregando...'
minHeightAltura mínima do modal.
Nota: Alturas menores que a default irão prejudicar a visualização do loading.
String'300px'
closeOnEscEmite o evento close ao usuario pressionar a tecla escBooleantrue
fullscreenIndica se o modal ocupa a tela inteiraBooleanfalse
passiveRemove o fotter do modalBooleanfalse

Eventos

NomeDescrição
closeEmitido quando o modal é fechado
confirmEmitido quando a ação de confirmação é realizada

Slots

NomeDescrição
headerConteúdo personalizado para o cabeçalho do modal.
Nota: O titulo e o botão de fechar não serão exibidos se este slot for utilizado.
title-contentConteúdo personalizado para o o titulo do modal.
contentConteúdo principal do modal
footerConteúdo personalizado para o rodapé do modal.
Nota: Os botões padrão de fechar e confirmar não serão exibidos se este slot for utilizado.
loadingConteúdo exibido durante o carregamento.
Nota: Por padrão usa o componente LxLoading.
btn-close-contentConteúdo personalizado para o botão de fechar
btn-confirm-contentConteúdo personalizado para o botão de confirmar

OBS: Algumas propriedades/eventos relacionados ao slot utilizado não terão efeito pois o conteúdo do componente será substituido pelo conteúdo do slot utilizado.

Atributos de Passagem

O componente LxModal permite que você passe atributos personalizados para os botões no rodapé utilizando fallthrough attributes do Vue. Isso é feito através do uso de useAttrs para herdar atributos não reconhecidos e aplicá-los aos elementos apropriados.

Atributos Disponíveis

AtributoDescrição
btn-closeAtributos personalizados para o botão de fechar no rodapé do modal.
Nota: Se forem passadas classes por atributos as classes padrões serão removidas. Você pode definir a label do botão passando o atributo label.
btn-confirmAtributos personalizados para o botão de confirmar no rodapé do modal.
Nota: Se forem passadas classes por atributos as classes padrões serão removidas. Você pode definir a label do botão passando o atributo label.

Exemplo de Uso

Você pode passar atributos personalizados para os botões no rodapé do modal utilizando a sintaxe correta. Veja um exemplo de como passar um id e uma class personalizada para o botão de fechar:

Clique para visualizar o código
vue
<template>
  <LxModal
    btn-close="{ id: 'custom-close-btn', class: 'custom-close-class', disabled: true }"
    btn-confirm="{ id: 'custom-confirm-btn', class: 'custom-confirm-class', disabled: false }"
  />
</template>

Classes Padrão

O componente LxModal utiliza uma série de classes CSS padrão que podem ser personalizadas. Essas classes permitem que você estilize qualquer parte do modal usando ::v-deep com a classe desejada.

Nome da ClasseDescrição
lx-modal-wrapperClasse aplicada ao contêiner principal do modal
lx-modal-backdropClasse aplicada ao backdrop do modal
lx-modalClasse aplicada ao modal
lx-modal-dialogClasse aplicada ao diálogo do modal
lx-modal-contentClasse aplicada ao conteúdo do modal
lx-modal-headerClasse aplicada ao cabeçalho do modal
lx-modal-header-titleClasse aplicada ao titulo do modal
lx-modal-bodyClasse aplicada ao corpo do modal
lx-modal-footerClasse aplicada ao rodapé do modal
lx-modal-footer-btn-closeClasse aplicada ao botão de fechar no rodapé do modal
lx-modal-footer-btn-confirmClasse aplicada ao botão de confirmar no rodapé do modal

Exemplo de Personalização

Você pode personalizar o estilo do modal utilizando as classes padrão com o seletor ::v-deep. Veja um exemplo de como alterar o estilo do cabeçalho do modal:

Clique para visualizar o código
vue
<style scoped>
::v-deep(.lx-modal-header) {
  background-color: #f8f9fa;
  border-bottom: 1px solid #dee2e6;
}
</style>

Playground

Clique para exibir o código
vue
<script setup>
import { ref } from 'vue';
import { LxModal } from '@lde/lxcomponents';

const title = ref('Exemplo de Modal');
const size = ref('');
const fullscreen = ref(false);
const loading = ref(false);
const loadingMsg = ref('Carregando...');
const minHeight = ref('300px');
const btnCloseAttrs = ref('{"label": "Fechar"}');
const btnConfirmAttrs = ref('{"label": "Confirmar"}');
const passive = ref(false);

const isModalVisible = ref(false);

const openModal = () => {
	isModalVisible.value = true;
};

const handleClose = () => {
	console.log('Modal fechado');
	isModalVisible.value = false;
};

const handleConfirm = () => {
	console.log('Modal confirmado');
	isModalVisible.value = false;
};

const parseAttrs = (attrs) => {
	try {
		return JSON.parse(attrs);
	} catch (e) {
		return {};
	}
};
</script>

<template>
	<div class="d-flex flex-column">
		<div class="d-flex flex-column gap-4">
			<div class="d-flex flex-column align-items-start gap-1">
				<label for="title" class="form-label">Título:</label>
				<input id="title" v-model="title" type="text" class="form-control mb-2" />

				<div class="d-flex gap-4 w-100 justify-content-between align-items-end">
					<div class="flex-grow-1 w-50">
						<label for="size" class="form-label">Tamanho:</label>
						<select id="size" v-model="size" class="form-select mb-2">
							<option value="">Default</option>
							<option value="sm">Small</option>
							<option value="lg">Large</option>
							<option value="xl">Extra Large</option>
						</select>
					</div>

					<div class="flex-grow-1 w-50">
						<label for="minHeight" class="form-label">Altura Mínima:</label>
						<input id="minHeight" v-model="minHeight" type="text" class="form-control mb-2" />
					</div>

					<div class="w-50 form-check d-flex align-items-center gap-2">
						<input id="fullscreen" v-model="fullscreen" type="checkbox" class="form-check-input" />
						<label for="fullscreen" class="form-check-label">Tela cheia</label>
					</div>
				</div>

				<div class="d-flex gap-4 w-100 justify-content-between align-items-end">
					<div class="w-50">
						<label for="loadingMsg" class="form-label">Mensagem de Carregamento:</label>
						<input id="loadingMsg" v-model="loadingMsg" type="text" class="form-control mb-2" />
					</div>

					<div class="w-50 form-check d-flex align-items-center gap-2">
						<input id="loading" v-model="loading" type="checkbox" class="form-check-input" />
						<label for="loading" class="form-check-label">Carregando</label>
					</div>
				</div>

				<div class="d-flex gap-4 w-100 justify-content-between">
					<div class="flex-grow-1 w-50">
						<label for="btnCloseAttrs" class="form-label">Atributos do Botão Fechar:</label>
						<input
							id="btnCloseAttrs"
							v-model="btnCloseAttrs"
							type="text"
							class="form-control mb-2"
							placeholder='{"id": "custom-close-btn", "class": "custom-close-class", "label": "Fechar"}'
						/>
					</div>
					<div class="flex-grow-1 w-50">
						<label for="btnConfirmAttrs" class="form-label">Atributos do Botão Confirmar:</label>
						<input
							id="btnConfirmAttrs"
							v-model="btnConfirmAttrs"
							type="text"
							class="form-control mb-2"
							placeholder='{"id": "custom-confirm-btn", "class": "custom-confirm-class", "label": "Confirmar"}'
						/>
					</div>
				</div>

				<div class="w-50 form-check d-flex align-items-center gap-2">
					<input id="passive" v-model="passive" type="checkbox" class="form-check-input" />
					<label for="passive" class="form-check-label">Passivo</label>
				</div>

				<button @click="openModal" class="btn btn-primary mt-3">Abrir Modal</button>
			</div>
		</div>

		<LxModal
			v-if="isModalVisible"
			:title="title"
			:size="size"
			:loading="loading"
			:loadingMsg="loadingMsg"
			:minHeight="minHeight"
			@close="handleClose"
			@confirm="handleConfirm"
			:fullscreen="fullscreen"
			:passive="passive"
			:btn-close="parseAttrs(btnCloseAttrs)"
			:btn-confirm="parseAttrs(btnConfirmAttrs)"
		>
			<template #content>
				<h1>Aqui vai o conteúdo do modal.</h1>
			</template>
		</LxModal>
	</div>
</template>

<style scoped></style>