feat: use typographySettingsStore everywhere for the typography settings

This commit is contained in:
Ilia Mashkov
2026-04-16 08:44:49 +03:00
parent fbeb84270b
commit 8645c7dcc8
9 changed files with 82 additions and 87 deletions

View File

@@ -35,7 +35,6 @@ const { Story } = defineMeta({
<script lang="ts"> <script lang="ts">
import type { UnifiedFont } from '$entities/Font'; import type { UnifiedFont } from '$entities/Font';
import { controlManager } from '$features/SetupFont';
// Mock fonts for testing // Mock fonts for testing
const mockArial: UnifiedFont = { const mockArial: UnifiedFont = {

View File

@@ -8,14 +8,13 @@ import {
FontApplicator, FontApplicator,
type UnifiedFont, type UnifiedFont,
} from '$entities/Font'; } from '$entities/Font';
import { controlManager } from '$features/SetupFont'; import { typographySettingsStore } from '$features/SetupFont/model';
import { import {
Badge, Badge,
ContentEditable, ContentEditable,
Divider, Divider,
Footnote, Footnote,
Stat, Stat,
StatGroup,
} from '$shared/ui'; } from '$shared/ui';
import { fly } from 'svelte/transition'; import { fly } from 'svelte/transition';
@@ -37,11 +36,6 @@ interface Props {
let { font, text = $bindable(), index = 0 }: Props = $props(); let { font, text = $bindable(), index = 0 }: Props = $props();
const fontWeight = $derived(controlManager.weight);
const fontSize = $derived(controlManager.renderedSize);
const lineHeight = $derived(controlManager.height);
const letterSpacing = $derived(controlManager.spacing);
// Adjust the property name to match your UnifiedFont type // Adjust the property name to match your UnifiedFont type
const fontType = $derived((font as any).type ?? (font as any).category ?? ''); const fontType = $derived((font as any).type ?? (font as any).category ?? '');
@@ -52,10 +46,10 @@ const providerBadge = $derived(
); );
const stats = $derived([ const stats = $derived([
{ label: 'SZ', value: `${fontSize}PX` }, { label: 'SZ', value: `${typographySettingsStore.renderedSize}PX` },
{ label: 'WGT', value: `${fontWeight}` }, { label: 'WGT', value: `${typographySettingsStore.weight}` },
{ label: 'LH', value: lineHeight?.toFixed(2) }, { label: 'LH', value: typographySettingsStore.height?.toFixed(2) },
{ label: 'LTR', value: `${letterSpacing}` }, { label: 'LTR', value: `${typographySettingsStore.spacing}` },
]); ]);
</script> </script>
@@ -75,7 +69,7 @@ const stats = $derived([
min-h-60 min-h-60
rounded-none rounded-none
" "
style:font-weight={fontWeight} style:font-weight={typographySettingsStore.weight}
> >
<!-- ── Header bar ─────────────────────────────────────────────────── --> <!-- ── Header bar ─────────────────────────────────────────────────── -->
<div <div
@@ -140,12 +134,12 @@ const stats = $derived([
<!-- ── Main content area ──────────────────────────────────────────── --> <!-- ── 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"> <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">
<FontApplicator {font} weight={fontWeight}> <FontApplicator {font} weight={typographySettingsStore.weight}>
<ContentEditable <ContentEditable
bind:text bind:text
{fontSize} fontSize={typographySettingsStore.renderedSize}
{lineHeight} lineHeight={typographySettingsStore.height}
{letterSpacing} letterSpacing={typographySettingsStore.spacing}
/> />
</FontApplicator> </FontApplicator>
</div> </div>

View File

@@ -21,10 +21,7 @@ import {
fontStore, fontStore,
getFontUrl, getFontUrl,
} from '$entities/Font'; } from '$entities/Font';
import { import { typographySettingsStore } from '$features/SetupFont/model';
DEFAULT_TYPOGRAPHY_CONTROLS_DATA,
createTypographyControlManager,
} from '$features/SetupFont';
import { createPersistentStore } from '$shared/lib'; import { createPersistentStore } from '$shared/lib';
import { untrack } from 'svelte'; import { untrack } from 'svelte';
@@ -68,8 +65,8 @@ export class ComparisonStore {
#side = $state<Side>('A'); #side = $state<Side>('A');
/** Slider position for character morphing (0-100) */ /** Slider position for character morphing (0-100) */
#sliderPosition = $state(50); #sliderPosition = $state(50);
/** Typography controls for this comparison */ // /** Typography controls for this comparison */
#typography = createTypographyControlManager(DEFAULT_TYPOGRAPHY_CONTROLS_DATA, 'glyphdiff:comparison:typography'); // #typography = createTypographyControlManager(DEFAULT_TYPOGRAPHY_CONTROLS_DATA, 'glyphdiff:comparison:typography');
/** TanStack Query-backed batch font fetcher */ /** TanStack Query-backed batch font fetcher */
#batchStore: BatchFontStore; #batchStore: BatchFontStore;
@@ -99,7 +96,7 @@ export class ComparisonStore {
$effect(() => { $effect(() => {
const fa = this.#fontA; const fa = this.#fontA;
const fb = this.#fontB; const fb = this.#fontB;
const weight = this.#typography.weight; const weight = typographySettingsStore.weight;
if (!fa || !fb) return; if (!fa || !fb) return;
@@ -152,8 +149,8 @@ export class ComparisonStore {
return; return;
} }
const weight = this.#typography.weight; const weight = typographySettingsStore.weight;
const size = this.#typography.renderedSize; const size = typographySettingsStore.renderedSize;
const fontAName = this.#fontA?.name; const fontAName = this.#fontA?.name;
const fontBName = this.#fontB?.name; const fontBName = this.#fontB?.name;
@@ -201,12 +198,12 @@ export class ComparisonStore {
}; };
} }
// ── Getters / Setters ───────────────────────────────────────────────────── // // ── Getters / Setters ─────────────────────────────────────────────────────
/** Typography control manager */ // /** Typography control manager */
get typography() { // get typography() {
return this.#typography; // return typographySettingsStore;
} // }
/** Font for side A */ /** Font for side A */
get fontA() { get fontA() {
@@ -273,7 +270,7 @@ export class ComparisonStore {
this.#fontB = undefined; this.#fontB = undefined;
this.#batchStore.setIds([]); this.#batchStore.setIds([]);
storage.clear(); storage.clear();
this.#typography.reset(); typographySettingsStore.reset();
} }
} }

View File

@@ -3,6 +3,7 @@
Renders a single character with morphing animation Renders a single character with morphing animation
--> -->
<script lang="ts"> <script lang="ts">
import { typographySettingsStore } from '$features/SetupFont';
import { cn } from '$shared/shadcn/utils/shadcn-utils'; import { cn } from '$shared/shadcn/utils/shadcn-utils';
import { comparisonStore } from '../../model'; import { comparisonStore } from '../../model';
@@ -25,7 +26,7 @@ let { char, proximity, isPast }: Props = $props();
const fontA = $derived(comparisonStore.fontA); const fontA = $derived(comparisonStore.fontA);
const fontB = $derived(comparisonStore.fontB); const fontB = $derived(comparisonStore.fontB);
const typography = $derived(comparisonStore.typography); const typography = $derived(typographySettingsStore);
let slot = $state<0 | 1>(0); let slot = $state<0 | 1>(0);
let slotFonts = $state<[string, string]>(['', '']); let slotFonts = $state<[string, string]>(['', '']);

View File

@@ -15,14 +15,13 @@ import {
getContext, getContext,
untrack, untrack,
} from 'svelte'; } from 'svelte';
import { comparisonStore } from '../../model';
import FontList from '../FontList/FontList.svelte'; import FontList from '../FontList/FontList.svelte';
import Header from '../Header/Header.svelte'; import Header from '../Header/Header.svelte';
import Sidebar from '../Sidebar/Sidebar.svelte'; import Sidebar from '../Sidebar/Sidebar.svelte';
import SliderArea from '../SliderArea/SliderArea.svelte'; import SliderArea from '../SliderArea/SliderArea.svelte';
const responsive = getContext<ResponsiveManager>('responsive'); const responsive = getContext<ResponsiveManager>('responsive');
const typography = $derived(comparisonStore.typography); // const typography = $derived(comparisonStore.typography);
const isMobileOrTabletPortrait = $derived(responsive.isMobile || responsive.isTabletPortrait); const isMobileOrTabletPortrait = $derived(responsive.isMobile || responsive.isTabletPortrait);
let isSidebarOpen = $state(!isMobileOrTabletPortrait); let isSidebarOpen = $state(!isMobileOrTabletPortrait);
@@ -45,7 +44,7 @@ $effect(() => {
{#snippet main()} {#snippet main()}
<FontList /> <FontList />
{/snippet} {/snippet}
<!--
{#snippet controls()} {#snippet controls()}
{#if typography.sizeControl && typography.weightControl && typography.heightControl && typography.spacingControl} {#if typography.sizeControl && typography.weightControl && typography.heightControl && typography.spacingControl}
<ControlGroup label="Size"> <ControlGroup label="Size">
@@ -89,6 +88,7 @@ $effect(() => {
</div> </div>
{/if} {/if}
{/snippet} {/snippet}
-->
</Sidebar> </Sidebar>
{/snippet} {/snippet}
</SidebarContainer> </SidebarContainer>

View File

@@ -8,6 +8,7 @@ import {
FontVirtualList, FontVirtualList,
type UnifiedFont, type UnifiedFont,
} from '$entities/Font'; } from '$entities/Font';
import { typographySettingsStore } from '$features/SetupFont';
import { import {
Button, Button,
Label, Label,
@@ -18,7 +19,7 @@ import { crossfade } from 'svelte/transition';
import { comparisonStore } from '../../model'; import { comparisonStore } from '../../model';
const side = $derived(comparisonStore.side); const side = $derived(comparisonStore.side);
const typography = $derived(comparisonStore.typography); const typography = $derived(typographySettingsStore);
let prevIndexA: number | null = null; let prevIndexA: number | null = null;
let prevIndexB: number | null = null; let prevIndexB: number | null = null;

View File

@@ -3,8 +3,8 @@
Renders a line of text in the SliderArea Renders a line of text in the SliderArea
--> -->
<script lang="ts"> <script lang="ts">
import { typographySettingsStore } from '$features/SetupFont';
import type { Snippet } from 'svelte'; import type { Snippet } from 'svelte';
import { comparisonStore } from '../../model';
interface LineChar { interface LineChar {
char: string; char: string;
@@ -26,7 +26,7 @@ interface Props {
*/ */
character: Snippet<[{ char: string; index: number }]>; character: Snippet<[{ char: string; index: number }]>;
} }
const typography = $derived(comparisonStore.typography); const typography = $derived(typographySettingsStore);
let { chars, character }: Props = $props(); let { chars, character }: Props = $props();
</script> </script>

View File

@@ -8,6 +8,8 @@
- Performance optimized using offscreen canvas for measurements and transform-based animations. - Performance optimized using offscreen canvas for measurements and transform-based animations.
--> -->
<script lang="ts"> <script lang="ts">
import { TypographyMenu } from '$features/SetupFont';
import { typographySettingsStore } from '$features/SetupFont/model';
import { import {
type ResponsiveManager, type ResponsiveManager,
debounce, debounce,
@@ -42,7 +44,7 @@ let { isSidebarOpen = false, class: className }: Props = $props();
const fontA = $derived(comparisonStore.fontA); const fontA = $derived(comparisonStore.fontA);
const fontB = $derived(comparisonStore.fontB); const fontB = $derived(comparisonStore.fontB);
const isLoading = $derived(comparisonStore.isLoading || !comparisonStore.isReady); const isLoading = $derived(comparisonStore.isLoading || !comparisonStore.isReady);
const typography = $derived(comparisonStore.typography); const typography = $derived(typographySettingsStore);
let container = $state<HTMLElement>(); let container = $state<HTMLElement>();
@@ -179,12 +181,7 @@ const scaleClass = $derived(
The paper div inside scales down when the sidebar opens on desktop. The paper div inside scales down when the sidebar opens on desktop.
--> -->
<div class={cn('flex-1 relative flex items-center justify-center p-0 overflow-hidden bg-surface dark:bg-dark-bg', className)}> <div class={cn('flex-1 relative flex items-center justify-center p-0 overflow-hidden bg-surface dark:bg-dark-bg', className)}>
<!-- <!-- Paper surface -->
Paper surface.
Replaces the old glassmorphism card with a clean white/dark sheet.
Scale transition replaces motion.div spring — CSS transition-transform
is smooth enough here; a JS spring would add ~4kb for minimal gain.
-->
<div <div
class={cn( class={cn(
'w-full h-full flex flex-col items-center justify-center relative', 'w-full h-full flex flex-col items-center justify-center relative',
@@ -248,4 +245,10 @@ const scaleClass = $derived(
{/if} {/if}
</div> </div>
</div> </div>
<TypographyMenu
class={cn(
'absolute bottom-4 sm:bottom-5 right-4 sm:left-1/2 sm:right-[unset] sm:-translate-x-1/2 z-50',
)}
/>
</div> </div>

View File

@@ -14,7 +14,7 @@ import {
import { FontSampler } from '$features/DisplayFont'; import { FontSampler } from '$features/DisplayFont';
import { import {
TypographyMenu, TypographyMenu,
controlManager, typographySettingsStore,
} from '$features/SetupFont'; } from '$features/SetupFont';
import { throttle } from '$shared/lib/utils'; import { throttle } from '$shared/lib/utils';
import { Skeleton } from '$shared/ui'; import { Skeleton } from '$shared/ui';
@@ -60,11 +60,11 @@ const checkPosition = throttle(() => {
const fontRowHeight = $derived.by(() => const fontRowHeight = $derived.by(() =>
createFontRowSizeResolver({ createFontRowSizeResolver({
getFonts: () => fontStore.fonts, getFonts: () => fontStore.fonts,
getWeight: () => controlManager.weight, getWeight: () => typographySettingsStore.weight,
getPreviewText: () => text, getPreviewText: () => text,
getContainerWidth: () => containerWidth, getContainerWidth: () => containerWidth,
getFontSizePx: () => controlManager.renderedSize, getFontSizePx: () => typographySettingsStore.renderedSize,
getLineHeightPx: () => controlManager.height * controlManager.renderedSize, getLineHeightPx: () => typographySettingsStore.height * typographySettingsStore.renderedSize,
getStatus: key => appliedFontsManager.statuses.get(key), getStatus: key => appliedFontsManager.statuses.get(key),
contentHorizontalPadding: SAMPLER_CONTENT_PADDING_X, contentHorizontalPadding: SAMPLER_CONTENT_PADDING_X,
chromeHeight: SAMPLER_CHROME_HEIGHT, chromeHeight: SAMPLER_CHROME_HEIGHT,
@@ -97,7 +97,7 @@ const fontRowHeight = $derived.by(() =>
<FontVirtualList <FontVirtualList
itemHeight={fontRowHeight} itemHeight={fontRowHeight}
useWindowScroll={true} useWindowScroll={true}
weight={controlManager.weight} weight={typographySettingsStore.weight}
columns={layoutManager.columns} columns={layoutManager.columns}
gap={layoutManager.gap} gap={layoutManager.gap}
{skeleton} {skeleton}