chore: follow the general comments style
This commit is contained in:
@@ -29,9 +29,13 @@ import { untrack } from 'svelte';
|
||||
* Storage schema for comparison state
|
||||
*/
|
||||
interface ComparisonState {
|
||||
/** Font ID for side A (left/top) */
|
||||
/**
|
||||
* Unique identifier for the primary font being compared (Side A)
|
||||
*/
|
||||
fontAId: string | null;
|
||||
/** Font ID for side B (right/bottom) */
|
||||
/**
|
||||
* Unique identifier for the secondary font being compared (Side B)
|
||||
*/
|
||||
fontBId: string | null;
|
||||
}
|
||||
|
||||
@@ -53,21 +57,33 @@ const storage = createPersistentStore<ComparisonState>('glyphdiff:comparison', {
|
||||
* storage is empty.
|
||||
*/
|
||||
export class ComparisonStore {
|
||||
/** Font for side A */
|
||||
/**
|
||||
* The primary font model for Side A (left/top)
|
||||
*/
|
||||
#fontA = $state<UnifiedFont | undefined>();
|
||||
/** Font for side B */
|
||||
/**
|
||||
* The secondary font model for Side B (right/bottom)
|
||||
*/
|
||||
#fontB = $state<UnifiedFont | undefined>();
|
||||
/** Sample text to display */
|
||||
/**
|
||||
* The preview text string displayed in the comparison area
|
||||
*/
|
||||
#sampleText = $state('The quick brown fox jumps over the lazy dog');
|
||||
/** Whether fonts are loaded and ready to display */
|
||||
/**
|
||||
* Flag indicating if both fonts are successfully loaded and ready for rendering
|
||||
*/
|
||||
#fontsReady = $state(false);
|
||||
/** Active side for single-font operations */
|
||||
/**
|
||||
* Currently active side (A or B) for single-font adjustments
|
||||
*/
|
||||
#side = $state<Side>('A');
|
||||
/** Slider position for character morphing (0-100) */
|
||||
/**
|
||||
* Interactive slider position (0-100) used for morphing/layout transitions
|
||||
*/
|
||||
#sliderPosition = $state(50);
|
||||
// /** Typography controls for this comparison */
|
||||
// #typography = createTypographyControlManager(DEFAULT_TYPOGRAPHY_CONTROLS_DATA, 'glyphdiff:comparison:typography');
|
||||
/** TanStack Query-backed batch font fetcher */
|
||||
/**
|
||||
* TanStack Query-backed store for efficient batch font retrieval
|
||||
*/
|
||||
#batchStore: BatchFontStore;
|
||||
|
||||
constructor() {
|
||||
@@ -211,14 +227,9 @@ export class ComparisonStore {
|
||||
};
|
||||
}
|
||||
|
||||
// // ── Getters / Setters ─────────────────────────────────────────────────────
|
||||
|
||||
// /** Typography control manager */
|
||||
// get typography() {
|
||||
// return typographySettingsStore;
|
||||
// }
|
||||
|
||||
/** Font for side A */
|
||||
/**
|
||||
* Primary font for comparison (reactive)
|
||||
*/
|
||||
get fontA() {
|
||||
return this.#fontA;
|
||||
}
|
||||
@@ -228,7 +239,9 @@ export class ComparisonStore {
|
||||
this.updateStorage();
|
||||
}
|
||||
|
||||
/** Font for side B */
|
||||
/**
|
||||
* Secondary font for comparison (reactive)
|
||||
*/
|
||||
get fontB() {
|
||||
return this.#fontB;
|
||||
}
|
||||
@@ -238,7 +251,9 @@ export class ComparisonStore {
|
||||
this.updateStorage();
|
||||
}
|
||||
|
||||
/** Sample text to display */
|
||||
/**
|
||||
* Shared preview text string (reactive)
|
||||
*/
|
||||
get text() {
|
||||
return this.#sampleText;
|
||||
}
|
||||
@@ -247,7 +262,9 @@ export class ComparisonStore {
|
||||
this.#sampleText = value;
|
||||
}
|
||||
|
||||
/** Active side for single-font operations */
|
||||
/**
|
||||
* Side currently selected for focused manipulation (reactive)
|
||||
*/
|
||||
get side() {
|
||||
return this.#side;
|
||||
}
|
||||
@@ -256,7 +273,9 @@ export class ComparisonStore {
|
||||
this.#side = value;
|
||||
}
|
||||
|
||||
/** Slider position (0-100) for character morphing */
|
||||
/**
|
||||
* Morphing slider position (0-100) used by Character components (reactive)
|
||||
*/
|
||||
get sliderPosition() {
|
||||
return this.#sliderPosition;
|
||||
}
|
||||
@@ -265,12 +284,16 @@ export class ComparisonStore {
|
||||
this.#sliderPosition = value;
|
||||
}
|
||||
|
||||
/** Whether both fonts are selected and loaded */
|
||||
/**
|
||||
* True if both fonts are ready for side-by-side display (reactive)
|
||||
*/
|
||||
get isReady() {
|
||||
return !!this.#fontA && !!this.#fontB && this.#fontsReady;
|
||||
}
|
||||
|
||||
/** Whether currently loading (batch fetch in flight or fonts not yet painted) */
|
||||
/**
|
||||
* True if any font is currently being fetched or loaded (reactive)
|
||||
*/
|
||||
get isLoading() {
|
||||
return this.#batchStore.isLoading || !this.#fontsReady;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
* Controls network behaviour via vi.spyOn on the proxyFonts API layer.
|
||||
*/
|
||||
|
||||
/** @vitest-environment jsdom */
|
||||
/**
|
||||
* @vitest-environment jsdom
|
||||
*/
|
||||
|
||||
import type { UnifiedFont } from '$entities/Font';
|
||||
import { UNIFIED_FONTS } from '$entities/Font/lib/mocks';
|
||||
@@ -18,8 +20,6 @@ import {
|
||||
vi,
|
||||
} from 'vitest';
|
||||
|
||||
// ── Persistent-store mock ─────────────────────────────────────────────────────
|
||||
|
||||
const mockStorage = vi.hoisted(() => {
|
||||
const storage: any = {};
|
||||
storage._value = { fontAId: null, fontBId: null };
|
||||
@@ -51,8 +51,6 @@ vi.mock('$shared/lib/helpers/createPersistentStore/createPersistentStore.svelte'
|
||||
createPersistentStore: vi.fn(() => mockStorage),
|
||||
}));
|
||||
|
||||
// ── $entities/Font mock — keep real BatchFontStore, stub singletons ───────────
|
||||
|
||||
vi.mock('$entities/Font', async importOriginal => {
|
||||
const actual = await importOriginal<typeof import('$entities/Font')>();
|
||||
const { BatchFontStore } = await import(
|
||||
@@ -73,8 +71,6 @@ vi.mock('$entities/Font', async importOriginal => {
|
||||
};
|
||||
});
|
||||
|
||||
// ── $features/SetupFont mock ──────────────────────────────────────────────────
|
||||
|
||||
vi.mock('$features/SetupFont', () => ({
|
||||
DEFAULT_TYPOGRAPHY_CONTROLS_DATA: [],
|
||||
createTypographyControlManager: vi.fn(() => ({
|
||||
@@ -92,8 +88,6 @@ vi.mock('$features/SetupFont/model', () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
// ── Imports (after mocks) ─────────────────────────────────────────────────────
|
||||
|
||||
import {
|
||||
appliedFontsManager,
|
||||
fontStore,
|
||||
@@ -101,8 +95,6 @@ import {
|
||||
import * as proxyFonts from '$entities/Font/api/proxy/proxyFonts';
|
||||
import { ComparisonStore } from './comparisonStore.svelte';
|
||||
|
||||
// ── Tests ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
describe('ComparisonStore', () => {
|
||||
const mockFontA: UnifiedFont = UNIFIED_FONTS.roboto; // id: 'roboto'
|
||||
const mockFontB: UnifiedFont = UNIFIED_FONTS.openSans; // id: 'open-sans'
|
||||
@@ -129,8 +121,6 @@ describe('ComparisonStore', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// ── Initialization ────────────────────────────────────────────────────────
|
||||
|
||||
describe('Initialization', () => {
|
||||
it('should create store with initial empty state', () => {
|
||||
const store = new ComparisonStore();
|
||||
@@ -139,8 +129,6 @@ describe('ComparisonStore', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// ── Restoration from Storage ──────────────────────────────────────────────
|
||||
|
||||
describe('Restoration from Storage (via BatchFontStore)', () => {
|
||||
it('should restore fontA and fontB from stored IDs', async () => {
|
||||
mockStorage._value.fontAId = mockFontA.id;
|
||||
@@ -169,8 +157,6 @@ describe('ComparisonStore', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// ── Default Fallbacks ─────────────────────────────────────────────────────
|
||||
|
||||
describe('Default Fallbacks', () => {
|
||||
it('should update storage with default IDs when storage is empty', async () => {
|
||||
(fontStore as any).fonts = [mockFontA, mockFontB];
|
||||
@@ -185,8 +171,6 @@ describe('ComparisonStore', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// ── Loading State ─────────────────────────────────────────────────────────
|
||||
|
||||
describe('Aggregate Loading State', () => {
|
||||
it('should be loading initially when storage has IDs', async () => {
|
||||
mockStorage._value.fontAId = mockFontA.id;
|
||||
@@ -202,8 +186,6 @@ describe('ComparisonStore', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// ── Reset ─────────────────────────────────────────────────────────────────
|
||||
|
||||
describe('Reset Functionality', () => {
|
||||
it('should reset all state and clear storage', () => {
|
||||
const store = new ComparisonStore();
|
||||
@@ -225,8 +207,6 @@ describe('ComparisonStore', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// ── Pin / Unpin ───────────────────────────────────────────────────────────
|
||||
|
||||
describe('Pin / Unpin (eviction guard)', () => {
|
||||
it('pins fontA and fontB when they are loaded', async () => {
|
||||
mockStorage._value.fontAId = mockFontA.id;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
<!--
|
||||
Component: Search
|
||||
Typeface search input for the comparison view.
|
||||
Updates the global filterManager query to filter the font list.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { filterManager } from '$features/GetFonts';
|
||||
import { SearchBar } from '$shared/ui';
|
||||
|
||||
@@ -22,6 +22,9 @@ import { responsiveManager } from '$shared/lib';
|
||||
export type LayoutMode = 'list' | 'grid';
|
||||
|
||||
interface LayoutConfig {
|
||||
/**
|
||||
* Active display mode (list | grid)
|
||||
*/
|
||||
mode: LayoutMode;
|
||||
}
|
||||
|
||||
@@ -40,9 +43,13 @@ const DEFAULT_CONFIG: LayoutConfig = {
|
||||
* calculation. Persists user preference to localStorage.
|
||||
*/
|
||||
class LayoutManager {
|
||||
/** Current layout mode */
|
||||
/**
|
||||
* Reactive layout mode state
|
||||
*/
|
||||
#mode = $state<LayoutMode>(DEFAULT_CONFIG.mode);
|
||||
/** Persistent storage for layout preference */
|
||||
/**
|
||||
* Persistence layer for saving layout between sessions
|
||||
*/
|
||||
#store = createPersistentStore<LayoutConfig>(STORAGE_KEY, DEFAULT_CONFIG);
|
||||
|
||||
constructor() {
|
||||
@@ -53,7 +60,9 @@ class LayoutManager {
|
||||
}
|
||||
}
|
||||
|
||||
/** Current layout mode ('list' or 'grid') */
|
||||
/**
|
||||
* Current active layout mode
|
||||
*/
|
||||
get mode(): LayoutMode {
|
||||
return this.#mode;
|
||||
}
|
||||
@@ -66,12 +75,16 @@ class LayoutManager {
|
||||
return responsiveManager.isMobile || responsiveManager.isTabletPortrait ? SM_GAP_PX : MD_GAP_PX;
|
||||
}
|
||||
|
||||
/** Whether currently in list mode */
|
||||
/**
|
||||
* True if currently showing a single-column list
|
||||
*/
|
||||
get isListMode(): boolean {
|
||||
return this.#mode === 'list';
|
||||
}
|
||||
|
||||
/** Whether currently in grid mode */
|
||||
/**
|
||||
* True if currently showing a multi-column grid
|
||||
*/
|
||||
get isGridMode(): boolean {
|
||||
return this.#mode === 'grid';
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/** @vitest-environment jsdom */
|
||||
/**
|
||||
* @vitest-environment jsdom
|
||||
*/
|
||||
|
||||
import {
|
||||
afterEach,
|
||||
|
||||
Reference in New Issue
Block a user