diff --git a/src/widgets/ComparisonSlider/index.ts b/src/widgets/ComparisonSlider/index.ts deleted file mode 100644 index b34444e..0000000 --- a/src/widgets/ComparisonSlider/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './model'; -export { ComparisonSlider } from './ui'; diff --git a/src/widgets/ComparisonSlider/model/index.ts b/src/widgets/ComparisonSlider/model/index.ts deleted file mode 100644 index 993fd73..0000000 --- a/src/widgets/ComparisonSlider/model/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { comparisonStore } from './stores/comparisonStore.svelte'; diff --git a/src/widgets/ComparisonSlider/model/stores/comparisonStore.svelte.ts b/src/widgets/ComparisonSlider/model/stores/comparisonStore.svelte.ts deleted file mode 100644 index 270bb96..0000000 --- a/src/widgets/ComparisonSlider/model/stores/comparisonStore.svelte.ts +++ /dev/null @@ -1,224 +0,0 @@ -import { - type UnifiedFont, - fetchFontsByIds, - unifiedFontStore, -} from '$entities/Font'; -import { - DEFAULT_TYPOGRAPHY_CONTROLS_DATA, - createTypographyControlManager, -} from '$features/SetupFont'; -import { createPersistentStore } from '$shared/lib'; - -/** - * Storage schema for comparison state - */ -interface ComparisonState { - fontAId: string | null; - fontBId: string | null; -} - -// Persistent storage for selected comparison fonts -const storage = createPersistentStore('glyphdiff:comparison', { - fontAId: null, - fontBId: null, -}); - -/** - * Store for managing font comparison state - * - Persists selection to localStorage - * - Handles font fetching on initialization - * - Manages sample text - */ -class ComparisonStore { - #fontA = $state(); - #fontB = $state(); - #sampleText = $state('The quick brown fox jumps over the lazy dog'); - #isRestoring = $state(true); - #fontsReady = $state(false); - #typography = createTypographyControlManager(DEFAULT_TYPOGRAPHY_CONTROLS_DATA, 'glyphdiff:comparison:typography'); - - constructor() { - this.restoreFromStorage(); - - // Reactively set defaults if we aren't restoring and have no selection - $effect.root(() => { - $effect(() => { - // Wait until we are done checking storage - if (this.#isRestoring) { - return; - } - - // If we already have a selection, do nothing - if (this.#fontA && this.#fontB) { - this.#checkFontsLoaded(); - return; - } - - // Check if fonts are available to set as defaults - const fonts = unifiedFontStore.fonts; - if (fonts.length >= 2) { - // Only set if we really have nothing (fallback) - if (!this.#fontA) this.#fontA = fonts[0]; - if (!this.#fontB) this.#fontB = fonts[fonts.length - 1]; - - // Sync defaults to storage so they persist if the user leaves - this.updateStorage(); - } - }); - }); - } - - /** - * Checks if fonts are actually loaded in the browser at current weight. - * Uses CSS Font Loading API to prevent FOUT. - */ - async #checkFontsLoaded() { - if (!('fonts' in document)) { - this.#fontsReady = true; - return; - } - - const weight = this.#typography.weight; - const size = this.#typography.renderedSize; - const fontAName = this.#fontA?.name; - const fontBName = this.#fontB?.name; - - if (!fontAName || !fontBName) return; - - const fontAString = `${weight} ${size}px "${fontAName}"`; - const fontBString = `${weight} ${size}px "${fontBName}"`; - - // Check if already loaded to avoid UI flash - const isALoaded = document.fonts.check(fontAString); - const isBLoaded = document.fonts.check(fontBString); - - if (isALoaded && isBLoaded) { - this.#fontsReady = true; - return; - } - - this.#fontsReady = false; - - try { - // Step 1: Load fonts into memory - await Promise.all([ - document.fonts.load(fontAString), - document.fonts.load(fontBString), - ]); - - // Step 2: Wait for browser to be ready to render - await document.fonts.ready; - - // Step 3: Force a layout/paint cycle (critical!) - await new Promise(resolve => { - requestAnimationFrame(() => { - requestAnimationFrame(resolve); // Double rAF ensures paint completes - }); - }); - - this.#fontsReady = true; - } catch (error) { - console.warn('[ComparisonStore] Font loading failed:', error); - setTimeout(() => this.#fontsReady = true, 1000); - } - } - /** - * Restore state from persistent storage - */ - async restoreFromStorage() { - this.#isRestoring = true; - const { fontAId, fontBId } = storage.value; - - if (fontAId && fontBId) { - try { - // Batch fetch the saved fonts - const fonts = await fetchFontsByIds([fontAId, fontBId]); - const loadedFontA = fonts.find((f: UnifiedFont) => f.id === fontAId); - const loadedFontB = fonts.find((f: UnifiedFont) => f.id === fontBId); - - if (loadedFontA && loadedFontB) { - this.#fontA = loadedFontA; - this.#fontB = loadedFontB; - } - } catch (error) { - console.warn('[ComparisonStore] Failed to restore fonts:', error); - } - } - - // Mark restoration as complete (whether success or fail) - this.#isRestoring = false; - } - - /** - * Update storage with current state - */ - private updateStorage() { - // Don't save if we are currently restoring (avoid race) - if (this.#isRestoring) return; - - storage.value = { - fontAId: this.#fontA?.id ?? null, - fontBId: this.#fontB?.id ?? null, - }; - } - - // --- Getters & Setters --- - get typography() { - return this.#typography; - } - - get fontA() { - return this.#fontA; - } - - set fontA(font: UnifiedFont | undefined) { - this.#fontA = font; - this.updateStorage(); - } - - get fontB() { - return this.#fontB; - } - - set fontB(font: UnifiedFont | undefined) { - this.#fontB = font; - this.updateStorage(); - } - - get text() { - return this.#sampleText; - } - - set text(value: string) { - this.#sampleText = value; - } - - /** - * Check if both fonts are selected - */ - get isReady() { - return !!this.#fontA && !!this.#fontB && this.#fontsReady; - } - - get isLoading() { - return this.#isRestoring || !this.#fontsReady; - } - /** - * Public initializer (optional, as constructor starts it) - * Kept for compatibility if manual re-init is needed - */ - initialize() { - if (!this.#isRestoring && !this.#fontA && !this.#fontB) { - this.restoreFromStorage(); - } - } - - resetAll() { - this.#fontA = undefined; - this.#fontB = undefined; - storage.clear(); - this.#typography.reset(); - } -} - -export const comparisonStore = new ComparisonStore(); diff --git a/src/widgets/ComparisonSlider/ui/ComparisonSlider/ComparisonSlider.stories.svelte b/src/widgets/ComparisonSlider/ui/ComparisonSlider/ComparisonSlider.stories.svelte deleted file mode 100644 index e46e755..0000000 --- a/src/widgets/ComparisonSlider/ui/ComparisonSlider/ComparisonSlider.stories.svelte +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - {@const _ = (comparisonStore.fontA = mockArial, comparisonStore.fontB = mockGeorgia)} - -
-
- -
-
-
-
- - - {@const _ = (comparisonStore.fontA = undefined, comparisonStore.fontB = undefined)} - -
-
- -
-
-
-
diff --git a/src/widgets/ComparisonSlider/ui/ComparisonSlider/ComparisonSlider.svelte b/src/widgets/ComparisonSlider/ui/ComparisonSlider/ComparisonSlider.svelte deleted file mode 100644 index fd0ed45..0000000 --- a/src/widgets/ComparisonSlider/ui/ComparisonSlider/ComparisonSlider.svelte +++ /dev/null @@ -1,278 +0,0 @@ - - - -{#snippet renderLine(line: LineData, index: number)} - {@const pos = sliderPos} - {@const element = lineElements[index]} -
- {#each line.text.split('') as char, index} - {@const { proximity, isPast } = charComparison.getCharState(index, pos, element, container)} - - {#if fontA && fontB} - - {/if} - {/each} -
-{/snippet} - - - - - -
- {#if isLoading} -
- -
- {:else} - - -
-
- {#each charComparison.lines as line, lineIndex} -
- {@render renderLine(line, lineIndex)} -
- {/each} -
- - - {#if !isInSettingsMode} - - {/if} -
-
- - - {/if} -
diff --git a/src/widgets/ComparisonSlider/ui/ComparisonSlider/components/CharacterSlot.svelte b/src/widgets/ComparisonSlider/ui/ComparisonSlider/components/CharacterSlot.svelte deleted file mode 100644 index 3c6ce24..0000000 --- a/src/widgets/ComparisonSlider/ui/ComparisonSlider/components/CharacterSlot.svelte +++ /dev/null @@ -1,73 +0,0 @@ - - - -{#if fontA && fontB} - 0.5 - ? '0 0 15px rgba(99,102,241,0.3)' - : 'none'} - style:will-change={proximity > 0 - ? 'transform, font-family, color' - : 'auto'} - > - {char === ' ' ? '\u00A0' : char} - -{/if} - - diff --git a/src/widgets/ComparisonSlider/ui/ComparisonSlider/components/Controls.svelte b/src/widgets/ComparisonSlider/ui/ComparisonSlider/components/Controls.svelte deleted file mode 100644 index 452f9ee..0000000 --- a/src/widgets/ComparisonSlider/ui/ComparisonSlider/components/Controls.svelte +++ /dev/null @@ -1,131 +0,0 @@ - - - -{#if responsive.isMobile} - - {#snippet trigger({ onClick })} -
- -
- {/snippet} - {#snippet content({ className })} -
-
- {fontB?.name ?? 'typeface_01'} -
-
-
- {fontA?.name ?? 'typeface_02'} -
-
-
-
- {/snippet} -
-{:else} - - {#snippet action()} - -
- -
- {/snippet} -
-{/if} diff --git a/src/widgets/ComparisonSlider/ui/ComparisonSlider/components/FontList.svelte b/src/widgets/ComparisonSlider/ui/ComparisonSlider/components/FontList.svelte deleted file mode 100644 index db053b3..0000000 --- a/src/widgets/ComparisonSlider/ui/ComparisonSlider/components/FontList.svelte +++ /dev/null @@ -1,215 +0,0 @@ - - - -{#snippet rightBrackets(className?: string)} - - - - - - - -{/snippet} - -{#snippet leftBrackets(className?: string)} - - - - - - -{/snippet} - -{#snippet brackets( - renderLeft?: boolean, - renderRight?: boolean, - className?: string, -)} - {#if renderLeft} - {@render leftBrackets(className)} - {/if} - {#if renderRight} - {@render rightBrackets(className)} - {/if} -{/snippet} - -
-
- - {#snippet children({ item: font })} - {@const isSelectedA = isFontA(font)} - {@const isSelectedB = isFontB(font)} - {@const isEither = isSelectedA || isSelectedB} - {@const isBoth = isSelectedA && isSelectedB} - {@const handleSelectFontA = () => selectFontA(font)} - {@const handleSelectFontB = () => selectFontB(font)} - -
-
-
- - --- {font.name} --- - -
-
- - - - -
- {/snippet} -
-
-
diff --git a/src/widgets/ComparisonSlider/ui/ComparisonSlider/components/SliderLine.svelte b/src/widgets/ComparisonSlider/ui/ComparisonSlider/components/SliderLine.svelte deleted file mode 100644 index d638607..0000000 --- a/src/widgets/ComparisonSlider/ui/ComparisonSlider/components/SliderLine.svelte +++ /dev/null @@ -1,55 +0,0 @@ - - - -
- -
-
-
- - -
-
-
-
diff --git a/src/widgets/ComparisonSlider/ui/ComparisonSlider/components/ToggleMenuButton.svelte b/src/widgets/ComparisonSlider/ui/ComparisonSlider/components/ToggleMenuButton.svelte deleted file mode 100644 index 733450d..0000000 --- a/src/widgets/ComparisonSlider/ui/ComparisonSlider/components/ToggleMenuButton.svelte +++ /dev/null @@ -1,88 +0,0 @@ - - - -{#snippet icon(className?: string)} - - - {#if isActive} - - {:else} - - {/if} - -{/snippet} - - diff --git a/src/widgets/ComparisonSlider/ui/ComparisonSlider/components/TypographyControls.svelte b/src/widgets/ComparisonSlider/ui/ComparisonSlider/components/TypographyControls.svelte deleted file mode 100644 index 68492fe..0000000 --- a/src/widgets/ComparisonSlider/ui/ComparisonSlider/components/TypographyControls.svelte +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - -{#if typography.weightControl && typography.sizeControl && typography.heightControl} -
- - - - - -
-{/if} diff --git a/src/widgets/ComparisonSlider/ui/index.ts b/src/widgets/ComparisonSlider/ui/index.ts deleted file mode 100644 index ccad21a..0000000 --- a/src/widgets/ComparisonSlider/ui/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import ComparisonSlider from './ComparisonSlider/ComparisonSlider.svelte'; - -export { ComparisonSlider };