Last active
July 17, 2022 15:43
-
-
Save wobsoriano/1e63708d7771c34f835c0f6e3c5e731a to your computer and use it in GitHub Desktop.
Vuetify + Composition API Dialog component that can be used globally
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
<template> | |
<div v-frag> | |
<slot /> | |
<v-dialog | |
v-model="isOpen" | |
:max-width="options.width" | |
:persistent="options.persistent" | |
> | |
<v-card> | |
<v-card-title>{{ title }}</v-card-title> | |
<v-card-text v-show="!!content">{{ content }}</v-card-text> | |
<v-card-actions class="pt-0"> | |
<v-spacer></v-spacer> | |
<v-btn | |
v-show="!!options.showCancel" | |
color="primary" | |
text | |
@click="cancel" | |
>Cancel</v-btn | |
> | |
<v-btn color="primary" text @click="agree">Yes</v-btn> | |
</v-card-actions> | |
</v-card> | |
</v-dialog> | |
</div> | |
</template> | |
<script lang="ts"> | |
import frag from 'vue-frag'; | |
import { | |
defineComponent, | |
provide, | |
reactive, | |
toRefs, | |
} from '@nuxtjs/composition-api'; | |
import { | |
CreateConfirmDialogKey, | |
CreateConfirmDialogOptions, | |
} from '~/composables'; | |
export default defineComponent({ | |
directives: { | |
frag, | |
}, | |
setup() { | |
const state = reactive({ | |
isOpen: false, | |
resolve: (_val: boolean) => {}, | |
reject: (_val: boolean) => {}, | |
content: '', | |
title: '', | |
options: { | |
width: 300, | |
showCancel: true, | |
persistent: false, | |
} as CreateConfirmDialogOptions, | |
}); | |
const createConfirmDialog = ( | |
title: string, | |
content: string, | |
options: CreateConfirmDialogOptions = {} | |
) => { | |
state.isOpen = true; | |
state.title = title; | |
state.content = content; | |
state.options = Object.assign(state.options, options); | |
return new Promise<boolean>((resolve, reject) => { | |
state.resolve = resolve; | |
state.reject = reject; | |
}); | |
}; | |
provide(CreateConfirmDialogKey, createConfirmDialog); | |
const agree = () => { | |
state.resolve(true); | |
state.isOpen = false; | |
}; | |
const cancel = () => { | |
state.resolve(false); | |
state.isOpen = false; | |
}; | |
return { | |
...toRefs(state), | |
agree, | |
cancel, | |
}; | |
}, | |
}); | |
</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
<template> | |
<v-app> | |
<v-main> | |
<v-container> | |
<DialogProvider> | |
<Nuxt /> | |
</DialogProvider> | |
</v-container> | |
</v-main> | |
</v-app> | |
</template> | |
<script lang="ts"> | |
import { defineComponent } from '@nuxtjs/composition-api'; | |
import DialogProvider from '~/components/DialogProvider.vue'; | |
export default defineComponent({ | |
components: { | |
DialogProvider, | |
} | |
}); | |
</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
<script lang="ts"> | |
import { defineComponent } from '@nuxtjs/composition-api'; | |
import { useDialog } from '~/composables'; | |
export default defineComponent({ | |
setup() { | |
const createConfirmDialog = useDialog(); | |
const handleDelete = async () => { | |
try { | |
const shouldProceed = await createConfirmDialog( | |
'Confirm', | |
'Delete this post?', | |
{ width: 300 } | |
); | |
if (shouldProceed) { | |
// delete post | |
} | |
} catch (_e) {} | |
}; | |
return { | |
handleDelete | |
}; | |
}, | |
}); | |
</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
import { inject, InjectionKey } from '@nuxtjs/composition-api'; | |
export interface CreateConfirmDialogOptions { | |
width?: string | number; | |
showCancel?: boolean; | |
persistent?: boolean; | |
} | |
export type CreateConfirmDialog = ( | |
title: string, | |
content: string, | |
options: CreateConfirmDialogOptions | |
) => Promise<boolean>; | |
export const CreateConfirmDialogKey: InjectionKey<CreateConfirmDialog> = Symbol( | |
'CreateConfirmDialogKey' | |
); | |
export function useDialog() { | |
const dialog = inject(CreateConfirmDialogKey); | |
if (!dialog) { | |
throw new Error('Could not resolve provider'); | |
} | |
return dialog; | |
} |
Thanks @some-user123 !
Could you provide us with a JS version, for those that are not on TS (yet)..?
@Sjoerd82 sure, will take a look tomorrow
Hi wobsoriano, do you have a pen with a working example? Much appreciated!
cheers, Patrick
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I think in line 22 of
useDialog.ts
if (!confirm) {
should be replaced with
if (!dialog) {
.