Skip to content

Instantly share code, notes, and snippets.

@wobsoriano
Last active December 19, 2024 13:25

Revisions

  1. wobsoriano revised this gist Jan 11, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion useDialog.ts
    Original file line number Diff line number Diff line change
    @@ -19,7 +19,7 @@ export const CreateConfirmDialogKey: InjectionKey<CreateConfirmDialog> = Symbol(
    export function useDialog() {
    const dialog = inject(CreateConfirmDialogKey);

    if (!confirm) {
    if (!dialog) {
    throw new Error('Could not resolve provider');
    }

  2. wobsoriano revised this gist Jul 19, 2021. 1 changed file with 5 additions and 1 deletion.
    6 changes: 5 additions & 1 deletion DialogProvider.vue
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    <template>
    <div>
    <div v-frag>
    <slot />
    <v-dialog
    v-model="isOpen"
    @@ -26,6 +26,7 @@
    </template>

    <script lang="ts">
    import frag from 'vue-frag';
    import {
    defineComponent,
    provide,
    @@ -38,6 +39,9 @@ import {
    } from '~/composables';
    export default defineComponent({
    directives: {
    frag,
    },
    setup() {
    const state = reactive({
    isOpen: false,
  3. wobsoriano revised this gist Jul 19, 2021. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions useDialog.ts
    Original file line number Diff line number Diff line change
    @@ -17,11 +17,11 @@ export const CreateConfirmDialogKey: InjectionKey<CreateConfirmDialog> = Symbol(
    );

    export function useDialog() {
    const createConfirmDialog = inject(CreateConfirmDialogKey);
    const dialog = inject(CreateConfirmDialogKey);

    if (!confirm) {
    throw new Error('Could not resolve provider');
    }

    return createConfirmDialog;
    return dialog;
    }
  4. wobsoriano revised this gist Jul 19, 2021. 3 changed files with 6 additions and 6 deletions.
    4 changes: 2 additions & 2 deletions DialogProvider.vue
    Original file line number Diff line number Diff line change
    @@ -52,7 +52,7 @@ export default defineComponent({
    } as CreateConfirmDialogOptions,
    });
    const open = (
    const createConfirmDialog = (
    title: string,
    content: string,
    options: CreateConfirmDialogOptions = {}
    @@ -67,7 +67,7 @@ export default defineComponent({
    });
    };
    provide(CreateConfirmDialogKey, open);
    provide(CreateConfirmDialogKey, createConfirmDialog);
    const agree = () => {
    state.resolve(true);
    4 changes: 2 additions & 2 deletions Page.vue
    Original file line number Diff line number Diff line change
    @@ -4,11 +4,11 @@ import { useDialog } from '~/composables';
    export default defineComponent({
    setup() {
    const dialog = useDialog();
    const createConfirmDialog = useDialog();
    const handleDelete = async () => {
    try {
    const shouldProceed = await dialog.confirm(
    const shouldProceed = await createConfirmDialog(
    'Confirm',
    'Delete this post?',
    { width: 300 }
    4 changes: 2 additions & 2 deletions useDialog.ts
    Original file line number Diff line number Diff line change
    @@ -17,11 +17,11 @@ export const CreateConfirmDialogKey: InjectionKey<CreateConfirmDialog> = Symbol(
    );

    export function useDialog() {
    const confirm = inject(CreateConfirmDialogKey);
    const createConfirmDialog = inject(CreateConfirmDialogKey);

    if (!confirm) {
    throw new Error('Could not resolve provider');
    }

    return { confirm };
    return createConfirmDialog;
    }
  5. wobsoriano revised this gist Jul 18, 2021. No changes.
  6. wobsoriano revised this gist Jul 18, 2021. 5 changed files with 131 additions and 99 deletions.
    28 changes: 0 additions & 28 deletions ConfirmDialog.vue
    Original file line number Diff line number Diff line change
    @@ -1,28 +0,0 @@
    <template>
    <v-dialog
    v-model="dialog"
    :width="options.width"
    :persistent="options.persistent"
    >
    <v-card>
    <v-card-title>{{ title }}</v-card-title>
    <v-card-text v-show="!!message">{{ message }}</v-card-text>
    <v-card-actions class="pt-0">
    <v-spacer></v-spacer>
    <v-btn color="grey" v-show="!!options.showCancel" text @click="cancel">Cancel</v-btn>
    <v-btn color="primary darken-1" depressed @click="agree">Ok</v-btn>
    </v-card-actions>
    </v-card>
    </v-dialog>
    </template>

    <script lang="ts">
    import { defineComponent } from '@nuxtjs/composition-api';
    import useDialog from '~/composables/useDialog';
    export default defineComponent({
    setup() {
    return useDialog();
    },
    });
    </script>
    89 changes: 89 additions & 0 deletions DialogProvider.vue
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,89 @@
    <template>
    <div>
    <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 {
    defineComponent,
    provide,
    reactive,
    toRefs,
    } from '@nuxtjs/composition-api';
    import {
    CreateConfirmDialogKey,
    CreateConfirmDialogOptions,
    } from '~/composables';
    export default defineComponent({
    setup() {
    const state = reactive({
    isOpen: false,
    resolve: (_val: boolean) => {},
    reject: (_val: boolean) => {},
    content: '',
    title: '',
    options: {
    width: 300,
    showCancel: true,
    persistent: false,
    } as CreateConfirmDialogOptions,
    });
    const open = (
    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, open);
    const agree = () => {
    state.resolve(true);
    state.isOpen = false;
    };
    const cancel = () => {
    state.resolve(false);
    state.isOpen = false;
    };
    return {
    ...toRefs(state),
    agree,
    cancel,
    };
    },
    });
    </script>
    25 changes: 13 additions & 12 deletions Page.vue
    Original file line number Diff line number Diff line change
    @@ -1,26 +1,27 @@
    <template>
    <div>
    <button @click="showDialog">Show dialog</button>
    </div>
    </template>

    <script lang="ts">
    import { defineComponent } from '@nuxtjs/composition-api';
    import useDialog from '~/composables/useDialog';
    import { useDialog } from '~/composables';
    export default defineComponent({
    layout: 'layout',
    setup() {
    const dialog = useDialog();
    const showDialog = async () => {
    const handleDelete = async () => {
    try {
    const result = await dialog.show('Delete', 'Are you sure?');
    // result = true/false
    const shouldProceed = await dialog.confirm(
    'Confirm',
    'Delete this post?',
    { width: 300 }
    );
    if (shouldProceed) {
    // delete post
    }
    } catch (_e) {}
    };
    return { showDialog };
    return {
    handleDelete
    };
    },
    });
    </script>
    19 changes: 13 additions & 6 deletions layout.vue
    Original file line number Diff line number Diff line change
    @@ -1,15 +1,22 @@
    <template>
    <div>
    <Nuxt />
    <ConfirmDialog />
    </div>
    <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 ConfirmDialog from '~/components/ConfirmDialog.vue';
    import DialogProvider from '~/components/DialogProvider.vue';
    export default defineComponent({
    components: { ConfirmDialog }
    components: {
    DialogProvider,
    }
    });
    </script>
    69 changes: 16 additions & 53 deletions useDialog.ts
    Original file line number Diff line number Diff line change
    @@ -1,64 +1,27 @@
    import { reactive, readonly, toRefs, watch } from '@nuxtjs/composition-api';
    import { inject, InjectionKey } from '@nuxtjs/composition-api';

    interface Options {
    export interface CreateConfirmDialogOptions {
    width?: string | number;
    showCancel?: boolean;
    persistent?: boolean;
    }

    const defaultOptions: Options = {
    width: 400,
    showCancel: true,
    persistent: false,
    };
    export type CreateConfirmDialog = (
    title: string,
    content: string,
    options: CreateConfirmDialogOptions
    ) => Promise<boolean>;

    const state = reactive({
    dialog: false,
    resolve: (_val: boolean) => {},
    reject: (_val: boolean) => {},
    message: '',
    title: '',
    options: {
    ...defaultOptions,
    },
    });
    export const CreateConfirmDialogKey: InjectionKey<CreateConfirmDialog> = Symbol(
    'CreateConfirmDialogKey'
    );

    export default function useConfirmDialog() {
    const show = (title: string, message: string, options?: Options) => {
    state.dialog = true;
    state.title = title;
    state.message = message;
    state.options = Object.assign(state.options, options);
    return new Promise<boolean>((resolve, reject) => {
    state.resolve = resolve;
    state.reject = reject;
    });
    };
    export function useDialog() {
    const confirm = inject(CreateConfirmDialogKey);

    const agree = () => {
    state.resolve(true);
    state.dialog = false;
    };
    if (!confirm) {
    throw new Error('Could not resolve provider');
    }

    const cancel = () => {
    state.resolve(false);
    state.dialog = false;
    };

    // On close, reset options
    watch(
    () => state.dialog,
    (val) => {
    if (!val) {
    state.options = { ...defaultOptions };
    }
    }
    );

    return {
    ...toRefs(readonly(state)),
    show,
    agree,
    cancel,
    };
    return { confirm };
    }
  7. wobsoriano revised this gist Jul 17, 2021. 2 changed files with 8 additions and 8 deletions.
    2 changes: 1 addition & 1 deletion Page.vue
    Original file line number Diff line number Diff line change
    @@ -15,7 +15,7 @@ export default defineComponent({
    const showDialog = async () => {
    try {
    const result = await dialog.open('Delete', 'Are you sure?');
    const result = await dialog.show('Delete', 'Are you sure?');
    // result = true/false
    } catch (_e) {}
    };
    14 changes: 7 additions & 7 deletions useDialog.ts
    Original file line number Diff line number Diff line change
    @@ -13,7 +13,7 @@ const defaultOptions: Options = {
    };

    const state = reactive({
    show: false,
    dialog: false,
    resolve: (_val: boolean) => {},
    reject: (_val: boolean) => {},
    message: '',
    @@ -24,8 +24,8 @@ const state = reactive({
    });

    export default function useConfirmDialog() {
    const open = (title: string, message: string, options?: Options) => {
    state.show = true;
    const show = (title: string, message: string, options?: Options) => {
    state.dialog = true;
    state.title = title;
    state.message = message;
    state.options = Object.assign(state.options, options);
    @@ -37,17 +37,17 @@ export default function useConfirmDialog() {

    const agree = () => {
    state.resolve(true);
    state.show = false;
    state.dialog = false;
    };

    const cancel = () => {
    state.resolve(false);
    state.show = false;
    state.dialog = false;
    };

    // On close, reset options
    watch(
    () => state.show,
    () => state.dialog,
    (val) => {
    if (!val) {
    state.options = { ...defaultOptions };
    @@ -57,7 +57,7 @@ export default function useConfirmDialog() {

    return {
    ...toRefs(readonly(state)),
    open,
    show,
    agree,
    cancel,
    };
  8. wobsoriano revised this gist Jul 17, 2021. 1 changed file with 24 additions and 10 deletions.
    34 changes: 24 additions & 10 deletions useDialog.ts
    Original file line number Diff line number Diff line change
    @@ -1,27 +1,31 @@
    import { reactive, readonly, toRefs } from '@nuxtjs/composition-api';
    import { reactive, readonly, toRefs, watch } from '@nuxtjs/composition-api';

    interface Options {
    width?: string | number;
    showCancel?: boolean;
    persistent?: boolean;
    }

    const defaultOptions: Options = {
    width: 400,
    showCancel: true,
    persistent: false,
    };

    const state = reactive({
    dialog: false,
    show: false,
    resolve: (_val: boolean) => {},
    reject: (_val: boolean) => {},
    message: '',
    title: '',
    options: {
    width: 400,
    showCancel: true,
    persistent: false,
    ...defaultOptions,
    },
    });

    export default function useDialog() {
    export default function useConfirmDialog() {
    const open = (title: string, message: string, options?: Options) => {
    state.dialog = true;
    state.show = true;
    state.title = title;
    state.message = message;
    state.options = Object.assign(state.options, options);
    @@ -33,16 +37,26 @@ export default function useDialog() {

    const agree = () => {
    state.resolve(true);
    state.dialog = false;
    state.show = false;
    };

    const cancel = () => {
    state.resolve(false);
    state.dialog = false;
    state.show = false;
    };

    // On close, reset options
    watch(
    () => state.show,
    (val) => {
    if (!val) {
    state.options = { ...defaultOptions };
    }
    }
    );

    return {
    ...toRefs(readonly(state)), // be sure to make it readonly so other components cannot overwrite it
    ...toRefs(readonly(state)),
    open,
    agree,
    cancel,
  9. wobsoriano revised this gist Jul 17, 2021. 2 changed files with 7 additions and 8 deletions.
    9 changes: 3 additions & 6 deletions ConfirmDialog.vue
    Original file line number Diff line number Diff line change
    @@ -2,18 +2,15 @@
    <v-dialog
    v-model="dialog"
    :width="options.width"
    :style="{ zIndex: options.zIndex }"
    @keydown.esc="cancel"
    :persistent="options.persistent"
    >
    <v-card>
    <v-card-title>{{ title }}</v-card-title>
    <v-card-text v-show="!!message">{{ message }}</v-card-text>
    <v-card-actions class="pt-0">
    <v-spacer></v-spacer>
    <v-btn color="grey" text @click.native="cancel">Cancel</v-btn>
    <v-btn color="primary darken-1" depressed @click.native="agree"
    >Ok</v-btn
    >
    <v-btn color="grey" v-show="!!options.showCancel" text @click="cancel">Cancel</v-btn>
    <v-btn color="primary darken-1" depressed @click="agree">Ok</v-btn>
    </v-card-actions>
    </v-card>
    </v-dialog>
    6 changes: 4 additions & 2 deletions useDialog.ts
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,8 @@ import { reactive, readonly, toRefs } from '@nuxtjs/composition-api';

    interface Options {
    width?: string | number;
    zIndex?: number;
    showCancel?: boolean;
    persistent?: boolean;
    }

    const state = reactive({
    @@ -13,7 +14,8 @@ const state = reactive({
    title: '',
    options: {
    width: 400,
    zIndex: 200,
    showCancel: true,
    persistent: false,
    },
    });

  10. wobsoriano revised this gist Jul 17, 2021. 3 changed files with 29 additions and 3 deletions.
    4 changes: 2 additions & 2 deletions ConfirmDialog.vue
    Original file line number Diff line number Diff line change
    @@ -21,11 +21,11 @@

    <script lang="ts">
    import { defineComponent } from '@nuxtjs/composition-api';
    import useConfirmDialog from '~/composables/useConfirmDialog';
    import useDialog from '~/composables/useDialog';
    export default defineComponent({
    setup() {
    return useConfirmDialog();
    return useDialog();
    },
    });
    </script>
    26 changes: 26 additions & 0 deletions Page.vue
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,26 @@
    <template>
    <div>
    <button @click="showDialog">Show dialog</button>
    </div>
    </template>

    <script lang="ts">
    import { defineComponent } from '@nuxtjs/composition-api';
    import useDialog from '~/composables/useDialog';
    export default defineComponent({
    layout: 'layout',
    setup() {
    const dialog = useDialog();
    const showDialog = async () => {
    try {
    const result = await dialog.open('Delete', 'Are you sure?');
    // result = true/false
    } catch (_e) {}
    };
    return { showDialog };
    },
    });
    </script>
    2 changes: 1 addition & 1 deletion layout.vue
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    <template>
    <div>
    <Nuxt />
    <AppConfirmDialog />
    <ConfirmDialog />
    </div>
    </template>

  11. wobsoriano revised this gist Jul 17, 2021. 2 changed files with 63 additions and 0 deletions.
    15 changes: 15 additions & 0 deletions layout.vue
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,15 @@
    <template>
    <div>
    <Nuxt />
    <AppConfirmDialog />
    </div>
    </template>

    <script lang="ts">
    import { defineComponent } from '@nuxtjs/composition-api';
    import ConfirmDialog from '~/components/ConfirmDialog.vue';
    export default defineComponent({
    components: { ConfirmDialog }
    });
    </script>
    48 changes: 48 additions & 0 deletions useDialog.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,48 @@
    import { reactive, readonly, toRefs } from '@nuxtjs/composition-api';

    interface Options {
    width?: string | number;
    zIndex?: number;
    }

    const state = reactive({
    dialog: false,
    resolve: (_val: boolean) => {},
    reject: (_val: boolean) => {},
    message: '',
    title: '',
    options: {
    width: 400,
    zIndex: 200,
    },
    });

    export default function useDialog() {
    const open = (title: string, message: string, options?: Options) => {
    state.dialog = true;
    state.title = title;
    state.message = message;
    state.options = Object.assign(state.options, options);
    return new Promise<boolean>((resolve, reject) => {
    state.resolve = resolve;
    state.reject = reject;
    });
    };

    const agree = () => {
    state.resolve(true);
    state.dialog = false;
    };

    const cancel = () => {
    state.resolve(false);
    state.dialog = false;
    };

    return {
    ...toRefs(readonly(state)), // be sure to make it readonly so other components cannot overwrite it
    open,
    agree,
    cancel,
    };
    }
  12. wobsoriano created this gist Jul 17, 2021.
    31 changes: 31 additions & 0 deletions ConfirmDialog.vue
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,31 @@
    <template>
    <v-dialog
    v-model="dialog"
    :width="options.width"
    :style="{ zIndex: options.zIndex }"
    @keydown.esc="cancel"
    >
    <v-card>
    <v-card-title>{{ title }}</v-card-title>
    <v-card-text v-show="!!message">{{ message }}</v-card-text>
    <v-card-actions class="pt-0">
    <v-spacer></v-spacer>
    <v-btn color="grey" text @click.native="cancel">Cancel</v-btn>
    <v-btn color="primary darken-1" depressed @click.native="agree"
    >Ok</v-btn
    >
    </v-card-actions>
    </v-card>
    </v-dialog>
    </template>

    <script lang="ts">
    import { defineComponent } from '@nuxtjs/composition-api';
    import useConfirmDialog from '~/composables/useConfirmDialog';
    export default defineComponent({
    setup() {
    return useConfirmDialog();
    },
    });
    </script>