-
Notifications
You must be signed in to change notification settings - Fork 609
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(Modal): open programmatically (#1319)
- Loading branch information
Showing
11 changed files
with
168 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ | |
<span v-html="title" /> | ||
</template> | ||
</UNotifications> | ||
<UModals /> | ||
</div> | ||
</template> | ||
|
||
|
17 changes: 17 additions & 0 deletions
17
docs/components/content/examples/ModalExampleComponent.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<script lang="ts" setup> | ||
defineProps({ | ||
count: { | ||
type: Number, | ||
default: 0 | ||
} | ||
}) | ||
</script> | ||
|
||
<template> | ||
<UModal> | ||
<UCard> | ||
<p>This modal was opened programmatically !</p> | ||
<p>Count: {{ count }}</p> | ||
</UCard> | ||
</UModal> | ||
</template> |
17 changes: 17 additions & 0 deletions
17
docs/components/content/examples/ModalExampleComposable.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<script setup lang="ts"> | ||
import { ModalExampleComponent } from '#components' | ||
const modal = useModal() | ||
const count = ref(0) | ||
function openModal () { | ||
count.value += 1 | ||
modal.open(ModalExampleComponent, { | ||
count: count.value | ||
}) | ||
} | ||
</script> | ||
|
||
<template> | ||
<UButton label="Reveal modal" @click="openModal" /> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<template> | ||
<component :is="modalState.component" v-bind="modalState.props" v-model="isOpen" /> | ||
</template> | ||
|
||
<script lang="ts" setup> | ||
import { inject } from 'vue' | ||
import { useModal, modalInjectionKey } from '../../composables/useModal' | ||
const modalState = inject(modalInjectionKey) | ||
const { isOpen } = useModal() | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { ref, inject } from 'vue' | ||
import type { ShallowRef, Component, InjectionKey } from 'vue' | ||
import { createSharedComposable } from '@vueuse/core' | ||
import type { ComponentProps } from '../types/component' | ||
import type { Modal, ModalState } from '../types/modal' | ||
|
||
export const modalInjectionKey: InjectionKey<ShallowRef<ModalState>> = Symbol('nuxt-ui.modal') | ||
|
||
function _useModal () { | ||
const modalState = inject(modalInjectionKey) | ||
|
||
const isOpen = ref(false) | ||
|
||
function open<T extends Component> (component: T, props?: Modal & ComponentProps<T>) { | ||
modalState.value = { | ||
component, | ||
props: props ?? {} | ||
} | ||
isOpen.value = true | ||
} | ||
|
||
function close () { | ||
isOpen.value = false | ||
modalState.value = { | ||
component: 'div', | ||
props: {} | ||
} | ||
} | ||
|
||
/** | ||
* Allows updating the modal props | ||
*/ | ||
function patch <T extends Component = {}> (props: Partial<Modal & ComponentProps<T>>) { | ||
modalState.value = { | ||
...modalState.value, | ||
props: { | ||
...modalState.value.props, | ||
...props | ||
} | ||
} | ||
} | ||
|
||
return { | ||
isOpen, | ||
open, | ||
close, | ||
patch | ||
} | ||
} | ||
|
||
export const useModal = createSharedComposable(_useModal) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { defineNuxtPlugin } from '#imports' | ||
import { shallowRef } from 'vue' | ||
import { modalInjectionKey } from '../composables/useModal' | ||
import type { ModalState } from '../types/modal' | ||
|
||
export default defineNuxtPlugin((nuxtApp) => { | ||
const modalState = shallowRef<ModalState>({ | ||
component: 'div', | ||
props: {} | ||
}) | ||
|
||
nuxtApp.vueApp.provide(modalInjectionKey, modalState) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
export type ComponentProps<T> = | ||
T extends new () => { $props: infer P } ? NonNullable<P> : | ||
T extends (props: infer P, ...args: any) => any ? P : | ||
{} | ||
|
||
export type ComponentSlots<T> = | ||
T extends new () => { $slots: infer S } ? NonNullable<S> : | ||
T extends (props: any, ctx: { slots: infer S; attrs: any; emit: any }, ...args: any) => any ? NonNullable<S> : | ||
{} | ||
|
||
export type ComponentEmit<T> = | ||
T extends new () => { $emit: infer E } ? NonNullable<E> : | ||
T extends (props: any, ctx: { slots: any; attrs: any; emit: infer E }, ...args: any) => any ? NonNullable<E> : | ||
{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import type { Component } from 'vue' | ||
|
||
export interface Modal { | ||
appear?: boolean | ||
overlay?: boolean | ||
transition?: boolean | ||
preventClose?: boolean | ||
fullscreen?: boolean | ||
class?: string | Object | string[] | ||
ui?: any | ||
onClose?: () => void | ||
onClosePrevented?: () => void | ||
} | ||
|
||
export interface ModalState { | ||
component: Component | string | ||
props: Modal | ||
} |