Modal mechanism
Guides and tips about mechanisms of the Modal compoennt.
Data flow
In term of data flow, a default modal has 2 events:
@dismiss: emited when the user clicks the secondary button at footer, the ❌ icon at the top-right corner, the underlying mask... This event hides the modal.@resolve: emited when the user clicks the primary button at footer. This event hides the modal.
Typically, when creating a new modal, you often want to re-define the 2 events but with more data (as event parameters) so the caller can listen to them and control the data flow after hiding the modal.
Show & Hide
1. In <template>
This is the simplest way to use modal. Just create a ref and bind it to v-model:shown:
In this method, the modal works like a normal Vue component, which means you can simply define any props, emits, slots, injections,... and all Vue behaviors will apply as expected:
2. Programmatically
Sometimes, you may want to show a modal, doing something with it, and then expects it to return some data in an imperative manner. You can achieve that by passing an entire Vue component into the open() function injected via the useModal() composable.
PREREQUISITES
To make this work, you must ensure the following conditions are met:
- There must be a
<HModalProvider>placed as an ancestor of whereveruseModal()is called - The modal component passed to
open():- Must place
<HModal>at root and make sureinheritAttrs = trueOR setinheritAttrs = falseand bind all the attrs to<HModal v-bind="$attrs"> - If defined, the following props and events must be bound to
<HModal>:shownprop and@update:shownevents@dismissand@resolveevents
- Must place
To pass props to the modal component, you can use the 2nd argument of open(). Moreover, the composable is an infallible function which means it always returns a Promise containing data depends on either @dismiss or @resolve is emited:
- If
@dismissis emited,Promisecontains an object that hasstate = 'dismiss' - If
@resolveis emited,Promisecontains an object that hasstate = 'resolve'anddatawhich is an array of parameters defined by@resolveitself.
💪 Typing
The 2nd argument of open() and the data property are automatically typed based on the passed modal component!
If automatic typings is not desirable, you can manually adjust them via generics when calling open(). For example: open<typeof Modal, CustomProps, CustomData>(Modal)
Don't want to await?
You can use onDismiss and onResolve callbacks when passing the 2nd argument to open() instead of awaiting and then checking for the values of state and data.
This also applies to all events defined by the modal component if you want to do something without closing the modal. All events are just props with an additional on prefix!
💉 provide/inject
All modal components passed to open() are mounted as direct children of <HModalProvider>. Therefore, you can leverage this behavior to inject the relevant contexts (if you're tired of props/emiting data flow) for the modals by placing <HModalProvider> at appropriate place!