Updated to work with live site Added components from somewhere fixed some css background image
This commit is contained in:
parent
faf1fb29b8
commit
a046f7c3f2
16 changed files with 885 additions and 4 deletions
249
src/components/Modal.svelte
Normal file
249
src/components/Modal.svelte
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
<script>
|
||||
import {setContext as baseSetContext, createEventDispatcher} from 'svelte';
|
||||
import {fade} from 'svelte/transition';
|
||||
|
||||
export let key = 'simple-modal';
|
||||
export let closeButton = true;
|
||||
export let closeOnEsc = true;
|
||||
export let closeOnOuterClick = true;
|
||||
export let transitionBg = fade;
|
||||
export let transitionBgProps = {duration: 250};
|
||||
export let transitionWindow = transitionBg;
|
||||
export let transitionWindowProps = transitionBgProps;
|
||||
export let styleBg = {top: 0, left: 0};
|
||||
export let styleWindow = {};
|
||||
export let styleContent = {};
|
||||
export let setContext = baseSetContext;
|
||||
|
||||
let Component = null;
|
||||
let props = null;
|
||||
|
||||
let background;
|
||||
let wrap;
|
||||
let customStyleBg = {};
|
||||
let customStyleWindow = {};
|
||||
let customStyleContent = {};
|
||||
|
||||
let Callback = (props) => {
|
||||
};
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
const camelCaseToDash = str => str
|
||||
.replace(/([a-zA-Z])(?=[A-Z])/g, '$1-').toLowerCase();
|
||||
|
||||
const toCssString = (props) => Object.keys(props)
|
||||
.reduce((str, key) => `${str}; ${camelCaseToDash(key)}: ${props[key]}`, '');
|
||||
|
||||
$: cssBg = toCssString(Object.assign({}, styleBg, customStyleBg));
|
||||
$: cssWindow = toCssString(Object.assign({}, styleWindow, customStyleWindow));
|
||||
$: cssContent = toCssString(Object.assign({}, styleContent, customStyleContent));
|
||||
|
||||
const open = (NewComponent, newProps = {}, style = {bg: {}, window: {}, content: {}}, newCallback = () => {
|
||||
}) => {
|
||||
Component = NewComponent;
|
||||
props = newProps;
|
||||
Callback = newCallback;
|
||||
customStyleBg = style.bg || {};
|
||||
customStyleWindow = style.window || {};
|
||||
customStyleContent = style.content || {};
|
||||
};
|
||||
|
||||
const close = () => {
|
||||
Callback(props);
|
||||
Component = null;
|
||||
props = null;
|
||||
customStyleBg = {};
|
||||
customStyleWindow = {};
|
||||
customStyleContent = {};
|
||||
};
|
||||
|
||||
const handleKeyup = ({key}) => {
|
||||
if (closeOnEsc && Component && key === 'Escape') {
|
||||
event.preventDefault();
|
||||
close();
|
||||
}
|
||||
};
|
||||
|
||||
const handleOuterClick = (event) => {
|
||||
if (
|
||||
closeOnOuterClick && (
|
||||
event.target === background || event.target === wrap
|
||||
)
|
||||
) {
|
||||
event.preventDefault();
|
||||
close();
|
||||
}
|
||||
};
|
||||
|
||||
setContext(key, {open, close});
|
||||
</script>
|
||||
|
||||
<!--
|
||||
|
||||
** LICENSE **
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Fritz Lekschas
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
https://github.com/flekschas/svelte-simple-moda
|
||||
-->
|
||||
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.bg {
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: rgba(0, 0, 0, 0.66);
|
||||
}
|
||||
|
||||
.window-wrap {
|
||||
position: relative;
|
||||
margin: 2rem;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.window {
|
||||
position: relative;
|
||||
width: 40rem;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
margin: 2rem auto;
|
||||
color: black;
|
||||
border-radius: 0.5rem;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
padding: 1rem;
|
||||
max-height: calc(100vh - 4rem);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.close {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
top: 1rem;
|
||||
right: 1rem;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
border: 0;
|
||||
color: black;
|
||||
border-radius: 1.5rem;
|
||||
background: white;
|
||||
box-shadow: 0 0 0 1px black;
|
||||
transition: transform 0.2s cubic-bezier(0.25, 0.1, 0.25, 1),
|
||||
background 0.2s cubic-bezier(0.25, 0.1, 0.25, 1);
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
.close:before, .close:after {
|
||||
content: '';
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
width: 1rem;
|
||||
height: 1px;
|
||||
background: black;
|
||||
transform-origin: center;
|
||||
transition: height 0.2s cubic-bezier(0.25, 0.1, 0.25, 1),
|
||||
background 0.2s cubic-bezier(0.25, 0.1, 0.25, 1);
|
||||
}
|
||||
|
||||
.close:before {
|
||||
-webkit-transform: translate(0, -50%) rotate(45deg);
|
||||
-moz-transform: translate(0, -50%) rotate(45deg);
|
||||
transform: translate(0, -50%) rotate(45deg);
|
||||
left: 0.25rem;
|
||||
}
|
||||
|
||||
.close:after {
|
||||
-webkit-transform: translate(0, -50%) rotate(-45deg);
|
||||
-moz-transform: translate(0, -50%) rotate(-45deg);
|
||||
transform: translate(0, -50%) rotate(-45deg);
|
||||
left: 0.25rem;
|
||||
}
|
||||
|
||||
.close:hover {
|
||||
background: black;
|
||||
}
|
||||
|
||||
.close:hover:before, .close:hover:after {
|
||||
height: 2px;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.close:focus {
|
||||
border-color: #3399ff;
|
||||
box-shadow: 0 0 0 2px #3399ff;
|
||||
}
|
||||
|
||||
.close:active {
|
||||
transform: scale(0.9);
|
||||
}
|
||||
|
||||
.close:hover, .close:focus, .close:active {
|
||||
outline: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<svelte:window on:keyup={handleKeyup}/>
|
||||
|
||||
<div>
|
||||
{#if Component}
|
||||
<div
|
||||
class="bg"
|
||||
on:click={handleOuterClick}
|
||||
bind:this={background}
|
||||
transition:transitionBg={transitionBgProps}
|
||||
style={cssBg}>
|
||||
<div class="window-wrap" bind:this={wrap}>
|
||||
<div
|
||||
class="window"
|
||||
transition:transitionWindow={transitionWindowProps}
|
||||
style={cssWindow}>
|
||||
{#if closeButton}
|
||||
<button on:click={close} class="close"></button>
|
||||
{/if}
|
||||
<div class="content" style={cssContent}>
|
||||
<Component {...props} {close}/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<slot></slot>
|
||||
</div>
|
||||
Loading…
Reference in a new issue