<template> <teleport to="body"> <div class="container" @click="$emit('close')" > <div class="dialog" @click.stop="events.emit('blur')" > <div v-if="title || $slots.header" class="header" > <slot name="header"> <h2 class="header-title">{{ title }}</h2> </slot> <Icon icon="cross2" class="close" @click="$emit('close')" /> </div> <div class="body"> <slot /> </div> </div> </div> </teleport> </template> <script> function mounted() { this.events.emit('blur'); } export default { props: { title: { type: String, default: null, }, }, emits: ['close'], mounted, }; </script> <style lang="scss" scoped> .container { display: flex; align-items: center; justify-content: center; position: fixed; top: 0; left: 0; width: 100%; height: 100%; box-sizing: border-box; padding: 1rem; background: var(--darken-strong); z-index: 10; } .dialog { display: flex; flex-direction: column; max-width: 100%; max-height: 100%; background: var(--background); box-shadow: 0 0 3px var(--darken-weak); } .header { display: flex; justify-content: space-between; align-items: center; background: var(--primary); color: var(--text-light); font-size: 1.5rem; font-weight: bold; } .header-title { padding: .5rem .5rem .5rem 1rem; margin: 0; overflow: hidden; text-overflow: ellipsis; font-size: 1.25rem; } .close { height: 100%; padding: 0 1rem; fill: var(--lighten); &:hover { fill: var(--lighten-strong); cursor: pointer; } } .body { display: flex; flex-direction: column; flex-grow: 1; overflow: hidden; ::v-deep(.section) { padding: 1rem; } } ::v-deep(.dialog-body) { flex-grow: 1; box-sizing: border-box; padding: 1rem; overflow-y: auto; } ::v-deep(.dialog-section:not(:last-child)) { padding-bottom: 1rem; border-bottom: solid 1px var(--shadow-hint); margin-bottom: 1rem; overflow: auto; } ::v-deep(.dialog-actions) { display: flex; margin: 1rem 0 0 0; &.center { justify-content: center; } &.right { justify-content: flex-end; } } </style>