feat(front/NavMenu): put logout button on the Account link under an extendable dropdown menu
This commit is contained in:
parent
9f17c5b8cd
commit
fd2852c387
@ -67,16 +67,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: stretch;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
@include large-ge {
|
@include large-ge {
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
72
src/assets/views/components/NavMenuDropdown.svelte
Normal file
72
src/assets/views/components/NavMenuDropdown.svelte
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import Icon from "../utils/Icon.svelte";
|
||||||
|
|
||||||
|
export let open: boolean = false;
|
||||||
|
let hovered = false;
|
||||||
|
|
||||||
|
function onMouseEnter() {
|
||||||
|
hovered = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMouseLeave() {
|
||||||
|
hovered = false;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import "../../scss/helpers";
|
||||||
|
|
||||||
|
ul {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include large-ge() {
|
||||||
|
ul:not(.open) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
position: absolute;
|
||||||
|
top: calc(100% - 3px);
|
||||||
|
right: 0;
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
@include surface(3);
|
||||||
|
padding: 16px;
|
||||||
|
border-top: 3px solid #ffffff1c;
|
||||||
|
border-radius: 0 0 3px 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-container {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 2;
|
||||||
|
left: 50%;
|
||||||
|
top: calc(100% - 8px);
|
||||||
|
|
||||||
|
transition: transform 50ms linear;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
|
||||||
|
&.open {
|
||||||
|
transform: translateX(-50%) translateY(8px) rotateX(180deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include medium-le {
|
||||||
|
.icon-container {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="icon-container" class:open={open || hovered}>
|
||||||
|
<Icon name="chevron-down"/>
|
||||||
|
</div>
|
||||||
|
<ul class:open={open || hovered} on:mouseenter={onMouseEnter} on:mouseleave={onMouseLeave}>
|
||||||
|
<slot/>
|
||||||
|
</ul>
|
@ -6,27 +6,34 @@
|
|||||||
export let icon;
|
export let icon;
|
||||||
export let text;
|
export let text;
|
||||||
export let action = false;
|
export let action = false;
|
||||||
|
export let hovered = false;
|
||||||
|
|
||||||
|
function onMouseEnter() {
|
||||||
|
hovered = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMouseLeave() {
|
||||||
|
hovered = false;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "../../scss/helpers";
|
@import "../../scss/helpers";
|
||||||
|
|
||||||
li {
|
li {
|
||||||
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: stretch;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
|
|
||||||
@include medium-le {
|
@mixin aHover {
|
||||||
&:not(:first-child) {
|
background-color: rgba(0, 0, 0, 0.07);
|
||||||
margin-top: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include large-ge {
|
@include darkMode {
|
||||||
&:not(:first-child) {
|
background-color: rgba(255, 255, 255, 0.07);
|
||||||
margin-left: 8px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,17 +45,23 @@
|
|||||||
height: auto;
|
height: auto;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
|
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba(0, 0, 0, 0.07);
|
|
||||||
|
|
||||||
@include darkMode {
|
|
||||||
background-color: rgba(255, 255, 255, 0.07);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
|
||||||
|
@include medium-le {
|
||||||
|
&:hover {
|
||||||
|
@include aHover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include large-ge {
|
||||||
|
&:hover > a {
|
||||||
|
@include aHover;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(form) {
|
:global(form) {
|
||||||
@ -69,7 +82,7 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<li>
|
<li on:mouseenter={onMouseEnter} on:mouseleave={onMouseLeave}>
|
||||||
{#if action}
|
{#if action}
|
||||||
<Form action={href} submitIcon={icon} submitText={text}/>
|
<Form action={href} submitIcon={icon} submitText={text}/>
|
||||||
{:else}
|
{:else}
|
||||||
@ -77,4 +90,5 @@
|
|||||||
<Icon name={icon}/>
|
<Icon name={icon}/>
|
||||||
<span class="tip">{text}</span></a>
|
<span class="tip">{text}</span></a>
|
||||||
{/if}
|
{/if}
|
||||||
|
<slot/>
|
||||||
</li>
|
</li>
|
||||||
|
@ -2,8 +2,11 @@
|
|||||||
import {locals} from "../../../ts/stores.js";
|
import {locals} from "../../../ts/stores.js";
|
||||||
import NavMenuItem from "../../components/NavMenuItem.svelte";
|
import NavMenuItem from "../../components/NavMenuItem.svelte";
|
||||||
import {hasRoute, route} from "../../../../common/Routing";
|
import {hasRoute, route} from "../../../../common/Routing";
|
||||||
|
import NavMenuDropdown from "../../components/NavMenuDropdown.svelte";
|
||||||
|
import BaseNavMenuAuthAccountDropdownAdditionalLinks from "./BaseNavMenuAuthAccountDropdownAdditionalLinks.svelte";
|
||||||
|
|
||||||
export let noLoginLink = false;
|
export let noLoginLink = false;
|
||||||
|
let accountItemHovered;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if hasRoute('auth')}
|
{#if hasRoute('auth')}
|
||||||
@ -12,8 +15,12 @@
|
|||||||
<NavMenuItem href={route('backend')} icon="settings" text="Backend"/>
|
<NavMenuItem href={route('backend')} icon="settings" text="Backend"/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<NavMenuItem href={route('account')} icon="user" text={$locals.user.name || 'Account'}/>
|
<NavMenuItem href={route('account')} icon="user" text={$locals.user.name || 'Account'} bind:hovered={accountItemHovered}>
|
||||||
|
<NavMenuDropdown bind:open={accountItemHovered}>
|
||||||
|
<BaseNavMenuAuthAccountDropdownAdditionalLinks/>
|
||||||
<NavMenuItem href={route('logout')} icon="log-out" text="Logout" action/>
|
<NavMenuItem href={route('logout')} icon="log-out" text="Logout" action/>
|
||||||
|
</NavMenuDropdown>
|
||||||
|
</NavMenuItem>
|
||||||
{:else if !noLoginLink}
|
{:else if !noLoginLink}
|
||||||
<NavMenuItem href={route('auth')} icon="log-in" text="Log in / Register"/>
|
<NavMenuItem href={route('auth')} icon="log-in" text="Log in / Register"/>
|
||||||
{/if}
|
{/if}
|
||||||
|
Loading…
Reference in New Issue
Block a user