@aldoivan10/vuetify-dialog v1.1.1
⭐ Dialog
Dialog
es una librería para crear diálogos vuetify mediante código.
📦 Instalación
npm i @aldoivan/vuetify-dialog
pnpm add @aldoivan/vuetify-dialog
Luego, importa e instala la librería en tu proyecto Vue:
import { createApp } from "vue"
import { Dialog } from "@aldoivan/vuetify-dialog"
import { createVuetify } from "vuetify"
const app = createApp(App)
// Instalar primero vuetify
app.use(createVuetify(...))
// Instalar después el plugin para un correcto funcionamiento
app.use(Dialog)
Singleton
Por defecto, los diálogos estan configurados de tal forma que se montan y desmontan por cada uso (al cerrarse se desmonta), esto es beneficioso cuando no se recuere un uso constante de ellos.
Sin embargo, cuando su uso es recurrente, se tiene la opción de usar un único diálogo al cual solo se le cambian las propiedades (singleton).
Para activar este modo hay que pasar el parámetro a las opciones:
app.use(Dialog, { singleton: true }) // Por defecto false
También se puede activar/desactivar mediante la función de clase:
const dialog = useDialog()
dialog.setSingleton(boolean)
📖 Uso
Composable useDialog
Puedes usar el composable useDialog
en cualquier parte del código (stores, scripts, etc):
const dialog = useDialog()
dialog.alert({ body: { content: "Diálogo desde el código" } })
$dialog
De igual forma, puedes acceder dentro del template
a la variable global $dialog
para mostrar los diálogos:
<template>
<button
@click="$dialog.alert({ body: { content: 'Diálogo desde elemento' } })"
>
Mostrar diálogo
</button>
</template>
Cerrar diálogo mediante $emit
Cuando el body, header o actions es un Component
se puede cerrar el diálogo haciendo uso de $emit
y pasando un valor (opcional) en cualquier momento llamando al event closeDialog
:
// ChoiceForm.vue
<script setup lang="ts">
import { ref } from "vue"
defineEmits<{
closeDialog: [value: number]
}>()
const users = ref([
{ id: 1, name: "Aldo" },
{ id: 2, name: "Ivonne" },
{ id: 3, name: "Laura" },
{ id: 4, name: "Pedro" },
])
</script>
<template>
<v-card-text>
<v-row>
<v-col
:cols="12"
v-for="({ id, name }, key) in users"
:key
>
<v-btn
:text="name"
@click="$emit('closeDialog', id)"
variant="tonal"
color="secondary"
class="w-100"
/>
</v-col>
</v-row>
</v-card-text>
</template>
Cerrar diálogo mediante onClick
prop
Si las actions
se crean usando el arreglo Button[]
, las funciones onClick
recibirán como primer parámetro la función closeDialog
, la cual al ser llamada cerrará el diálogo, dicha función opcionalmente puede recibir un parámetro que retornará el valor del modal.
Adicionalmente se ha agregado la capacidad de recibir ref
en las propiedades pasadas en cada elemento, y se obtendrá como segundo parámetro props
(puedes checar algunos ejemplos en code/src ):
const loading = ref(false)
const disabled = ref(false)
const result = await dialog.show<true | undefined>({
body: { content: "Cerrar mediante <b>onClick</b>", props: { html: true } },
actions: [
{
text: "Aceptar",
variant: "flat",
onClick: (closeDialog) => closeDialog(true),
},
{
text: "Cancelar",
variant: "flat",
color: "error",
loading,
disabled,
onClick: (closeDialog, props) => {
props.loading = true
props.disabled = true
setTimeout(() => closeDialog(), 3000) // Cerrar en 3 segundos
},
},
],
})
console.log(result)
🗪 Diálogos por defecto
Simple
Este diálog únicamente renderiza el Header
y Body
, no puede recibir Actions
, por tanto, debe cerrarse mediante el evento $emit
:
import ChoiceForm from "./components/ChoiceForm.vue"
const result = await dialog.simple<any>({
header: { content: { title: "Escoge al usuario" } },
body: { content: markRaw(ChoiceForm) }, // content: Component
})
console.log(result)
Alert
Este diálog únicamente renderiza el Header
y Body
, y como Actions
tiene un único botón (con valor undefined) personalizable (el prop value, es el valor retornado al cerrar el diálogo):
const result = await dialog.alert<number>({
header: { content: { title: "¡Alerta!", subtitle: "Urgente" } },
body: { content: "Soy una <b>alerta<b> :D", props: { html: true } },
action: { value: 123, text: "Aceptar" }, // action: Button
})
console.log(result) // result = 123
Confirm
Este diálog únicamente renderiza el Header
y Body
, y como Actions
tiene un 2 bótones personalizables para cancelar (con valor false) y aceptar (con valor true) (el prop value, es el valor retornado al cerrar el diálogo):
const result = await dialog.confirm<boolean>({
header: { content: { title: "¡Alto!", subtitle: "Responde" } },
body: { content: "¿Te ha gustado?", props: { html: true } },
acceptBtn: { text: "Sí" },
cancelBtn: { text: "No" },
})
console.log(result) // true ó false
Custom
Diálogo 100% personalizable mediante las props:
const result = await dialog.show<string | number | Array<number> | Object>({
header: { content: { title: "Personalizado", subtitle: ":D" } },
body: { content: "Soy un componente <b>custom</b>", props: { html: true } },
actions: [
{
text: "Aceptar",
variant: "flat",
onClick: (closeDialog) => closeDialog("Boton 1"),
},
{
text: "Cancelar",
color: "error",
onClick: (closeDialog) => closeDialog(20),
},
{
text: "Extra 1",
color: "success",
variant: "tonal",
onClick: (closeDialog) => closeDialog({ id: 1, name: "Nameless" }),
},
{
onClick: (closeDialog) => closeDialog([1, 2, 3, 4]),
text: "Extra 2",
variant: "outlined",
color: "primary",
},
],
})
console.log(result) // true ó false
📚 API
Propiedades
Para lanzar un diálogo es necesario pasar un objeto con las siguientes propiedades:
Propiedad | Tipo | Descripción |
---|---|---|
header? | Header | Opcional, cabecera del diálogo |
body? | Body | Opcional, cuerpo del diálogo |
actions? | Actions | Button[] | Opcional, acciones del diálogo, puede se run objeto o un arreglo de propiedades de VBtn |
transition? | string | Opcional, por defecto: "scale-transition" |
fullscreen? | boolean | Opcional, por defecto: false |
persistent? | boolean | Opcional, por defecto: true |
minWidth? | string | number | Opcional, por defecto: "25%" |
width? | string | number | Opcional, por defecto: "fit-content" |
Key: string? | any | Opcionales, todas las propiedades admisibles de VDialog |
Header
Propiedad | Tipo | Descripción |
---|---|---|
content | { title?: string, subtitle?: string, prependAvatar?: string, appendAvatar?: string, preppendIcon?: string, appendIcon?: string, class?: string } | Component | Contenido del Header, debe ser un objeto con las propiedades descritas o un Component de Vue |
props? | Record<string, any> | Opcional, props que se pasarán solo cuando content sea un Component |
Body
Propiedad | Tipo | Descripción |
---|---|---|
content | string | Component | Contenido del Body, debe una cadena o un Component de Vue |
props? | Record<string, any> & { html?: boolean } | Opcional, props que se pasarán solo cuando content sea un Component . Cuando content es una cadena solo recibe si la cadena se debe renderizar como html. |
Actions
Propiedad | Tipo | Descripción |
---|---|---|
content | Component | Component a renderizar |
props? | Record<string, any> | Opcional, props que se pasarán al content. |
Button
Propiedad | Tipo | Descripción |
---|---|---|
onClick | (closeDialog: (val?: any) => void, props: Record<string, any>) => void | Opcional, acción a hacer clic sobre el botón. |
shortcut? | { value: string, modifiers?: { click?: boolean; prevent?: boolean } } | Opcional, atajo del teclado para poder hacer clic sobre el botón. (Solo si se tiene instalada la dependencia VShortcut) |
Key: string? | any | Opcionales, todas las propiedades admisibles de VBtn |
📃 Licencia
Este proyecto está bajo la licencia MIT. Consulta el archivo LICENSE para más detalles.