2026-01-18 14:35:35 +03:00
|
|
|
|
<!--
|
|
|
|
|
|
Component: FontSampler
|
|
|
|
|
|
Displays a sample text with a given font in a contenteditable element.
|
2026-02-27 12:42:18 +03:00
|
|
|
|
Visual design matches FontCard: sharp corners, red hover accent, header stats.
|
2026-01-18 14:35:35 +03:00
|
|
|
|
-->
|
|
|
|
|
|
<script lang="ts">
|
2026-01-18 14:48:36 +03:00
|
|
|
|
import {
|
|
|
|
|
|
FontApplicator,
|
|
|
|
|
|
type UnifiedFont,
|
|
|
|
|
|
} from '$entities/Font';
|
2026-04-16 08:44:49 +03:00
|
|
|
|
import { typographySettingsStore } from '$features/SetupFont/model';
|
2026-01-30 00:56:21 +03:00
|
|
|
|
import {
|
2026-02-27 18:42:20 +03:00
|
|
|
|
Badge,
|
2026-01-30 00:56:21 +03:00
|
|
|
|
ContentEditable,
|
2026-02-27 18:42:20 +03:00
|
|
|
|
Divider,
|
2026-02-06 15:56:48 +03:00
|
|
|
|
Footnote,
|
2026-02-27 18:42:20 +03:00
|
|
|
|
Stat,
|
2026-01-30 00:56:21 +03:00
|
|
|
|
} from '$shared/ui';
|
2026-02-27 12:42:18 +03:00
|
|
|
|
import { fly } from 'svelte/transition';
|
2026-01-18 14:35:35 +03:00
|
|
|
|
|
|
|
|
|
|
interface Props {
|
2026-03-02 22:20:48 +03:00
|
|
|
|
/**
|
|
|
|
|
|
* Font info
|
|
|
|
|
|
*/
|
2026-01-18 14:48:36 +03:00
|
|
|
|
font: UnifiedFont;
|
2026-03-02 22:20:48 +03:00
|
|
|
|
/**
|
|
|
|
|
|
* Sample text
|
|
|
|
|
|
*/
|
2026-01-18 14:48:36 +03:00
|
|
|
|
text: string;
|
2026-03-02 22:20:48 +03:00
|
|
|
|
/**
|
|
|
|
|
|
* Position index
|
|
|
|
|
|
* @default 0
|
|
|
|
|
|
*/
|
2026-01-30 17:42:06 +03:00
|
|
|
|
index?: number;
|
2026-01-18 14:35:35 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-27 12:42:18 +03:00
|
|
|
|
let { font, text = $bindable(), index = 0 }: Props = $props();
|
2026-01-20 14:21:07 +03:00
|
|
|
|
|
2026-02-27 12:42:18 +03:00
|
|
|
|
// Adjust the property name to match your UnifiedFont type
|
|
|
|
|
|
const fontType = $derived((font as any).type ?? (font as any).category ?? '');
|
|
|
|
|
|
|
2026-03-02 14:53:54 +03:00
|
|
|
|
// Extract provider badge with fallback
|
|
|
|
|
|
const providerBadge = $derived(
|
|
|
|
|
|
font.providerBadge
|
|
|
|
|
|
?? (font.provider === 'google' ? 'Google Fonts' : 'Fontshare'),
|
|
|
|
|
|
);
|
|
|
|
|
|
|
2026-02-27 12:42:18 +03:00
|
|
|
|
const stats = $derived([
|
2026-04-16 08:44:49 +03:00
|
|
|
|
{ label: 'SZ', value: `${typographySettingsStore.renderedSize}PX` },
|
|
|
|
|
|
{ label: 'WGT', value: `${typographySettingsStore.weight}` },
|
|
|
|
|
|
{ label: 'LH', value: typographySettingsStore.height?.toFixed(2) },
|
|
|
|
|
|
{ label: 'LTR', value: `${typographySettingsStore.spacing}` },
|
2026-02-27 12:42:18 +03:00
|
|
|
|
]);
|
2026-01-18 14:35:35 +03:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<div
|
2026-02-27 12:42:18 +03:00
|
|
|
|
in:fly={{ y: 20, duration: 400, delay: index * 50 }}
|
2026-01-18 14:35:35 +03:00
|
|
|
|
class="
|
2026-02-27 12:42:18 +03:00
|
|
|
|
group relative
|
2026-02-27 18:42:20 +03:00
|
|
|
|
w-full h-full
|
2026-02-27 12:42:18 +03:00
|
|
|
|
bg-paper dark:bg-dark-card
|
2026-04-16 16:32:41 +03:00
|
|
|
|
border border-subtle
|
2026-02-27 12:42:18 +03:00
|
|
|
|
hover:border-brand dark:hover:border-brand
|
2026-02-27 18:42:20 +03:00
|
|
|
|
hover:shadow-brand/10
|
|
|
|
|
|
hover:shadow-[5px_5px_0px_0px]
|
2026-02-27 12:42:18 +03:00
|
|
|
|
transition-all duration-200
|
|
|
|
|
|
overflow-hidden
|
2026-01-30 17:42:06 +03:00
|
|
|
|
flex flex-col
|
2026-02-27 12:42:18 +03:00
|
|
|
|
min-h-60
|
|
|
|
|
|
rounded-none
|
2026-01-18 14:35:35 +03:00
|
|
|
|
"
|
2026-04-16 08:44:49 +03:00
|
|
|
|
style:font-weight={typographySettingsStore.weight}
|
2026-01-18 14:35:35 +03:00
|
|
|
|
>
|
2026-02-27 12:42:18 +03:00
|
|
|
|
<!-- ── Header bar ─────────────────────────────────────────────────── -->
|
|
|
|
|
|
<div
|
|
|
|
|
|
class="
|
|
|
|
|
|
flex items-center justify-between
|
|
|
|
|
|
px-4 sm:px-5 md:px-6 py-3 sm:py-4
|
2026-04-16 16:32:41 +03:00
|
|
|
|
border-b border-subtle
|
2026-02-27 12:42:18 +03:00
|
|
|
|
bg-paper dark:bg-dark-card
|
|
|
|
|
|
"
|
|
|
|
|
|
>
|
2026-03-02 14:53:54 +03:00
|
|
|
|
<!-- Left: index · name · type badge · provider badge -->
|
2026-02-27 18:42:20 +03:00
|
|
|
|
<div class="flex items-center gap-2 sm:gap-4 min-w-0 shrink-0">
|
2026-04-17 09:42:24 +03:00
|
|
|
|
<span class="font-mono text-2xs tracking-widest text-neutral-400 uppercase leading-none shrink-0">
|
2026-02-27 12:42:18 +03:00
|
|
|
|
{String(index + 1).padStart(2, '0')}
|
|
|
|
|
|
</span>
|
2026-02-27 18:42:20 +03:00
|
|
|
|
<Divider orientation="vertical" class="h-3 shrink-0" />
|
2026-02-27 12:42:18 +03:00
|
|
|
|
|
|
|
|
|
|
<span
|
|
|
|
|
|
class="font-primary font-bold text-sm text-swiss-black dark:text-neutral-200 leading-none tracking-tight uppercase truncate"
|
|
|
|
|
|
>
|
2026-01-30 17:42:06 +03:00
|
|
|
|
{font.name}
|
2026-02-27 12:42:18 +03:00
|
|
|
|
</span>
|
|
|
|
|
|
|
|
|
|
|
|
{#if fontType}
|
2026-04-17 08:53:16 +03:00
|
|
|
|
<Badge size="xs" variant="default" nowrap>
|
2026-02-27 12:42:18 +03:00
|
|
|
|
{fontType}
|
2026-02-27 18:42:20 +03:00
|
|
|
|
</Badge>
|
2026-02-27 12:42:18 +03:00
|
|
|
|
{/if}
|
2026-03-02 14:53:54 +03:00
|
|
|
|
|
|
|
|
|
|
<!-- Provider badge -->
|
|
|
|
|
|
{#if providerBadge}
|
2026-04-17 08:53:16 +03:00
|
|
|
|
<Badge size="xs" variant="default" nowrap data-provider={font.provider}>
|
2026-03-02 14:53:54 +03:00
|
|
|
|
{providerBadge}
|
|
|
|
|
|
</Badge>
|
|
|
|
|
|
{/if}
|
2026-01-30 17:42:06 +03:00
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-02-27 12:42:18 +03:00
|
|
|
|
<!-- Right: stats, hidden on mobile, fade in on group hover -->
|
2026-02-27 18:42:20 +03:00
|
|
|
|
<div
|
|
|
|
|
|
class="
|
|
|
|
|
|
flex-1 min-w-0
|
|
|
|
|
|
hidden md:block @container
|
|
|
|
|
|
opacity-50 group-hover:opacity-100
|
|
|
|
|
|
transition-opacity duration-200 ml-4
|
|
|
|
|
|
"
|
|
|
|
|
|
>
|
|
|
|
|
|
<!-- Switches: narrow → 2×2, wide enough → 1 row -->
|
|
|
|
|
|
<div
|
|
|
|
|
|
class="
|
|
|
|
|
|
max-w-64 ml-auto
|
|
|
|
|
|
grid grid-cols-2 gap-x-3 gap-y-2
|
|
|
|
|
|
@[160px]:grid-cols-4 @[160px]:gap-y-0
|
|
|
|
|
|
items-center
|
|
|
|
|
|
"
|
|
|
|
|
|
>
|
|
|
|
|
|
{#each stats as stat}
|
|
|
|
|
|
<Stat label={stat.label} value={stat.value} />
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
</div>
|
2026-02-27 12:42:18 +03:00
|
|
|
|
</div>
|
2026-01-30 00:56:21 +03:00
|
|
|
|
</div>
|
2026-01-30 17:42:06 +03:00
|
|
|
|
|
2026-02-27 12:42:18 +03:00
|
|
|
|
<!-- ── Main content area ──────────────────────────────────────────── -->
|
|
|
|
|
|
<div class="flex-1 p-4 sm:p-5 md:p-8 flex items-center overflow-hidden bg-paper dark:bg-dark-card relative z-10">
|
2026-04-16 08:44:49 +03:00
|
|
|
|
<FontApplicator {font} weight={typographySettingsStore.weight}>
|
2026-01-30 00:56:21 +03:00
|
|
|
|
<ContentEditable
|
2026-02-18 16:57:52 +03:00
|
|
|
|
bind:text
|
2026-04-16 08:44:49 +03:00
|
|
|
|
fontSize={typographySettingsStore.renderedSize}
|
|
|
|
|
|
lineHeight={typographySettingsStore.height}
|
|
|
|
|
|
letterSpacing={typographySettingsStore.spacing}
|
2026-01-30 00:56:21 +03:00
|
|
|
|
/>
|
|
|
|
|
|
</FontApplicator>
|
|
|
|
|
|
</div>
|
2026-01-30 17:42:06 +03:00
|
|
|
|
|
2026-02-27 12:42:18 +03:00
|
|
|
|
<!-- ── Mobile stats footer (md:hidden — header stats take over above) -->
|
2026-04-16 16:32:41 +03:00
|
|
|
|
<div class="md:hidden px-4 sm:px-5 py-1.5 sm:py-2 border-t border-subtle flex gap-2 sm:gap-4 bg-paper dark:bg-dark-card mt-auto">
|
2026-02-27 12:42:18 +03:00
|
|
|
|
{#each stats as stat, i}
|
2026-04-17 09:42:24 +03:00
|
|
|
|
<Footnote class="text-5xs sm:text-4xs tracking-wider {i === 0 ? 'ml-auto' : ''}">
|
2026-02-27 12:42:18 +03:00
|
|
|
|
{stat.label}:{stat.value}
|
|
|
|
|
|
</Footnote>
|
|
|
|
|
|
{#if i < stats.length - 1}
|
|
|
|
|
|
<div class="w-px h-2 sm:h-2.5 self-center bg-black/10 dark:bg-white/10 hidden sm:block"></div>
|
|
|
|
|
|
{/if}
|
|
|
|
|
|
{/each}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ── Red hover line ─────────────────────────────────────────────── -->
|
|
|
|
|
|
<div
|
|
|
|
|
|
class="
|
2026-02-27 18:42:20 +03:00
|
|
|
|
absolute bottom-0 left-0 right-0
|
2026-02-27 12:42:18 +03:00
|
|
|
|
w-full h-0.5 bg-brand
|
|
|
|
|
|
scale-x-0 group-hover:scale-x-100
|
2026-02-27 18:42:20 +03:00
|
|
|
|
transition-transform cubic-bezier(0.25, 0.1, 0.25, 1) origin-left duration-400
|
|
|
|
|
|
z-10
|
2026-02-27 12:42:18 +03:00
|
|
|
|
"
|
|
|
|
|
|
>
|
2026-01-30 17:42:06 +03:00
|
|
|
|
</div>
|
2026-01-18 14:35:35 +03:00
|
|
|
|
</div>
|