133 lines
3.8 KiB
Svelte
133 lines
3.8 KiB
Svelte
|
|
<!--
|
||
|
|
Component: Header
|
||
|
|
Top bar for the font comparison view.
|
||
|
|
-->
|
||
|
|
<script lang="ts">
|
||
|
|
import { ThemeSwitch } from '$features/ChangeAppTheme';
|
||
|
|
import type { ResponsiveManager } from '$shared/lib';
|
||
|
|
import { cn } from '$shared/shadcn/utils/shadcn-utils';
|
||
|
|
import {
|
||
|
|
Badge,
|
||
|
|
Divider,
|
||
|
|
IconButton,
|
||
|
|
Input,
|
||
|
|
Label,
|
||
|
|
Logo,
|
||
|
|
TechText,
|
||
|
|
} from '$shared/ui';
|
||
|
|
import PanelLeftClose from '@lucide/svelte/icons/panel-left-close';
|
||
|
|
import PanelLeftOpen from '@lucide/svelte/icons/panel-left-open';
|
||
|
|
import { getContext } from 'svelte';
|
||
|
|
import { comparisonStore } from '../../model';
|
||
|
|
|
||
|
|
interface Props {
|
||
|
|
/**
|
||
|
|
* Sidebar open state
|
||
|
|
*/
|
||
|
|
isSidebarOpen: boolean;
|
||
|
|
/**
|
||
|
|
* Sidebar toggle callback
|
||
|
|
*/
|
||
|
|
onSidebarToggle: () => void;
|
||
|
|
/**
|
||
|
|
* CSS classes
|
||
|
|
*/
|
||
|
|
class?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
let {
|
||
|
|
isSidebarOpen,
|
||
|
|
onSidebarToggle,
|
||
|
|
class: className,
|
||
|
|
}: Props = $props();
|
||
|
|
|
||
|
|
const responsive = getContext<ResponsiveManager>('responsive');
|
||
|
|
|
||
|
|
const position = $derived(comparisonStore.sliderPosition.toFixed(0));
|
||
|
|
const fontAName = $derived(comparisonStore.fontA?.name ?? '');
|
||
|
|
const fontBName = $derived(comparisonStore.fontB?.name ?? '');
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<header
|
||
|
|
class={cn(
|
||
|
|
'flex items-center justify-between',
|
||
|
|
'px-4 md:px-8 py-4 md:py-6',
|
||
|
|
'h-16 md:h-20 z-20',
|
||
|
|
'border-b border-black/5 dark:border-white/10',
|
||
|
|
'bg-surface dark:bg-dark-bg',
|
||
|
|
className,
|
||
|
|
)}
|
||
|
|
>
|
||
|
|
<!-- Sidebar toggle + logo -->
|
||
|
|
<div class="flex items-center gap-3 md:gap-6 shrink-0">
|
||
|
|
<IconButton
|
||
|
|
onclick={onSidebarToggle}
|
||
|
|
title={isSidebarOpen ? 'Close Config' : 'Open Config'}
|
||
|
|
size={responsive.isMobile ? 'sm' : 'md'}
|
||
|
|
>
|
||
|
|
{#snippet icon()}
|
||
|
|
{#if isSidebarOpen}
|
||
|
|
<PanelLeftClose class={responsive.isMobile ? 'size-4' : 'size-5'} />
|
||
|
|
{:else}
|
||
|
|
<PanelLeftOpen class={responsive.isMobile ? 'size-4' : 'size-5'} />
|
||
|
|
{/if}
|
||
|
|
{/snippet}
|
||
|
|
</IconButton>
|
||
|
|
|
||
|
|
<!-- Logo + BETA badge -->
|
||
|
|
<Logo />
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Center: text input (lg+ only) -->
|
||
|
|
<div class="flex-1 max-w-xl mx-4 md:mx-8 hidden lg:block">
|
||
|
|
<Input
|
||
|
|
class="text-center"
|
||
|
|
bind:value={comparisonStore.text}
|
||
|
|
variant="underline"
|
||
|
|
size="lg"
|
||
|
|
placeholder="The quick brown fox..."
|
||
|
|
fullWidth
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Font names + slider % + theme toggle -->
|
||
|
|
<div class="flex items-center gap-3 md:gap-8 shrink-0 select-none">
|
||
|
|
<div class="hidden lg:flex items-center gap-6">
|
||
|
|
<div class="flex flex-col items-end leading-tight gap-0.5">
|
||
|
|
<TechText class="uppercase" variant="default" size="sm">
|
||
|
|
{fontAName}
|
||
|
|
</TechText>
|
||
|
|
<Label variant="accent" size="xs">Primary</Label>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Rotated 1px divider -->
|
||
|
|
<Divider
|
||
|
|
orientation="vertical"
|
||
|
|
class="h-8 rotate-12"
|
||
|
|
/>
|
||
|
|
|
||
|
|
<div class="flex flex-col items-start leading-tight gap-0.5">
|
||
|
|
<TechText class="uppercase" variant="default" size="sm">
|
||
|
|
{fontBName}
|
||
|
|
</TechText>
|
||
|
|
<Label variant="muted" size="xs">Secondary</Label>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<Divider
|
||
|
|
orientation="vertical"
|
||
|
|
class="h-8 rotate-12"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Slider percentage — sm+ only -->
|
||
|
|
<div class="hidden sm:block w-8 text-right tabular-nums">
|
||
|
|
<TechText variant="default" size="sm">
|
||
|
|
{position}<span class="text-neutral-400">%</span>
|
||
|
|
</TechText>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Theme toggle -->
|
||
|
|
<ThemeSwitch />
|
||
|
|
</div>
|
||
|
|
</header>
|