diff --git a/.eslintignore b/.eslintignore
index 654b922..4ebe047 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -5,4 +5,3 @@ dist/
coverage/
.github/
.vscode/
-demo/
diff --git a/.eslintrc.js b/.eslintrc.js
index 760c487..8a7e15a 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -6,27 +6,65 @@ module.exports = {
"vue/setup-compiler-macros": true,
},
extends: [
- "plugin:vue/vue3-recommended",
"eslint:recommended",
- "plugin:import/errors",
- "plugin:import/warnings",
- "plugin:import/typescript",
- "plugin:@typescript-eslint/eslint-recommended",
+ "plugin:vue/vue3-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
+ "plugin:import/recommended",
+ "plugin:import/typescript",
],
parser: "vue-eslint-parser",
parserOptions: {
parser: "@typescript-eslint/parser",
sourceType: "module",
},
- plugins: ["vue", "@typescript-eslint"],
+ plugins: ["vue", "@typescript-eslint", "jsx-a11y"],
rules: {
- "@typescript-eslint/no-use-before-define": "off",
- "@typescript-eslint/explicit-module-boundary-types": "off",
"no-console": process.env.NODE_ENV === "production" ? "error" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "error" : "off",
- "no-useless-escape": "off",
+ "@typescript-eslint/no-empty-function": ["off"],
+ "import/order": [
+ "error",
+ {
+ groups: [
+ "builtin",
+ "external",
+ "internal",
+ "parent",
+ "object",
+ "type",
+ "sibling",
+ "index",
+ ],
+ warnOnUnassignedImports: true,
+ pathGroups: [
+ {
+ pattern: "vue",
+ group: "builtin",
+ position: "before",
+ },
+ {
+ pattern: "**/*.{css,scss}",
+ group: "index",
+ position: "after",
+ },
+ ],
+ pathGroupsExcludedImportTypes: ["builtin", "vue", "**/*.{css,scss}"],
+ "newlines-between": "always",
+ alphabetize: {
+ order: "asc",
+ caseInsensitive: true,
+ },
+ },
+ ],
+ "import/first": "error",
+ "import/no-duplicates": "error",
+ "import/newline-after-import": "error",
+ "import/no-unassigned-import": [
+ "error",
+ { allow: ["**/*.css", "**/*.scss", "**/*.sass"] },
+ ],
+ "import/no-named-default": "error",
},
overrides: [
{
@@ -39,4 +77,9 @@ module.exports = {
},
},
],
+ settings: {
+ "import/parsers": {
+ "@typescript-eslint/parser": [".ts", ".tsx"],
+ },
+ },
}
diff --git a/demo/src/App.vue b/demo/src/App.vue
index 5e10d72..6b49258 100644
--- a/demo/src/App.vue
+++ b/demo/src/App.vue
@@ -1,12 +1,27 @@
-
-
+ 
+
diff --git a/demo/src/main.ts b/demo/src/main.ts
index 8f13e72..7aa6ee4 100644
--- a/demo/src/main.ts
+++ b/demo/src/main.ts
@@ -1,5 +1,7 @@
-import { createApp } from 'vue'
-import App from './App.vue'
+import { createApp } from "vue"
+
import Toast from "../../src"
-createApp(App).use(Toast).mount('#app')
+import App from "./App.vue"
+
+createApp(App).use(Toast).mount("#app")
diff --git a/package.json b/package.json
index d7e4b41..5a0700e 100644
--- a/package.json
+++ b/package.json
@@ -8,18 +8,18 @@
"dev": "yarn vite --mode demo",
"prebuild": "rimraf ./dist",
"build": "yarn build:code && yarn build:tsc",
- "build:code": "vite build --mode lib",
- "build:tsc": "vue-tsc --emitDeclarationOnly --project tsconfig.build.json",
- "build:demo": "vite build --mode demo",
+ "build:code": "MODE=lib vite build",
+ "build:tsc": "NODE_ENV=production tsc --emitDeclarationOnly --project tsconfig.build.json",
+ "build:demo": "MODE=demo vite build",
"test:unit": "jest",
"test": "yarn test:unit",
"test:watch": "yarn test --watch",
- "lint": "yarn lint:tsc && yarn lint:eslint",
- "lint:fix": "yarn lint:tsc && yarn lint:eslint:fix",
- "lint:tsc": "vue-tsc --noEmit",
- "lint:eslint": "eslint --ext .vue,.ts .",
- "lint:eslint:fix": "yarn lint:eslint --fix",
- "preview": "vite preview --port 3000 demo",
+ "lint": "yarn lint:tsc && yarn lint:eslint .",
+ "lint:fix": "yarn lint --fix",
+ "lint:tsc": "NODE_ENV=production vue-tsc --noEmit",
+ "lint:eslint": "NODE_ENV=production eslint --ext vue,ts,tsx",
+ "lint:staged": "yarn lint:tsc && yarn lint:eslint --fix",
+ "preview": "NODE_ENV=production vite preview --port 3000 demo",
"prepublishOnly": "yarn lint && yarn test && yarn build",
"prepare": "husky install"
},
@@ -52,6 +52,7 @@
"eslint": "^8.8.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.25.4",
+ "eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-vue": "^8.4.0",
"husky": "^7.0.4",
@@ -68,7 +69,7 @@
},
"lint-staged": {
"*.{js,jsx,vue,ts,tsx}": [
- "eslint --ext .vue,.ts --fix"
+ "yarn lint:staged"
]
},
"peerDependencies": {
diff --git a/src/components/VtCloseButton.vue b/src/components/VtCloseButton.vue
index a12fac1..c22b399 100644
--- a/src/components/VtCloseButton.vue
+++ b/src/components/VtCloseButton.vue
@@ -9,34 +9,27 @@
-
-
-
-
-
-
+
+
diff --git a/src/components/VtTransition.vue b/src/components/VtTransition.vue
index 2a3ab91..f3c445d 100644
--- a/src/components/VtTransition.vue
+++ b/src/components/VtTransition.vue
@@ -14,27 +14,22 @@
-
-
diff --git a/src/components/icons/VtInfoIcon.vue b/src/components/icons/VtInfoIcon.vue
index f10395b..f5e92dd 100644
--- a/src/components/icons/VtInfoIcon.vue
+++ b/src/components/icons/VtInfoIcon.vue
@@ -2,9 +2,6 @@
-
diff --git a/src/components/icons/VtSuccessIcon.vue b/src/components/icons/VtSuccessIcon.vue
index 04199ac..03a1a5c 100644
--- a/src/components/icons/VtSuccessIcon.vue
+++ b/src/components/icons/VtSuccessIcon.vue
@@ -2,9 +2,6 @@
-
diff --git a/src/components/icons/VtWarningIcon.vue b/src/components/icons/VtWarningIcon.vue
index 51142ba..4de5aad 100644
--- a/src/components/icons/VtWarningIcon.vue
+++ b/src/components/icons/VtWarningIcon.vue
@@ -2,9 +2,6 @@
-
diff --git a/src/index.ts b/src/index.ts
index 451cec7..f051a6c 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,86 +1,25 @@
-import { Plugin, InjectionKey, provide, inject, getCurrentInstance } from "vue"
-import { buildInterface } from "./ts/interface"
import type { ToastInterface } from "./ts/interface"
-import { POSITION, TYPE, VT_NAMESPACE } from "./ts/constants"
-import { EventBusInterface, isEventBusInterface, EventBus } from "./ts/eventBus"
-import type { PluginOptions } from "./types"
-import * as ownExports from "./index"
-import "./scss/index.scss"
-import { isBrowser } from "./ts/utils"
-
-const createMockToastInterface = (): ToastInterface => {
- const toast = () =>
- console.warn(`[${VT_NAMESPACE}] This plugin does not support SSR!`)
- return new Proxy(toast, {
- get() {
- return toast
- },
- }) as unknown as ToastInterface
-}
-
-function createToastInterface(eventBus: EventBusInterface): ToastInterface
-function createToastInterface(options?: PluginOptions): ToastInterface
-function createToastInterface(
- optionsOrEventBus?: PluginOptions | EventBusInterface
-): ToastInterface {
- if (!isBrowser()) {
- return createMockToastInterface()
- }
- if (isEventBusInterface(optionsOrEventBus)) {
- return buildInterface({ eventBus: optionsOrEventBus }, false)
- }
- return buildInterface(optionsOrEventBus, true)
-}
-
-const toastInjectionKey: InjectionKey =
- Symbol("VueToastification")
-
-const globalEventBus = new EventBus()
+import type { PluginOptions } from "./types/plugin"
-const VueToastificationPlugin: Plugin = (App, options?: PluginOptions) => {
- if (options?.shareAppContext === true) {
- options.shareAppContext = App
- }
- const inter = ownExports.createToastInterface({
- eventBus: globalEventBus,
- ...options,
- })
- App.provide(toastInjectionKey, inter)
-}
-
-const provideToast = (options?: PluginOptions) => {
- const toast = ownExports.createToastInterface(options)
- if (getCurrentInstance()) {
- provide(toastInjectionKey, toast)
- }
-}
-
-const useToast = (eventBus?: EventBus) => {
- if (eventBus) {
- return ownExports.createToastInterface(eventBus)
- }
- const toast = getCurrentInstance()
- ? inject(toastInjectionKey, undefined)
- : undefined
- return toast ? toast : ownExports.createToastInterface(globalEventBus)
-}
+import "./scss/index.scss"
+import {
+ createToastInstance,
+ provideToast,
+ useToast,
+} from "./ts/composables/useToast"
+import { POSITION, TYPE } from "./ts/constants"
+import { EventBus } from "./ts/eventBus"
+import { VueToastificationPlugin } from "./ts/plugin"
export default VueToastificationPlugin
export {
- // Types
- ToastInterface,
- PluginOptions,
- // Consts
- POSITION,
- TYPE,
- toastInjectionKey,
- // Functions
- createToastInterface,
- useToast,
+ createToastInstance,
provideToast,
- // Classes
+ useToast,
EventBus,
- // Instances
- globalEventBus,
+ POSITION,
+ TYPE,
+ PluginOptions,
+ ToastInterface,
}
diff --git a/src/ts/composables/useDraggable.ts b/src/ts/composables/useDraggable.ts
index 0724441..cd11abf 100644
--- a/src/ts/composables/useDraggable.ts
+++ b/src/ts/composables/useDraggable.ts
@@ -7,12 +7,14 @@ import {
computed,
watch,
} from "vue"
-import { ToastOptions } from "../../types"
+
import { isDOMRect, getX, getY } from "../utils"
+import type { Draggable } from "../../types/common"
+
export const useDraggable = (
el: Ref,
- props: Required>
+ props: Required
) => {
// Extract used props
const { draggablePercent, draggable } = toRefs(props)
diff --git a/src/ts/composables/useFocusable.ts b/src/ts/composables/useFocusable.ts
index 84306d0..82ca31e 100644
--- a/src/ts/composables/useFocusable.ts
+++ b/src/ts/composables/useFocusable.ts
@@ -1,9 +1,10 @@
import { toRefs, ref, Ref, onMounted, onBeforeUnmount } from "vue"
-import { ToastOptions } from "../../types"
+
+import type { Focusable } from "../../types/common"
export const useFocusable = (
el: Ref,
- props: Required>
+ props: Required
) => {
const { pauseOnFocusLoss } = toRefs(props)
const focused = ref(true)
diff --git a/src/ts/composables/useHoverable.ts b/src/ts/composables/useHoverable.ts
index 3004164..ba3cb0b 100644
--- a/src/ts/composables/useHoverable.ts
+++ b/src/ts/composables/useHoverable.ts
@@ -1,9 +1,10 @@
import { toRefs, ref, Ref, onMounted, onBeforeUnmount } from "vue"
-import { ToastOptions } from "../../types"
+
+import type { Hoverable } from "../../types/common"
export const useHoverable = (
el: Ref,
- props: Required>
+ props: Required
) => {
const { pauseOnHover } = toRefs(props)
const hovering = ref(false)
diff --git a/src/ts/composables/useToast.ts b/src/ts/composables/useToast.ts
new file mode 100644
index 0000000..5e033d1
--- /dev/null
+++ b/src/ts/composables/useToast.ts
@@ -0,0 +1,74 @@
+import { InjectionKey, provide, inject, getCurrentInstance } from "vue"
+
+import { VT_NAMESPACE } from "../constants"
+import {
+ EventBusInterface,
+ isEventBusInterface,
+ EventBus,
+ globalEventBus,
+} from "../eventBus"
+import { buildInterface } from "../interface"
+import { isBrowser } from "../utils"
+
+import type { PluginOptions } from "../../types/plugin"
+import type { ToastInterface } from "../interface"
+
+import { createToastInstance as ownExports_createToastInstance } from "./useToast"
+
+const toastInjectionKey: InjectionKey =
+ Symbol("VueToastification")
+
+/**
+ * Creates (or recovers) a toast instance and returns
+ * an interface to it
+ */
+interface CreateToastInstance {
+ /**
+ * Creates an interface to an existing instance from its interface
+ */
+ (eventBus: EventBusInterface): ToastInterface
+ /**
+ * Creats a new instance of Vue Toastification
+ */
+ (options?: PluginOptions): ToastInterface
+}
+
+const createMockToastInstance: CreateToastInstance = () => {
+ const toast = () =>
+ // eslint-disable-next-line no-console
+ console.warn(`[${VT_NAMESPACE}] This plugin does not support SSR!`)
+ return new Proxy(toast, {
+ get() {
+ return toast
+ },
+ }) as unknown as ToastInterface
+}
+
+const createToastInstance: CreateToastInstance = optionsOrEventBus => {
+ if (!isBrowser()) {
+ return createMockToastInstance()
+ }
+ if (isEventBusInterface(optionsOrEventBus)) {
+ return buildInterface({ eventBus: optionsOrEventBus }, false)
+ }
+ return buildInterface(optionsOrEventBus, true)
+}
+
+const provideToast = (options?: PluginOptions) => {
+ if (getCurrentInstance()) {
+ const toast = ownExports_createToastInstance(options)
+ provide(toastInjectionKey, toast)
+ }
+}
+
+const useToast = (eventBus?: EventBus) => {
+ if (eventBus) {
+ return ownExports_createToastInstance(eventBus)
+ }
+ const toast = getCurrentInstance()
+ ? inject(toastInjectionKey, undefined)
+ : undefined
+ return toast ? toast : ownExports_createToastInstance(globalEventBus)
+}
+
+export { useToast, provideToast, toastInjectionKey, createToastInstance }
diff --git a/src/ts/eventBus.ts b/src/ts/eventBus.ts
index fc6ed66..5f6120b 100644
--- a/src/ts/eventBus.ts
+++ b/src/ts/eventBus.ts
@@ -1,15 +1,16 @@
-import type { EVENTS } from "./constants"
-import { hasProp, isFunction } from "./utils"
+import type { ToastID } from "../types/common"
import type {
- ToastOptionsAndRequiredContent,
- ToastID,
+ ToastOptionsAndContent,
ToastContent,
ToastOptions,
- PluginOptions,
-} from "../types/index"
+} from "../types/toast"
+import type { ToastContainerOptions } from "../types/toastContainer"
+import type { EVENTS } from "./constants"
+
+import { hasProp, isFunction } from "./utils"
type EventData = {
- [EVENTS.ADD]: ToastOptionsAndRequiredContent & {
+ [EVENTS.ADD]: ToastOptionsAndContent & {
id: ToastID
}
[EVENTS.CLEAR]: undefined
@@ -25,7 +26,7 @@ type EventData = {
options: Partial & { content: ToastContent }
create: true
}
- [EVENTS.UPDATE_DEFAULTS]: PluginOptions
+ [EVENTS.UPDATE_DEFAULTS]: ToastContainerOptions
}
type Handler = (event: EventData[E]) => void
@@ -66,3 +67,5 @@ export class EventBus implements EventBusInterface {
export const isEventBusInterface = (e: unknown): e is EventBusInterface =>
["on", "off", "emit"].every(f => hasProp(e, f) && isFunction(e[f]))
+
+export const globalEventBus = new EventBus()
diff --git a/src/ts/interface.ts b/src/ts/interface.ts
index 004a7e5..35202cb 100644
--- a/src/ts/interface.ts
+++ b/src/ts/interface.ts
@@ -1,139 +1,210 @@
import { createApp, nextTick } from "vue"
-import { EventBus } from "./eventBus"
+
import ToastContainer from "../components/VtToastContainer.vue"
-import {
+
+import type { ToastID } from "../types/common"
+import type { BasePluginOptions, PluginOptions } from "../types/plugin"
+import type {
ToastContent,
ToastOptions,
- ToastID,
- PluginOptions,
- ToastOptionsAndRequiredContent,
-} from "../types"
-import { TYPE, EVENTS, VT_NAMESPACE } from "./constants"
-import { getId, isUndefined } from "./utils"
+ ToastOptionsAndContent,
+} from "../types/toast"
-export const buildInterface = (
- globalOptions: PluginOptions = {},
- mountContainer = true
-) => {
- const events = (globalOptions.eventBus =
- globalOptions.eventBus || new EventBus())
- if (mountContainer) {
- nextTick(() => {
- const app = createApp(ToastContainer, {
- ...globalOptions,
- })
- const component = app.mount(document.createElement("div"))
-
- const onMounted = globalOptions.onMounted
- if (!isUndefined(onMounted)) {
- onMounted(component, app)
- }
-
- if (globalOptions.shareAppContext) {
- const baseApp = globalOptions.shareAppContext
- if (baseApp === true) {
- console.warn(
- `[${VT_NAMESPACE}] App to share context with was not provided.`
- )
- } else {
- app._context.components = baseApp._context.components
- app._context.directives = baseApp._context.directives
- app._context.mixins = baseApp._context.mixins
- app._context.provides = baseApp._context.provides
- app.config.globalProperties = baseApp.config.globalProperties
- }
- }
- })
- }
- /**
- * Display a toast
- */
- const toast = (content: ToastContent, options?: ToastOptions): ToastID => {
- const props: ToastOptionsAndRequiredContent & {
- id: ToastID
- } = Object.assign({}, { id: getId(), type: TYPE.DEFAULT }, options, {
- content,
- })
- events.emit(EVENTS.ADD, props)
- return props.id
- }
+import { TYPE, EVENTS } from "./constants"
+import { EventBus, EventBusInterface } from "./eventBus"
+import { asContainerProps, getId, isUndefined } from "./utils"
+
+/**
+ * Display a toast
+ */
+interface ToastMethod {
/**
- * Clear all toasts
+ * @param content Toast content.
+ *
+ * Can be a string, JSX or a custom component passed directly
+ *
+ * To provide props and listeners to the custom component, you
+ * do so by providing an object with the following shape:
+ *
+ * ```ts
+ * {
+ * component: JSX | VueComponent
+ * props: Record
+ * listeners: Record
+ * }
+ * ```
+ *
+ * for more details, see https://github.com/Maronato/vue-toastification#toast-content-object
+ *
+ * @param options Toast configuration
+ *
+ * For details, see: https://github.com/Maronato/vue-toastification#toast-options-object
+ *
+ * @returns ID of the created toast
*/
- toast.clear = () => events.emit(EVENTS.CLEAR, undefined)
+ (content: ToastContent, options?: ToastOptions & { type?: T }): ToastID
+}
+
+interface DismissToast {
/**
- * Update Plugin Defaults
+ * @param toastID ID of the toast to be dismissed
*/
- toast.updateDefaults = (update: PluginOptions) => {
- events.emit(EVENTS.UPDATE_DEFAULTS, update)
- }
+ (toastID: ToastID): void
+}
+
+interface ClearToasts {
+ (): void
+}
+
+interface UpdateDefaults {
/**
- * Dismiss toast specified by an id
+ * @param update Plugin options to update
+ *
+ * Accepts all* options provided during plugin
+ * registration and updates them.
+ *
+ * For details, see https://github.com/Maronato/vue-toastification#updating-default-options
*/
- toast.dismiss = (id: ToastID) => {
- events.emit(EVENTS.DISMISS, id)
- }
+ (update: BasePluginOptions): void
+}
+
+interface UpdateToast {
/**
- * Update Toast
+ * @param toastID ID of the toast to update
+ * @param update Object that may contain the content to update, or the options to merge
+ * @param create If set to false, this method only updates existing toasts and does
+ * nothing if the provided `toastID` does not exist
*/
- function updateToast(
- id: ToastID,
- { content, options }: { content?: ToastContent; options?: ToastOptions },
+ (
+ toastID: ToastID,
+ update: { content?: ToastContent; options?: ToastOptions },
create?: false
): void
- function updateToast(
- id: ToastID,
- { content, options }: { content: ToastContent; options?: ToastOptions },
- create?: true
+ /**
+ * @param toastID ID of the toast to create / update
+ * @param update Object that must contain the toast content and may contain the options to merge
+ * @param create If set to true, this method updates existing toasts or creates new toasts if
+ * the provided `toastID` does not exist
+ */
+ (
+ toastID: ToastID,
+ update: { content: ToastContent; options?: ToastOptions },
+ create: true
): void
- function updateToast(
- id: ToastID,
- { content, options }: { content?: ToastContent; options?: ToastOptions },
- create = false
- ): void {
- const opt = Object.assign({}, options, { content }) as ToastOptions & {
- content: ToastContent
- }
- events.emit(EVENTS.UPDATE, {
- id,
- options: opt,
- create,
- })
- }
- toast.update = updateToast
+}
+
+export interface ToastInterface extends ToastMethod {
/**
* Display a success toast
*/
- toast.success = (
- content: ToastContent,
- options?: ToastOptions & { type?: TYPE.SUCCESS }
- ) => toast(content, Object.assign({}, options, { type: TYPE.SUCCESS }))
-
+ success: ToastMethod
/**
* Display an info toast
*/
- toast.info = (
- content: ToastContent,
- options?: ToastOptions & { type?: TYPE.INFO }
- ) => toast(content, Object.assign({}, options, { type: TYPE.INFO }))
-
+ info: ToastMethod
+ /**
+ * Display a warning toast
+ */
+ warning: ToastMethod
/**
* Display an error toast
*/
- toast.error = (
- content: ToastContent,
- options?: ToastOptions & { type?: TYPE.ERROR }
- ) => toast(content, Object.assign({}, options, { type: TYPE.ERROR }))
-
+ error: ToastMethod
/**
- * Display a warning toast
+ * Dismiss toast specified by an id
*/
- toast.warning = (
- content: ToastContent,
- options?: ToastOptions & { type?: TYPE.WARNING }
- ) => toast(content, Object.assign({}, options, { type: TYPE.WARNING }))
+ dismiss: DismissToast
+ /**
+ * Update Toast
+ */
+ update: UpdateToast
+ /**
+ * Clear all toasts
+ */
+ clear: ClearToasts
+ /**
+ * Update Plugin Defaults
+ */
+ updateDefaults: UpdateDefaults
+}
+
+/**
+ * Creates and mounts the plugin app
+ * @param options Plugin options passed during init
+ */
+function mountPlugin(options: PluginOptions) {
+ const { shareAppContext, onMounted, ...basePluginOptions } = options
+
+ const containerProps = asContainerProps(basePluginOptions)
+
+ const app = createApp(ToastContainer, {
+ ...containerProps,
+ })
+
+ if (shareAppContext && shareAppContext !== true) {
+ const userApp = shareAppContext
+ app._context.components = userApp._context.components
+ app._context.directives = userApp._context.directives
+ app._context.mixins = userApp._context.mixins
+ app._context.provides = userApp._context.provides
+ app.config.globalProperties = userApp.config.globalProperties
+ }
+
+ const component = app.mount(document.createElement("div"))
- return toast
+ if (!isUndefined(onMounted)) {
+ onMounted(component, app)
+ }
}
-export type ToastInterface = ReturnType
+const createInterface = (events: EventBusInterface): ToastInterface => {
+ const createToastMethod = (
+ type: T
+ ): ToastMethod => {
+ const method: ToastMethod = (content, options) => {
+ const props: ToastOptionsAndContent & {
+ id: ToastID
+ } = Object.assign({ id: getId(), type, content }, options)
+ events.emit(EVENTS.ADD, props)
+ return props.id
+ }
+ return method
+ }
+
+ const dismiss: DismissToast = toastID => events.emit(EVENTS.DISMISS, toastID)
+ const clear: ClearToasts = () => events.emit(EVENTS.CLEAR, undefined)
+ const updateDefaults: UpdateDefaults = update =>
+ events.emit(EVENTS.UPDATE_DEFAULTS, asContainerProps(update))
+ const update: UpdateToast = (toastID, update, create) => {
+ const { content, options } = update
+ events.emit(EVENTS.UPDATE, {
+ id: toastID,
+ create: create || false,
+ options: { ...options, content: content as ToastContent },
+ })
+ }
+
+ return Object.assign(createToastMethod(TYPE.DEFAULT), {
+ success: createToastMethod(TYPE.SUCCESS),
+ info: createToastMethod(TYPE.INFO),
+ warning: createToastMethod(TYPE.WARNING),
+ error: createToastMethod(TYPE.ERROR),
+ dismiss,
+ clear,
+ update,
+ updateDefaults,
+ })
+}
+
+export const buildInterface = (
+ globalOptions: PluginOptions = {},
+ mountContainer = true
+): ToastInterface => {
+ const options = { ...globalOptions }
+ const events = (options.eventBus = options.eventBus || new EventBus())
+
+ if (mountContainer) {
+ nextTick(() => mountPlugin(options))
+ }
+ return createInterface(events)
+}
diff --git a/src/ts/plugin.ts b/src/ts/plugin.ts
new file mode 100644
index 0000000..8ab5302
--- /dev/null
+++ b/src/ts/plugin.ts
@@ -0,0 +1,20 @@
+import { Plugin } from "vue"
+
+import type { PluginOptions } from "../types/plugin"
+
+import { createToastInstance, toastInjectionKey } from "./composables/useToast"
+import { globalEventBus } from "./eventBus"
+
+export const VueToastificationPlugin: Plugin = (
+ App,
+ options?: PluginOptions
+) => {
+ if (options?.shareAppContext === true) {
+ options.shareAppContext = App
+ }
+ const inter = createToastInstance({
+ eventBus: globalEventBus,
+ ...options,
+ })
+ App.provide(toastInjectionKey, inter)
+}
diff --git a/src/ts/propValidators.ts b/src/ts/propValidators.ts
index 40e422c..7f991eb 100644
--- a/src/ts/propValidators.ts
+++ b/src/ts/propValidators.ts
@@ -1,42 +1,57 @@
/* eslint-disable @typescript-eslint/no-empty-function */
-import type { PluginOptions } from "../types"
-import { EventBus } from "./eventBus"
-import { POSITION, VT_NAMESPACE } from "./constants"
import { InferDefaults } from "../types/vue-helper"
+import type { ToastOptions } from "../types/toast"
+import type { ToastContainerOptions } from "../types/toastContainer"
+
+import { POSITION, VT_NAMESPACE, TYPE } from "./constants"
+import { EventBus } from "./eventBus"
+
+const defaultEventBus = /* istanbul ignore next */ () => new EventBus()
+const emptyFunction = /* istanbul ignore next */ () => {}
+
// This wraps a method to be returned as a factory function
const asFactory = (f: T) => (() => f) as unknown as T
-export const PLUGIN_DEFAULTS: Required>> =
- {
- accessibility: () => ({
- toastRole: "alert",
- closeButtonLabel: "close",
- }),
- bodyClassName: () => [],
- closeButton: () => "button",
- closeButtonClassName: () => [],
- closeOnClick: true,
- container: () => document.body,
- containerClassName: () => [],
- draggable: true,
- draggablePercent: 0.6,
- eventBus: /* istanbul ignore next */ () => new EventBus(),
- filterBeforeCreate: asFactory(toast => toast),
- filterToasts: asFactory(toasts => toasts),
- hideProgressBar: false,
- icon: () => true,
- maxToasts: 20,
- newestOnTop: true,
- onMounted: () => {},
- pauseOnFocusLoss: true,
- pauseOnHover: true,
- position: POSITION.TOP_RIGHT,
- rtl: false,
- shareAppContext: false,
- showCloseButtonOnHover: false,
- timeout: 5000,
- toastClassName: () => [],
- toastDefaults: () => ({}),
- transition: `${VT_NAMESPACE}__bounce`,
- }
+export const TOAST_DEFAULTS: Required>> = {
+ id: 0,
+ accessibility: () => ({
+ toastRole: "alert",
+ closeButtonLabel: "close",
+ }),
+ bodyClassName: () => [],
+ closeButton: () => "button",
+ closeButtonClassName: () => [],
+ closeOnClick: true,
+ draggable: true,
+ draggablePercent: 0.6,
+ eventBus: defaultEventBus,
+ hideProgressBar: false,
+ icon: () => true,
+ pauseOnFocusLoss: true,
+ pauseOnHover: true,
+ position: POSITION.TOP_RIGHT,
+ rtl: false,
+ showCloseButtonOnHover: false,
+ timeout: 5000,
+ toastClassName: () => [],
+ onClick: emptyFunction,
+ onClose: emptyFunction,
+ type: TYPE.DEFAULT,
+}
+
+export const TOAST_CONTAINER_DEFAULTS: Required<
+ InferDefaults>
+> = {
+ position: TOAST_DEFAULTS.position,
+ container: () => document.body,
+ containerClassName: () => [],
+ eventBus: defaultEventBus,
+ filterBeforeCreate: asFactory(toast => toast),
+ filterToasts: asFactory(toasts => toasts),
+ maxToasts: 20,
+ newestOnTop: true,
+ toastDefaults: () => ({}),
+ transition: `${VT_NAMESPACE}__bounce`,
+ defaultToastProps: /* istanbul ignore next */ () => ({}),
+}
diff --git a/src/ts/utils.ts b/src/ts/utils.ts
index 947e636..da85d47 100644
--- a/src/ts/utils.ts
+++ b/src/ts/utils.ts
@@ -1,9 +1,12 @@
import { Component, defineComponent, toRaw, unref } from "vue"
+
+import type { BasePluginOptions } from "../types/plugin"
import type {
ToastComponent,
ToastContent,
RenderableToastContent,
-} from "../types"
+} from "../types/toast"
+import type { ToastContainerOptions } from "../types/toastContainer"
interface DictionaryLike {
[index: string]: unknown
@@ -123,6 +126,43 @@ const normalizeToastComponent = (obj: ToastContent): ToastContent => {
const isBrowser = () => typeof window !== "undefined"
+const asContainerProps = (
+ options: BasePluginOptions
+): ToastContainerOptions => {
+ const {
+ position,
+ container,
+ newestOnTop,
+ maxToasts,
+ transition,
+ toastDefaults,
+ eventBus,
+ filterBeforeCreate,
+ filterToasts,
+ containerClassName,
+ ...defaultToastProps
+ } = options
+ const containerProps = {
+ position,
+ container,
+ newestOnTop,
+ maxToasts,
+ transition,
+ toastDefaults,
+ eventBus,
+ filterBeforeCreate,
+ filterToasts,
+ containerClassName,
+ defaultToastProps,
+ }
+ const keys = Object.keys(containerProps) as (keyof ToastContainerOptions)[]
+ keys.forEach(
+ key =>
+ typeof containerProps[key] === "undefined" && delete containerProps[key]
+ )
+ return containerProps
+}
+
export {
getId,
getX,
@@ -139,4 +179,5 @@ export {
isFunction,
isBrowser,
getProp,
+ asContainerProps,
}
diff --git a/src/types/common.ts b/src/types/common.ts
new file mode 100644
index 0000000..e91d516
--- /dev/null
+++ b/src/types/common.ts
@@ -0,0 +1,60 @@
+import type { Component } from "vue"
+
+import type { EventBusInterface } from "../ts/eventBus"
+
+export declare type ToastID = string | number
+
+export declare type ClassNames = string | string[]
+
+export declare interface EventBusable {
+ /**
+ * EventBus instance used to pass events across the interface
+ *
+ * Created by default, but you can use your own if you want
+ */
+ eventBus?: EventBusInterface
+}
+
+export declare interface Draggable {
+ /**
+ * Position of the toast on the screen.
+ *
+ * Can be any of top-right, top-center, top-left, bottom-right, bottom-center, bottom-left.
+ */
+ draggable?: boolean
+ /**
+ * By how much of the toast width in percent (0 to 1) it must be dragged before being dismissed.
+ */
+ draggablePercent?: number
+}
+
+export declare interface Hoverable {
+ /**
+ * Whether or not the toast is paused when it is hovered by the mouse.
+ */
+ pauseOnHover?: boolean
+}
+
+export declare interface Focusable {
+ /**
+ * Whether or not the toast is paused when the window loses focus.
+ */
+ pauseOnFocusLoss?: boolean
+}
+
+export declare type Icon =
+ | boolean
+ | string
+ | {
+ iconTag?: keyof HTMLElementTagNameMap
+ iconChildren?: string
+ iconClass?: string
+ }
+ | Component
+ | JSX.Element
+
+export declare type Button =
+ | false
+ | keyof HTMLElementTagNameMap
+ | Component
+ | JSX.Element
diff --git a/src/types/index.ts b/src/types/index.ts
deleted file mode 100644
index 63d082c..0000000
--- a/src/types/index.ts
+++ /dev/null
@@ -1,233 +0,0 @@
-import type { App, Component, ComponentPublicInstance } from "vue"
-import type { EventBusInterface } from "../ts/eventBus"
-import type { TYPE, POSITION } from "../ts/constants"
-
-export type ToastID = string | number
-
-export type ClassNames = string | string[]
-
-export interface CommonOptions {
- /**
- * Position of the toast on the screen.
- *
- * Can be any of top-right, top-center, top-left, bottom-right, bottom-center, bottom-left.
- */
- position?: POSITION
- /**
- * Position of the toast on the screen.
- *
- * Can be any of top-right, top-center, top-left, bottom-right, bottom-center, bottom-left.
- */
- draggable?: boolean
- /**
- * By how much of the toast width in percent (0 to 1) it must be dragged before being dismissed.
- */
- draggablePercent?: number
- /**
- * Whether or not the toast is paused when the window loses focus.
- */
- pauseOnFocusLoss?: boolean
- /**
- * Whether or not the toast is paused when it is hovered by the mouse.
- */
- pauseOnHover?: boolean
- /**
- * Whether or not the toast is closed when clicked.
- */
- closeOnClick?: boolean
- /**
- * How many milliseconds for the toast to be auto dismissed, or false to disable.
- */
- timeout?: number | false
- /**
- * Custom classes applied to the toast.
- */
- toastClassName?: ClassNames
- /**
- * Custom classes applied to the body of the toast.
- */
- bodyClassName?: ClassNames
- /**
- * Whether or not the progress bar is hidden.
- */
- hideProgressBar?: boolean
- /**
- * Only shows the close button when hovering the toast
- */
- showCloseButtonOnHover?: boolean
- /**
- * Custom icon class to be used.
- *
- * When set to `true`, the icon is set automatically depending on the toast type and `false` disables the icon.
- */
- icon?:
- | boolean
- | string
- | {
- iconTag?: keyof HTMLElementTagNameMap
- iconChildren?: string
- iconClass?: string
- }
- | Component
- | JSX.Element
- /**
- * Custom close button component
- *
- * Alternative close button component to be displayed in toasts
- */
- closeButton?: false | keyof HTMLElementTagNameMap | Component | JSX.Element
- /**
- * Custom classes applied to the close button of the toast.
- */
- closeButtonClassName?: ClassNames
- /**
- * Accessibility options
- */
- accessibility?: {
- /**
- * Toast accessibility role
- *
- * Accessibility option "role" for screen readers. Defaults to "alert".
- */
- toastRole?: string
- /**
- * Close button label
- *
- * Accessibility option of the closeButton's "label" for screen readers. Defaults to "close".
- */
- closeButtonLabel?: string
- }
- /**
- * Right-to-Left support.
- *
- * If true, switches the toast contents from right to left. Defaults to false.
- */
- rtl?: boolean
- /**
- * EventBus instance used to pass events across the interface
- *
- * Created by default, but you can use your own if you want
- */
- eventBus?: EventBusInterface
-}
-
-type ContainerCallback = () => HTMLElement | Promise
-
-export interface PluginOptions extends CommonOptions {
- /**
- * Container where the toasts are mounted.
- */
- container?: HTMLElement | ContainerCallback
- /**
- * Whether or not the newest toasts are placed on the top of the stack.
- */
- newestOnTop?: boolean
- /**
- * Maximum number of toasts on each stack at a time. Overflows wait until older toasts are dismissed to appear.
- */
- maxToasts?: number
- /**
- * Name of the Vue Transition or object with classes to use.
- *
- * Only `enter-active`, `leave-active` and `move` are applied.
- */
- transition?: string | Record<"enter" | "leave" | "move", string>
- /**
- * Toast's defaults object for configuring default toast options for each toast type.
- *
- * Possible object properties can be any of `success error default info warning`
- */
- toastDefaults?: Partial>
- /**
- * Callback to filter toasts during creation
- *
- * Takes the new toast and a list of the current toasts and returns a modified toast or false.
- */
- filterBeforeCreate?: (
- toast: ToastOptionsAndRequiredContent,
- toasts: ToastOptionsAndRequiredContent[]
- ) => ToastOptionsAndRequiredContent | false
- /**
- * Callback to filter toasts during render
- *
- * Filter toasts during render and queues filtered toasts.
- */
- filterToasts?: (
- toasts: ToastOptionsAndRequiredContent[]
- ) => ToastOptionsAndRequiredContent[]
- /**
- * Extra CSS class or classes added to each of the Toast containers.
- *
- * Keep in mind that there is one container for each possible toast position.
- */
- containerClassName?: ClassNames
- /**
- * Callback executed when the toast container is mounted.
- *
- * Receives the Container vue instance as a parameter.
- */
- onMounted?: (
- containerComponent: ComponentPublicInstance,
- containerApp: App
- ) => void
- /**
- * Shares the context of your app with your toasts
- *
- * This allows toasts to use your app's plugins, mixins, global components, etc.
- *
- * If you set it to `true`, the app wherein the plugin is installed will be used.
- * You may also provide the app instance you wish to use.
- */
- shareAppContext?: boolean | App
-}
-
-export interface ToastOptions extends CommonOptions {
- /**
- * ID of the toast.
- */
- id?: ToastID
- /**
- * Type of the toast.
- *
- * Can be any of `success error default info warning`
- */
- type?: TYPE
- /**
- * Callback executed when the toast is clicked.
- *
- * A closeToast callback is passed as argument to onClick when it is called.
- */
- // eslint-disable-next-line @typescript-eslint/ban-types
- onClick?: (closeToast: Function) => void
- /**
- * Callback executed when the toast is closed.
- */
- onClose?: () => void
-}
-
-export type RenderableToastContent = string | Component
-
-export interface ToastComponent {
- /**
- * Component that will be rendered.
- */
- component: ToastContent
- /**
- * `propName: propValue` pairs of props that will be passed to the component.
- *
- * __These are not reactive__
- */
- props?: { [propName: string]: unknown }
- /**
- * `eventName: eventHandler` pairs of events that the component can emit.
- */
- // eslint-disable-next-line @typescript-eslint/ban-types
- listeners?: { [listenerEvent: string]: Function }
-}
-
-export type ToastContent = RenderableToastContent | JSX.Element | ToastComponent
-
-export type ToastOptionsAndContent = ToastOptions & { content?: ToastContent }
-export type ToastOptionsAndRequiredContent = ToastOptions & {
- content: ToastContent
-}
diff --git a/src/types/plugin.ts b/src/types/plugin.ts
new file mode 100644
index 0000000..b3194b3
--- /dev/null
+++ b/src/types/plugin.ts
@@ -0,0 +1,29 @@
+import type { App, ComponentPublicInstance } from "vue"
+
+import type { BaseToastOptions } from "./toast"
+import type { BaseToastContainerOptions } from "./toastContainer"
+
+export declare interface BasePluginOptions
+ extends BaseToastContainerOptions,
+ BaseToastOptions {}
+
+export declare interface PluginOptions extends BasePluginOptions {
+ /**
+ * Callback executed when the toast container is mounted.
+ *
+ * Receives the Container vue instance as a parameter.
+ */
+ onMounted?: (
+ containerComponent: ComponentPublicInstance,
+ containerApp: App
+ ) => void
+ /**
+ * Shares the context of your app with your toasts
+ *
+ * This allows toasts to use your app's plugins, mixins, global components, etc.
+ *
+ * If you set it to `true`, the app wherein the plugin is installed will be used.
+ * You may also provide the app instance you wish to use.
+ */
+ shareAppContext?: boolean | App
+}
diff --git a/src/types/toast.ts b/src/types/toast.ts
new file mode 100644
index 0000000..f2c94f7
--- /dev/null
+++ b/src/types/toast.ts
@@ -0,0 +1,143 @@
+import type { Component } from "vue"
+
+import type { TYPE, POSITION } from "../ts/constants"
+import type {
+ Button,
+ ClassNames,
+ Draggable,
+ EventBusable,
+ Focusable,
+ Hoverable,
+ Icon,
+ ToastID,
+} from "./common"
+
+export declare interface BaseToastOptions
+ extends EventBusable,
+ Draggable,
+ Hoverable,
+ Focusable {
+ /**
+ * Position of the toast on the screen.
+ *
+ * Can be any of top-right, top-center, top-left, bottom-right, bottom-center, bottom-left.
+ */
+ position?: POSITION
+
+ /**
+ * Whether or not the toast is closed when clicked.
+ */
+ closeOnClick?: boolean
+ /**
+ * How many milliseconds for the toast to be auto dismissed, or false to disable.
+ */
+ timeout?: number | false
+ /**
+ * Custom classes applied to the toast.
+ */
+ toastClassName?: ClassNames
+ /**
+ * Custom classes applied to the body of the toast.
+ */
+ bodyClassName?: ClassNames
+ /**
+ * Whether or not the progress bar is hidden.
+ */
+ hideProgressBar?: boolean
+ /**
+ * Only shows the close button when hovering the toast
+ */
+ showCloseButtonOnHover?: boolean
+ /**
+ * Custom icon class to be used.
+ *
+ * When set to `true`, the icon is set automatically depending on the toast type and `false` disables the icon.
+ */
+ icon?: Icon
+ /**
+ * Custom close button component
+ *
+ * Alternative close button component to be displayed in toasts
+ */
+ closeButton?: Button
+ /**
+ * Custom classes applied to the close button of the toast.
+ */
+ closeButtonClassName?: ClassNames
+ /**
+ * Accessibility options
+ */
+ accessibility?: {
+ /**
+ * Toast accessibility role
+ *
+ * Accessibility option "role" for screen readers. Defaults to "alert".
+ */
+ toastRole?: string
+ /**
+ * Close button label
+ *
+ * Accessibility option of the closeButton's "label" for screen readers. Defaults to "close".
+ */
+ closeButtonLabel?: string
+ }
+ /**
+ * Right-to-Left support.
+ *
+ * If true, switches the toast contents from right to left. Defaults to false.
+ */
+ rtl?: boolean
+}
+
+export declare interface ToastOptions extends BaseToastOptions {
+ /**
+ * ID of the toast.
+ */
+ id?: ToastID
+ /**
+ * Type of the toast.
+ *
+ * Can be any of `success error default info warning`
+ */
+ type?: TYPE
+ /**
+ * Callback executed when the toast is clicked.
+ *
+ * A closeToast callback is passed as argument to onClick when it is called.
+ */
+ // eslint-disable-next-line @typescript-eslint/ban-types
+ onClick?: (closeToast: Function) => void
+ /**
+ * Callback executed when the toast is closed.
+ */
+ onClose?: () => void
+}
+
+export declare type RenderableToastContent = string | Component
+
+export declare interface ToastComponent {
+ /**
+ * Component that will be rendered.
+ */
+ component: ToastContent
+ /**
+ * `propName: propValue` pairs of props that will be passed to the component.
+ *
+ * __These are not reactive__
+ */
+ props?: { [propName: string]: unknown }
+ /**
+ * `eventName: eventHandler` pairs of events that the component can emit.
+ */
+ // eslint-disable-next-line @typescript-eslint/ban-types
+ listeners?: { [listenerEvent: string]: Function }
+}
+
+export declare type ToastContent =
+ | RenderableToastContent
+ | JSX.Element
+ | ToastComponent
+
+export declare type ToastOptionsAndContent = ToastOptions & {
+ content: ToastContent
+}
diff --git a/src/types/toastContainer.ts b/src/types/toastContainer.ts
new file mode 100644
index 0000000..c1016e2
--- /dev/null
+++ b/src/types/toastContainer.ts
@@ -0,0 +1,63 @@
+import type { TYPE } from "../ts/constants"
+import type { ClassNames, EventBusable } from "./common"
+import type {
+ BaseToastOptions,
+ ToastOptions,
+ ToastOptionsAndContent,
+} from "./toast"
+
+type ContainerCallback = () => HTMLElement | Promise
+
+export declare interface BaseToastContainerOptions extends EventBusable {
+ position?: BaseToastOptions["position"]
+ /**
+ * Container where the toasts are mounted.
+ */
+ container?: HTMLElement | ContainerCallback
+ /**
+ * Whether or not the newest toasts are placed on the top of the stack.
+ */
+ newestOnTop?: boolean
+ /**
+ * Maximum number of toasts on each stack at a time. Overflows wait until older toasts are dismissed to appear.
+ */
+ maxToasts?: number
+ /**
+ * Name of the Vue Transition or object with classes to use.
+ *
+ * Only `enter-active`, `leave-active` and `move` are applied.
+ */
+ transition?: string | Record<"enter" | "leave" | "move", string>
+ /**
+ * Toast's defaults object for configuring default toast options for each toast type.
+ *
+ * Possible object properties can be any of `success error default info warning`
+ */
+ toastDefaults?: Partial>
+ /**
+ * Callback to filter toasts during creation
+ *
+ * Takes the new toast and a list of the current toasts and returns a modified toast or false.
+ */
+ filterBeforeCreate?: (
+ toast: ToastOptionsAndContent,
+ toasts: ToastOptionsAndContent[]
+ ) => ToastOptionsAndContent | false
+ /**
+ * Callback to filter toasts during render
+ *
+ * Filter toasts during render and queues filtered toasts.
+ */
+ filterToasts?: (toasts: ToastOptionsAndContent[]) => ToastOptionsAndContent[]
+ /**
+ * Extra CSS class or classes added to each of the Toast containers.
+ *
+ * Keep in mind that there is one container for each possible toast position.
+ */
+ containerClassName?: ClassNames
+}
+
+export declare interface ToastContainerOptions
+ extends BaseToastContainerOptions {
+ defaultToastProps?: BaseToastOptions
+}
diff --git a/tests/unit/components/VtCloseButton.spec.ts b/tests/unit/components/VtCloseButton.spec.ts
index 9e04139..b024a0a 100644
--- a/tests/unit/components/VtCloseButton.spec.ts
+++ b/tests/unit/components/VtCloseButton.spec.ts
@@ -1,5 +1,7 @@
-import { mount } from "@vue/test-utils"
import { markRaw } from "vue"
+
+import { mount } from "@vue/test-utils"
+
import VtCloseButton from "../../../src/components/VtCloseButton.vue"
import { VT_NAMESPACE } from "../../../src/ts/constants"
import Simple from "../../utils/components/Simple.vue"
diff --git a/tests/unit/components/VtIcon.spec.ts b/tests/unit/components/VtIcon.spec.ts
index 73fcced..5cf78cd 100644
--- a/tests/unit/components/VtIcon.spec.ts
+++ b/tests/unit/components/VtIcon.spec.ts
@@ -1,12 +1,14 @@
+import { markRaw } from "vue"
+
import { mount } from "@vue/test-utils"
-import { TYPE, VT_NAMESPACE } from "../../../src/ts/constants"
-import VtIcon from "../../../src/components/VtIcon.vue"
-import VtSuccessIcon from "../../../src/components/icons/VtSuccessIcon.vue"
+
+import VtErrorIcon from "../../../src/components/icons/VtErrorIcon.vue"
import VtInfoIcon from "../../../src/components/icons/VtInfoIcon.vue"
+import VtSuccessIcon from "../../../src/components/icons/VtSuccessIcon.vue"
import VtWarningIcon from "../../../src/components/icons/VtWarningIcon.vue"
-import VtErrorIcon from "../../../src/components/icons/VtErrorIcon.vue"
+import VtIcon from "../../../src/components/VtIcon.vue"
+import { TYPE, VT_NAMESPACE } from "../../../src/ts/constants"
import Simple from "../../utils/components/Simple.vue"
-import { markRaw } from "vue"
describe("VtIcon", () => {
describe("snapshots", () => {
diff --git a/tests/unit/components/VtProgressBar.spec.ts b/tests/unit/components/VtProgressBar.spec.ts
index caf902e..3ed16ab 100644
--- a/tests/unit/components/VtProgressBar.spec.ts
+++ b/tests/unit/components/VtProgressBar.spec.ts
@@ -1,5 +1,7 @@
-import { mount } from "@vue/test-utils"
import { nextTick } from "vue"
+
+import { mount } from "@vue/test-utils"
+
import VtProgressBar from "../../../src/components/VtProgressBar.vue"
import { VT_NAMESPACE } from "../../../src/ts/constants"
diff --git a/tests/unit/components/VtToast.spec.ts b/tests/unit/components/VtToast.spec.ts
index 9ce80e8..0bae3b5 100644
--- a/tests/unit/components/VtToast.spec.ts
+++ b/tests/unit/components/VtToast.spec.ts
@@ -1,16 +1,19 @@
import { ComponentPublicInstance, nextTick, ref } from "vue"
+
import { mount, VueWrapper } from "@vue/test-utils"
import merge from "lodash.merge"
-import VtToast from "../../../src/components/VtToast.vue"
+
+import { EventBus } from "../../../src"
+import VtCloseButton from "../../../src/components/VtCloseButton.vue"
import VtIcon from "../../../src/components/VtIcon.vue"
import VtProgressBar from "../../../src/components/VtProgressBar.vue"
-import VtCloseButton from "../../../src/components/VtCloseButton.vue"
-import { ToastOptionsAndContent } from "../../../src/types"
+import VtToast from "../../../src/components/VtToast.vue"
+import * as useDraggableModule from "../../../src/ts/composables/useDraggable"
import { VT_NAMESPACE, TYPE, POSITION, EVENTS } from "../../../src/ts/constants"
-import Simple from "../../utils/components/Simple.vue"
-import { EventBus } from "../../../src"
import { normalizeToastComponent } from "../../../src/ts/utils"
-import * as useDraggableModule from "../../../src/ts/composables/useDraggable"
+import Simple from "../../utils/components/Simple.vue"
+
+import type { ToastOptionsAndContent } from "../../../src/types/toast"
const setData = (
wrapper: VueWrapper,
@@ -19,7 +22,11 @@ const setData = (
merge(wrapper.vm, override)
}
-const mountToast = ({ id, content, ...props }: ToastOptionsAndContent = {}) =>
+const mountToast = ({
+ id,
+ content,
+ ...props
+}: Partial = {}) =>
mount(VtToast, {
props: {
id: id || 1,
diff --git a/tests/unit/components/VtToastContainer.spec.ts b/tests/unit/components/VtToastContainer.spec.ts
index 7d67fba..0739e44 100644
--- a/tests/unit/components/VtToastContainer.spec.ts
+++ b/tests/unit/components/VtToastContainer.spec.ts
@@ -1,17 +1,25 @@
-import { PluginOptions } from "../../../src/types"
-import { EVENTS, POSITION, TYPE } from "../../../src/ts/constants"
-import VtToastContainer from "../../../src/components/VtToastContainer.vue"
-import VtToast from "../../../src/components/VtToast.vue"
-import VtProgressBar from "../../../src/components/VtProgressBar.vue"
import { ComponentPublicInstance, h, nextTick } from "vue"
+
import { mount, VueWrapper } from "@vue/test-utils"
-import { createToastInterface, EventBus } from "../../../src"
+
+import { createToastInstance, EventBus } from "../../../src"
+import VtProgressBar from "../../../src/components/VtProgressBar.vue"
+import VtToast from "../../../src/components/VtToast.vue"
+import VtToastContainer from "../../../src/components/VtToastContainer.vue"
+import { EVENTS, POSITION, TYPE } from "../../../src/ts/constants"
+import { asContainerProps } from "../../../src/ts/utils"
+
+import type { PluginOptions } from "../../../src/types/plugin"
const mountToastContainer = async (props: PluginOptions = {}) => {
const eventBus = new EventBus()
- const toast = createToastInterface(eventBus)
+ const toast = createToastInstance(eventBus)
+ const options: PluginOptions = {
+ eventBus,
+ ...props,
+ }
const wrapper = mount(VtToastContainer, {
- props: { container: undefined, eventBus, ...props },
+ props: { container: undefined, ...asContainerProps(options) },
})
await nextTick()
return {
diff --git a/tests/unit/components/VtTransition.spec.ts b/tests/unit/components/VtTransition.spec.ts
index 6e07eda..5183b7d 100644
--- a/tests/unit/components/VtTransition.spec.ts
+++ b/tests/unit/components/VtTransition.spec.ts
@@ -1,5 +1,7 @@
import { TransitionGroup } from "vue"
+
import { mount } from "@vue/test-utils"
+
import VtTransition from "../../../src/components/VtTransition.vue"
const asEmitter = (arg: unknown) =>
diff --git a/tests/unit/components/__snapshots__/VtIcon.spec.ts.snap b/tests/unit/components/__snapshots__/VtIcon.spec.ts.snap
index 6f91cc7..0c939d9 100644
--- a/tests/unit/components/__snapshots__/VtIcon.spec.ts.snap
+++ b/tests/unit/components/__snapshots__/VtIcon.spec.ts.snap
@@ -43,9 +43,7 @@ exports[`VtIcon renders custom components renders custom icon tag 1`] = `
exports[`VtIcon renders custom components renders regular icon if true 1`] = `