// noinspection IncorrectFormatting import '@material/web/dialog/dialog.js'; import {Dialog as MDDialog} from '@material/web/dialog/internal/dialog'; import { VnodeCollection, VnodeCollectionItem } from '@osm/typings/jsx'; import collect from 'collect.js'; import Mithril, { Children, Vnode } from 'mithril'; import Stream from 'mithril/stream'; import { Attributes, Component } from 'mithril-utilities'; import {KebabCasedProperties} from 'type-fest'; export interface DialogAttributes extends Attributes, Partial>> { open?: Stream; onOpen?: () => void; onClose?: () => void; } export default abstract class Dialog extends Component { declare element: MDDialog; open!: Stream; oninit(vnode: Vnode) { super.oninit(vnode); let {open} = vnode.attrs; if (open === undefined) { open = Stream(false); } this.open = open; } public view(vnode: Vnode): Children { let open = this.open(); // If dialog is open but element isn't created yet, don't open it (wait for oncreate, see below) if (open && this.element === undefined) { open = false; } const contents = this.contents(vnode) ?? vnode.children; const actions = this.actions(vnode); return ( {this.icon() &&
{this.icon()}
} {this.headline() &&
{this.headline()}
} {contents &&
{contents}
} {actions.isNotEmpty() &&
{actions.toArray()}
}
); } oncreate(vnode: Mithril.VnodeDOM) { super.oncreate(vnode); // TODO: [BUG] Dialog not opening by default on creation. Wait for https://github.com/material-components/material-web/issues/4728 setTimeout(() => { if (this.open()) { void this.show(); } }, 0); } onDialogClosed(vnode:Vnode) { vnode.attrs.onClose?.(); this.open(false); } icon(): Children { return undefined; } headline(): Children { return undefined; } contents(vnode: Vnode): Children { return undefined; } actions(vnode: Vnode): VnodeCollection { return collect(); } public async show() { return this.element.show(); } public async close(action?: string) { return this.element.close(action); } }