feat(ComparisonView): add redesigned font comparison widget
This commit is contained in:
110
src/widgets/ComparisonView/ui/Sidebar/Sidebar.svelte
Normal file
110
src/widgets/ComparisonView/ui/Sidebar/Sidebar.svelte
Normal file
@@ -0,0 +1,110 @@
|
||||
<!--
|
||||
Component: Sidebar
|
||||
Layout shell for the font comparison sidebar.
|
||||
Owns the wrapper, header, and A/B side toggle.
|
||||
Content (font list, controls) is injected via snippets.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { cn } from '$shared/shadcn/utils/shadcn-utils';
|
||||
import {
|
||||
ButtonGroup,
|
||||
Label,
|
||||
ToggleButton,
|
||||
} from '$shared/ui';
|
||||
import type { Snippet } from 'svelte';
|
||||
import {
|
||||
type Side,
|
||||
comparisonStore,
|
||||
} from '../../model';
|
||||
|
||||
interface Props {
|
||||
/**
|
||||
* Main area snippet
|
||||
*/
|
||||
main?: Snippet;
|
||||
/**
|
||||
* Controls area snippet
|
||||
*/
|
||||
controls?: Snippet;
|
||||
/**
|
||||
* CSS classes
|
||||
*/
|
||||
class?: string;
|
||||
}
|
||||
|
||||
let {
|
||||
main,
|
||||
controls,
|
||||
class: className,
|
||||
}: Props = $props();
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={cn(
|
||||
'flex flex-col h-full',
|
||||
'w-80',
|
||||
'bg-surface dark:bg-dark-bg',
|
||||
'border-r border-black/5 dark:border-white/10',
|
||||
'transition-colors duration-500',
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<!-- ── Header: title + A/B toggle ────────────────────────────────── -->
|
||||
<div
|
||||
class="
|
||||
p-6 shrink-0
|
||||
border-b border-black/5 dark:border-white/10
|
||||
bg-surface dark:bg-dark-bg
|
||||
"
|
||||
>
|
||||
<!-- Title -->
|
||||
<Label variant="default" size="lg" bold class="mb-6 block tracking-tight leading-none">
|
||||
Configuration
|
||||
</Label>
|
||||
|
||||
<!--
|
||||
A/B side toggle.
|
||||
Two ghost buttons (unsized) side by side in a bordered grid.
|
||||
active prop drives white card state on the selected side.
|
||||
No size prop → no square sizing, layout comes from class.
|
||||
-->
|
||||
<ButtonGroup>
|
||||
<ToggleButton
|
||||
active={comparisonStore.side === 'A'}
|
||||
onclick={() => comparisonStore.side = 'A'}
|
||||
class="flex-1 tracking-wide font-bold uppercase text-[0.625rem]"
|
||||
>
|
||||
<span>Left Font</span>
|
||||
</ToggleButton>
|
||||
|
||||
<ToggleButton
|
||||
class="flex-1 tracking-wide font-bold uppercase text-[0.625rem]"
|
||||
active={comparisonStore.side === 'B'}
|
||||
onclick={() => comparisonStore.side = 'B'}
|
||||
>
|
||||
<span class="uppercase">Right Font</span>
|
||||
</ToggleButton>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
|
||||
<!-- ── Main: content area (no scroll - VirtualList handles scrolling) ─────────────────────────────── -->
|
||||
<div class="flex-1 min-h-0 bg-surface dark:bg-dark-bg">
|
||||
{#if main}
|
||||
{@render main()}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<!-- ── Bottom: fixed controls ─────────────────────────────────────── -->
|
||||
{#if controls}
|
||||
<div
|
||||
class="
|
||||
shrink-0 p-6
|
||||
bg-surface dark:bg-dark-bg
|
||||
border-t border-black/5 dark:border-white/10
|
||||
z-10
|
||||
"
|
||||
>
|
||||
{@render controls()}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
Reference in New Issue
Block a user