UNPKG

oui-kit

Version:

🎯 *UI toolkit with a French touch* 🇫🇷

116 lines (97 loc) • 3.04 kB
import type { Component } from 'vue' import { useDispose } from 'zeed' import { mountComponentAsApp } from '../basic/app-helper' import { onEnterFree } from './focus' import OuiDialog from './oui-dialog.vue' /** Environment for JS dialog replacements */ export function useDialog<T extends Component>(component?: T) { let cancel: any const dispose = useDispose() dispose.add(() => cancel?.()) async function showDialog<T>(props: any) { const dialogApp = mountComponentAsApp<T>(component ?? OuiDialog, props, 400) cancel = dialogApp.cancel // This will fix focussing on iOS, because it only works onClick // A workaround would also be to focus a hidden input field on click // and then focus the right one, because switching focus fields // also works programmatically. It might also work with setTimeout... dispose.add(onEnterFree(() => { const el = document.querySelector('._focus') as HTMLElement if (el) el.focus({ preventScroll: true }) }, () => { const el = document.querySelector('._focus_fake') as HTMLElement if (el) el.focus({ preventScroll: true }) })) const result = dialogApp.awaitDone return result } // todo this is called outside of setup! // onBeforeUnmount(dispose) return { dispose, async alert(this: void, message: string) { return await showDialog<void>({ message, cancel: 'OK', mode: 'alert', }) }, async confirm(this: void, message: string) { return await showDialog<boolean>({ message, mode: 'confirm', }) }, async prompt(this: void, message: string, dft?: string) { return (await showDialog<string | null>({ message, defaultValue: dft ?? '', mode: 'prompt', })) as string }, async dialog(this: void, props: any) { return await showDialog({ mode: 'dialog', ...props, }) }, /** Open custom dialog, will return `null` for "no result". */ async open(this: void, props?: any) { return await showDialog({ ...props, }) ?? null }, } } export function dialogOpen<T = any>(component: Component, props?: T) { const { open } = useDialog(component) open(props) } export function useDialogOpen(component: Component) { const { open } = useDialog(component) return open } let dialogDefault: ReturnType<typeof useDialog> | null = null function getDialogDefault() { if (!dialogDefault) dialogDefault = useDialog() return dialogDefault } export function ouiAlert(message: string) { const { alert } = getDialogDefault() return alert(message) } export function ouiConfirm(message: string) { const { confirm } = getDialogDefault() return confirm(message) } export function ouiPrompt(message: string, dft?: string) { const { prompt } = getDialogDefault() return prompt(message, dft) } export function ouiDialog(props: any) { const { dialog } = getDialogDefault() return dialog(props) }