@vbardo/modal v1.0.4
Modal
modal is a vue 3 plugin for managing modals.
Installation
Note: this package require animejs
and shortid
npm package.
CDN
this package published as vbardoModal
module in umd.
<link
rel="stylesheet"
href="https://unpkg.com/@vbardo/modal/dist/style.css"
/>
<script src="https://unpkg.com/@vbardo/modal"></script>
NPM
npm i @vbardo/modal
import { createApp } from "vue";
import App from "./App.vue";
import Modal from "@vbardo/modal";
createApp(App)
.use(Modal)
.mount("#app");
install modal container with custom name:
import { createApp } from "vue";
import App from "./App.vue";
import { Container } from "@vbardo/modal";
createApp(App)
.component("modal-container", Container)
.mount("#app");
Options
modal has three level options:
- global options (used by default for all container)
- container options (passed as container property and override global options)
- modal options (passed on creation time and override container and global options)
Option | Type | Description | Default |
---|---|---|---|
closable | boolean | modal can close by click on overlay or not | false |
enterAnimation | AnimeParams | show animation (animejs animation option) | scale in |
leaveAnimation | AnimeParams | hide animation (animejs animation option) | scale out |
refuseAnimation | AnimeParams | play when click on overlay and modal not closable | attention |
onOpen | (firstTime: boolean) => void; | called after modal opened | null |
onAction | (key: string, data?: unknown) => Promise<boolean> | action handler. if return true modal will closed | null |
onClose | (mode: "overlay" | "click" | "action") => void | called after modal close | null |
Usage
Add Modal Container
fo showing modal in your app you need to add modal container component in your template.
<template>
<modal
name="default"
:options="{ closable: false }"
@modal="defaultTotalCount = $event"
/>
</template>
Property | Type | Description | Default |
---|---|---|---|
name | string | container name | default |
options | ModalOptions | default options used for creating new modal | {} |
Note: you can have multiple container in your app. every container must have a unique name.
Note: you can use createModal
and createSimpleModal
to creating modal for named container or use createDefaultModal
and createDefaultSimpleModal
to creating modal for unnamed (default) container.
Event | Callback Signature | Description |
---|---|---|
modal | (count: number) => void | This event call when modals count change |
Show Simple Modal
Note: Simple modals has no actions. if you want modal with actions support you must use custom modal.
Note: title is optional and you can create modal without title.
import { defineComponent } from "vue";
import { createDefaultSimpleModal } from "@vbardo/modal";
export default defineComponent({
setup() {
function showModal() {
const globalId = createDefaultSimpleModal(
{
content: "Welcome to our app!",
title: "Greeting",
class: "my-custom-class"
},
{
closable: true,
onOpen: (firstTime: boolean) => {
if (firstTime) {
console.log("modal opened for first time!");
} else {
console.log("modal shown again!");
}
},
onClose: (mode: "overlay" | "click" | "action") => {
console.log(`modal closed by ${mode} mode`);
}
}
);
console.log(`new modal by globalId: ${modalId} created!`);
}
return { showModal };
}
});
Custom Modals
for create custom modal you need define a normal vue component with modal library composition api helpers useModal
and create modal instance using createModal
function.
Note: by default every modal received globalId
and options
props. you must define this props in your components and use it to define new modal component.
Note: you can define any props in your custom modal component and pass this props when you want create new modal.
useModal Parameters
Caution: if container not passed modal animations doesn't work!
Parameter | Type | Description |
---|---|---|
globalId | string | global modal id |
options | ModalOptions | modal options |
container | Ref<HTMLElement> | modal root node reference |
useModal Return Values
Name | Type | Description |
---|---|---|
loading | boolean | on action, loading state will active until action promise complete |
action | (key: string, data?: unknown) => void | helper method to call modal action handler |
close | () => void | close modal |
<template>
<div class="my-modal" ref="container">
<div v-if="loading">Loading...</div>
<p>{{ message }}</p>
<div class="actions" v-if="!loading">
<span @click.stop="action('yes')">{{ yesText || "yes" }}</span>
<span @click.stop="action('no', 'data')">{{ noText || "no" }}</span>
<span @click.stop="close">Cancel</span>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from "vue";
import { ModalOptions, useModal } from "@vbardo/modal";
export default defineComponent({
name: "MyModal",
props: {
globalId: {
type: String,
required: true
},
options: {
type: Object as () => ModalOptions,
required: true
},
// custom props
message: String,
yesText: String,
noText: String
},
setup(props, { emit }) {
const container = ref<HTMLElement>(); // template ref
const { loading, action, close } = useModal(
props.globalId,
props.options,
container
);
return { loading, action, close, container };
}
});
</script>
Use Custom Modal
createModal
method parameters:
Note: when using createDefaultModal
method container parameters not exists.
Parameter | Type | Description |
---|---|---|
container | string | container name |
com | Object | component |
props | Object | component props |
options | ModalOptions | modal options |
Note: createModal return new modal global id as result.
import { defineComponent } from "vue";
import { createDefaultModal } from "@vbardo/modal";
import MyModal from "./MyModal.vue";
export default defineComponent({
setup() {
const showModal = () => {
createDefaultModal(
MyModal,
{
message: "are you want to delete record",
yesText: "Delete",
noText: "Discard"
},
{
onAction: async (key: string, data?: unknown) => {
if (key == "yes") {
const res = await doSomeLongAsyncWork();
return res
? Promise.resolve(true)
: Promise.resolve(false);
} else {
Promise.resolve(true);
}
}
}
);
};
return { showModal };
}
});
Styling
for using default styles you must import style.css
in your app.
<template>
<modal />
</template>
<style>
@import "@vbardo/modal/dist/style.css";
</style>
Container Styles
Class | Description |
---|---|
is-light | light background for container |
is-sub | add this class to container when use container inside some part of ui (for non-fullscreen containers) |
Note: Parent node of sub containers must have position: relative;
style!
Customize Styling
modal plugin use Mui for advanced styling. if you use mui in your project you can import @vbardo/modal/dist/style.scss
in your mui root file and use custom styling.
// Mui root file
// ... Other styles
@import "@vbardo/modal/dist/style.scss";
For overriding default style you must use set-var('vb-modal', $VAR)
. Following vars are used for styling modal plugin:
Var | Description | Default |
---|---|---|
container-padding | container padding | 1rem |
container-background | container background | rgba(0, 0, 0, 0.75) |
container-background-light | light container background | rgba(255, 255, 255, 0.75) |
container-z-index | container z-index (by default .layout class of mui has 0 z-index) | 1 |
background | modal background | get-color('container') |
width | modal width | 30rem |
padding | modal padding | 2rem |
border | modal border | none |
shadow | modal box-shadow | a simple shadow |
Note: by default you can use all defined iterable colors with is-
prefix for coloring modal. e.g: is-primary
, is-success
you can override border and box-shadow of colored modal by defining border-{iterable color}
and shadow-{iterable color}
. e.g:
@include set-var(
"vb-modal",
"border-success",
1px solid palette("success", "200")
);
@include set-var(
"vb-modal",
"shadow-error",
rgba(palette("error", "900"), 0.05) 0px 0.25em 1em
);
@import "@vbardo/modal/dist/style.scss";
Note: When using Mui you can add action
class to action buttons. also you can add is-default
class to your action and style action as default action.