refactor(Font): consolidate API layer and update type structure

This commit is contained in:
Ilia Mashkov
2026-03-02 22:18:21 +03:00
parent ba186d00a1
commit af4137f47f
17 changed files with 325 additions and 558 deletions

View File

@@ -3,13 +3,31 @@ import type {
UnifiedFont,
} from '../../model';
/** Valid font weight values (100-900 in increments of 100) */
const SIZES = [100, 200, 300, 400, 500, 600, 700, 800, 900];
/**
* Constructs a URL for a font based on the provided font and weight.
* @param font - The font object.
* @param weight - The weight of the font.
* @returns The URL for the font.
* Gets the URL for a font file at a specific weight
*
* Constructs the appropriate URL for loading a font file based on
* the font object and requested weight. Handles variable fonts and
* provides fallbacks for static fonts.
*
* @param font - Unified font object containing style URLs
* @param weight - Font weight (100-900)
* @returns URL string for the font file, or undefined if not found
* @throws Error if weight is not a valid value (100-900)
*
* @example
* ```ts
* const url = getFontUrl(roboto, 700); // Returns URL for Roboto Bold
*
* // Variable fonts: backend maps weight to VF URL
* const vfUrl = getFontUrl(inter, 450); // Returns variable font URL
*
* // Fallback for missing weights
* const fallback = getFontUrl(font, 900); // Falls back to regular/400 if 900 missing
* ```
*/
export function getFontUrl(font: UnifiedFont, weight: number): string | undefined {
if (!SIZES.includes(weight)) {
@@ -18,12 +36,11 @@ export function getFontUrl(font: UnifiedFont, weight: number): string | undefine
const weightKey = weight.toString() as FontWeight;
// 1. Try exact match (Backend now maps "100".."900" to VF URL if variable)
// Try exact match (backend maps weight to VF URL for variable fonts)
if (font.styles.variants?.[weightKey]) {
return font.styles.variants[weightKey];
}
// 2. Fallbacks for Static Fonts (if exact weight missing)
// Try 'regular' or '400' as safe defaults
// Fallbacks for static fonts when exact weight is missing
return font.styles.regular || font.styles.variants?.['400'] || font.styles.variants?.['regular'];
}

View File

@@ -1,7 +1,5 @@
/**
* ============================================================================
* MOCK FONT FILTER DATA
* ============================================================================
* Mock font filter data
*
* Factory functions and preset mock data for font-related filters.
* Used in Storybook stories for font filtering components.
@@ -36,9 +34,7 @@ import type {
import type { Property } from '$shared/lib';
import { createFilter } from '$shared/lib';
// ============================================================================
// TYPE DEFINITIONS
// ============================================================================
/**
* Options for creating a mock filter
@@ -60,9 +56,7 @@ export interface MockFilters {
subsets: ReturnType<typeof createFilter<FontSubset>>;
}
// ============================================================================
// FONT CATEGORIES
// ============================================================================
/**
* Google Fonts categories
@@ -98,9 +92,7 @@ export const UNIFIED_CATEGORIES: Property<FontCategory>[] = [
{ id: 'monospace', name: 'Monospace', value: 'monospace' },
];
// ============================================================================
// FONT SUBSETS
// ============================================================================
/**
* Common font subsets
@@ -114,9 +106,7 @@ export const FONT_SUBSETS: Property<FontSubset>[] = [
{ id: 'devanagari', name: 'Devanagari', value: 'devanagari' },
];
// ============================================================================
// FONT PROVIDERS
// ============================================================================
/**
* Font providers
@@ -126,9 +116,7 @@ export const FONT_PROVIDERS: Property<FontProvider>[] = [
{ id: 'fontshare', name: 'Fontshare', value: 'fontshare' },
];
// ============================================================================
// FILTER FACTORIES
// ============================================================================
/**
* Create a mock filter from properties
@@ -172,9 +160,7 @@ export function createProvidersFilter(options?: { selected?: FontProvider[] }) {
return createFilter<FontProvider>({ properties });
}
// ============================================================================
// PRESET FILTERS
// ============================================================================
/**
* Preset mock filters - use these directly in stories
@@ -251,9 +237,7 @@ export const MOCK_FILTERS_ALL_SELECTED: MockFilters = {
}),
};
// ============================================================================
// GENERIC FILTER MOCKS
// ============================================================================
/**
* Create a mock filter with generic string properties

View File

@@ -50,9 +50,7 @@ import type {
UnifiedFont,
} from '$entities/Font/model/types';
// ============================================================================
// GOOGLE FONTS MOCKS
// ============================================================================
/**
* Options for creating a mock Google Font
@@ -186,9 +184,7 @@ export const GOOGLE_FONTS: Record<string, GoogleFontItem> = {
}),
};
// ============================================================================
// FONTHARE MOCKS
// ============================================================================
/**
* Options for creating a mock Fontshare font
@@ -399,9 +395,7 @@ export const FONTHARE_FONTS: Record<string, FontshareFont> = {
}),
};
// ============================================================================
// UNIFIED FONT MOCKS
// ============================================================================
/**
* Options for creating a mock UnifiedFont

View File

@@ -35,9 +35,7 @@ import {
generateMockFonts,
} from './fonts.mock';
// ============================================================================
// TANSTACK QUERY MOCK TYPES
// ============================================================================
/**
* Mock TanStack Query state
@@ -83,9 +81,7 @@ export interface MockQueryObserverResult<TData = unknown, TError = Error> {
isPaused?: boolean;
}
// ============================================================================
// TANSTACK QUERY MOCK FACTORIES
// ============================================================================
/**
* Create a mock query state for TanStack Query
@@ -142,9 +138,7 @@ export function createSuccessState<TData>(data: TData): MockQueryObserverResult<
return createMockQueryState<TData>({ status: 'success', data, error: undefined });
}
// ============================================================================
// FONT STORE MOCKS
// ============================================================================
/**
* Mock UnifiedFontStore state
@@ -332,9 +326,7 @@ export const MOCK_FONT_STORE_STATES = {
}),
};
// ============================================================================
// MOCK STORE OBJECT
// ============================================================================
/**
* Create a mock store object that mimics TanStack Query behavior
@@ -469,9 +461,7 @@ export const MOCK_STORES = {
},
};
// ============================================================================
// REACTIVE STATE MOCKS
// ============================================================================
/**
* Create a reactive state object using Svelte 5 runes pattern
@@ -525,9 +515,7 @@ export function createMockComparisonStore(config: {
};
}
// ============================================================================
// MOCK DATA GENERATORS
// ============================================================================
/**
* Generate paginated font data