81 lines
2.1 KiB
Vue
81 lines
2.1 KiB
Vue
<script setup lang="ts">
|
|
import { type ColorProps, type DefaultProps, color } from '~/composables/color';
|
|
import { watchEffect } from 'vue';
|
|
import onKeyboardShortcut from '~/composables/onKeyboardShortcut';
|
|
|
|
import Button from '~/components/ui/Button.vue'
|
|
import Spacer from '~/components/ui/Spacer.vue'
|
|
import Layout from '~/components/ui/Layout.vue'
|
|
|
|
const props = defineProps<{
|
|
title: string,
|
|
overPopover?: true,
|
|
destructive?: true
|
|
} & (ColorProps | DefaultProps)>()
|
|
|
|
const isOpen = defineModel<boolean>({ default:false })
|
|
|
|
watchEffect(() =>
|
|
isOpen.value
|
|
? document.querySelector('#app')?.setAttribute('inert', 'true')
|
|
: document.querySelector('#app')?.removeAttribute('inert')
|
|
)
|
|
|
|
onKeyboardShortcut('escape', () => isOpen.value = false)
|
|
|
|
// TODO:
|
|
// When overflowing content: Add inset shadow to indicate scrollability
|
|
// - [ ] Add aria role to inform screenreaders
|
|
</script>
|
|
|
|
<template>
|
|
<Teleport to="body">
|
|
<Transition mode="out-in">
|
|
<div v-if="isOpen"
|
|
@click.exact.stop="isOpen = false"
|
|
class="funkwhale overlay"
|
|
>
|
|
<div @click.stop
|
|
class="funkwhale modal"
|
|
:class="[
|
|
{ 'is-destructive': destructive,
|
|
'has-alert': !!$slots.alert,
|
|
'over-popover': overPopover,
|
|
}
|
|
]"
|
|
v-bind="color(props)"
|
|
>
|
|
<h2
|
|
:class="{
|
|
'destructive-header': destructive
|
|
}"
|
|
>
|
|
{{ title }}
|
|
<Button icon="bi-x-lg" ghost @click="isOpen = false" />
|
|
</h2>
|
|
|
|
<div class="modal-content">
|
|
<Transition>
|
|
<div v-if="$slots.alert" class="alert-container">
|
|
<div>
|
|
<slot name="alert" />
|
|
</div>
|
|
</div>
|
|
</Transition>
|
|
|
|
<slot />
|
|
</div>
|
|
<Layout flex gap-12 style="flex-wrap: wrap;" v-if="$slots.actions" class="modal-actions">
|
|
<slot name="actions" />
|
|
</Layout>
|
|
<Spacer :size="64" v-else />
|
|
</div>
|
|
</div>
|
|
</Transition>
|
|
</Teleport>
|
|
</template>
|
|
|
|
<style lang="scss">
|
|
@import './modal.scss'
|
|
</style>
|