chore: follow the general comments style

This commit is contained in:
Ilia Mashkov
2026-04-17 12:14:55 +03:00
parent 0ebf75b24e
commit cfaff46d59
56 changed files with 1600 additions and 499 deletions
@@ -3,7 +3,9 @@ import type {
UnifiedFont,
} from '../../model';
/** Valid font weight values (100-900 in increments of 100) */
/**
* Valid font weight values (100-900 in increments of 100)
*/
const SIZES = [100, 200, 300, 400, 500, 600, 700, 800, 900];
/**
+30 -52
View File
@@ -1,31 +1,3 @@
/**
* Mock font filter data
*
* Factory functions and preset mock data for font-related filters.
* Used in Storybook stories for font filtering components.
*
* ## Usage
*
* ```ts
* import {
* createMockFilter,
* MOCK_FILTERS,
* } from '$entities/Font/lib/mocks';
*
* // Create a custom filter
* const customFilter = createMockFilter({
* properties: [
* { id: 'option1', name: 'Option 1', value: 'option1' },
* { id: 'option2', name: 'Option 2', value: 'option2', selected: true },
* ],
* });
*
* // Use preset filters
* const categoriesFilter = MOCK_FILTERS.categories;
* const subsetsFilter = MOCK_FILTERS.subsets;
* ```
*/
import type {
FontCategory,
FontProvider,
@@ -34,13 +6,13 @@ import type {
import type { Property } from '$shared/lib';
import { createFilter } from '$shared/lib';
// TYPE DEFINITIONS
/**
* Options for creating a mock filter
*/
export interface MockFilterOptions {
/** Filter properties */
/**
* Initial set of properties for the mock filter
*/
properties: Property<string>[];
}
@@ -48,16 +20,20 @@ export interface MockFilterOptions {
* Preset mock filters for font filtering
*/
export interface MockFilters {
/** Provider filter (Google, Fontshare) */
/**
* Provider filter (Google, Fontshare)
*/
providers: ReturnType<typeof createFilter<'google' | 'fontshare'>>;
/** Category filter (sans-serif, serif, display, etc.) */
/**
* Category filter (sans-serif, serif, display, etc.)
*/
categories: ReturnType<typeof createFilter<FontCategory>>;
/** Subset filter (latin, latin-ext, cyrillic, etc.) */
/**
* Subset filter (latin, latin-ext, cyrillic, etc.)
*/
subsets: ReturnType<typeof createFilter<FontSubset>>;
}
// FONT CATEGORIES
/**
* Unified categories (combines both providers)
*/
@@ -71,8 +47,6 @@ export const UNIFIED_CATEGORIES: Property<FontCategory>[] = [
{ id: 'script', name: 'Script', value: 'script' },
];
// FONT SUBSETS
/**
* Common font subsets
*/
@@ -85,8 +59,6 @@ export const FONT_SUBSETS: Property<FontSubset>[] = [
{ id: 'devanagari', name: 'Devanagari', value: 'devanagari' },
];
// FONT PROVIDERS
/**
* Font providers
*/
@@ -95,8 +67,6 @@ export const FONT_PROVIDERS: Property<FontProvider>[] = [
{ id: 'fontshare', name: 'Fontshare', value: 'fontshare' },
];
// FILTER FACTORIES
/**
* Create a mock filter from properties
*/
@@ -139,8 +109,6 @@ export function createProvidersFilter(options?: { selected?: FontProvider[] }) {
return createFilter<FontProvider>({ properties });
}
// PRESET FILTERS
/**
* Preset mock filters - use these directly in stories
*/
@@ -216,8 +184,6 @@ export const MOCK_FILTERS_ALL_SELECTED: MockFilters = {
}),
};
// GENERIC FILTER MOCKS
/**
* Create a mock filter with generic string properties
* Useful for testing generic filter components
@@ -239,7 +205,9 @@ export function createGenericFilter(
* Preset generic filters for testing
*/
export const GENERIC_FILTERS = {
/** Small filter with 3 items */
/**
* Small filter with 3 items
*/
small: createFilter({
properties: [
{ id: 'option-1', name: 'Option 1', value: 'option-1' },
@@ -247,7 +215,9 @@ export const GENERIC_FILTERS = {
{ id: 'option-3', name: 'Option 3', value: 'option-3' },
],
}),
/** Medium filter with 6 items */
/**
* Medium filter with 6 items
*/
medium: createFilter({
properties: [
{ id: 'alpha', name: 'Alpha', value: 'alpha' },
@@ -258,7 +228,9 @@ export const GENERIC_FILTERS = {
{ id: 'zeta', name: 'Zeta', value: 'zeta' },
],
}),
/** Large filter with 12 items */
/**
* Large filter with 12 items
*/
large: createFilter({
properties: [
{ id: 'jan', name: 'January', value: 'jan' },
@@ -275,7 +247,9 @@ export const GENERIC_FILTERS = {
{ id: 'dec', name: 'December', value: 'dec' },
],
}),
/** Filter with some pre-selected items */
/**
* Filter with some pre-selected items
*/
partial: createFilter({
properties: [
{ id: 'red', name: 'Red', value: 'red', selected: true },
@@ -284,7 +258,9 @@ export const GENERIC_FILTERS = {
{ id: 'yellow', name: 'Yellow', value: 'yellow', selected: false },
],
}),
/** Filter with all items selected */
/**
* Filter with all items selected
*/
allSelected: createFilter({
properties: [
{ id: 'cat', name: 'Cat', value: 'cat', selected: true },
@@ -292,7 +268,9 @@ export const GENERIC_FILTERS = {
{ id: 'bird', name: 'Bird', value: 'bird', selected: true },
],
}),
/** Empty filter (no items) */
/**
* Empty filter (no items)
*/
empty: createFilter({
properties: [],
}),
+27 -9
View File
@@ -51,23 +51,41 @@ import type {
* Options for creating a mock UnifiedFont
*/
export interface MockUnifiedFontOptions {
/** Unique identifier (default: derived from name) */
/**
* Unique identifier (default: derived from name)
*/
id?: string;
/** Font display name (default: 'Mock Font') */
/**
* Font display name (default: 'Mock Font')
*/
name?: string;
/** Font provider (default: 'google') */
/**
* Font provider (default: 'google')
*/
provider?: FontProvider;
/** Font category (default: 'sans-serif') */
/**
* Font category (default: 'sans-serif')
*/
category?: FontCategory;
/** Font subsets (default: ['latin']) */
/**
* Font subsets (default: ['latin'])
*/
subsets?: FontSubset[];
/** Font variants (default: ['regular', '700', 'italic', '700italic']) */
/**
* Font variants (default: ['regular', '700', 'italic', '700italic'])
*/
variants?: FontVariant[];
/** Style URLs (if not provided, mock URLs are generated) */
/**
* Style URLs (if not provided, mock URLs are generated)
*/
styles?: FontStyleUrls;
/** Metadata overrides */
/**
* Metadata overrides
*/
metadata?: Partial<FontMetadata>;
/** Features overrides */
/**
* Features overrides
*/
features?: Partial<FontFeatures>;
}
+311 -39
View File
@@ -1,8 +1,4 @@
/**
* ============================================================================
* MOCK FONT STORE HELPERS
* ============================================================================
*
* Factory functions and preset mock data for TanStack Query stores and state management.
* Used in Storybook stories for components that use reactive stores.
*
@@ -35,27 +31,73 @@ import {
generateMockFonts,
} from './fonts.mock';
// TANSTACK QUERY MOCK TYPES
/**
* Mock TanStack Query state
*/
export interface MockQueryState<TData = unknown, TError = Error> {
/**
* Primary query status (pending, success, error)
*/
status: QueryStatus;
/**
* Payload data (present on success)
*/
data?: TData;
/**
* Caught error object (present on error)
*/
error?: TError;
/**
* True if initial load is in progress
*/
isLoading?: boolean;
/**
* True if background fetch is in progress
*/
isFetching?: boolean;
/**
* True if query resolved successfully
*/
isSuccess?: boolean;
/**
* True if query failed
*/
isError?: boolean;
/**
* True if query is waiting to be executed
*/
isPending?: boolean;
/**
* Timestamp of last successful data retrieval
*/
dataUpdatedAt?: number;
/**
* Timestamp of last recorded error
*/
errorUpdatedAt?: number;
/**
* Total number of consecutive failures
*/
failureCount?: number;
/**
* Detailed reason for the last failure
*/
failureReason?: TError;
/**
* Number of times an error has been caught
*/
errorUpdateCount?: number;
/**
* True if currently refetching in background
*/
isRefetching?: boolean;
/**
* True if refetch attempt failed
*/
isRefetchError?: boolean;
/**
* True if query is paused (e.g. offline)
*/
isPaused?: boolean;
}
@@ -63,26 +105,72 @@ export interface MockQueryState<TData = unknown, TError = Error> {
* Mock TanStack Query observer result
*/
export interface MockQueryObserverResult<TData = unknown, TError = Error> {
/**
* Current observer status
*/
status?: QueryStatus;
/**
* Cached or active data payload
*/
data?: TData;
/**
* Caught error from the observer
*/
error?: TError;
/**
* Loading flag for the observer
*/
isLoading?: boolean;
/**
* Fetching flag for the observer
*/
isFetching?: boolean;
/**
* Success flag for the observer
*/
isSuccess?: boolean;
/**
* Error flag for the observer
*/
isError?: boolean;
/**
* Pending flag for the observer
*/
isPending?: boolean;
/**
* Last update time for data
*/
dataUpdatedAt?: number;
/**
* Last update time for error
*/
errorUpdatedAt?: number;
/**
* Consecutive failure count
*/
failureCount?: number;
/**
* Failure reason object
*/
failureReason?: TError;
/**
* Error count for the observer
*/
errorUpdateCount?: number;
/**
* Refetching flag
*/
isRefetching?: boolean;
/**
* Refetch error flag
*/
isRefetchError?: boolean;
/**
* Paused flag
*/
isPaused?: boolean;
}
// TANSTACK QUERY MOCK FACTORIES
/**
* Create a mock query state for TanStack Query
*/
@@ -138,33 +226,53 @@ export function createSuccessState<TData>(data: TData): MockQueryObserverResult<
return createMockQueryState<TData>({ status: 'success', data, error: undefined });
}
// FONT STORE MOCKS
/**
* Mock UnifiedFontStore state
*/
export interface MockFontStoreState {
/** All cached fonts */
/**
* Map of mock fonts indexed by ID
*/
fonts: Record<string, UnifiedFont>;
/** Current page */
/**
* Currently active page number
*/
page: number;
/** Total pages available */
/**
* Total number of pages calculated from limit
*/
totalPages: number;
/** Items per page */
/**
* Number of items per page
*/
limit: number;
/** Total font count */
/**
* Total number of available fonts
*/
total: number;
/** Loading state */
/**
* Store-level loading status
*/
isLoading: boolean;
/** Error state */
/**
* Caught error object
*/
error: Error | null;
/** Search query */
/**
* Mock search filter string
*/
searchQuery: string;
/** Selected provider */
/**
* Mock provider filter selection
*/
provider: 'google' | 'fontshare' | 'all';
/** Selected category */
/**
* Mock category filter selection
*/
category: string | null;
/** Selected subset */
/**
* Mock subset filter selection
*/
subset: string | null;
}
@@ -210,10 +318,12 @@ export function createMockFontStoreState(
}
/**
* Preset font store states
* Preset font store states for UI testing
*/
export const MOCK_FONT_STORE_STATES = {
/** Initial loading state */
/**
* Initial loading state with no data
*/
loading: createMockFontStoreState({
isLoading: true,
fonts: {},
@@ -221,7 +331,9 @@ export const MOCK_FONT_STORE_STATES = {
page: 1,
}),
/** Empty state (no fonts found) */
/**
* State with no fonts matching filters
*/
empty: createMockFontStoreState({
fonts: {},
total: 0,
@@ -229,7 +341,9 @@ export const MOCK_FONT_STORE_STATES = {
isLoading: false,
}),
/** First page with fonts */
/**
* First page of results (10 items)
*/
firstPage: createMockFontStoreState({
fonts: Object.fromEntries(
Object.values(UNIFIED_FONTS).slice(0, 10).map(font => [font.id, font]),
@@ -241,7 +355,9 @@ export const MOCK_FONT_STORE_STATES = {
isLoading: false,
}),
/** Second page with fonts */
/**
* Second page of results (10 items)
*/
secondPage: createMockFontStoreState({
fonts: Object.fromEntries(
Object.values(UNIFIED_FONTS).slice(10, 20).map(font => [font.id, font]),
@@ -253,7 +369,9 @@ export const MOCK_FONT_STORE_STATES = {
isLoading: false,
}),
/** Last page with fonts */
/**
* Final page of results (5 items)
*/
lastPage: createMockFontStoreState({
fonts: Object.fromEntries(
Object.values(UNIFIED_FONTS).slice(0, 5).map(font => [font.id, font]),
@@ -265,7 +383,9 @@ export const MOCK_FONT_STORE_STATES = {
isLoading: false,
}),
/** Error state */
/**
* Terminal failure state
*/
error: createMockFontStoreState({
fonts: {},
error: new Error('Failed to load fonts'),
@@ -274,7 +394,9 @@ export const MOCK_FONT_STORE_STATES = {
isLoading: false,
}),
/** With search query */
/**
* State with active search query
*/
withSearch: createMockFontStoreState({
fonts: Object.fromEntries(
Object.values(UNIFIED_FONTS).slice(0, 3).map(font => [font.id, font]),
@@ -285,7 +407,9 @@ export const MOCK_FONT_STORE_STATES = {
searchQuery: 'Roboto',
}),
/** Filtered by category */
/**
* State with active category filter
*/
filteredByCategory: createMockFontStoreState({
fonts: Object.fromEntries(
Object.values(UNIFIED_FONTS)
@@ -299,7 +423,9 @@ export const MOCK_FONT_STORE_STATES = {
category: 'serif',
}),
/** Filtered by provider */
/**
* State with active provider filter
*/
filteredByProvider: createMockFontStoreState({
fonts: Object.fromEntries(
Object.values(UNIFIED_FONTS)
@@ -313,7 +439,9 @@ export const MOCK_FONT_STORE_STATES = {
provider: 'google',
}),
/** Large dataset */
/**
* Large collection for performance testing (50 items)
*/
largeDataset: createMockFontStoreState({
fonts: Object.fromEntries(
generateMockFonts(50).map(font => [font.id, font]),
@@ -326,17 +454,30 @@ export const MOCK_FONT_STORE_STATES = {
}),
};
// MOCK STORE OBJECT
/**
* Create a mock store object that mimics TanStack Query behavior
* Useful for components that subscribe to store properties
*/
export function createMockStore<T>(config: {
/**
* Reactive data payload
*/
data?: T;
/**
* Loading status flag
*/
isLoading?: boolean;
/**
* Error status flag
*/
isError?: boolean;
/**
* Catch-all error object
*/
error?: Error;
/**
* Background fetching flag
*/
isFetching?: boolean;
}) {
const {
@@ -348,24 +489,45 @@ export function createMockStore<T>(config: {
} = config;
return {
/**
* Returns the active data payload
*/
get data() {
return data;
},
/**
* True if initially loading
*/
get isLoading() {
return isLoading;
},
/**
* True if last request failed
*/
get isError() {
return isError;
},
/**
* Returns the caught error object
*/
get error() {
return error;
},
/**
* True if fetching in background
*/
get isFetching() {
return isFetching;
},
/**
* True if query is stable and has data
*/
get isSuccess() {
return !isLoading && !isError && data !== undefined;
},
/**
* Returns semantic status string
*/
get status() {
if (isLoading) return 'pending';
if (isError) return 'error';
@@ -375,23 +537,29 @@ export function createMockStore<T>(config: {
}
/**
* Preset mock stores
* Preset mock stores for common UI states
*/
export const MOCK_STORES = {
/** Font store in loading state */
/**
* Initial loading state
*/
loadingFontStore: createMockStore<UnifiedFont[]>({
isLoading: true,
data: undefined,
}),
/** Font store with fonts loaded */
/**
* Successful data load state
*/
successFontStore: createMockStore<UnifiedFont[]>({
data: Object.values(UNIFIED_FONTS),
isLoading: false,
isError: false,
}),
/** Font store with error */
/**
* API error state
*/
errorFontStore: createMockStore<UnifiedFont[]>({
data: undefined,
isLoading: false,
@@ -399,7 +567,9 @@ export const MOCK_STORES = {
error: new Error('Failed to load fonts'),
}),
/** Font store with empty results */
/**
* Empty result set state
*/
emptyFontStore: createMockStore<UnifiedFont[]>({
data: [],
isLoading: false,
@@ -414,36 +584,69 @@ export const MOCK_STORES = {
const mockState = createMockFontStoreState(state);
return {
// State properties
/**
* Collection of mock fonts
*/
get fonts() {
return mockState.fonts;
},
/**
* Current mock page
*/
get page() {
return mockState.page;
},
/**
* Total mock pages
*/
get totalPages() {
return mockState.totalPages;
},
/**
* Mock items per page
*/
get limit() {
return mockState.limit;
},
/**
* Total mock items
*/
get total() {
return mockState.total;
},
/**
* Mock loading status
*/
get isLoading() {
return mockState.isLoading;
},
/**
* Mock error status
*/
get error() {
return mockState.error;
},
/**
* Mock search string
*/
get searchQuery() {
return mockState.searchQuery;
},
/**
* Mock provider filter
*/
get provider() {
return mockState.provider;
},
/**
* Mock category filter
*/
get category() {
return mockState.category;
},
/**
* Mock subset filter
*/
get subset() {
return mockState.subset;
},
@@ -464,15 +667,45 @@ export const MOCK_STORES = {
* Matches FontStore's public API for Storybook use
*/
fontStore: (config: {
/**
* Preset font list
*/
fonts?: UnifiedFont[];
/**
* Total item count
*/
total?: number;
/**
* Items per page
*/
limit?: number;
/**
* Pagination offset
*/
offset?: number;
/**
* Loading flag
*/
isLoading?: boolean;
/**
* Fetching flag
*/
isFetching?: boolean;
/**
* Error flag
*/
isError?: boolean;
/**
* Catch-all error object
*/
error?: Error | null;
/**
* Has more pages flag
*/
hasMore?: boolean;
/**
* Current page number
*/
page?: number;
} = {}) => {
const {
@@ -495,27 +728,51 @@ export const MOCK_STORES = {
return {
// State getters
/**
* Current mock parameters
*/
get params() {
return state.params;
},
/**
* Mock font list
*/
get fonts() {
return mockFonts;
},
/**
* Mock loading state
*/
get isLoading() {
return isLoading;
},
/**
* Mock fetching state
*/
get isFetching() {
return isFetching;
},
/**
* Mock error state
*/
get isError() {
return isError;
},
/**
* Mock error object
*/
get error() {
return error;
},
/**
* Mock empty state check
*/
get isEmpty() {
return !isLoading && !isFetching && mockFonts.length === 0;
},
/**
* Mock pagination metadata
*/
get pagination() {
return {
total: mockTotal,
@@ -527,18 +784,33 @@ export const MOCK_STORES = {
};
},
// Category getters
/**
* Derived sans-serif filter
*/
get sansSerifFonts() {
return mockFonts.filter(f => f.category === 'sans-serif');
},
/**
* Derived serif filter
*/
get serifFonts() {
return mockFonts.filter(f => f.category === 'serif');
},
/**
* Derived display filter
*/
get displayFonts() {
return mockFonts.filter(f => f.category === 'display');
},
/**
* Derived handwriting filter
*/
get handwritingFonts() {
return mockFonts.filter(f => f.category === 'handwriting');
},
/**
* Derived monospace filter
*/
get monospaceFonts() {
return mockFonts.filter(f => f.category === 'monospace');
},
@@ -13,15 +13,25 @@ import type {
* (e.g. `SvelteMap.get()`) is automatically tracked as a dependency.
*/
export interface FontRowSizeResolverOptions {
/** Returns the current fonts array. Index `i` corresponds to row `i`. */
/**
* Returns the current fonts array. Index `i` corresponds to row `i`.
*/
getFonts: () => UnifiedFont[];
/** Returns the active font weight (e.g. 400). */
/**
* Returns the active font weight (e.g. 400).
*/
getWeight: () => number;
/** Returns the preview text string. */
/**
* Returns the preview text string.
*/
getPreviewText: () => string;
/** Returns the scroll container's inner width in pixels. Returns 0 before mount. */
/**
* Returns the scroll container's inner width in pixels. Returns 0 before mount.
*/
getContainerWidth: () => number;
/** Returns the font size in pixels (e.g. `controlManager.renderedSize`). */
/**
* Returns the font size in pixels (e.g. `controlManager.renderedSize`).
*/
getFontSizePx: () => number;
/**
* Returns the computed line height in pixels.
@@ -44,9 +54,13 @@ export interface FontRowSizeResolverOptions {
* the content width is never over-estimated, keeping the height estimate safe.
*/
contentHorizontalPadding: number;
/** Fixed height in pixels of chrome that is not text content (header bar, etc.). */
/**
* Fixed height in pixels of chrome that is not text content (header bar, etc.).
*/
chromeHeight: number;
/** Height in pixels to return when the font is not loaded or container width is 0. */
/**
* Height in pixels to return when the font is not loaded or container width is 0.
*/
fallbackHeight: number;
}