Skip to content

Commit c1670dc

Browse files
Merge pull request #217 from frappe/dialog-action-context
fix: dialog action context object
2 parents d693faf + bdb8bf8 commit c1670dc

File tree

2 files changed

+47
-34
lines changed

2 files changed

+47
-34
lines changed

src/components/Dialog.story.vue

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ import { Button } from './Button'
55
66
const dialog1 = ref(false)
77
const dialog2 = ref(false)
8+
9+
const createPromise = () => {
10+
return new Promise((resolve) => {
11+
setTimeout(resolve, 2000)
12+
})
13+
}
814
</script>
915
<template>
1016
<Story :layout="{ width: 500, type: 'grid' }">
@@ -15,7 +21,15 @@ const dialog2 = ref(false)
1521
title: 'Confirm',
1622
message: 'Are you sure you want to confirm this action?',
1723
size: 'xl',
18-
actions: [{ label: 'Confirm', variant: 'solid', onClick: () => {} }],
24+
actions: [
25+
{
26+
label: 'Confirm',
27+
variant: 'solid',
28+
onClick: () => {
29+
return createPromise()
30+
},
31+
},
32+
],
1933
}"
2034
v-model="dialog1"
2135
/>

src/components/Dialog.vue

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<TransitionRoot
33
as="template"
4-
:show="open"
4+
:show="isOpen"
55
@after-leave="$emit('after-leave')"
66
>
77
<HDialog
@@ -116,13 +116,13 @@
116116
</slot>
117117
<div
118118
class="px-4 pb-7 pt-4 sm:px-6"
119-
v-if="dialogActions.length || $slots.actions"
119+
v-if="actions.length || $slots.actions"
120120
>
121121
<slot name="actions" v-bind="{ close }">
122122
<div class="space-y-2">
123123
<Button
124124
class="w-full"
125-
v-for="action in dialogActions"
125+
v-for="action in actions"
126126
:key="action.label"
127127
v-bind="action"
128128
>
@@ -147,7 +147,7 @@ import {
147147
TransitionChild,
148148
TransitionRoot,
149149
} from '@headlessui/vue'
150-
import { computed, ref, watch } from 'vue'
150+
import { computed, reactive } from 'vue'
151151
import { Button, ButtonProps } from './Button'
152152
import FeatherIcon from './FeatherIcon.vue'
153153
@@ -178,8 +178,11 @@ type DialogOptions = {
178178
position?: 'top' | 'center'
179179
}
180180
181+
type DialogActionContext = {
182+
close: () => void
183+
}
181184
type DialogAction = ButtonProps & {
182-
onClick?: (close: () => void) => Promise<void> | void
185+
onClick?: (context: DialogActionContext) => void | Promise<void>
183186
}
184187
185188
interface DialogProps {
@@ -199,37 +202,33 @@ const emit = defineEmits<{
199202
(event: 'after-leave'): void
200203
}>()
201204
202-
const dialogActions = ref<Array<DialogAction>>([])
203-
watch(
204-
() => props.options.actions,
205-
(actions) => {
206-
if (!actions?.length) return
205+
const actions = computed(() => {
206+
let actions = props.options.actions
207+
if (!actions?.length) return []
207208
208-
dialogActions.value = actions.map((action) => {
209-
let loading = ref(false)
210-
return {
211-
...action,
212-
loading,
213-
onClick: !action.onClick
214-
? close
215-
: async () => {
216-
loading.value = true
217-
try {
218-
if (action.onClick) {
219-
// pass close function to action
220-
await action.onClick(close)
221-
}
222-
} finally {
223-
loading.value = false
209+
return actions.map((action) => {
210+
let _action = reactive({
211+
...action,
212+
loading: false,
213+
onClick: !action.onClick
214+
? close
215+
: async () => {
216+
_action.loading = true
217+
try {
218+
if (action.onClick) {
219+
let context: DialogActionContext = { close }
220+
await action.onClick(context)
224221
}
225-
},
226-
}
222+
} finally {
223+
_action.loading = false
224+
}
225+
},
227226
})
228-
},
229-
{ immediate: true },
230-
)
227+
return _action
228+
})
229+
})
231230
232-
const open = computed({
231+
const isOpen = computed({
233232
get() {
234233
return props.modelValue
235234
},
@@ -242,7 +241,7 @@ const open = computed({
242241
})
243242
244243
function close() {
245-
open.value = false
244+
isOpen.value = false
246245
}
247246
248247
const icon = computed(() => {

0 commit comments

Comments
 (0)