feat(ComparisonView): add redesigned font comparison widget

This commit is contained in:
Ilia Mashkov
2026-03-02 22:18:05 +03:00
parent 6cd325ce38
commit ba186d00a1
14 changed files with 1884 additions and 0 deletions
@@ -0,0 +1,132 @@
<!--
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>