Make core portal layout responsive with mobile drawer menu
This commit is contained in:
parent
87aa4b18b1
commit
0c0e656b34
|
@ -13,6 +13,7 @@
|
||||||
class="spectrum-SideNav-item"
|
class="spectrum-SideNav-item"
|
||||||
class:is-selected={selected}
|
class:is-selected={selected}
|
||||||
class:is-disabled={disabled}
|
class:is-disabled={disabled}
|
||||||
|
on:click
|
||||||
>
|
>
|
||||||
{#if heading}
|
{#if heading}
|
||||||
<h2 class="spectrum-SideNav-heading" id="nav-heading-{heading}">
|
<h2 class="spectrum-SideNav-heading" id="nav-heading-{heading}">
|
||||||
|
|
|
@ -134,7 +134,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ModalContent
|
<ModalContent
|
||||||
title={template ? "Import app" : "Create new app"}
|
title={template ? "Import app" : "Create app"}
|
||||||
confirmText={template ? "Import app" : "Create app"}
|
confirmText={template ? "Import app" : "Create app"}
|
||||||
onConfirm={createNewApp}
|
onConfirm={createNewApp}
|
||||||
disabled={!valid}
|
disabled={!valid}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
let loaded = false
|
let loaded = false
|
||||||
let userInfoModal
|
let userInfoModal
|
||||||
let changePasswordModal
|
let changePasswordModal
|
||||||
|
let mobileMenuVisible = false
|
||||||
|
|
||||||
$: menu = buildMenu($auth.isAdmin)
|
$: menu = buildMenu($auth.isAdmin)
|
||||||
|
|
||||||
|
@ -60,6 +61,9 @@
|
||||||
return menu
|
return menu
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const showMobileMenu = () => (mobileMenuVisible = true)
|
||||||
|
const hideMobileMenu = () => (mobileMenuVisible = false)
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
// Prevent non-builders from accessing the portal
|
// Prevent non-builders from accessing the portal
|
||||||
if ($auth.user) {
|
if ($auth.user) {
|
||||||
|
@ -75,7 +79,7 @@
|
||||||
|
|
||||||
{#if $auth.user && loaded}
|
{#if $auth.user && loaded}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="nav">
|
<div class="nav" class:visible={mobileMenuVisible}>
|
||||||
<Layout paddingX="L" paddingY="L">
|
<Layout paddingX="L" paddingY="L">
|
||||||
<div class="branding">
|
<div class="branding">
|
||||||
<div class="name" on:click={() => $goto("./apps")}>
|
<div class="name" on:click={() => $goto("./apps")}>
|
||||||
|
@ -89,7 +93,12 @@
|
||||||
<div class="menu">
|
<div class="menu">
|
||||||
<Navigation>
|
<Navigation>
|
||||||
{#each menu as { title, href, heading }}
|
{#each menu as { title, href, heading }}
|
||||||
<Item selected={$isActive(href)} {href} {heading}>{title}</Item>
|
<Item
|
||||||
|
on:click={hideMobileMenu}
|
||||||
|
selected={$isActive(href)}
|
||||||
|
{href}
|
||||||
|
{heading}>{title}</Item
|
||||||
|
>
|
||||||
{/each}
|
{/each}
|
||||||
</Navigation>
|
</Navigation>
|
||||||
</div>
|
</div>
|
||||||
|
@ -97,35 +106,50 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<div class="toolbar">
|
<div class="toolbar">
|
||||||
<div />
|
<div class="mobile-toggle">
|
||||||
<ActionMenu align="right">
|
<Icon hoverable name="ShowMenu" on:click={showMobileMenu} />
|
||||||
<div slot="control" class="avatar">
|
</div>
|
||||||
<Avatar
|
<div class="mobile-logo">
|
||||||
size="M"
|
<img
|
||||||
initials={$auth.initials}
|
src={$organisation?.logoUrl || Logo}
|
||||||
url={$auth.user.pictureUrl}
|
alt={$organisation?.company || "Budibase"}
|
||||||
/>
|
/>
|
||||||
<Icon size="XL" name="ChevronDown" />
|
</div>
|
||||||
</div>
|
<div class="user-dropdown">
|
||||||
<MenuItem icon="UserEdit" on:click={() => userInfoModal.show()}>
|
<ActionMenu align="right">
|
||||||
Update user information
|
<div slot="control" class="avatar">
|
||||||
</MenuItem>
|
<Avatar
|
||||||
<MenuItem
|
size="M"
|
||||||
icon="LockClosed"
|
initials={$auth.initials}
|
||||||
on:click={() => changePasswordModal.show()}
|
url={$auth.user.pictureUrl}
|
||||||
>
|
/>
|
||||||
Update password
|
<Icon size="XL" name="ChevronDown" />
|
||||||
</MenuItem>
|
</div>
|
||||||
<MenuItem icon="UserDeveloper" on:click={() => $goto("../apps")}>
|
<MenuItem icon="UserEdit" on:click={() => userInfoModal.show()}>
|
||||||
Close developer mode
|
Update user information
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem icon="LogOut" on:click={auth.logout}>Log out</MenuItem>
|
<MenuItem
|
||||||
</ActionMenu>
|
icon="LockClosed"
|
||||||
|
on:click={() => changePasswordModal.show()}
|
||||||
|
>
|
||||||
|
Update password
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem icon="UserDeveloper" on:click={() => $goto("../apps")}>
|
||||||
|
Close developer mode
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem icon="LogOut" on:click={auth.logout}>Log out</MenuItem>
|
||||||
|
</ActionMenu>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
class="mobile-click-handler"
|
||||||
|
class:visible={mobileMenuVisible}
|
||||||
|
on:click={hideMobileMenu}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Modal bind:this={userInfoModal}>
|
<Modal bind:this={userInfoModal}>
|
||||||
<UpdateUserInfoModal />
|
<UpdateUserInfoModal />
|
||||||
|
@ -138,16 +162,20 @@
|
||||||
<style>
|
<style>
|
||||||
.container {
|
.container {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: grid;
|
display: flex;
|
||||||
grid-template-columns: 250px 1fr;
|
flex-direction: row;
|
||||||
|
justify-content: flex-start;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
}
|
}
|
||||||
.nav {
|
.nav {
|
||||||
background: var(--background);
|
background: var(--background);
|
||||||
border-right: var(--border-light);
|
border-right: var(--border-light);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: 250px;
|
||||||
}
|
}
|
||||||
.main {
|
.main {
|
||||||
|
flex: 1 1 auto;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: auto 1fr;
|
grid-template-rows: auto 1fr;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -181,11 +209,21 @@
|
||||||
.toolbar {
|
.toolbar {
|
||||||
background: var(--background);
|
background: var(--background);
|
||||||
border-bottom: var(--border-light);
|
border-bottom: var(--border-light);
|
||||||
display: grid;
|
display: flex;
|
||||||
grid-template-columns: 250px auto;
|
flex-direction: row;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: var(--spacing-m) calc(var(--spacing-xl) * 2);
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
padding: var(--spacing-m) calc(var(--spacing-xl) * 2);
|
||||||
|
}
|
||||||
|
.mobile-toggle,
|
||||||
|
.mobile-logo {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.user-dropdown {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
img {
|
img {
|
||||||
width: 28px;
|
width: 28px;
|
||||||
|
@ -199,4 +237,41 @@
|
||||||
.content {
|
.content {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
.mobile-click-handler {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.nav {
|
||||||
|
position: absolute;
|
||||||
|
left: -250px;
|
||||||
|
height: 100%;
|
||||||
|
transition: left ease-in-out 230ms;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
.nav.visible {
|
||||||
|
left: 0;
|
||||||
|
box-shadow: 0 0 80px 20px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-toggle,
|
||||||
|
.mobile-logo {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-toggle,
|
||||||
|
.user-dropdown {
|
||||||
|
flex: 1 1 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-click-handler.visible {
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -201,7 +201,7 @@
|
||||||
<Heading>Apps</Heading>
|
<Heading>Apps</Heading>
|
||||||
<ButtonGroup>
|
<ButtonGroup>
|
||||||
<Button secondary on:click={initiateAppImport}>Import app</Button>
|
<Button secondary on:click={initiateAppImport}>Import app</Button>
|
||||||
<Button cta on:click={initiateAppCreation}>Create new app</Button>
|
<Button cta on:click={initiateAppCreation}>Create app</Button>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter">
|
<div class="filter">
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue