11<script setup lang="ts">
2- import type { HTMLAttributes } from ' vue '
2+ import type { DrawerEmits , DrawerProps } from ' . '
33import { cn } from ' @/utils'
44import {
55 Sheet ,
@@ -15,32 +15,7 @@ defineOptions({
1515})
1616
1717const props = withDefaults (
18- defineProps <{
19- modelValue? : boolean
20- side? : ' top' | ' bottom' | ' left' | ' right'
21- title: string
22- description? : string
23- loading? : boolean
24- closable? : boolean
25- centered? : boolean
26- bordered? : boolean
27- overlay? : boolean
28- overlayBlur? : boolean
29- showConfirmButton? : boolean
30- showCancelButton? : boolean
31- confirmButtonText? : string
32- cancelButtonText? : string
33- confirmButtonDisabled? : boolean
34- confirmButtonLoading? : boolean
35- header? : boolean
36- footer? : boolean
37- closeOnClickOverlay? : boolean
38- closeOnPressEscape? : boolean
39- destroyOnClose? : boolean
40- contentClass? : HTMLAttributes [' class' ]
41- headerClass? : HTMLAttributes [' class' ]
42- footerClass? : HTMLAttributes [' class' ]
43- }>(),
18+ defineProps <DrawerProps >(),
4419 {
4520 modelValue: false ,
4621 side: ' right' ,
@@ -64,15 +39,7 @@ const props = withDefaults(
6439 },
6540)
6641
67- const emits = defineEmits <{
68- ' update:modelValue' : [value : boolean ]
69- ' open' : []
70- ' opened' : []
71- ' close' : []
72- ' closed' : []
73- ' confirm' : []
74- ' cancel' : []
75- }>()
42+ const emits = defineEmits <DrawerEmits >()
7643
7744const id = useId ()
7845provide (' DrawerId' , id )
@@ -86,9 +53,16 @@ watch(() => props.modelValue, (newValue) => {
8653const hasOpened = ref (false )
8754const isClosed = ref (true )
8855
89- watch (() => isOpen .value , (value ) => {
56+ watch (isOpen , (val ) => {
57+ emits (' update:modelValue' , val )
58+ if (val ) {
59+ emits (' open' )
60+ }
61+ else {
62+ emits (' close' )
63+ }
9064 isClosed .value = false
91- if (value && ! hasOpened .value ) {
65+ if (val && ! hasOpened .value ) {
9266 hasOpened .value = true
9367 }
9468}, {
@@ -97,25 +71,62 @@ watch(() => isOpen.value, (value) => {
9771
9872const forceMount = computed (() => ! props .destroyOnClose && hasOpened .value )
9973
100- function updateOpen(value : boolean ) {
101- isOpen .value = value
102- emits (' update:modelValue' , value )
74+ async function updateOpen(value : boolean ) {
10375 if (value ) {
76+ isOpen .value = value
10477 emits (' open' )
10578 }
10679 else {
107- emits (' close' )
80+ if (props .beforeClose ) {
81+ await props .beforeClose (
82+ ' close' ,
83+ () => {
84+ isOpen .value = value
85+ emits (' close' )
86+ },
87+ )
88+ }
89+ else {
90+ isOpen .value = value
91+ emits (' close' )
92+ }
10893 }
10994}
11095
111- function onConfirm() {
112- updateOpen (false )
113- emits (' confirm' )
96+ const isConfirmButtonLoading = ref (false )
97+
98+ async function onConfirm() {
99+ if (props .beforeClose ) {
100+ isConfirmButtonLoading .value = true
101+ await props .beforeClose (
102+ ' confirm' ,
103+ () => {
104+ isOpen .value = false
105+ emits (' confirm' )
106+ },
107+ )
108+ isConfirmButtonLoading .value = false
109+ }
110+ else {
111+ isOpen .value = false
112+ emits (' confirm' )
113+ }
114114}
115115
116- function onCancel() {
117- updateOpen (false )
118- emits (' cancel' )
116+ async function onCancel() {
117+ if (props .beforeClose ) {
118+ await props .beforeClose (
119+ ' cancel' ,
120+ () => {
121+ isOpen .value = false
122+ emits (' cancel' )
123+ },
124+ )
125+ }
126+ else {
127+ isOpen .value = false
128+ emits (' cancel' )
129+ }
119130}
120131
121132function handleFocusOutside(e : Event ) {
@@ -187,10 +198,10 @@ function handleAnimationEnd() {
187198 <div class =" p-4" >
188199 <slot />
189200 </div >
201+ <div v-show =" props.loading" class =" absolute inset-0 z-1000 size-full flex-center bg-popover/75" >
202+ <FaIcon name =" i-line-md:loading-twotone-loop" class =" size-10" />
203+ </div >
190204 </FaScrollArea >
191- <div v-show =" props.loading" class =" absolute inset-0 z-1000 size-full flex-center bg-popover/75" >
192- <FaIcon name =" i-line-md:loading-twotone-loop" class =" size-10" />
193- </div >
194205 </div >
195206 <SheetFooter
196207 v-if =" footer" :class =" cn('p-2 gap-y-2', props.footerClass, {
0 commit comments