budibase/packages/bbui/src/Modal/Modal.svelte

104 lines
2.2 KiB
Svelte
Raw Normal View History

2021-03-31 11:59:07 +02:00
<script>
2021-04-08 14:47:57 +02:00
import "@spectrum-css/modal/dist/index-vars.css"
import "@spectrum-css/underlay/dist/index-vars.css"
import { createEventDispatcher, setContext, tick } from "svelte"
2021-03-31 11:59:07 +02:00
import { fade, fly } from "svelte/transition"
import Portal from "svelte-portal"
import Context from "../context"
import clickOutside from "../Actions/click_outside"
2021-03-31 11:59:07 +02:00
const dispatch = createEventDispatcher()
2021-03-31 11:59:07 +02:00
let visible = false
$: dispatch(visible ? "show" : "hide")
export function show() {
if (visible) {
return
}
visible = true
}
export function hide() {
if (!visible) {
return
}
visible = false
}
function handleKey(e) {
if (visible && e.key === "Escape") {
hide()
}
}
async function focusFirstInput(node) {
const inputs = node.querySelectorAll("input")
if (inputs?.length) {
await tick()
inputs[0].focus()
}
}
2021-03-31 11:59:07 +02:00
setContext(Context.Modal, { show, hide })
</script>
<svelte:window on:keydown={handleKey} />
{#if visible}
<Portal target=".modal-container">
<div
class="spectrum-Underlay is-open"
transition:fade={{ duration: 200 }}
on:mousedown|self={hide}>
<div class="modal-wrapper" on:mousedown|self={hide}>
<div class="modal-inner-wrapper" on:mousedown|self={hide}>
<div
use:focusFirstInput
class="spectrum-Modal is-open"
transition:fly={{ y: 30, duration: 200 }}>
<slot />
</div>
2021-03-31 11:59:07 +02:00
</div>
2021-04-08 14:47:57 +02:00
</div>
2021-03-31 11:59:07 +02:00
</div>
</Portal>
{/if}
<style>
.spectrum-Underlay {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
z-index: 999;
overflow: auto;
overflow-x: hidden;
}
.modal-wrapper {
flex: 1 1 auto;
display: flex;
flex-direction: row;
-moz-box-pack: center;
justify-content: center;
align-items: flex-start;
max-height: 100%;
}
.modal-inner-wrapper {
flex: 1 1 auto;
display: flex;
flex-direction: row;
-moz-box-pack: center;
justify-content: center;
align-items: flex-start;
width: 0;
}
.spectrum-Modal {
overflow: visible;
max-height: none;
margin: 40px 0;
transform: none;
}
</style>