Add header dropdown and replace icon library

This commit is contained in:
Melon 2022-11-27 01:36:23 +00:00
parent 64dbe4a91b
commit 7eb58bfa90
Signed by: melon
GPG Key ID: 6C9D970C50D26A25
9 changed files with 151 additions and 127 deletions

View File

@ -20,6 +20,7 @@
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^1.0.2",
"@tsconfig/svelte": "^3.0.0",
"lucide-svelte": "^0.102.0",
"prettier": "^2.7.1",
"prettier-plugin-svelte": "^2.8.0",
"sass": "^1.55.0",
@ -30,5 +31,6 @@
"tslib": "^2.4.0",
"typescript": "^4.6.4",
"vite": "^3.1.0"
}
},
"dependencies": {}
}

View File

@ -1,15 +1,10 @@
<script lang="ts">
import {Router, Route, navigate, link} from "svelte-navigator";
import {getUser} from "./api/login";
import Dropdown from "./lib/Dropdown.svelte";
import HeaderDropdown from "./lib/HeaderDropdown.svelte";
import LazyComponent from "./lib/LazyComponent.svelte";
import {loginStore, profileStore, type LoginStore, type ProfileData} from "./stores/login";
function logoutAction() {
loginStore.set(null);
navigate("/");
}
let profile: ProfileData;
loginStore.subscribe((value: LoginStore) => {
@ -44,23 +39,7 @@
<nav>
{#if profile !== undefined}
<Dropdown>
<div slot="header" class="dropdown-header">
{#if profile.icon == "0"}
<img
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="
alt="Profile Icon"
class="header-icon"
/>
{:else}
<img src={profile.icon} alt="Profile Icon" class="header-icon" />
{/if}
<span>{profile.display_name}</span>
</div>
<div slot="body" class="dropdown-body">
<a href="/logout" on:click|preventDefault={logoutAction}>Logout</a>
</div>
</Dropdown>
<HeaderDropdown {profile} />
{:else}
<a href="/register" use:link>Register</a>
<a href="/login" use:link>Login</a>
@ -115,23 +94,6 @@
background-color: var(--primary-main);
border-radius: 0 0 var(--large-curve) var(--large-curve);
> nav {
.dropdown-header {
display: flex;
align-items: center;
> .header-icon {
> img {
width: 32px;
height: 32px;
}
}
}
.dropdown-body {
}
}
> .central-header {
padding: 0 32px;
height: 50px;
@ -144,6 +106,12 @@
max-width: min(100%, 1000px);
margin: auto;
> nav {
height: 100%;
display: flex;
align-items: center;
}
a {
color: #eeeeee;

View File

@ -1,5 +1,3 @@
@import "./assets/material-symbols.scss";
:root {
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
font-size: 16px;

View File

@ -1,23 +0,0 @@
/* fallback */
@font-face {
font-family: "Material Symbols Outlined";
font-style: normal;
font-weight: 400;
src: url(~/assets/material-symbols.woff2) format("woff2");
}
@mixin mso {
font-family: "Material Symbols Outlined";
font-weight: normal;
font-style: normal;
font-size: 24px;
line-height: 1;
letter-spacing: normal;
text-transform: none;
display: inline-block;
white-space: nowrap;
word-wrap: normal;
direction: ltr;
-moz-font-feature-settings: "liga";
-moz-osx-font-smoothing: grayscale;
}

Binary file not shown.

View File

@ -1,60 +0,0 @@
<script lang="ts">
export let align = "left";
let open = false;
</script>
<div class="dropdown align-{align}">
<div class="dropdown-header">
<div>
<slot name="header" />
</div>
<div class="flex-gap" />
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 32 32"
fill="currentColor"
preserveAspectRatio="xMidYMid meet"
width="16"
height="16"
role="img"
aria-label="Open menu"
style="--darkreader-inline-fill: currentColor;"
data-darkreader-inline-fill=""><path d="M16 22L6 12 7.4 10.6 16 19.2 24.6 10.6 26 12z" /></svg
>
</div>
{#if open}
<div class="dropdown-body">
<slot name="body" />
</div>
{/if}
</div>
<style lang="scss">
.dropdown {
position: relative;
> .dropdown-header {
display: flex;
align-items: center;
}
> .dropdown-body {
position: absolute;
top: 100%;
background: var(--bg-panel);
}
&.align-left > .dropdown-body {
left: 0;
}
&.align-right > .dropdown-body {
right: 0;
}
}
.flex-gap {
flex-grow: 1;
}
</style>

View File

@ -0,0 +1,134 @@
<script lang="ts">
import {loginStore, type ProfileData} from "~/stores/login";
import {User, Settings, LogOut, ChevronUp, ChevronDown} from "lucide-svelte";
import {link, navigate} from "svelte-navigator";
export let profile: ProfileData;
let open = false;
function handleClick() {
open = !open;
}
function logoutAction() {
loginStore.set(null);
navigate("/");
}
</script>
<div class="dropdown {open ? 'dropdown-open' : ''}">
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div class="dropdown-header" on:click={handleClick}>
<div class="dropdown-title">
{#if profile.icon == "0"}
<img
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="
alt="Profile Icon"
class="header-icon"
/>
{:else}
<img src={profile.icon} alt="Profile Icon" class="header-icon" />
{/if}
<span>{profile.display_name}</span>
</div>
{#if open}
<ChevronUp />
{:else}
<ChevronDown />
{/if}
</div>
{#if open}
<div class="dropdown-floating">
<div class="dropdown-body">
<a href="/profile" use:link>
<User />
<span>Profile</span>
</a>
<a href="/settings" use:link>
<Settings />
<span>Settings</span>
</a>
<a href="/logout" on:click|preventDefault={logoutAction}>
<LogOut />
<span>Logout</span>
</a>
</div>
</div>
{/if}
</div>
<style lang="scss">
.dropdown {
position: relative;
height: 100%;
display: flex;
align-items: center;
z-index: 9999;
&.dropdown-open {
background-color: var(--bg-panel-action);
}
> .dropdown-header {
display: flex;
align-items: center;
cursor: pointer;
user-select: none;
height: 100%;
padding: 0 16px;
&:hover {
background-color: var(--bg-panel);
}
> .dropdown-title {
display: flex;
align-items: center;
margin-right: 4px;
> .header-icon {
width: 32px;
height: 32px;
margin-right: 8px;
}
}
}
> .dropdown-floating {
z-index: 9998;
position: absolute;
top: 100%;
right: 0;
background: var(--bg-panel-action);
width: 100%;
border-radius: 0 0 8px 8px;
-webkit-box-shadow: 0px 0px 10px 2px rgba(0, 0, 0, 0.5);
-moz-box-shadow: 0px 0px 10px 2px rgba(0, 0, 0, 0.5);
box-shadow: 0px 0px 10px 2px rgba(0, 0, 0, 0.5);
clip-path: inset(0px -10px -10px -10px);
> .dropdown-body {
border-radius: 0 0 8px 8px;
overflow: hidden;
display: flex;
flex-direction: column;
text-align: center;
> a {
display: flex;
padding: 8px 16px 8px;
&:hover {
background-color: var(--bg-panel);
}
> span {
margin-left: 8px;
}
}
}
}
}
</style>

View File

@ -34,7 +34,7 @@
}
onMount(async function () {
updatePage(postLogin({}, ""));
updatePage(postLogin({}));
});
let loading = false;

View File

@ -442,6 +442,11 @@ lower-case@^2.0.2:
dependencies:
tslib "^2.0.3"
lucide-svelte@^0.102.0:
version "0.102.0"
resolved "https://registry.yarnpkg.com/lucide-svelte/-/lucide-svelte-0.102.0.tgz#4a8bca665e6f01d21d60bb057996c35a6e878eb5"
integrity sha512-r8Nmz3XnRiesT3BxTaQvJnkbvutJMDv7HHADfDVZ1VLo3tWInfSBzWQya1V12dFfdBoz/bMwBX0abpccw77v4A==
magic-string@^0.25.7:
version "0.25.9"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c"