|
1 | 1 | <script lang="ts">
|
2 |
| - import { createEventDispatcher, onDestroy, onMount } from 'svelte'; |
3 |
| - import { Alert } from '$lib/components'; |
| 2 | + import { Alert, ModalWrapper } from '$lib/components'; |
4 | 3 | import { trackEvent } from '$lib/actions/analytics';
|
5 | 4 | import { Form } from '$lib/elements/forms';
|
6 | 5 | import { disableCommands } from '$lib/commandCenter';
|
|
18 | 17 | export let title = '';
|
19 | 18 | export let description = '';
|
20 | 19 |
|
21 |
| - let dialog: HTMLDialogElement; |
22 | 20 | let alert: HTMLElement;
|
23 | 21 |
|
24 |
| - const dispatch = createEventDispatcher(); |
25 |
| -
|
26 |
| - onMount(() => { |
27 |
| - if (show) openModal(); |
28 |
| - }); |
29 |
| -
|
30 |
| - onDestroy(() => { |
31 |
| - if (show) closeModal(); |
32 |
| - }); |
33 |
| -
|
34 |
| - function handleBLur(event: MouseEvent) { |
35 |
| - if (event.target === dialog) { |
36 |
| - trackEvent('click_close_modal', { |
37 |
| - from: 'backdrop' |
38 |
| - }); |
39 |
| - closeModal(); |
40 |
| - } |
41 |
| - } |
42 |
| - function openModal() { |
43 |
| - if (dialog && !dialog.open) { |
44 |
| - dialog.showModal(); |
45 |
| - document.documentElement.classList.add('u-overflow-hidden'); |
46 |
| - } |
47 |
| - } |
48 |
| -
|
49 |
| - function closeModal() { |
50 |
| - if (closable) { |
51 |
| - if (dialog && dialog.open) { |
52 |
| - dispatch('close'); |
53 |
| - dialog.close(); |
54 |
| - show = false; |
55 |
| - document.documentElement.classList.remove('u-overflow-hidden'); |
56 |
| - } |
57 |
| - } |
58 |
| - } |
59 |
| -
|
60 |
| - function handleKeydown(event: KeyboardEvent) { |
61 |
| - if (event.key === 'Escape') { |
62 |
| - event.preventDefault(); |
63 |
| - trackEvent('click_close_modal', { |
64 |
| - from: 'escape' |
65 |
| - }); |
66 |
| - closeModal(); |
67 |
| - } |
68 |
| - } |
69 |
| -
|
70 |
| - $: if (show) { |
71 |
| - openModal(); |
72 |
| - } else { |
73 |
| - closeModal(); |
74 |
| - } |
75 |
| -
|
76 | 22 | $: $disableCommands(show);
|
77 | 23 |
|
78 | 24 | $: if (error) {
|
79 | 25 | alert?.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'nearest' });
|
80 | 26 | }
|
81 | 27 | </script>
|
82 | 28 |
|
83 |
| -<svelte:window on:mousedown={handleBLur} on:keydown={handleKeydown} /> |
84 |
| - |
85 |
| -<dialog |
86 |
| - class="modal" |
87 |
| - class:is-small={size === 'small'} |
88 |
| - class:is-big={size === 'big'} |
89 |
| - class:is-separate-header={headerDivider} |
90 |
| - bind:this={dialog} |
91 |
| - on:cancel|preventDefault> |
92 |
| - {#if show} |
93 |
| - <Form isModal {onSubmit}> |
94 |
| - <header class="modal-header"> |
95 |
| - <div class="u-flex u-main-space-between u-cross-center u-gap-16"> |
96 |
| - <div class="u-flex u-cross-center u-gap-16"> |
97 |
| - {#if icon} |
98 |
| - <div |
99 |
| - class="avatar is-medium" |
100 |
| - class:is-success={state === 'success'} |
101 |
| - class:is-warning={state === 'warning'} |
102 |
| - class:is-danger={state === 'error'} |
103 |
| - class:is-info={state === 'info'}> |
104 |
| - <span class={`icon-${icon}`} aria-hidden="true" /> |
105 |
| - </div> |
106 |
| - {/if} |
107 |
| - |
108 |
| - <h4 class="modal-title heading-level-5"> |
109 |
| - <slot name="title"> |
110 |
| - {title} |
111 |
| - </slot> |
112 |
| - </h4> |
113 |
| - </div> |
114 |
| - {#if closable} |
115 |
| - <button |
116 |
| - type="button" |
117 |
| - class="button is-text is-only-icon" |
118 |
| - style="--button-size:1.5rem;" |
119 |
| - aria-label="Close Modal" |
120 |
| - title="Close Modal" |
121 |
| - on:click={() => |
122 |
| - trackEvent('click_close_modal', { |
123 |
| - from: 'button' |
124 |
| - })} |
125 |
| - on:click={closeModal}> |
126 |
| - <span class="icon-x" aria-hidden="true" /> |
127 |
| - </button> |
| 29 | +<ModalWrapper bind:show {size} {headerDivider} let:close> |
| 30 | + <Form isModal {onSubmit}> |
| 31 | + <header class="modal-header"> |
| 32 | + <div class="u-flex u-main-space-between u-cross-center u-gap-16"> |
| 33 | + <div class="u-flex u-cross-center u-gap-16"> |
| 34 | + {#if icon} |
| 35 | + <div |
| 36 | + class="avatar is-medium" |
| 37 | + class:is-success={state === 'success'} |
| 38 | + class:is-warning={state === 'warning'} |
| 39 | + class:is-danger={state === 'error'} |
| 40 | + class:is-info={state === 'info'}> |
| 41 | + <span class={`icon-${icon}`} aria-hidden="true" /> |
| 42 | + </div> |
128 | 43 | {/if}
|
| 44 | + |
| 45 | + <h4 class="modal-title heading-level-5"> |
| 46 | + <slot name="title"> |
| 47 | + {title} |
| 48 | + </slot> |
| 49 | + </h4> |
129 | 50 | </div>
|
130 |
| - <p class="u-margin-block-start-4"> |
131 |
| - <slot name="description"> |
132 |
| - {description} |
133 |
| - </slot> |
134 |
| - </p> |
135 |
| - </header> |
136 |
| - <div class="modal-content"> |
137 |
| - {#if error} |
138 |
| - <div bind:this={alert}> |
139 |
| - <Alert |
140 |
| - dismissible |
141 |
| - type="warning" |
142 |
| - on:dismiss={() => { |
143 |
| - error = null; |
144 |
| - }}> |
145 |
| - {error} |
146 |
| - </Alert> |
147 |
| - </div> |
| 51 | + {#if closable} |
| 52 | + <button |
| 53 | + type="button" |
| 54 | + class="button is-text is-only-icon" |
| 55 | + style="--button-size:1.5rem;" |
| 56 | + aria-label="Close Modal" |
| 57 | + title="Close Modal" |
| 58 | + on:click={() => |
| 59 | + trackEvent('click_close_modal', { |
| 60 | + from: 'button' |
| 61 | + })} |
| 62 | + on:click={close}> |
| 63 | + <span class="icon-x" aria-hidden="true" /> |
| 64 | + </button> |
148 | 65 | {/if}
|
149 |
| - <slot /> |
150 | 66 | </div>
|
151 |
| - |
152 |
| - {#if $$slots.footer} |
153 |
| - <div class="modal-footer"> |
154 |
| - <div class="u-flex u-main-end u-gap-16"> |
155 |
| - <slot name="footer" /> |
156 |
| - </div> |
| 67 | + <p class="u-margin-block-start-4"> |
| 68 | + <slot name="description"> |
| 69 | + {description} |
| 70 | + </slot> |
| 71 | + </p> |
| 72 | + </header> |
| 73 | + <div class="modal-content"> |
| 74 | + {#if error} |
| 75 | + <div bind:this={alert}> |
| 76 | + <Alert |
| 77 | + dismissible |
| 78 | + type="warning" |
| 79 | + on:dismiss={() => { |
| 80 | + error = null; |
| 81 | + }}> |
| 82 | + {error} |
| 83 | + </Alert> |
157 | 84 | </div>
|
158 | 85 | {/if}
|
159 |
| - </Form> |
160 |
| - {/if} |
161 |
| -</dialog> |
| 86 | + <slot /> |
| 87 | + </div> |
| 88 | + |
| 89 | + {#if $$slots.footer} |
| 90 | + <div class="modal-footer"> |
| 91 | + <div class="u-flex u-main-end u-gap-16"> |
| 92 | + <slot name="footer" /> |
| 93 | + </div> |
| 94 | + </div> |
| 95 | + {/if} |
| 96 | + </Form> |
| 97 | +</ModalWrapper> |
0 commit comments