ui: mockup layout

This commit is contained in:
2025-09-30 16:36:44 -04:00
parent 9ccbdbd27f
commit 9785df45f8
3 changed files with 201 additions and 103 deletions

View File

@@ -1,4 +1,6 @@
<script lang="ts">
import { beforeNavigate } from '$app/navigation';
const icons = {
back: '/icons/leftarrow.png',
forward: '/icons/rightarrow.png',
@@ -6,13 +8,56 @@
search: '/icons/internet.png',
globe: '/icons/github.svg'
};
let history: string[] = $state([]);
let currentIndex = $state(-1);
beforeNavigate((navigation) => {
if (navigation.to?.url.pathname) {
// Remove any forward history when navigating to a new page
history = history.slice(0, currentIndex + 1);
history.push(navigation.to.url.pathname);
currentIndex = history.length - 1;
}
});
function goBack() {
if (currentIndex > 0) {
currentIndex--;
window.history.back();
}
}
function goForward() {
if (currentIndex < history.length - 1) {
currentIndex++;
window.history.forward();
}
}
$effect(() => {
if (history.length === 0 && typeof window !== 'undefined') {
history = [window.location.pathname];
currentIndex = 0;
}
});
</script>
<div class="toolbar">
<button class="toolbar-button" disabled title="Back">
<button
class="toolbar-button"
disabled={currentIndex <= 0}
title="Back"
onclick={goBack}
>
<img src={icons.back} alt="Back" />
</button>
<button class="toolbar-button" disabled title="Forward">
<button
class="toolbar-button"
disabled={currentIndex >= history.length - 1}
title="Forward"
onclick={goForward}
>
<img src={icons.forward} alt="Forward" />
</button>

View File

@@ -4,7 +4,143 @@
import ToolBar from "$lib/ToolBar.svelte";
</script>
<TitleBar />
<MenuBar />
<ToolBar />
<slot />
<div class="app-container">
<TitleBar />
<MenuBar />
<ToolBar />
<div class="main-layout">
<aside class="sidebar sunken-panel">
<nav class="sidebar-nav">
<a href="/" class="nav-item">
<img src="/icons/home-car.png" alt="" class="nav-icon" />
Home
</a>
<a href="/library" class="nav-item">
<img src="/icons/laptop.png" alt="" class="nav-icon" />
Library
</a>
<details class="nav-collapsible">
<summary class="nav-item">
<img src="/icons/cassette-tape.png" alt="" class="nav-icon" />
Playlists
</summary>
<div class="nav-submenu">
<a href="/playlists/favorites" class="nav-item nav-subitem">
<img src="/icons/eighthnote-white.svg" alt="" class="nav-icon" />
Favorites
</a>
<a href="/playlists/recently-played" class="nav-item nav-subitem">
<img src="/icons/eighthnote-white.svg" alt="" class="nav-icon" />
Recently Played
</a>
<a href="/playlists/workout" class="nav-item nav-subitem">
<img src="/icons/eighthnote-white.svg" alt="" class="nav-icon" />
Workout Mix
</a>
</div>
</details>
<a href="/services" class="nav-item">
<img src="/icons/world-star.png" alt="" class="nav-icon" />
Services
</a>
</nav>
</aside>
<main class="content-area sunken-panel">
<slot />
</main>
</div>
<div class="status-text">Ready</div>
</div>
<style>
.app-container {
display: flex;
flex-direction: column;
height: 100vh;
}
.main-layout {
display: flex;
flex: 1;
overflow: hidden;
padding: 8px 8px 0 8px;
gap: 8px;
}
.sidebar {
width: 200px;
flex-shrink: 0;
padding: 0;
overflow-y: auto;
}
.sidebar-nav {
display: flex;
flex-direction: column;
padding: 4px;
}
.nav-item {
display: flex;
align-items: center;
gap: 6px;
padding: 2px 4px;
text-decoration: none;
color: light-dark(#222, #ddd);
font-family: "Pixelated MS Sans Serif", Arial;
font-size: 11px;
cursor: pointer;
border: 1px solid transparent;
}
.nav-item:hover {
background: light-dark(silver, #2b2b2b);
}
.nav-icon {
width: 16px;
height: 16px;
image-rendering: pixelated;
flex-shrink: 0;
}
.nav-collapsible {
margin: 0;
}
.nav-collapsible summary {
list-style: none;
}
.nav-collapsible summary::-webkit-details-marker {
display: none;
}
.nav-submenu {
margin-left: 12px;
}
.nav-subitem {
padding-left: 8px;
}
.content-area {
flex: 1;
min-width: 0;
overflow-y: auto;
padding: 8px;
font-family: "Pixelated MS Sans Serif", Arial;
}
.status-text {
padding: 6px 8px 10px 10px;
font-family: "Pixelated MS Sans Serif", Arial;
font-size: 11px;
color: light-dark(#222, #ddd);
margin: 0;
}
</style>

View File

@@ -1,102 +1,19 @@
<script lang="ts">
import { invoke } from "@tauri-apps/api/core";
<div>
<h2>Welcome to Shark!</h2>
<p>Your music library manager and player.</p>
let name = $state("");
let greetMsg = $state("");
async function greet(event: Event) {
event.preventDefault();
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
greetMsg = await invoke("greet", { name });
}
</script>
<main>
<h1>Welcome to Tauri + Svelte</h1>
<div class="row">
<a href="https://vite.dev" target="_blank">
<img src="/vite.svg" class="logo vite" alt="Vite Logo" />
</a>
<a href="https://tauri.app" target="_blank">
<img src="/tauri.svg" class="logo tauri" alt="Tauri Logo" />
</a>
<a href="https://svelte.dev" target="_blank">
<img src="/svelte.svg" class="logo svelte-kit" alt="SvelteKit Logo" />
</a>
<section class="quick-stats">
<div class="field-row-stacked">
</div>
<p>Click on the Tauri, Vite, and SvelteKit logos to learn more.</p>
<fieldset>
<legend>Greet</legend>
<form class="field-row" onsubmit={greet}>
<label for="greet-input">Name:</label>
<input id="greet-input" type="text" placeholder="Enter a name..." bind:value={name} />
<button type="submit">Greet</button>
</form>
</fieldset>
{#if greetMsg}
<div class="status-bar">
<p class="status-bar-field">{greetMsg}</p>
</div>
{/if}
</main>
</section>
</div>
<style>
main {
padding: 20px;
max-width: 800px;
margin: 0 auto;
}
h2 {
margin-top: 0;
}
.logo {
height: 4em;
padding: 1em;
will-change: filter;
transition: 0.75s;
}
.logo.vite:hover {
filter: drop-shadow(0 0 2em #747bff);
}
.logo.svelte-kit:hover {
filter: drop-shadow(0 0 2em #ff3e00);
}
.logo.tauri:hover {
filter: drop-shadow(0 0 2em #24c8db);
}
.row {
display: flex;
justify-content: center;
align-items: center;
gap: 1em;
margin: 1em 0;
}
h1 {
text-align: center;
font-size: 2rem;
margin: 1em 0;
}
p {
text-align: center;
}
.field-row {
align-items: center;
gap: 8px;
}
fieldset {
margin: 20px 0;
}
.status-bar {
.quick-stats {
margin-top: 20px;
}
}
</style>