Unify web-player design tokens and componentize collection headers
Migrates remaining one-off colors (bg-white/[N%], border-white/N, hardcoded shadows/gradients) to the existing --mf-* tokens so light mode reacts consistently everywhere, including a fix to --color-hover which was hardcoded instead of pointing at --mf-surface-2. Extracts CollectionHeader (album/playlist/mix/liked headers) and AccountMenu (TopBar/MobileHeader) to remove five and two duplicated implementations respectively, and normalizes inconsistent empty-state copy.
This commit is contained in:
@@ -7,14 +7,7 @@
|
||||
import X from '@lucide/svelte/icons/x';
|
||||
import ChevronLeft from '@lucide/svelte/icons/chevron-left';
|
||||
import ChevronRight from '@lucide/svelte/icons/chevron-right';
|
||||
import LogOut from '@lucide/svelte/icons/log-out';
|
||||
import User from '@lucide/svelte/icons/user';
|
||||
import Settings from '@lucide/svelte/icons/settings';
|
||||
import Sun from '@lucide/svelte/icons/sun';
|
||||
import Moon from '@lucide/svelte/icons/moon';
|
||||
import MenuItem from './ui/MenuItem.svelte';
|
||||
import GlassMenu from './ui/GlassMenu.svelte';
|
||||
import { themeMode } from '$lib/theme/mode.svelte';
|
||||
import AccountMenu from './AccountMenu.svelte';
|
||||
|
||||
interface Props {
|
||||
user: SessionUser | null;
|
||||
@@ -26,8 +19,6 @@
|
||||
let query = $derived(
|
||||
page.url.pathname === '/explore' ? (page.url.searchParams.get('q') ?? '') : ''
|
||||
);
|
||||
let menuOpen = $state(false);
|
||||
let menuRef: HTMLDivElement | undefined = $state();
|
||||
let searchInput: HTMLInputElement | undefined = $state();
|
||||
let searchTimeout: ReturnType<typeof setTimeout> | undefined;
|
||||
|
||||
@@ -61,10 +52,6 @@
|
||||
clearTimeout(searchTimeout);
|
||||
runSearch(query.trim());
|
||||
}
|
||||
|
||||
function onDocumentClick(event: MouseEvent) {
|
||||
if (menuRef && !menuRef.contains(event.target as Node)) menuOpen = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<header class="hidden items-center gap-3.5 px-6.5 pt-4 pb-3 sm:flex">
|
||||
@@ -73,13 +60,13 @@
|
||||
type="button"
|
||||
onclick={() => history.back()}
|
||||
aria-label="Atrás"
|
||||
class="grid h-7.5 w-7.5 place-items-center rounded-full bg-white/[3.5%] text-fg-2 transition-colors hover:bg-white/7 hover:text-fg"
|
||||
class="grid h-7.5 w-7.5 place-items-center rounded-full bg-surface-2 text-fg-2 transition-colors hover:bg-surface-hover hover:text-fg"
|
||||
>
|
||||
<ChevronLeft class="h-[15px] w-[15px]" strokeWidth={1.9} />
|
||||
</button>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="grid h-7.5 w-7.5 place-items-center rounded-full bg-white/[3.5%] text-muted"
|
||||
class="grid h-7.5 w-7.5 place-items-center rounded-full bg-surface-2 text-muted"
|
||||
>
|
||||
<ChevronRight class="h-[15px] w-[15px]" strokeWidth={1.9} />
|
||||
</span>
|
||||
@@ -87,7 +74,7 @@
|
||||
|
||||
<form onsubmit={onSubmit} class="max-w-[480px] min-w-0 flex-1">
|
||||
<label
|
||||
class="flex h-9.5 w-full items-center gap-2.5 rounded-[11px] bg-white/[3.5%] px-3.5 transition focus-within:bg-white/[6%]"
|
||||
class="flex h-9.5 w-full items-center gap-2.5 rounded-[11px] bg-surface-2 px-3.5 transition focus-within:bg-surface-hover"
|
||||
>
|
||||
<Search class="h-[15px] w-[15px] shrink-0 text-fg-3" strokeWidth={1.8} />
|
||||
<input
|
||||
@@ -96,7 +83,7 @@
|
||||
bind:value={query}
|
||||
oninput={onInput}
|
||||
placeholder="Canciones, artistas, álbumes o playlists"
|
||||
class="w-full min-w-0 bg-transparent text-[13px] text-fg placeholder:text-muted focus:outline-none"
|
||||
class="w-full min-w-0 bg-transparent text-sm text-fg placeholder:text-muted focus:outline-none"
|
||||
/>
|
||||
{#if query}
|
||||
<button
|
||||
@@ -113,51 +100,32 @@
|
||||
|
||||
<div class="flex-1"></div>
|
||||
|
||||
<div class="relative shrink-0" bind:this={menuRef}>
|
||||
<div class="relative shrink-0">
|
||||
{#if user}
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => (menuOpen = !menuOpen)}
|
||||
aria-label="Tu cuenta"
|
||||
class="block h-8.25 w-8.25 shrink-0 overflow-hidden rounded-full border border-white/10 transition active:scale-95"
|
||||
<AccountMenu
|
||||
{user}
|
||||
{accountUrl}
|
||||
panelClass="absolute top-full right-0 z-20 mt-2 w-52 overflow-hidden"
|
||||
>
|
||||
{#if user.picture}
|
||||
<img src={user.picture} alt="" class="h-full w-full object-cover opacity-90" />
|
||||
{:else}
|
||||
<span
|
||||
class="grid h-full w-full place-items-center bg-surface-2 text-xs font-semibold text-fg uppercase"
|
||||
{#snippet trigger({ toggle })}
|
||||
<button
|
||||
type="button"
|
||||
onclick={toggle}
|
||||
aria-label="Tu cuenta"
|
||||
class="block h-8.25 w-8.25 shrink-0 overflow-hidden rounded-full border border-line-strong transition active:scale-95"
|
||||
>
|
||||
{user.name.charAt(0)}
|
||||
</span>
|
||||
{/if}
|
||||
</button>
|
||||
{#if menuOpen}
|
||||
<GlassMenu class="absolute top-full right-0 z-20 mt-2 w-52 overflow-hidden">
|
||||
<MenuItem
|
||||
icon={User}
|
||||
label="Ver perfil"
|
||||
href="/u/{user.sub}"
|
||||
onclick={() => (menuOpen = false)}
|
||||
/>
|
||||
{#if accountUrl}
|
||||
<MenuItem
|
||||
icon={Settings}
|
||||
label="Ajustes"
|
||||
href={accountUrl}
|
||||
target="_blank"
|
||||
onclick={() => (menuOpen = false)}
|
||||
/>
|
||||
{/if}
|
||||
<MenuItem
|
||||
icon={themeMode.current === 'dark' ? Sun : Moon}
|
||||
label={themeMode.current === 'dark' ? 'Modo blanco' : 'Modo oscuro'}
|
||||
onclick={() => themeMode.toggle()}
|
||||
/>
|
||||
<form method="POST" action="/logout" data-sveltekit-reload>
|
||||
<MenuItem icon={LogOut} label="Cerrar sesión" type="submit" />
|
||||
</form>
|
||||
</GlassMenu>
|
||||
{/if}
|
||||
{#if user.picture}
|
||||
<img src={user.picture} alt="" class="h-full w-full object-cover opacity-90" />
|
||||
{:else}
|
||||
<span
|
||||
class="grid h-full w-full place-items-center bg-surface-2 text-xs font-semibold text-fg uppercase"
|
||||
>
|
||||
{user.name.charAt(0)}
|
||||
</span>
|
||||
{/if}
|
||||
</button>
|
||||
{/snippet}
|
||||
</AccountMenu>
|
||||
{:else}
|
||||
<a
|
||||
href="/auth/login"
|
||||
@@ -169,5 +137,3 @@
|
||||
{/if}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<svelte:window onclick={onDocumentClick} />
|
||||
|
||||
Reference in New Issue
Block a user