Skip to content

Modal & confirm() ​

Accessible modal dialogs (focus trap, scroll lock, Esc, backdrop), a drawer, and a promise-based confirm().

Modal
vue
<div class="thl-demo-row">
  <ThlButton v-for="s in ['sm','md','lg','xl']" :key="s" variant="primary" @click="size = s; open = true">{{ s }}</ThlButton>
  <ThlModal v-model:open="open" :size="size" :title="`Modal ${size}`"><p>Cras mattis consectetur purus sit amet fermentum.</p><template #footer="{ close }"><ThlButton @click="close">Close</ThlButton><ThlButton variant="primary" @click="close">Save</ThlButton></template></ThlModal>
</div>
tsx
const [open, setOpen] = useState(false);
<Button variant="primary" onClick={() => setOpen(true)}>Open</Button>
<Modal open={open} onClose={() => setOpen(false)} size="lg" title="Modal"
  footer={<><Button onClick={() => setOpen(false)}>Close</Button><Button variant="primary">Save</Button></>}>
  <p>Cras mattis consectetur purus sit amet fermentum.</p>
</Modal>
html
<button thl-button variant="primary" (click)="open.set(true)">Open</button>
<thl-modal [(open)]="open" size="lg" title="Modal">
  <p>Cras mattis consectetur purus sit amet fermentum.</p>
  <div thlModalFooter><button thl-button (click)="open.set(false)">Close</button></div>
</thl-modal>

confirm() & Drawer ​

confirm() & Drawer
vue
<div class="thl-demo-row">
  <ThlButton variant="danger" icon="trash-2" @click="del">Delete…</ThlButton>
  <ThlButton variant="info" @click="confirm({ icon: 'success', title: 'Good job!', showCancel: false })">Success</ThlButton>
  <ThlButton @click="drawer = true">Open drawer</ThlButton>
  <ThlDrawer v-model:open="drawer" title="Drawer"><p>Side content.</p></ThlDrawer>
</div>
tsx
import { confirm } from '@thl-ui/react';
if (await confirm({ icon: 'warning', title: 'Delete this file?' })) remove();

<Drawer open={drawer} onClose={() => setDrawer(false)} title="Drawer">Side content.</Drawer>
html
readonly modals = inject(ThlModalService);
async del() { if (await this.modals.confirm({ icon: 'warning', title: 'Delete this file?' })) this.remove(); }

<thl-drawer [(open)]="drawer" title="Drawer">Side content.</thl-drawer>

confirm(options) options: title, text, icon (warning · danger · success · info · question), confirmText, cancelText, confirmVariant, showCancel. Default texts come from i18n (modal.confirmTitle, common.ok…). It needs one ConfirmHost mounted (included in AppLayout).

API ​

Modal

<ThlModal> · import { ThlModal } from '@thl-ui/vue'

PropTypeDefault
openboolean—
titlestring—
sizestring—
closeOnBackdropboolean—
closeOnEscboolean—
centeredboolean—
scrollableboolean—
hideCloseboolean—
modalClassstring—

Events: update:openclose

Slots: titledefaultfooter

ConfirmHost

<ThlConfirmHost> · import { ThlConfirmHost } from '@thl-ui/vue'

PropTypeDefault

Drawer

<ThlDrawer> · import { ThlDrawer } from '@thl-ui/vue'

PropTypeDefault
openboolean—
titlestring—
sidestring"end"
wideboolean—

Events: update:openclose

Slots: default