Modals
<template>
<div
:class="`${hidden} duration-300 overflow-y-auto overflow-x-hidden fixed ${positions[position]} w-full inset-1 h-full max-h-full`"
>
<div
:class="`relative w-full max-h-full ${sizes[size]} overflow-hidden ${!flat ? 'rounded-xl' : ''} border-xl z-50 ${scale} ${opacity} transform transition-transform`"
>
<div :class="`relative bg-white shadow`">
<!-- Modal header -->
<div
class="flex bg-slate-800 items-center justify-between p-4 md:p-5 border-b dark:border-gray-600"
>
<div class="px-4 sm:px-0">
<h3 class="text-base font-semibold leading-7 text-white">
{{ title }}
</h3>
<p
v-if="subtitle"
class="mt-1 max-w-2xl text-sm leading-6 text-gray-100"
>
{{ subtitle }}
</p>
</div>
<button
type="button"
class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white"
@click="$emit('update:modelValue', false)"
>
<svg-close class="w-8" />
</button>
</div>
<!-- Modal body -->
<div class="p-4 md:p-6 text-black">
<slot />
</div>
<!-- Modal footer -->
<slot v-if="!!$slots.footer" name="footer" />
<div
v-else
:class="`flex items-center justify-end p-4 md:p-5 border-t border-gray-200 dark:border-gray-600`"
>
<km-btn
type="button"
rounded="full"
@click="$emit('update:modelValue', false)"
>
Cerrar
</km-btn>
</div>
</div>
</div>
<div
:class="`bg-red-500 ${opacity} transition-opacity backdrop-blur-sm bg-slate-800/50 absolute z-40 w-full h-full`"
@click="$emit('update:modelValue', false)"
></div>
</div>
</template>
<script lang="ts">
type sizeType = "x-small" | "small" | "large" | "x-large";
type positionModal =
| "top-left"
| "top-right"
| "top-center"
| "center-left"
| "center-center"
| "center-right"
| "bottom-left"
| "bottom-center"
| "bottom-right";
export default {
data() {
return {
sizes: {
"x-small": "max-w-[250px]",
small: "max-w-md",
large: "max-w-4xl",
"x-large": "max-w-7xl",
},
positions: {
"top-left": "justify-start items-start",
"top-right": "justify-end items-start",
"top-center": "justify-center items-start",
"bottom-left": "justify-start items-end",
"bottom-right": "justify-end items-end",
"bottom-center": "justify-center items-end",
"center-left": "justify-start items-center",
"center-right": "justify-end items-center",
"center-center": "justify-center items-center",
},
scale: "scale-150",
hidden: "hidden",
opacity: "opacity-0",
};
},
watch: {
modelValue(newVal) {
if (newVal) {
this.hidden = "flex";
this.scale = "scale-150";
setTimeout(() => {
this.opacity = "";
this.scale = "";
}, 100);
} else {
this.scale = "scale-50";
setTimeout(() => {
this.hidden = "hidden";
this.opacity = "opacity-0";
this.scale = "scale-150";
}, 100);
}
},
},
props: {
modelValue: {
type: Boolean,
default: false,
},
title: {
type: String,
required: true,
},
flat: {
type: Boolean,
default: false,
},
subtitle: {
type: String,
},
size: {
type: String as PropType<sizeType>,
default: "small",
},
position: {
type: String as PropType<positionModal>,
default: "center-center",
},
},
};
</script>
Posicion
modal 1
top left
modal 1
top right
modal 1
top center
modal 1
bottom right
modal bottom left
bottom left
modal bottom center
bottom center
modal center right
center right
modal center left
center left
modal center center
center center
<template>
<km-btn type="button" rounded="full" @click="topLeft = true">
top left
</km-btn>
<km-modal v-model="topLeft" position="top-left" title="modal 1" subtitle="">
top left
</km-modal>
<km-btn type="button" rounded="full" @click="topRight = true">
top right
</km-btn>
<km-modal v-model="topRight" position="top-right" title="modal 1" subtitle="">
top right
</km-modal>
<km-btn type="button" rounded="full" @click="topCenter = true">
top center
</km-btn>
<km-modal
v-model="topCenter"
position="top-center"
title="modal 1"
subtitle=""
>
top center
</km-modal>
<km-btn type="button" rounded="full" @click="bottomRight = true">
bottom right
</km-btn>
<km-modal
v-model="bottomRight"
position="bottom-right"
title="modal 1"
subtitle=""
>
bottom right
</km-modal>
<km-btn type="button" rounded="full" @click="bottomLeft = true">
bottom left
</km-btn>
<km-modal
v-model="bottomLeft"
position="bottom-left"
title="modal bottom left"
subtitle=""
>
bottom left
</km-modal>
<km-btn type="button" rounded="full" @click="bottomCenter = true">
bottom center
</km-btn>
<km-modal
v-model="bottomCenter"
position="bottom-center"
title="modal bottom center"
subtitle=""
>
bottom center
</km-modal>
<km-btn type="button" rounded="full" @click="centerRight = true">
center right
</km-btn>
<km-modal
v-model="centerRight"
position="center-right"
title="modal center right"
subtitle=""
>
center right
</km-modal>
<km-btn type="button" rounded="full" @click="centerLeft = true">
center left
</km-btn>
<km-modal
v-model="centerLeft"
position="center-left"
title="modal center left"
subtitle=""
>
center left
</km-modal>
<km-btn type="button" rounded="full" @click="positionDefault = true">
position default
</km-btn>
<km-modal v-model="positionDefault" title="modal center center" subtitle="">
center center
</km-modal>
</template>
<script setup>
const topLeft = defineModel("topLeft", false);
const topRight = defineModel("topRight", false);
const topCenter = defineModel("topCenter", false);
const bottomRight = defineModel("bottomRight", false);
const bottomLeft = defineModel("bottomLeft", false);
const bottomCenter = defineModel("bottomCenter", false);
const centerRight = defineModel("centerRight", false);
const centerLeft = defineModel("centerLeft", false);
const positionDefault = defineModel("positionDefault", false);
</script>
Sizes
modal extra small
extra small
modal small
small
modal large
large
modal extra large
extra large
<template>
<km-btn type="button" rounded="full" @click="extraSmall = true">
extra small
</km-btn>
<km-modal
v-model="extraSmall"
title="modal extra small"
size="x-small"
subtitle=""
>
extra small
</km-modal>
<km-btn type="button" rounded="full" @click="small = true"> small </km-btn>
<km-modal v-model="small" title="modal small" size="small" subtitle="">
small
</km-modal>
<km-btn type="button" rounded="full" @click="large = true"> large </km-btn>
<km-modal v-model="large" title="modal large" size="large" subtitle="">
large
</km-modal>
<km-btn type="button" rounded="full" @click="extraLarge = true">
extra lager
</km-btn>
<km-modal
v-model="extraLarge"
title="modal extra large"
size="x-large"
subtitle=""
>
extra large
</km-modal>
</template>
<script setup>
const extraSmall = defineModel("extraSmall", false);
const small = defineModel("small", false);
const large = defineModel("large", false);
const extraLarge = defineModel("extraLarge", false);
</script>
Flat
modal flat
flat
<template>
<km-btn type="button" rounded="full" @click="flat = true"> flat </km-btn>
<km-modal v-model="flat" title="modal flat" flat subtitle=""> flat </km-modal>
</template>
<script setup>
const flat = defineModel("flat", false);
</script>