diff --git a/README.md b/README.md index 038d07e5..7c5e6d86 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,9 @@ pnpm build:vfm # Run both docs and viteplay pnpm dev +# Run dev for vue-final-modal +pnpm dev:vfm + # Run docs: http://localhost:3000/ pnpm dev:docs diff --git a/docs/app.config.ts b/docs/app.config.ts index 599232c4..b78223c5 100644 --- a/docs/app.config.ts +++ b/docs/app.config.ts @@ -2,19 +2,21 @@ export default defineAppConfig({ docus: { title: 'Vue Final Modal', description: 'Vue Final Modal is the most powerful yet most light-weight modal library for Vue 3', - layout: 'docs', + layout: 'default', image: 'https://vue-final-modal.org/preview.png', url: 'https://vue-final-modal.org', socials: { twitter: '@hunterliu1003', github: 'vue-final/vue-final-modal', }, - github: true, aside: { level: 1, }, header: { - logo: true, + logo: { + dark: '/logo-new.svg', + light: '/logo-new.svg', + }, }, footer: {}, }, diff --git a/docs/components/content/LoginFormVorms.vue b/docs/components/content/LoginFormVorms.vue index 2cab54c8..2c4431e3 100644 --- a/docs/components/content/LoginFormVorms.vue +++ b/docs/components/content/LoginFormVorms.vue @@ -33,7 +33,9 @@ const { value: remember, attrs: rememberAttrs } = register('remember') - - diff --git a/docs/components/content/ModalBottom.vue b/docs/components/content/ModalBottom.vue index baf78fc0..bbea0e46 100644 --- a/docs/components/content/ModalBottom.vue +++ b/docs/components/content/ModalBottom.vue @@ -16,7 +16,9 @@ defineProps<{

{{ title }}

-
Swipe down to close the modal
+
+ Swipe down to close the modal +
diff --git a/docs/content/2.get-started/1.guide/2.setup.md b/docs/content/2.get-started/1.guide/2.setup.md index dbce3c46..14a3f7bf 100644 --- a/docs/content/2.get-started/1.guide/2.setup.md +++ b/docs/content/2.get-started/1.guide/2.setup.md @@ -60,7 +60,7 @@ export default defineNuxtPlugin((nuxtApp) => { ## Import required CSS -vue-final-modal 4 has tiny size of required CSS (gzipped 0.49kb). All classes have a `.vfm-` prefix, so you don't have to worry about any CSS pollution. _[See style of ``.](https://github.com/vue-final/vue-final-modal/blob/v4/packages/vue-final-modal/src/components/CoreModal/CoreModal.vue#L184-L217)_ +vue-final-modal 4 has tiny size of required CSS (gzipped 0.49kb). All classes have a `.vfm-` prefix, so you don't have to worry about any CSS pollution. ### Vue 3 diff --git a/docs/content/2.get-started/1.guide/3.migration-guide.md b/docs/content/2.get-started/1.guide/3.migration-guide.md index c9d64f5d..6779b59e 100644 --- a/docs/content/2.get-started/1.guide/3.migration-guide.md +++ b/docs/content/2.get-started/1.guide/3.migration-guide.md @@ -125,11 +125,6 @@ open() `params` is not a good practice and hard to keep type-save in Typescript. So if you are using `params`, you have to re-written it with [useModal()](/api/composables/use-modal) composable. -### Removed `event.stop()` from both `@before-close` and `@before-open` - -`event.stop()` made the source code hard to read and maintain. -It's easy to have a condition before open or before close the modal. So it's not a required feature. - ### Delete Drag & Resize To keep vue-final-modal simple and easier to maintain, I decided to remove the Drag & Resize feature. diff --git a/docs/content/2.get-started/1.guide/4.types.md b/docs/content/2.get-started/1.guide/4.types.md index edb71124..5de9f844 100644 --- a/docs/content/2.get-started/1.guide/4.types.md +++ b/docs/content/2.get-started/1.guide/4.types.md @@ -2,12 +2,6 @@ The exported types in VueFinalModal. -## ComponentProps - -```ts -export type ComponentProps = ComponentPublicInstance['$props'] -``` - ## ModalId ```ts @@ -23,18 +17,18 @@ export type StyleValue = string | CSSProperties | (string | CSSProperties)[] ## ModalSlot ```ts -export interface ModalSlotOptions { component: Raw; attrs?: Record } -export type ModalSlot = string | Component | ModalSlotOptions +export interface ModalSlotOptions { component: Raw; attrs?: Record } +export type ModalSlot = string | ComponentType | ModalSlotOptions ``` ## UseModalOptions ```ts -export type UseModalOptions

= { +export type UseModalOptions = { defaultModelValue?: boolean keepAlive?: boolean - component?: Constructor

- attrs?: (RawProps & P) | ({} extends P ? null : never) + component?: T + attrs?: ComponentProps slots?: { [key: string]: ModalSlot } @@ -55,11 +49,11 @@ export type UseModalOptionsPrivate = { ## UseModalReturnType ```ts -export interface UseModalReturnType

{ - options: UseModalOptions

& UseModalOptionsPrivate +export interface UseModalReturnType { + options: UseModalOptions & UseModalOptionsPrivate open: () => Promise close: () => Promise - patchOptions: (options: Partial>) => void + patchOptions: (options: Partial>) => void destroy: () => void } ``` diff --git a/docs/content/3.api/1.components/1.vue-final-modal.md b/docs/content/3.api/1.components/1.vue-final-modal.md index 66aec4d2..1ff0a473 100644 --- a/docs/content/3.api/1.components/1.vue-final-modal.md +++ b/docs/content/3.api/1.components/1.vue-final-modal.md @@ -228,9 +228,11 @@ When set `:preventNavigationGestures="true"`{lang=ts}, there will be two invisib ## Events -- `(e: 'beforeOpen'): void`{lang=ts}: Emits while modal is still invisible, but before transition starting. +- `(e: 'beforeOpen', event: { stop: () => void }): void`{lang=ts}: Emits while modal is still invisible, but before transition starting. + - `event.stop()` is use to prevent the modal from opening. - `(e: 'opened'): void`{lang=ts}: Emits after modal became visible and transition ended. -- `(e: 'beforeClose'): void`{lang=ts}: Emits before modal is going to be closed. +- `(e: 'beforeClose', event: { stop: () => void }): void`{lang=ts}: Emits before modal is going to be closed. + - `event.stop()` is use to prevent the modal from closing. - `(e: 'closed'): void`{lang=ts}: Emits right before modal is destroyed. - `(e: 'clickOutside'): void`{lang=ts}: Emits while `.vfm` element on click. @@ -238,4 +240,16 @@ When set `:preventNavigationGestures="true"`{lang=ts}, there will be two invisib - The `default`{lang=ts} slot can be used to render the modal content. +You can also use scoped slots to close modal, for example: + +```html + + + +``` + - The `swipe-banner`{lang=ts} slot can be used to define the area that can be swipe to close diff --git a/docs/content/3.api/2.composables/1.use-modal.md b/docs/content/3.api/2.composables/1.use-modal.md index ecb11339..2a792f20 100644 --- a/docs/content/3.api/2.composables/1.use-modal.md +++ b/docs/content/3.api/2.composables/1.use-modal.md @@ -44,6 +44,7 @@ const { open, close, destroy, options, patchOptions } = useModal({ clickToClose: true, escToClose: true, // Bind events to the modal component (VueFinalModal in this case). + // Any custom events can be listened for when prefixed with "on", e.g. "onEventName". onBeforeOpen() { /* on before open */ }, onOpened() { /* on opened */ }, onBeforeClose() { /* on before close */ }, diff --git a/docs/package.json b/docs/package.json index 97ea9a69..850eb2b3 100644 --- a/docs/package.json +++ b/docs/package.json @@ -9,9 +9,9 @@ "preview": "nuxi preview" }, "devDependencies": { - "@nuxt-themes/docus": "^1.10.1", - "@nuxtjs/tailwindcss": "^6.6.4", - "nuxt": "^3.3.2" + "@nuxt-themes/docus": "^1.15.0", + "@nuxtjs/tailwindcss": "^6.10.1", + "nuxt": "^3.8.2" }, "dependencies": { "@vorms/core": "^1.1.0", diff --git a/examples/nuxt3/nuxt.config.ts b/examples/nuxt3/nuxt.config.ts index eaa94295..87388f85 100644 --- a/examples/nuxt3/nuxt.config.ts +++ b/examples/nuxt3/nuxt.config.ts @@ -1,5 +1,4 @@ export default defineNuxtConfig({ extends: '@nuxt-themes/docus', - modules: ['@nuxtjs/tailwindcss'], - css: ['vue-final-modal/style.css'], + modules: ['@nuxtjs/tailwindcss', '@vue-final-modal/nuxt'], }) diff --git a/examples/nuxt3/package.json b/examples/nuxt3/package.json index a0d9420e..b220fe8b 100644 --- a/examples/nuxt3/package.json +++ b/examples/nuxt3/package.json @@ -9,9 +9,9 @@ "postinstall": "nuxt prepare" }, "devDependencies": { - "@nuxt-themes/docus": "^1.6.0", - "@nuxtjs/tailwindcss": "^6.2.0", - "nuxt": "3.1.0" + "@nuxt-themes/docus": "^1.15.0", + "@nuxtjs/tailwindcss": "^6.10.1", + "nuxt": "3.8.2" }, "dependencies": { "@vue-final-modal/nuxt": "^1.0.2", diff --git a/examples/nuxt3/plugins/vfm.ts b/examples/nuxt3/plugins/vfm.ts deleted file mode 100644 index 1ed0afc3..00000000 --- a/examples/nuxt3/plugins/vfm.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { createVfm } from 'vue-final-modal' - -export default defineNuxtPlugin((nuxtApp) => { - const vfm = createVfm() - nuxtApp.vueApp.use(vfm) -}) diff --git a/examples/vue3/package.json b/examples/vue3/package.json index 185a937c..195c41f0 100644 --- a/examples/vue3/package.json +++ b/examples/vue3/package.json @@ -5,21 +5,20 @@ "type": "module", "scripts": { "dev": "vite", - "build": "vue-tsc && vite build", + "build": "vite build", "preview": "vite preview" }, "dependencies": { - "vue": "^3.3.4", + "vue": "^3.3.7", "vue-final-modal": "^4.4.6" }, "devDependencies": { - "@iconify/vue": "^4.0.0", - "@vitejs/plugin-vue": "^4.2.3", - "autoprefixer": "^10.4.13", - "postcss": "^8.4.21", - "tailwindcss": "^3.2.4", - "typescript": "^5.1.6", - "vite": "^4.3.9", - "vue-tsc": "^1.8.3" + "@iconify/vue": "^4.1.1", + "@vitejs/plugin-vue": "^4.5.0", + "autoprefixer": "^10.4.16", + "postcss": "^8.4.31", + "tailwindcss": "^3.3.5", + "typescript": "^5.3.2", + "vite": "^5.0.3" } } \ No newline at end of file diff --git a/package.json b/package.json index ba5435c5..1200bdf5 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "vfm", "private": true, "scripts": { - "dev": "concurrently \"pnpm:dev:*\"", + "dev": "concurrently \"pnpm:dev:docs\" \"pnpm:dev:viteplay\"", "dev:docs": "pnpm --filter docs dev", "build:docs": "pnpm --filter docs build", "generate:docs": "pnpm --filter docs generate", @@ -18,19 +18,18 @@ "postinstall": "pnpm build:vfm && pnpm prepare:module" }, "dependencies": { - "vue": "^3.3.4" + "vue": "^3.3.7" }, "devDependencies": { "@antfu/eslint-config": "^0.37.0", - "@types/node": "^18.15.10", - "@vitejs/plugin-vue": "^4.2.3", + "@types/node": "^20.10.0", + "@vitejs/plugin-vue": "^4.5.0", "@vue/test-utils": "^2.3.2", - "concurrently": "^7.6.0", + "concurrently": "^8.2.2", "eslint": "^8.36.0", - "pnpm": "^8.10.2", - "sass": "^1.60.0", - "typescript": "^5.1.6", - "vite": "^4.3.9", - "vue-tsc": "^1.8.3" + "pnpm": "^8.11.0", + "typescript": "^5.3.2", + "vite": "^5.0.3", + "vue-tsc": "1.8.20" } } \ No newline at end of file diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index bf6db573..718047fb 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -23,14 +23,14 @@ "release": "pnpm prepack && release-it" }, "dependencies": { - "@nuxt/kit": "^3.3.2", + "@nuxt/kit": "^3.8.2", "vue-final-modal": "^4.4.6" }, "devDependencies": { - "@nuxt/module-builder": "^0.2.1", - "@nuxt/schema": "^3.3.2", - "@nuxtjs/eslint-config-typescript": "^12.0.0", - "nuxt": "^3.3.2", + "@nuxt/module-builder": "^0.5.4", + "@nuxt/schema": "^3.8.2", + "@nuxtjs/eslint-config-typescript": "^12.1.0", + "nuxt": "^3.8.2", "release-it": "^16.1.3" }, "peerDependencies": { diff --git a/packages/nuxt/src/module.ts b/packages/nuxt/src/module.ts index b54d790d..7e5cdddd 100644 --- a/packages/nuxt/src/module.ts +++ b/packages/nuxt/src/module.ts @@ -6,10 +6,10 @@ export default defineNuxtModule({ configKey: 'vue-final-modal', }, setup(options, nuxt) { - const resolver = createResolver(import.meta.url) + const { resolve } = createResolver(import.meta.url) // Transpile runtime - nuxt.options.build.transpile.push(resolver.resolve('./runtime')) + nuxt.options.build.transpile.push(resolve('./runtime')) nuxt.hook('prepare:types', ({ references }) => { references.push({ types: '@vue-final-modal/nuxt' }) @@ -18,7 +18,7 @@ export default defineNuxtModule({ // Add runtime plugin before the router plugin // https://github.com/nuxt/framework/issues/9130 nuxt.hook('modules:done', () => { - addPlugin(resolver.resolve('./runtime/plugin')) + addPlugin(resolve('./runtime/plugin')) }) nuxt.options.css.push('vue-final-modal/style.css') diff --git a/packages/vue-final-modal/cypress/components/useZIndex.spec.ts b/packages/vue-final-modal/cypress/components/useZIndex.spec.ts index 1d477bb1..9075bb98 100644 --- a/packages/vue-final-modal/cypress/components/useZIndex.spec.ts +++ b/packages/vue-final-modal/cypress/components/useZIndex.spec.ts @@ -25,24 +25,22 @@ describe('Test useZIndex()', () => { stubs: { transition: false }, }, }).as('app') - cy.get('@app').then(() => { - firstModal.open() - }) + + cy.get('@app').then(() => firstModal.open()) cy.get('.first-modal').should(($el) => { expect($el).to.have.css('zIndex', '1000') }) - cy.get('@app').then(() => { - secondModal.open() - }) + + cy.get('@app').then(() => secondModal.open()) cy.get('.second-modal').should(($el) => { expect($el).to.have.css('zIndex', '1002') }) - cy.get('@app').then(() => { - thirdModal.open() - }) + + cy.get('@app').then(() => thirdModal.open()) cy.get('.third-modal').should(($el) => { expect($el).to.have.css('zIndex', '1004') }) + cy.get('@app').then(() => { thirdModal.patchOptions({ attrs: { @@ -53,9 +51,8 @@ describe('Test useZIndex()', () => { cy.get('.third-modal').should(($el) => { expect($el).to.have.css('zIndex', '1238') }) - cy.get('@app').then(() => { - firstModal.close() - }) + + cy.get('@app').then(() => firstModal.close()) cy.get('.second-modal').should(($el) => { expect($el).to.have.css('zIndex', '1000') }) diff --git a/packages/vue-final-modal/package.json b/packages/vue-final-modal/package.json index db66111c..706ca3af 100644 --- a/packages/vue-final-modal/package.json +++ b/packages/vue-final-modal/package.json @@ -2,13 +2,14 @@ "name": "vue-final-modal", "private": false, "version": "4.4.6", + "type": "module", "source": "src/index.ts", "main": "./dist/index.umd.js", - "module": "./dist/index.es.js", + "module": "./dist/index.es.mjs", "types": "./dist/index.d.ts", "exports": { ".": { - "import": "./dist/index.es.js", + "import": "./dist/index.es.mjs", "require": "./dist/index.umd.js", "types": "./dist/index.d.ts" }, @@ -21,8 +22,8 @@ "dist" ], "scripts": { - "dev": "vue-tsc --noEmit && vite build -w", - "build": "vue-tsc --noEmit && vite build && vue-tsc -p tsconfig.build-dts.json --declaration --emitDeclarationOnly && tsc-alias -p tsconfig.build-dts.json", + "dev": "vite build -w", + "build": "vite build", "cypress:open": "cypress open --browser chrome --component", "cypress:run": "cypress run --browser chrome --component", "typecheck": "vue-tsc --noEmit", @@ -37,12 +38,12 @@ "@cypress/vue": "^5.0.5", "@release-it/conventional-changelog": "^5.1.1", "@vue-macros/volar": "^0.8.4", - "cypress": "^12.16.0", + "cypress": "^13.6.0", "release-it": "^16.1.3", - "tsc-alias": "^1.8.7", "unplugin-vue-define-options": "^1.3.8", "unplugin-vue-macros": "^2.3.0", - "vue": "^3.3.4" + "vite-plugin-dts": "^3.6.3", + "vue": "^3.3.7" }, "peerDependencies": { "@vueuse/core": ">=10.0.0", diff --git a/packages/vue-final-modal/src/Modal.ts b/packages/vue-final-modal/src/Modal.ts index 5e5cef33..ef53cc3d 100644 --- a/packages/vue-final-modal/src/Modal.ts +++ b/packages/vue-final-modal/src/Modal.ts @@ -1,32 +1,35 @@ -import type { App, CSSProperties, Component, ComponentPublicInstance, ComputedRef, Raw, Ref, VNodeProps } from 'vue' - -export type ComponentProps = ComponentPublicInstance['$props'] +import type { App, CSSProperties, ComponentInternalInstance, FunctionalComponent, Raw, Ref } from 'vue' export type ModalId = number | string | symbol export type StyleValue = string | CSSProperties | (string | CSSProperties)[] -export interface Constructor

{ +/** A fake Component Constructor that is only used for extracting `$props` as type `P` */ +type Constructor

= { __isFragment?: never __isTeleport?: never __isSuspense?: never - new (...args: any[]): { $props: P } + new(...args: any[]): { $props: P } } -export type RawProps = VNodeProps & { - // used to differ from a single VNode object as children - __v_isVNode?: never - // used to differ from Array children - [Symbol.iterator]?: never -} & Record +export interface ModalSlotOptions { component: Raw; attrs?: Record } +export type ModalSlot = string | ComponentType | ModalSlotOptions + +type ComponentConstructor = (abstract new (...args: any) => any) +/** Including both generic and non-generic vue components */ +export type ComponentType = ComponentConstructor | FunctionalComponent -export interface ModalSlotOptions { component: Raw; attrs?: Record } -export type ModalSlot = string | Component | ModalSlotOptions +type FunctionalComponentProps = T extends FunctionalComponent ? P : Record +type NonGenericComponentProps = T extends Constructor ? P : Record +export type ComponentProps = + T extends ComponentConstructor + ? NonGenericComponentProps + : FunctionalComponentProps -export type UseModalOptions

= { +export type UseModalOptions = { defaultModelValue?: boolean keepAlive?: boolean - component?: Constructor

- attrs?: (RawProps & P) | ({} extends P ? null : never) + component?: T + attrs?: ComponentProps slots?: { [key: string]: ModalSlot } @@ -39,42 +42,32 @@ export type UseModalOptionsPrivate = { resolveClosed: () => void } -export interface UseModalReturnType

{ - options: UseModalOptions

& UseModalOptionsPrivate +export interface UseModalReturnType { + options: UseModalOptions & UseModalOptionsPrivate open: () => Promise close: () => Promise - patchOptions: (options: Partial>) => void + patchOptions: (options: Partial>) => void destroy: () => void } export type Vfm = { install(app: App): void - modals: ComputedRef[] - openedModals: ComputedRef[] - openedModalOverlays: ComputedRef[] + modals: ComponentInternalInstance[] + openedModals: ComponentInternalInstance[] + openedModalOverlays: ComponentInternalInstance[] dynamicModals: (UseModalOptions & UseModalOptionsPrivate)[] modalsContainers: Ref - get: (modalId: ModalId) => undefined | ComputedRef + get: (modalId: ModalId) => undefined | ComponentInternalInstance toggle: (modalId: ModalId, show?: boolean) => undefined | Promise open: (modalId: ModalId) => undefined | Promise close: (modalId: ModalId) => undefined | Promise - closeAll: () => Promise<[PromiseSettledResult[]>]> -} - -export type InternalVfm = { - deleteFromModals: (modal: ComputedRef) => void - moveToLastOpenedModals: (modal: ComputedRef) => void - deleteFromOpenedModals: (modal: ComputedRef) => void - moveToLastOpenedModalOverlays: (modal: ComputedRef) => void - deleteFromOpenedModalOverlays: (modal: ComputedRef) => void - openLastOverlay: () => Promise - resolvedClosed: (index: number) => void - resolvedOpened: (index: number) => void + closeAll: () => Promise[]> } -export type Modal = { - modalId?: ModalId - hideOverlay: Ref | undefined +export type ModalExposed = { + modalId?: Ref + hideOverlay?: Ref + overlayBehavior: Ref<'auto' | 'persist'> overlayVisible: Ref toggle: (show?: boolean) => Promise } diff --git a/packages/vue-final-modal/src/components/CoreModal/CoreModal.vue b/packages/vue-final-modal/src/components/CoreModal/CoreModal.vue deleted file mode 100644 index df592531..00000000 --- a/packages/vue-final-modal/src/components/CoreModal/CoreModal.vue +++ /dev/null @@ -1,333 +0,0 @@ - - - - - diff --git a/packages/vue-final-modal/src/components/CoreModal/CoreModalProps.ts b/packages/vue-final-modal/src/components/CoreModal/CoreModalProps.ts deleted file mode 100644 index ad467d47..00000000 --- a/packages/vue-final-modal/src/components/CoreModal/CoreModalProps.ts +++ /dev/null @@ -1,232 +0,0 @@ -import type { Options } from 'focus-trap' -import type { PropType, TransitionProps } from 'vue' -import type { ModalId, StyleValue } from '~/Modal' - -// Hack from: https://github.com/microsoft/TypeScript/issues/29729#issuecomment-1331857805 -type AnyString = string & {} -type VfmTransition = 'vfm-fade' | 'vfm-slide-down' | 'vfm-slide-up' | 'vfm-slide-right' | 'vfm-slide-left' | AnyString - -export const coreModalProps = { - /** - * @description An uniq name for the open/close a modal via vfm.open/vfm.close APIs. - * @default `undefined` - * @example Symbol: `Symbol('MyModal')` - * @example String: `'AUniqString'` - * @example Number: `300` - */ - modalId: { - type: [String, Number, Symbol] as PropType, - default: undefined, - }, - /** - * @description Display the modal or not. - * @default `undefined` - * @example - * ```js - * const showModal = ref(false) - * v-model="showModal" - * ``` - */ - modelValue: { - type: Boolean as PropType, - default: undefined, - }, - /** - * @description Render the modal via `if` or `show`. - * @default `'if'` - * @example - * ```js - * displayDirective: 'if' - * ``` - * @example - * ```js - * displayDirective: 'show' - * ``` - */ - displayDirective: { - type: String as PropType<'if' | 'show' | 'visible'>, - default: 'if', - validator: (prop: any) => ['if', 'show', 'visible'].includes(prop), - }, - /** - * @description Hide the overlay or not. - * @default `undefined` - * @example - * ```js - * hideOverlay="true" - * ``` - */ - hideOverlay: { - type: Boolean as PropType, - default: undefined, - }, - /** - * @description Customize the overlay transition. - * @default `undefined` - */ - overlayTransition: { - type: [String, Object] as PropType, - default: undefined, - }, - /** - * @description Customize the content transition. - * @default `undefined` - */ - contentTransition: { - type: [String, Object] as PropType, - default: undefined, - }, - /** - * @description Bind class to vfm__overlay. - * @default `undefined` - */ - overlayClass: { - type: undefined as unknown as PropType, - default: undefined, - }, - /** - * @description Bind class to vfm__content. - * @default `undefined` - */ - contentClass: { - type: undefined as unknown as PropType, - default: undefined, - }, - /** - * @description Bind style to vfm__overlay. - * @default `undefined` - */ - overlayStyle: { - type: [String, Object, Array] as PropType, - default: undefined, - }, - /** - * @description Bind style to vfm__content. - * @default `undefined` - */ - contentStyle: { - type: [String, Object, Array] as PropType, - default: undefined, - }, - /** - * @description Is it allow to close the modal by clicking the overlay. - * @default `true` - */ - clickToClose: { - type: Boolean as PropType, - default: true, - }, - /** - * @description Is it allow to close the modal by keypress `esc`. - * @default `true` - */ - escToClose: { - type: Boolean as PropType, - default: true, - }, - /** - * @description Is it allow to click outside of the vfm__content when the modal is opened - * @default `'non-interactive'` - */ - background: { - type: String as PropType<'interactive' | 'non-interactive'>, - default: 'non-interactive', - validator: (prop: any) => ['interactive', 'non-interactive'].includes(prop), - }, - /** - * @description - * * Use `{ disabled: true }` to disable the focusTrap. - * * Checkout the createOptions type here https://github.com/focus-trap/focus-trap for more. - * @default `{ allowOutsideClick: true }` - */ - focusTrap: { - type: [Boolean, Object] as PropType, - default: () => ({ - allowOutsideClick: true, - }), - }, - /** - * @description Lock body scroll or not when the modal is opened. - * @default `true` - */ - lockScroll: { - type: Boolean as PropType, - default: true, - }, - /** - * @description Creates a padding-right when scroll is locked to prevent the page from jumping - * @default `true` - */ - reserveScrollBarGap: { - type: Boolean as PropType, - default: true, - }, - /** - * @description Define how to increase the zIndex when there are nested modals - * @default `({ index }) => 1000 + 2 * index` - */ - zIndexFn: { - type: Function as PropType<(context: { index: number }) => number | undefined>, - default: ({ index }: { index: number }) => 1000 + 2 * index, - }, - /** - * @description The direction of swiping to close the modal - * @default `none` - * @example - * Set swipeToClose="none" to disable swiping to close - * ```js - * swipeToClose="none" - * ``` - */ - swipeToClose: { - type: String as PropType<'none' | 'up' | 'right' | 'down' | 'left'>, - default: 'none', - validator: (prop: any) => ['none', 'up', 'right', 'down', 'left'].includes(prop), - }, - /** - * @description Threshold for swipe to close - * @default `0` - */ - threshold: { - type: Number as PropType, - default: 0, - }, - /** - * @description If set `:showSwipeBanner="true"`, only allow clicking `swipe-banner` slot to swipe to close - * @default `undefined` - * @example - * ```js - * swipeToClose="right" - * :showSwipeBanner="true" - * ``` - * ```html - * - * - * ...modal content - * - * ``` - */ - showSwipeBanner: { - type: Boolean as PropType, - default: undefined, - }, - /** - * @description When set `:preventNavigationGestures="true"`, there will be two invisible bars for prevent navigation gestures including swiping back/forward on mobile webkit. For example: Safari mobile. - * @default `undefined` - * @example - * Set preventNavigationGestures="true" to prevent Safari navigation gestures including swiping back/forward. - * ```js - * :preventNavigationGestures="true" - * ``` - */ - preventNavigationGestures: { - type: Boolean as PropType, - default: undefined, - }, -} as const diff --git a/packages/vue-final-modal/src/components/CoreModal/useEvent.ts b/packages/vue-final-modal/src/components/CoreModal/useEvent.ts deleted file mode 100644 index 56bc2832..00000000 --- a/packages/vue-final-modal/src/components/CoreModal/useEvent.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type CoreModal from './CoreModal.vue' - -type Event = 'beforeOpen' | 'beforeClose' | 'opened' | 'closed' - -export function useEvent(emit: InstanceType['$emit']) { - function emitEvent(e: Event) { - switch (e) { - case 'beforeOpen': - emit(e) - break - case 'beforeClose': - emit(e) - break - case 'opened': - emit(e) - break - case 'closed': - emit(e) - break - } - } - - return { - emitEvent, - } -} diff --git a/packages/vue-final-modal/src/components/CoreModal/useModelValue.ts b/packages/vue-final-modal/src/components/CoreModal/useModelValue.ts deleted file mode 100644 index a24f1a03..00000000 --- a/packages/vue-final-modal/src/components/CoreModal/useModelValue.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Ref } from 'vue' -import { ref, watch } from 'vue' -import type CoreModal from './CoreModal.vue' - -export function useModelValue( - props: InstanceType['$props'], - emit: InstanceType['$emit'], -): { modelValueLocal: Ref } { - const modelValueLocal = ref(!!props.modelValue) - watch(() => props.modelValue, (val) => { - modelValueLocal.value = !!val - }) - watch(modelValueLocal, (val) => { - if (val !== props.modelValue) - emit('update:modelValue', val) - }) - - return { - modelValueLocal, - } -} diff --git a/packages/vue-final-modal/src/components/ModalsContainer.vue b/packages/vue-final-modal/src/components/ModalsContainer.vue index 05db1b3b..70a6526c 100644 --- a/packages/vue-final-modal/src/components/ModalsContainer.vue +++ b/packages/vue-final-modal/src/components/ModalsContainer.vue @@ -1,33 +1,42 @@