svelte-simple-modal
Version:
A small and simple modal for Svelte
1,017 lines (892 loc) • 30.8 kB
JavaScript
import { SvelteComponent, init, safe_not_equal, append_styles, create_slot, space, insert, listen, transition_in, group_outros, transition_out, check_outros, update_slot_base, get_all_dirty_from_scope, get_slot_changes, detach, globals, construct_svelte_component, element, create_component, attr, null_to_empty, toggle_class, append, mount_component, is_function, destroy_component, add_render_callback, create_bidirectional_transition, run_all, empty, binding_callbacks, noop } from 'svelte/internal';
import * as svelte from 'svelte';
import { mount, createEventDispatcher } from 'svelte';
import { fade } from 'svelte/transition';
// generated during release, do not modify
const PUBLIC_VERSION = '4';
if (typeof window !== 'undefined')
// @ts-ignore
(window.__svelte || (window.__svelte = { v: new Set() })).v.add(PUBLIC_VERSION);
/* src/Modal.svelte generated by Svelte v4.2.19 */
const { window: window_1 } = globals;
function add_css(target) {
append_styles(target, "svelte-jw1gd6", ".svelte-jw1gd6{box-sizing:border-box}.bg.svelte-jw1gd6{position:fixed;z-index:1000;top:0;left:0;display:flex;flex-direction:column;justify-content:center;width:100vw;height:100vh;background:rgba(0, 0, 0, 0.66)}@supports (-webkit-touch-callout: none){body{height:-webkit-fill-available}}.wrap.svelte-jw1gd6{position:relative;margin:2rem;max-height:100%}.window.svelte-jw1gd6{position:relative;width:40rem;max-width:100%;max-height:100%;margin:2rem auto;color:black;border-radius:0.5rem;background:white}.content.svelte-jw1gd6{position:relative;padding:1rem;max-height:calc(100vh - 4rem);overflow:auto}.close.svelte-jw1gd6{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),\n background 0.2s cubic-bezier(0.25, 0.1, 0.25, 1);-webkit-appearance:none}.close.svelte-jw1gd6:before,.close.svelte-jw1gd6: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),\n background 0.2s cubic-bezier(0.25, 0.1, 0.25, 1)}.close.svelte-jw1gd6: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.svelte-jw1gd6: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.svelte-jw1gd6:hover{background:black}.close.svelte-jw1gd6:hover:before,.close.svelte-jw1gd6:hover:after{height:2px;background:white}.close.svelte-jw1gd6:focus{border-color:#3399ff;box-shadow:0 0 0 2px #3399ff}.close.svelte-jw1gd6:active{transform:scale(0.9)}.close.svelte-jw1gd6:hover,.close.svelte-jw1gd6:focus,.close.svelte-jw1gd6:active{outline:none}");
}
// (472:0) {#if Component}
function create_if_block(ctx) {
let div3;
let div2;
let div1;
let t;
let div0;
let switch_instance;
let div0_class_value;
let div1_class_value;
let div1_aria_label_value;
let div1_aria_labelledby_value;
let div1_transition;
let div2_class_value;
let div3_id_value;
let div3_class_value;
let div3_transition;
let current;
let mounted;
let dispose;
let if_block = /*state*/ ctx[1].closeButton && create_if_block_1(ctx);
var switch_value = /*Component*/ ctx[2];
function switch_props(ctx, dirty) {
return {};
}
if (switch_value) {
switch_instance = construct_svelte_component(switch_value, switch_props());
}
return {
c() {
div3 = element("div");
div2 = element("div");
div1 = element("div");
if (if_block) if_block.c();
t = space();
div0 = element("div");
if (switch_instance) create_component(switch_instance.$$.fragment);
attr(div0, "class", div0_class_value = "" + (null_to_empty(/*state*/ ctx[1].classContent) + " svelte-jw1gd6"));
attr(div0, "style", /*cssContent*/ ctx[9]);
toggle_class(div0, "content", !/*unstyled*/ ctx[0]);
attr(div1, "class", div1_class_value = "" + (null_to_empty(/*state*/ ctx[1].classWindow) + " svelte-jw1gd6"));
attr(div1, "role", "dialog");
attr(div1, "aria-modal", "true");
attr(div1, "aria-label", div1_aria_label_value = /*state*/ ctx[1].ariaLabelledBy
? null
: /*state*/ ctx[1].ariaLabel || null);
attr(div1, "aria-labelledby", div1_aria_labelledby_value = /*state*/ ctx[1].ariaLabelledBy || null);
attr(div1, "style", /*cssWindow*/ ctx[8]);
toggle_class(div1, "window", !/*unstyled*/ ctx[0]);
attr(div2, "class", div2_class_value = "" + (null_to_empty(/*state*/ ctx[1].classWindowWrap) + " svelte-jw1gd6"));
attr(div2, "style", /*cssWindowWrap*/ ctx[7]);
toggle_class(div2, "wrap", !/*unstyled*/ ctx[0]);
attr(div3, "aria-hidden", "true");
attr(div3, "id", div3_id_value = /*state*/ ctx[1].id);
attr(div3, "class", div3_class_value = "" + (null_to_empty(/*state*/ ctx[1].classBg) + " svelte-jw1gd6"));
attr(div3, "style", /*cssBg*/ ctx[6]);
toggle_class(div3, "bg", !/*unstyled*/ ctx[0]);
},
m(target, anchor) {
insert(target, div3, anchor);
append(div3, div2);
append(div2, div1);
if (if_block) if_block.m(div1, null);
append(div1, t);
append(div1, div0);
if (switch_instance) mount_component(switch_instance, div0, null);
/*div1_binding*/ ctx[50](div1);
/*div2_binding*/ ctx[51](div2);
/*div3_binding*/ ctx[52](div3);
current = true;
if (!mounted) {
dispose = [
listen(div1, "introstart", function () {
if (is_function(/*onOpen*/ ctx[13])) /*onOpen*/ ctx[13].apply(this, arguments);
}),
listen(div1, "outrostart", function () {
if (is_function(/*onClose*/ ctx[14])) /*onClose*/ ctx[14].apply(this, arguments);
}),
listen(div1, "introend", function () {
if (is_function(/*onOpened*/ ctx[15])) /*onOpened*/ ctx[15].apply(this, arguments);
}),
listen(div1, "outroend", function () {
if (is_function(/*onClosed*/ ctx[16])) /*onClosed*/ ctx[16].apply(this, arguments);
}),
listen(div3, "mousedown", /*handleOuterMousedown*/ ctx[20]),
listen(div3, "mouseup", /*handleOuterMouseup*/ ctx[21])
];
mounted = true;
}
},
p(new_ctx, dirty) {
ctx = new_ctx;
if (/*state*/ ctx[1].closeButton) {
if (if_block) {
if_block.p(ctx, dirty);
if (dirty[0] & /*state*/ 2) {
transition_in(if_block, 1);
}
} else {
if_block = create_if_block_1(ctx);
if_block.c();
transition_in(if_block, 1);
if_block.m(div1, t);
}
} else if (if_block) {
group_outros();
transition_out(if_block, 1, 1, () => {
if_block = null;
});
check_outros();
}
if (dirty[0] & /*Component*/ 4 && switch_value !== (switch_value = /*Component*/ ctx[2])) {
if (switch_instance) {
group_outros();
const old_component = switch_instance;
transition_out(old_component.$$.fragment, 1, 0, () => {
destroy_component(old_component, 1);
});
check_outros();
}
if (switch_value) {
switch_instance = construct_svelte_component(switch_value, switch_props());
create_component(switch_instance.$$.fragment);
transition_in(switch_instance.$$.fragment, 1);
mount_component(switch_instance, div0, null);
} else {
switch_instance = null;
}
}
if (!current || dirty[0] & /*state*/ 2 && div0_class_value !== (div0_class_value = "" + (null_to_empty(/*state*/ ctx[1].classContent) + " svelte-jw1gd6"))) {
attr(div0, "class", div0_class_value);
}
if (!current || dirty[0] & /*cssContent*/ 512) {
attr(div0, "style", /*cssContent*/ ctx[9]);
}
if (!current || dirty[0] & /*state, unstyled*/ 3) {
toggle_class(div0, "content", !/*unstyled*/ ctx[0]);
}
if (!current || dirty[0] & /*state*/ 2 && div1_class_value !== (div1_class_value = "" + (null_to_empty(/*state*/ ctx[1].classWindow) + " svelte-jw1gd6"))) {
attr(div1, "class", div1_class_value);
}
if (!current || dirty[0] & /*state*/ 2 && div1_aria_label_value !== (div1_aria_label_value = /*state*/ ctx[1].ariaLabelledBy
? null
: /*state*/ ctx[1].ariaLabel || null)) {
attr(div1, "aria-label", div1_aria_label_value);
}
if (!current || dirty[0] & /*state*/ 2 && div1_aria_labelledby_value !== (div1_aria_labelledby_value = /*state*/ ctx[1].ariaLabelledBy || null)) {
attr(div1, "aria-labelledby", div1_aria_labelledby_value);
}
if (!current || dirty[0] & /*cssWindow*/ 256) {
attr(div1, "style", /*cssWindow*/ ctx[8]);
}
if (!current || dirty[0] & /*state, unstyled*/ 3) {
toggle_class(div1, "window", !/*unstyled*/ ctx[0]);
}
if (!current || dirty[0] & /*state*/ 2 && div2_class_value !== (div2_class_value = "" + (null_to_empty(/*state*/ ctx[1].classWindowWrap) + " svelte-jw1gd6"))) {
attr(div2, "class", div2_class_value);
}
if (!current || dirty[0] & /*cssWindowWrap*/ 128) {
attr(div2, "style", /*cssWindowWrap*/ ctx[7]);
}
if (!current || dirty[0] & /*state, unstyled*/ 3) {
toggle_class(div2, "wrap", !/*unstyled*/ ctx[0]);
}
if (!current || dirty[0] & /*state*/ 2 && div3_id_value !== (div3_id_value = /*state*/ ctx[1].id)) {
attr(div3, "id", div3_id_value);
}
if (!current || dirty[0] & /*state*/ 2 && div3_class_value !== (div3_class_value = "" + (null_to_empty(/*state*/ ctx[1].classBg) + " svelte-jw1gd6"))) {
attr(div3, "class", div3_class_value);
}
if (!current || dirty[0] & /*cssBg*/ 64) {
attr(div3, "style", /*cssBg*/ ctx[6]);
}
if (!current || dirty[0] & /*state, unstyled*/ 3) {
toggle_class(div3, "bg", !/*unstyled*/ ctx[0]);
}
},
i(local) {
if (current) return;
transition_in(if_block);
if (switch_instance) transition_in(switch_instance.$$.fragment, local);
if (local) {
add_render_callback(() => {
if (!current) return;
if (!div1_transition) div1_transition = create_bidirectional_transition(div1, /*currentTransitionWindow*/ ctx[12], /*state*/ ctx[1].transitionWindowProps, true);
div1_transition.run(1);
});
}
if (local) {
add_render_callback(() => {
if (!current) return;
if (!div3_transition) div3_transition = create_bidirectional_transition(div3, /*currentTransitionBg*/ ctx[11], /*state*/ ctx[1].transitionBgProps, true);
div3_transition.run(1);
});
}
current = true;
},
o(local) {
transition_out(if_block);
if (switch_instance) transition_out(switch_instance.$$.fragment, local);
if (local) {
if (!div1_transition) div1_transition = create_bidirectional_transition(div1, /*currentTransitionWindow*/ ctx[12], /*state*/ ctx[1].transitionWindowProps, false);
div1_transition.run(0);
}
if (local) {
if (!div3_transition) div3_transition = create_bidirectional_transition(div3, /*currentTransitionBg*/ ctx[11], /*state*/ ctx[1].transitionBgProps, false);
div3_transition.run(0);
}
current = false;
},
d(detaching) {
if (detaching) {
detach(div3);
}
if (if_block) if_block.d();
if (switch_instance) destroy_component(switch_instance);
/*div1_binding*/ ctx[50](null);
if (detaching && div1_transition) div1_transition.end();
/*div2_binding*/ ctx[51](null);
/*div3_binding*/ ctx[52](null);
if (detaching && div3_transition) div3_transition.end();
mounted = false;
run_all(dispose);
}
};
}
// (505:8) {#if state.closeButton}
function create_if_block_1(ctx) {
let show_if;
let current_block_type_index;
let if_block;
let if_block_anchor;
let current;
const if_block_creators = [create_if_block_2, create_else_block];
const if_blocks = [];
function select_block_type(ctx, dirty) {
if (dirty[0] & /*state*/ 2) show_if = null;
if (show_if == null) show_if = !!/*isFunction*/ ctx[17](/*state*/ ctx[1].closeButton);
if (show_if) return 0;
return 1;
}
current_block_type_index = select_block_type(ctx, [-1, -1, -1]);
if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
return {
c() {
if_block.c();
if_block_anchor = empty();
},
m(target, anchor) {
if_blocks[current_block_type_index].m(target, anchor);
insert(target, if_block_anchor, anchor);
current = true;
},
p(ctx, dirty) {
let previous_block_index = current_block_type_index;
current_block_type_index = select_block_type(ctx, dirty);
if (current_block_type_index === previous_block_index) {
if_blocks[current_block_type_index].p(ctx, dirty);
} else {
group_outros();
transition_out(if_blocks[previous_block_index], 1, 1, () => {
if_blocks[previous_block_index] = null;
});
check_outros();
if_block = if_blocks[current_block_type_index];
if (!if_block) {
if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
if_block.c();
} else {
if_block.p(ctx, dirty);
}
transition_in(if_block, 1);
if_block.m(if_block_anchor.parentNode, if_block_anchor);
}
},
i(local) {
if (current) return;
transition_in(if_block);
current = true;
},
o(local) {
transition_out(if_block);
current = false;
},
d(detaching) {
if (detaching) {
detach(if_block_anchor);
}
if_blocks[current_block_type_index].d(detaching);
}
};
}
// (508:10) {:else}
function create_else_block(ctx) {
let button;
let button_class_value;
let mounted;
let dispose;
return {
c() {
button = element("button");
attr(button, "class", button_class_value = "" + (null_to_empty(/*state*/ ctx[1].classCloseButton) + " svelte-jw1gd6"));
attr(button, "aria-label", "Close modal");
attr(button, "style", /*cssCloseButton*/ ctx[10]);
attr(button, "type", "button");
toggle_class(button, "close", !/*unstyled*/ ctx[0]);
},
m(target, anchor) {
insert(target, button, anchor);
if (!mounted) {
dispose = listen(button, "click", /*close*/ ctx[18]);
mounted = true;
}
},
p(ctx, dirty) {
if (dirty[0] & /*state*/ 2 && button_class_value !== (button_class_value = "" + (null_to_empty(/*state*/ ctx[1].classCloseButton) + " svelte-jw1gd6"))) {
attr(button, "class", button_class_value);
}
if (dirty[0] & /*cssCloseButton*/ 1024) {
attr(button, "style", /*cssCloseButton*/ ctx[10]);
}
if (dirty[0] & /*state, unstyled*/ 3) {
toggle_class(button, "close", !/*unstyled*/ ctx[0]);
}
},
i: noop,
o: noop,
d(detaching) {
if (detaching) {
detach(button);
}
mounted = false;
dispose();
}
};
}
// (506:10) {#if isFunction(state.closeButton)}
function create_if_block_2(ctx) {
let switch_instance;
let switch_instance_anchor;
let current;
var switch_value = /*state*/ ctx[1].closeButton;
function switch_props(ctx, dirty) {
return { props: { onClose: /*close*/ ctx[18] } };
}
if (switch_value) {
switch_instance = construct_svelte_component(switch_value, switch_props(ctx));
}
return {
c() {
if (switch_instance) create_component(switch_instance.$$.fragment);
switch_instance_anchor = empty();
},
m(target, anchor) {
if (switch_instance) mount_component(switch_instance, target, anchor);
insert(target, switch_instance_anchor, anchor);
current = true;
},
p(ctx, dirty) {
if (dirty[0] & /*state*/ 2 && switch_value !== (switch_value = /*state*/ ctx[1].closeButton)) {
if (switch_instance) {
group_outros();
const old_component = switch_instance;
transition_out(old_component.$$.fragment, 1, 0, () => {
destroy_component(old_component, 1);
});
check_outros();
}
if (switch_value) {
switch_instance = construct_svelte_component(switch_value, switch_props(ctx));
create_component(switch_instance.$$.fragment);
transition_in(switch_instance.$$.fragment, 1);
mount_component(switch_instance, switch_instance_anchor.parentNode, switch_instance_anchor);
} else {
switch_instance = null;
}
}
},
i(local) {
if (current) return;
if (switch_instance) transition_in(switch_instance.$$.fragment, local);
current = true;
},
o(local) {
if (switch_instance) transition_out(switch_instance.$$.fragment, local);
current = false;
},
d(detaching) {
if (detaching) {
detach(switch_instance_anchor);
}
if (switch_instance) destroy_component(switch_instance, detaching);
}
};
}
function create_fragment(ctx) {
let t;
let current;
let mounted;
let dispose;
let if_block = /*Component*/ ctx[2] && create_if_block(ctx);
const default_slot_template = /*#slots*/ ctx[49].default;
const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[48], null);
return {
c() {
if (if_block) if_block.c();
t = space();
if (default_slot) default_slot.c();
},
m(target, anchor) {
if (if_block) if_block.m(target, anchor);
insert(target, t, anchor);
if (default_slot) {
default_slot.m(target, anchor);
}
current = true;
if (!mounted) {
dispose = listen(window_1, "keydown", /*handleKeydown*/ ctx[19]);
mounted = true;
}
},
p(ctx, dirty) {
if (/*Component*/ ctx[2]) {
if (if_block) {
if_block.p(ctx, dirty);
if (dirty[0] & /*Component*/ 4) {
transition_in(if_block, 1);
}
} else {
if_block = create_if_block(ctx);
if_block.c();
transition_in(if_block, 1);
if_block.m(t.parentNode, t);
}
} else if (if_block) {
group_outros();
transition_out(if_block, 1, 1, () => {
if_block = null;
});
check_outros();
}
if (default_slot) {
if (default_slot.p && (!current || dirty[1] & /*$$scope*/ 131072)) {
update_slot_base(
default_slot,
default_slot_template,
ctx,
/*$$scope*/ ctx[48],
!current
? get_all_dirty_from_scope(/*$$scope*/ ctx[48])
: get_slot_changes(default_slot_template, /*$$scope*/ ctx[48], dirty, null),
null
);
}
}
},
i(local) {
if (current) return;
transition_in(if_block);
transition_in(default_slot, local);
current = true;
},
o(local) {
transition_out(if_block);
transition_out(default_slot, local);
current = false;
},
d(detaching) {
if (detaching) {
detach(t);
}
if (if_block) if_block.d(detaching);
if (default_slot) default_slot.d(detaching);
mounted = false;
dispose();
}
};
}
function bind(Component, props = {}) {
return function ModalComponent(options) {
return mount(Component, {
...options,
props: { ...props, ...options.props },
target: options.parentNode
});
};
}
function instance($$self, $$props, $$invalidate) {
let { $$slots: slots = {}, $$scope } = $$props;
const dispatch = createEventDispatcher();
const baseSetContext = svelte.setContext;
/**
* A basic function that checks if a node is tabbale
*/
const baseIsTabbable = node => node.tabIndex >= 0 && !node.hidden && !node.disabled && node.style.display !== 'none' && node.type !== 'hidden' && Boolean(node.offsetWidth || node.offsetHeight || node.getClientRects().length);
let { isTabbable = baseIsTabbable } = $$props;
let { show = null } = $$props;
let { id = null } = $$props;
let { key = 'simple-modal' } = $$props;
let { ariaLabel = null } = $$props;
let { ariaLabelledBy = null } = $$props;
let { closeButton = true } = $$props;
let { closeOnEsc = true } = $$props;
let { closeOnOuterClick = true } = $$props;
let { styleBg = {} } = $$props;
let { styleWindowWrap = {} } = $$props;
let { styleWindow = {} } = $$props;
let { styleContent = {} } = $$props;
let { styleCloseButton = {} } = $$props;
let { classBg = null } = $$props;
let { classWindowWrap = null } = $$props;
let { classWindow = null } = $$props;
let { classContent = null } = $$props;
let { classCloseButton = null } = $$props;
let { unstyled = false } = $$props;
let { setContext = baseSetContext } = $$props;
let { transitionBg = fade } = $$props;
let { transitionBgProps = { duration: 250 } } = $$props;
let { transitionWindow = transitionBg } = $$props;
let { transitionWindowProps = transitionBgProps } = $$props;
let { disableFocusTrap = false } = $$props;
const defaultState = {
id,
ariaLabel,
ariaLabelledBy,
closeButton,
closeOnEsc,
closeOnOuterClick,
styleBg,
styleWindowWrap,
styleWindow,
styleContent,
styleCloseButton,
classBg,
classWindowWrap,
classWindow,
classContent,
classCloseButton,
transitionBg,
transitionBgProps,
transitionWindow,
transitionWindowProps,
disableFocusTrap,
isTabbable,
unstyled
};
let state = { ...defaultState };
let Component = null;
let background;
let wrap;
let modalWindow;
let scrollY;
let cssBg;
let cssWindowWrap;
let cssWindow;
let cssContent;
let cssCloseButton;
let currentTransitionBg;
let currentTransitionWindow;
let prevBodyPosition;
let prevBodyOverflow;
let prevBodyWidth;
let outerClickTarget;
const camelCaseToDash = str => str.replace(/([a-zA-Z])(?=[A-Z])/g, '$1-').toLowerCase();
const toCssString = props => props
? Object.keys(props).reduce((str, key) => `${str}; ${camelCaseToDash(key)}: ${props[key]}`, '')
: '';
const isFunction = f => !!(f && f.constructor && f.call && f.apply);
const updateStyleTransition = () => {
$$invalidate(6, cssBg = toCssString(Object.assign(
{},
{
width: window.innerWidth,
height: window.innerHeight
},
state.styleBg
)));
$$invalidate(7, cssWindowWrap = toCssString(state.styleWindowWrap));
$$invalidate(8, cssWindow = toCssString(state.styleWindow));
$$invalidate(9, cssContent = toCssString(state.styleContent));
$$invalidate(10, cssCloseButton = toCssString(state.styleCloseButton));
$$invalidate(11, currentTransitionBg = state.transitionBg);
$$invalidate(12, currentTransitionWindow = state.transitionWindow);
};
const toVoid = () => {
};
let onOpen = toVoid;
let onClose = toVoid;
let onOpened = toVoid;
let onClosed = toVoid;
/**
* Open a modal.
* @description Calling this method will close the modal. Additionally, it
* allows to specify onClose and onClosed event handlers.`
* @type {Open}
*/
const open = (NewComponent, newProps = {}, options = {}, callbacks = {}) => {
$$invalidate(2, Component = bind(NewComponent, newProps));
$$invalidate(1, state = { ...defaultState, ...options });
updateStyleTransition();
disableScroll();
$$invalidate(13, onOpen = event => {
if (callbacks.onOpen) callbacks.onOpen(event);
/**
* The open event is fired right before the modal opens
* @event {void} open
*/
dispatch('open');
/**
* The opening event is fired right before the modal opens
* @event {void} opening
* @deprecated Listen to the `open` event instead
*/
dispatch('opening'); // Deprecated. Do not use!
});
$$invalidate(14, onClose = event => {
if (callbacks.onClose) callbacks.onClose(event);
/**
* The close event is fired right before the modal closes
* @event {void} close
*/
dispatch('close');
/**
* The closing event is fired right before the modal closes
* @event {void} closing
* @deprecated Listen to the `close` event instead
*/
dispatch('closing'); // Deprecated. Do not use!
});
$$invalidate(15, onOpened = event => {
if (callbacks.onOpened) callbacks.onOpened(event);
/**
* The opened event is fired after the modal's opening transition
* @event {void} opened
*/
dispatch('opened');
});
$$invalidate(16, onClosed = event => {
if (callbacks.onClosed) callbacks.onClosed(event);
/**
* The closed event is fired after the modal's closing transition
* @event {void} closed
*/
dispatch('closed');
});
};
/**
* Close the modal.
* @description Calling this method will close the modal. Additionally, it
* allows to specify onClose and onClosed event handlers.`
* @type {Close}
*/
const close = (callbacks = {}) => {
if (!Component) return;
$$invalidate(14, onClose = callbacks.onClose || onClose);
$$invalidate(16, onClosed = callbacks.onClosed || onClosed);
$$invalidate(2, Component = null);
enableScroll();
};
const handleKeydown = event => {
if (state.closeOnEsc && Component && event.key === 'Escape') {
event.preventDefault();
close();
}
if (Component && event.key === 'Tab' && !state.disableFocusTrap) {
// trap focus
const nodes = modalWindow.querySelectorAll('*');
const tabbable = Array.from(nodes).filter(state.isTabbable).sort((a, b) => a.tabIndex - b.tabIndex);
let index = tabbable.indexOf(document.activeElement);
if (index === -1 && event.shiftKey) index = 0;
index += tabbable.length + (event.shiftKey ? -1 : 1);
index %= tabbable.length;
tabbable[index].focus();
event.preventDefault();
}
};
const handleOuterMousedown = event => {
if (state.closeOnOuterClick && (event.target === background || event.target === wrap)) outerClickTarget = event.target;
};
const handleOuterMouseup = event => {
if (state.closeOnOuterClick && event.target === outerClickTarget) {
event.preventDefault();
close();
}
};
const disableScroll = () => {
scrollY = window.scrollY;
prevBodyPosition = document.body.style.position;
prevBodyOverflow = document.body.style.overflow;
prevBodyWidth = document.body.style.width;
document.body.style.position = 'fixed';
document.body.style.top = `-${scrollY}px`;
document.body.style.overflow = 'hidden';
document.body.style.width = '100%';
};
const enableScroll = () => {
document.body.style.position = prevBodyPosition || '';
document.body.style.top = '';
document.body.style.overflow = prevBodyOverflow || '';
document.body.style.width = prevBodyWidth || '';
window.scrollTo({
top: scrollY,
left: 0,
behavior: 'instant'
});
};
/**
* The exposed context methods: open() and close()
* @type {Context}
*/
const context = { open, close };
setContext(key, context);
let isMounted = false;
svelte.onDestroy(() => {
if (isMounted) close();
});
svelte.onMount(() => {
$$invalidate(47, isMounted = true);
});
function div1_binding($$value) {
binding_callbacks[$$value ? 'unshift' : 'push'](() => {
modalWindow = $$value;
$$invalidate(5, modalWindow);
});
}
function div2_binding($$value) {
binding_callbacks[$$value ? 'unshift' : 'push'](() => {
wrap = $$value;
$$invalidate(4, wrap);
});
}
function div3_binding($$value) {
binding_callbacks[$$value ? 'unshift' : 'push'](() => {
background = $$value;
$$invalidate(3, background);
});
}
$$self.$$set = $$props => {
if ('isTabbable' in $$props) $$invalidate(22, isTabbable = $$props.isTabbable);
if ('show' in $$props) $$invalidate(23, show = $$props.show);
if ('id' in $$props) $$invalidate(24, id = $$props.id);
if ('key' in $$props) $$invalidate(25, key = $$props.key);
if ('ariaLabel' in $$props) $$invalidate(26, ariaLabel = $$props.ariaLabel);
if ('ariaLabelledBy' in $$props) $$invalidate(27, ariaLabelledBy = $$props.ariaLabelledBy);
if ('closeButton' in $$props) $$invalidate(28, closeButton = $$props.closeButton);
if ('closeOnEsc' in $$props) $$invalidate(29, closeOnEsc = $$props.closeOnEsc);
if ('closeOnOuterClick' in $$props) $$invalidate(30, closeOnOuterClick = $$props.closeOnOuterClick);
if ('styleBg' in $$props) $$invalidate(31, styleBg = $$props.styleBg);
if ('styleWindowWrap' in $$props) $$invalidate(32, styleWindowWrap = $$props.styleWindowWrap);
if ('styleWindow' in $$props) $$invalidate(33, styleWindow = $$props.styleWindow);
if ('styleContent' in $$props) $$invalidate(34, styleContent = $$props.styleContent);
if ('styleCloseButton' in $$props) $$invalidate(35, styleCloseButton = $$props.styleCloseButton);
if ('classBg' in $$props) $$invalidate(36, classBg = $$props.classBg);
if ('classWindowWrap' in $$props) $$invalidate(37, classWindowWrap = $$props.classWindowWrap);
if ('classWindow' in $$props) $$invalidate(38, classWindow = $$props.classWindow);
if ('classContent' in $$props) $$invalidate(39, classContent = $$props.classContent);
if ('classCloseButton' in $$props) $$invalidate(40, classCloseButton = $$props.classCloseButton);
if ('unstyled' in $$props) $$invalidate(0, unstyled = $$props.unstyled);
if ('setContext' in $$props) $$invalidate(41, setContext = $$props.setContext);
if ('transitionBg' in $$props) $$invalidate(42, transitionBg = $$props.transitionBg);
if ('transitionBgProps' in $$props) $$invalidate(43, transitionBgProps = $$props.transitionBgProps);
if ('transitionWindow' in $$props) $$invalidate(44, transitionWindow = $$props.transitionWindow);
if ('transitionWindowProps' in $$props) $$invalidate(45, transitionWindowProps = $$props.transitionWindowProps);
if ('disableFocusTrap' in $$props) $$invalidate(46, disableFocusTrap = $$props.disableFocusTrap);
if ('$$scope' in $$props) $$invalidate(48, $$scope = $$props.$$scope);
};
$$self.$$.update = () => {
if ($$self.$$.dirty[0] & /*show*/ 8388608 | $$self.$$.dirty[1] & /*isMounted*/ 65536) {
{
if (isMounted) {
if (isFunction(show)) {
open(show);
} else {
close();
}
}
}
}
};
return [
unstyled,
state,
Component,
background,
wrap,
modalWindow,
cssBg,
cssWindowWrap,
cssWindow,
cssContent,
cssCloseButton,
currentTransitionBg,
currentTransitionWindow,
onOpen,
onClose,
onOpened,
onClosed,
isFunction,
close,
handleKeydown,
handleOuterMousedown,
handleOuterMouseup,
isTabbable,
show,
id,
key,
ariaLabel,
ariaLabelledBy,
closeButton,
closeOnEsc,
closeOnOuterClick,
styleBg,
styleWindowWrap,
styleWindow,
styleContent,
styleCloseButton,
classBg,
classWindowWrap,
classWindow,
classContent,
classCloseButton,
setContext,
transitionBg,
transitionBgProps,
transitionWindow,
transitionWindowProps,
disableFocusTrap,
isMounted,
$$scope,
slots,
div1_binding,
div2_binding,
div3_binding
];
}
class Modal extends SvelteComponent {
constructor(options) {
super();
init(
this,
options,
instance,
create_fragment,
safe_not_equal,
{
isTabbable: 22,
show: 23,
id: 24,
key: 25,
ariaLabel: 26,
ariaLabelledBy: 27,
closeButton: 28,
closeOnEsc: 29,
closeOnOuterClick: 30,
styleBg: 31,
styleWindowWrap: 32,
styleWindow: 33,
styleContent: 34,
styleCloseButton: 35,
classBg: 36,
classWindowWrap: 37,
classWindow: 38,
classContent: 39,
classCloseButton: 40,
unstyled: 0,
setContext: 41,
transitionBg: 42,
transitionBgProps: 43,
transitionWindow: 44,
transitionWindowProps: 45,
disableFocusTrap: 46
},
add_css,
[-1, -1, -1]
);
}
}
export { Modal, bind, Modal as default };