Skip to content

Commit

Permalink
Merge pull request #637 from appwrite/chore-prerelease-modal
Browse files Browse the repository at this point in the history
feat: pre release modal
  • Loading branch information
christyjacob4 authored Dec 4, 2023
2 parents ab9ef73 + fe16ac2 commit 0b8e66f
Show file tree
Hide file tree
Showing 9 changed files with 361 additions and 130 deletions.
2 changes: 2 additions & 0 deletions src/lib/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,5 @@ export { default as SvgIcon } from './svgIcon.svelte';
export { default as MigrationBox } from './migrationBox.svelte';
export { default as FloatingActionBar } from './floatingActionBar.svelte';
export { default as LoadingDots } from './loadingDots.svelte';
export { default as ModalWrapper } from './modalWrapper.svelte';
export { default as ModalSideCol } from './modalSideCol.svelte';
192 changes: 64 additions & 128 deletions src/lib/components/modal.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<script lang="ts">
import { createEventDispatcher, onDestroy, onMount } from 'svelte';
import { Alert } from '$lib/components';
import { Alert, ModalWrapper } from '$lib/components';
import { trackEvent } from '$lib/actions/analytics';
import { Form } from '$lib/elements/forms';
import { disableCommands } from '$lib/commandCenter';
Expand All @@ -18,144 +17,81 @@
export let title = '';
export let description = '';
let dialog: HTMLDialogElement;
let alert: HTMLElement;
const dispatch = createEventDispatcher();
onMount(() => {
if (show) openModal();
});
onDestroy(() => {
if (show) closeModal();
});
function handleBLur(event: MouseEvent) {
if (event.target === dialog) {
trackEvent('click_close_modal', {
from: 'backdrop'
});
closeModal();
}
}
function openModal() {
if (dialog && !dialog.open) {
dialog.showModal();
document.documentElement.classList.add('u-overflow-hidden');
}
}
function closeModal() {
if (closable) {
if (dialog && dialog.open) {
dispatch('close');
dialog.close();
show = false;
document.documentElement.classList.remove('u-overflow-hidden');
}
}
}
function handleKeydown(event: KeyboardEvent) {
if (event.key === 'Escape') {
event.preventDefault();
trackEvent('click_close_modal', {
from: 'escape'
});
closeModal();
}
}
$: if (show) {
openModal();
} else {
closeModal();
}
$: $disableCommands(show);
$: if (error) {
alert?.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'nearest' });
}
</script>

<svelte:window on:mousedown={handleBLur} on:keydown={handleKeydown} />

<dialog
class="modal"
class:is-small={size === 'small'}
class:is-big={size === 'big'}
class:is-separate-header={headerDivider}
bind:this={dialog}
on:cancel|preventDefault>
{#if show}
<Form isModal {onSubmit}>
<header class="modal-header">
<div class="u-flex u-main-space-between u-cross-center u-gap-16">
<div class="u-flex u-cross-center u-gap-16">
{#if icon}
<div
class="avatar is-medium"
class:is-success={state === 'success'}
class:is-warning={state === 'warning'}
class:is-danger={state === 'error'}
class:is-info={state === 'info'}>
<span class={`icon-${icon}`} aria-hidden="true" />
</div>
{/if}

<h4 class="modal-title heading-level-5">
<slot name="title">
{title}
</slot>
</h4>
</div>
{#if closable}
<button
type="button"
class="button is-text is-only-icon"
style="--button-size:1.5rem;"
aria-label="Close Modal"
title="Close Modal"
on:click={() =>
trackEvent('click_close_modal', {
from: 'button'
})}
on:click={closeModal}>
<span class="icon-x" aria-hidden="true" />
</button>
<ModalWrapper bind:show {size} {headerDivider} let:close>
<Form isModal {onSubmit}>
<header class="modal-header">
<div class="u-flex u-main-space-between u-cross-center u-gap-16">
<div class="u-flex u-cross-center u-gap-16">
{#if icon}
<div
class="avatar is-medium"
class:is-success={state === 'success'}
class:is-warning={state === 'warning'}
class:is-danger={state === 'error'}
class:is-info={state === 'info'}>
<span class={`icon-${icon}`} aria-hidden="true" />
</div>
{/if}

<h4 class="modal-title heading-level-5">
<slot name="title">
{title}
</slot>
</h4>
</div>
<p class="u-margin-block-start-4">
<slot name="description">
{description}
</slot>
</p>
</header>
<div class="modal-content">
{#if error}
<div bind:this={alert}>
<Alert
dismissible
type="warning"
on:dismiss={() => {
error = null;
}}>
{error}
</Alert>
</div>
{#if closable}
<button
type="button"
class="button is-text is-only-icon"
style="--button-size:1.5rem;"
aria-label="Close Modal"
title="Close Modal"
on:click={() =>
trackEvent('click_close_modal', {
from: 'button'
})}
on:click={close}>
<span class="icon-x" aria-hidden="true" />
</button>
{/if}
<slot />
</div>

{#if $$slots.footer}
<div class="modal-footer">
<div class="u-flex u-main-end u-gap-16">
<slot name="footer" />
</div>
<p class="u-margin-block-start-4">
<slot name="description">
{description}
</slot>
</p>
</header>
<div class="modal-content">
{#if error}
<div bind:this={alert}>
<Alert
dismissible
type="warning"
on:dismiss={() => {
error = null;
}}>
{error}
</Alert>
</div>
{/if}
</Form>
{/if}
</dialog>
<slot />
</div>

{#if $$slots.footer}
<div class="modal-footer">
<div class="u-flex u-main-end u-gap-16">
<slot name="footer" />
</div>
</div>
{/if}
</Form>
</ModalWrapper>
67 changes: 67 additions & 0 deletions src/lib/components/modalSideCol.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<script lang="ts">
import { ModalWrapper } from '$lib/components';
import { trackEvent } from '$lib/actions/analytics';
export let show = false;
export let title = '';
export let description = '';
export let style = '';
</script>

<ModalWrapper bind:show let:close {style}>
<div class="grid-1-1 u-width-full-line mk-grid">
<div class="mk-grid-item-1 u-width-full-line">
<slot name="side" />
</div>
<div class="u-padding-32 mk-grid-item-2">
<header class="modal-header">
<div class="u-flex u-main-space-between u-gap-16">
<h4 class="modal-title heading-level-5">
<slot name="title">
{title}
</slot>
</h4>
<button
type="button"
class="button is-text is-only-icon"
style="--button-size:1.5rem;"
aria-label="Close Modal"
title="Close Modal"
on:click={() =>
trackEvent('click_close_modal', {
from: 'button'
})}
on:click={close}>
<span class="icon-x" aria-hidden="true" />
</button>
</div>
<p class="u-margin-block-start-4">
<slot name="description">
{description}
</slot>
</p>
</header>
<div class="modal-content">
<slot />
</div>
</div>
</div>
</ModalWrapper>

<style lang="scss">
.mk-grid {
overflow: hidden;
}
@media screen and (max-width: 768px) {
.mk-grid {
&-item-1 {
order: 2;
max-height: 16rem;
}
&-item-2 {
order: 1;
}
}
}
</style>
82 changes: 82 additions & 0 deletions src/lib/components/modalWrapper.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<script lang="ts">
import { createEventDispatcher, onDestroy, onMount } from 'svelte';
import { trackEvent } from '$lib/actions/analytics';
import { disableCommands } from '$lib/commandCenter';
export let show = false;
export let size: 'small' | 'big' = null;
export let closable = true;
export let headerDivider = true;
export let style = '';
let dialog: HTMLDialogElement;
const dispatch = createEventDispatcher();
onMount(() => {
if (show) openModal();
});
onDestroy(() => {
if (show) closeModal();
});
function handleBLur(event: MouseEvent) {
if (event.target === dialog) {
trackEvent('click_close_modal', {
from: 'backdrop'
});
closeModal();
}
}
function openModal() {
if (dialog && !dialog.open) {
dialog.showModal();
document.documentElement.classList.add('u-overflow-hidden');
}
}
function closeModal() {
if (closable) {
if (dialog && dialog.open) {
dispatch('close');
dialog.close();
show = false;
document.documentElement.classList.remove('u-overflow-hidden');
}
}
}
function handleKeydown(event: KeyboardEvent) {
if (event.key === 'Escape') {
event.preventDefault();
trackEvent('click_close_modal', {
from: 'escape'
});
closeModal();
}
}
$: if (show) {
openModal();
} else {
closeModal();
}
$: $disableCommands(show);
</script>

<svelte:window on:mousedown={handleBLur} on:keydown={handleKeydown} />

<dialog
class="modal"
class:is-small={size === 'small'}
class:is-big={size === 'big'}
class:is-separate-header={headerDivider}
{style}
bind:this={dialog}
on:cancel|preventDefault>
{#if show}
<slot close={closeModal} />
{/if}
</dialog>
Loading

0 comments on commit 0b8e66f

Please sign in to comment.