You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
<script lang="ts"> import { createEventDispatcher, onMount } from 'svelte'; import Icon from './Icon.svelte';
export let title: string = ""; export let wide: boolean = false; export let error: string | null = null; export let closable: boolean = false; export let show: boolean = false;
onMount(() => { const listener = (ev: KeyboardEvent) => { if ((ev.ctrlKey || ev.altKey) && (ev.key === "Escape" || ev.key.toLowerCase() === "q")) { dispatch("close"); } }
document.addEventListener("keyup", listener);
return () => { document.removeEventListener("keyup", listener); } })
const dispatch = createEventDispatcher(); </script>
{#if show} <div class="modal-background"> <div class="modal" class:wide> <div class="header"> <div class="title" class:noclose={!closable}>{title}</div> {#if (closable)} <div class="x"> <div class="button" on:click={() => dispatch("close")}> <Icon name="times" /> </div> </div> {/if} </div> <hr /> {#if (error != null)} <div class="error">{error}</div> {/if} <div class="body"> <slot></slot> </div> </div> </div> {/if}
<style> div.modal-background { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.3); }
div.modal { position: absolute; left: 50%; top: 50%; width: calc(100vw - 4em); max-width: 40ch; max-height: calc(100vh - 4em); overflow: auto; transform: translate(-50%,-50%); padding: 1em; border-radius: 0.2em;
background: #333; } div.modal.wide { max-width: 60ch; }
div.modal :global(hr) { border: 0.5px solid gray; margin: 0; }
div.error { margin: 0.5em; padding: 0.5em;
border: 1px solid rgb(204, 65, 65); border-radius: 0.2em; background-color: rgb(133, 39, 39); color: rgb(211, 141, 141);
animation: fadein 0.5s; }
div.body { margin: 1em 0.25ch; }
div.title { color: #CCC; line-height: 1em; }
div.title.noclose { margin-bottom: 1.2em; }
div.x { position: relative; line-height: 1em; top: -1em; text-align: right; } div.x div.button { color: #CCC; display: inline-block; padding: 0em 0.5ch 0.1em 0.5ch; line-height: 1em; user-select: none; cursor: pointer; } div.x div.button:hover { color: #FFF; }
div.modal :global(button) { display: inline-block; padding: 0.25em 0.75ch 0.26em 0.75ch; margin: 0.75em 0.25ch 0.25em 0.25ch;
background: none; border: none; border-radius: 0.2em; color: #CCC;
cursor: pointer; }
div.modal :global(button:hover), div.modal :global(button:focus) { background: #222; color: #FFF; } div.modal :global(button:disabled) { background: #444; color: #AAA; }
div.modal :global(label) { padding: 0 0 0.125em 0.25ch; font-size: 0.75em; user-select: none; -webkit-user-select: none; -moz-user-select: none; }
div.modal :global(input), div.modal :global(select), div.modal :global(textarea) { width: 100%; margin-bottom: 0.5em;
background: #222; color: #777; border: none; outline: none; resize: vertical; } div.modal :global(select) { padding-left: 0.5ch; } div.modal :global(select:disabled) { background: #4a4a4a; color: #fff; } div.modal :global(input:disabled) { background: #444; color: #aaa; } div.modal :global(textarea) { min-height: 6em; height: 6em; } div.modal :global(textarea:disabled) { background: #444; color: #aaa; }
div.modal :global(input.nolast) { margin-bottom: 0.5em; }
div.modal :global(input[type="checkbox"]) { width: initial; display: inline-block; } div.modal :global(input[type="checkbox"] + label) { width: initial; display: inline-block; padding: 0; margin: 0; }
div.modal :global(input:focus), div.modal :global(select:focus), div.modal :global(textarea:focus) { background: #111; color: #CCC; border: none; outline: none; }
div.modal :global(p) { margin: 0.25em 1ch 1em 1ch; font-size: 0.9em; }
@keyframes fadein { from { opacity: 0; } to { opacity: 1; } } </style>
|