Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass modal and basement components as props #469

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/api/fixtures/orgAndUser.fixtures.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Org, Page, User } from "../types";
import { GroupOrg, IndividualOrg } from "../types/orgAndUser";
import type { Org, Page, User } from "../types";
import type { GroupOrg, IndividualOrg } from "../types/orgAndUser";

export const me: User = {
id: 4,
Expand Down
6 changes: 4 additions & 2 deletions src/lib/api/addons.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { type AddOnListItem } from "@/addons/types";
import type { Page } from "@/api/types/common";

import { error } from "@sveltejs/kit";

import { BASE_API_URL } from "@/config/config.js";
import { type AddOnListItem } from "@/addons/types";
import { isErrorCode } from "../utils";
import type { Page } from "@/api/types/common";

export async function getPinnedAddons(
fetch = globalThis.fetch,
Expand Down
233 changes: 171 additions & 62 deletions src/lib/components/MainLayout.svelte
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
<script lang="ts">
import type { ComponentType, SvelteComponent } from "svelte";
import type { Writable } from "svelte/store";
import type { User } from "@/api/types";

import { getContext } from "svelte";
import { SidebarCollapse16, SidebarExpand16 } from "svelte-octicons";

import OrgMenu from "./OrgMenu.svelte";
import Button from "./common/Button.svelte";
import Logo from "./common/Logo.svelte";
import SignedIn from "./common/SignedIn.svelte";
import { SidebarCollapse16, SidebarExpand16 } from "svelte-octicons";
import type { Writable } from "svelte/store";
import type { User } from "@/api/types";
import { SIGN_IN_URL } from "@/config/config";

export let modal: boolean = false;
/*
There is one modal position on the page, so setting the component opens the modal
*/
export let modal: ComponentType<SvelteComponent> = null;

/*
The basement component goes in the basement, and there are two sides
*/
export let basementComponent: ComponentType<SvelteComponent> = null;
export let basement: "left" | "right" | null = null;

let panel: "navigation" | "action" | null = null;
Expand All @@ -31,78 +40,100 @@
}

function closeModal() {
modal = false;
modal = null;
}

const me = getContext<Writable<User>>("me");
</script>

<div class="container">
<nav class="small">
<Button mode="ghost" on:click={openPanel("navigation")}>
<SidebarCollapse16 />
</Button>
<a href="/" class="logo"><Logo /></a>
<Button mode="ghost" on:click={openPanel("action")}>
<SidebarExpand16 />
</Button>
</nav>
<nav
class="navigation left large"
class:active={panel === "navigation"}
id="navigation"
<div
class="layout"
class:left={basement === "left"}
class:right={basement === "right"}
>
<div class="modal" tabindex="-1" class:hidden={!modal}>
<div class="backdrop" role="presentation" on:click={closeModal} />
<svelte:component this={modal} />
</div>

<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<div
class="container"
on:click={closeBasement}
on:keydown={closeBasement}
role="dialog"
>
<header class="header">
<div class="small closePane">
<Button mode="ghost" on:click={closePanel}>
<SidebarExpand16 />
</Button>
</div>
<nav class="small">
<Button mode="ghost" on:click={openPanel("navigation")}>
<SidebarCollapse16 />
</Button>
<a href="/" class="logo"><Logo /></a>
</header>
<main><slot name="navigation" /></main>
</nav>
<main class="content">
<slot name="content" />
</main>
<nav class="action right large" class:active={panel === "action"} id="action">
<header class="header">
<SignedIn>
<Button mode="ghost" on:click={openPanel("action")}>
<SidebarExpand16 />
</Button>
</nav>
<nav
class="navigation left large"
class:active={panel === "navigation"}
id="navigation"
>
<header class="header">
<div class="small closePane">
<Button mode="ghost" on:click={closePanel}>
<SidebarExpand16 />
</Button>
</div>
<a href="/" class="logo"><Logo /></a>
</header>
<main>
<slot name="navigation" />
</main>
</nav>
<main class="content">
<slot name="content" />
</main>
<nav
class="action right large"
class:active={panel === "action"}
id="action"
>
<header class="header">
<OrgMenu />
<Button slot="signedOut" mode="primary" href={SIGN_IN_URL}
>Sign In</Button
>
</SignedIn>
<div class="small closePane">
<Button mode="ghost" on:click={closePanel}>
<SidebarCollapse16 />
</Button>
</div>
</header>
<main><slot name="action" /></main>
<footer>
<SignedIn>{$me.name}</SignedIn>
<p>Language</p>
<p>Help</p>
</footer>
</nav>
<div
class="small overlay"
class:active={panel !== null}
role="presentation"
on:click={closePanel}
on:keydown={closePanel}
/>
<div class="small closePane">
<Button mode="ghost" on:click={closePanel}>
<SidebarCollapse16 />
</Button>
</div>
</header>
<main><slot name="action" /></main>
<footer>
<p>{$me?.name}</p>
<p>Language</p>
<p>Help</p>
</footer>
</nav>
<div
class="small overlay"
class:active={panel !== null}
role="presentation"
on:click={closePanel}
on:keydown={closePanel}
/>
</div>
<div class="basement">
<svelte:component this={basementComponent} />
</div>
</div>

<style>
.container {
display: flex;
width: 100vw;
height: 100vh;
width: 100%;
height: 100%;
gap: 0;
flex-shrink: 0;
background: var(--gray-1, #f5f6f7);
overflow: hidden;
}
header {
display: flex;
Expand Down Expand Up @@ -255,4 +286,82 @@
}
}
/* End Mobile Styles */

/* Basement and Layout Shift */
.layout {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
}
.container {
transform: translateX(0);
transition:
transform 0.5s ease-in-out,
border-radius 0.5s ease-in-out,
box-shadow 0.5s linear;
}
.basement {
position: absolute;
top: 0;
left: 0;
right: 0;
z-index: -1;
width: 100%;
height: 100%;
background: var(--blue-1);
}
.layout.right .container {
transform: translateX(-75%);
border-top-right-radius: 1rem;
border-bottom-right-radius: 1rem;
overflow: hidden;
box-shadow: 0px 4px 16px 4px var(--gray-3, #99a8b3);
}
.layout.right .basement {
padding-left: 25%;
}
.layout.left .container {
transform: translateX(75%);
border-top-left-radius: 1rem;
border-bottom-left-radius: 1rem;
overflow: hidden;
box-shadow: 0px 4px 16px 4px var(--gray-3, #99a8b3);
}
.layout.left .basement {
padding-right: 25%;
}

/* Modal */
.modal {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: absolute;
top: 0;
left: 0;
right: 0;
z-index: 1;
width: 100%;
height: 100%;
padding: 0 2rem;
scroll-padding: -2rem;
max-height: 100%;
overflow-y: auto;
}

.modal.hidden {
display: none;
background-color: transparent;
}

.modal .backdrop {
position: fixed;
z-index: -1;
width: 100%;
height: 100%;
background: rgba(35, 57, 68, 0.5);
backdrop-filter: blur(2px);
}
</style>
12 changes: 12 additions & 0 deletions src/lib/components/common/Card.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<div class="container">
<slot />
</div>

<style>
.container {
padding: 2rem;
border-radius: 1rem;
background: var(--gray-1, #f5f6f7);
box-shadow: var(--shadow);
}
</style>
84 changes: 84 additions & 0 deletions src/lib/components/stories/Basement.demo.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<div>
<h1>Basement</h1>
<p>
There now is your insular city of the Manhattoes, belted round by wharves as
Indian isles by coral reefs—commerce surrounds it with her surf. Right and
left, the streets take you waterward. Its extreme downtown is the battery,
where that noble mole is washed by waves, and cooled by breezes, which a few
hours previous were out of sight of land. Look at the crowds of water-gazers
there.
</p>

<p>
Circumambulate the city of a dreamy Sabbath afternoon. Go from Corlears Hook
to Coenties Slip, and from thence, by Whitehall, northward. What do you
see?—Posted like silent sentinels all around the town, stand thousands upon
thousands of mortal men fixed in ocean reveries. Some leaning against the
spiles; some seated upon the pier-heads; some looking over the bulwarks of
ships from China; some high aloft in the rigging, as if striving to get a
still better seaward peep. But these are all landsmen; of week days pent up
in lath and plaster—tied to counters, nailed to benches, clinched to desks.
How then is this? Are the green fields gone? What do they here?
</p>

<p>
But look! here come more crowds, pacing straight for the water, and
seemingly bound for a dive. Strange! Nothing will content them but the
extremest limit of the land; loitering under the shady lee of yonder
warehouses will not suffice. No. They must get just as nigh the water as
they possibly can without falling in. And there they stand—miles of
them—leagues. Inlanders all, they come from lanes and alleys, streets and
avenues—north, east, south, and west. Yet here they all unite. Tell me, does
the magnetic virtue of the needles of the compasses of all those ships
attract them thither?
</p>

<p>
Once more. Say you are in the country; in some high land of lakes. Take
almost any path you please, and ten to one it carries you down in a dale,
and leaves you there by a pool in the stream. There is magic in it. Let the
most absent-minded of men be plunged in his deepest reveries—stand that man
on his legs, set his feet a-going, and he will infallibly lead you to water,
if water there be in all that region. Should you ever be athirst in the
great American desert, try this experiment, if your caravan happen to be
supplied with a metaphysical professor. Yes, as every one knows, meditation
and water are wedded for ever.
</p>

<p>
But here is an artist. He desires to paint you the dreamiest, shadiest,
quietest, most enchanting bit of romantic landscape in all the valley of the
Saco. What is the chief element he employs? There stand his trees, each with
a hollow trunk, as if a hermit and a crucifix were within; and here sleeps
his meadow, and there sleep his cattle; and up from yonder cottage goes a
sleepy smoke. Deep into distant woodlands winds a mazy way, reaching to
overlapping spurs of mountains bathed in their hill-side blue. But though
the picture lies thus tranced, and though this pine-tree shakes down its
sighs like leaves upon this shepherd’s head, yet all were vain, unless the
shepherd’s eye were fixed upon the magic stream before him. Go visit the
Prairies in June, when for scores on scores of miles you wade knee-deep
among Tiger-lilies—what is the one charm wanting?—Water—there is not a drop
of water there! Were Niagara but a cataract of sand, would you travel your
thousand miles to see it? Why did the poor poet of Tennessee, upon suddenly
receiving two handfuls of silver, deliberate whether to buy him a coat,
which he sadly needed, or invest his money in a pedestrian trip to Rockaway
Beach? Why is almost every robust healthy boy with a robust healthy soul in
him, at some time or other crazy to go to sea? Why upon your first voyage as
a passenger, did you yourself feel such a mystical vibration, when first
told that you and your ship were now out of sight of land? Why did the old
Persians hold the sea holy? Why did the Greeks give it a separate deity, and
own brother of Jove? Surely all this is not without meaning. And still
deeper the meaning of that story of Narcissus, who because he could not
grasp the tormenting, mild image he saw in the fountain, plunged into it and
was drowned. But that same image, we ourselves see in all rivers and oceans.
It is the image of the ungraspable phantom of life; and this is the key to
it all.
</p>
</div>

<style>
div {
padding: 2rem;
overflow-y: auto;
}
</style>
Loading
Loading