doc: comments for codebase and updated documentation
This commit is contained in:
@@ -2,6 +2,13 @@ import { SvelteMap } from 'svelte/reactivity';
|
|||||||
|
|
||||||
export type FontStatus = 'loading' | 'loaded' | 'error';
|
export type FontStatus = 'loading' | 'loaded' | 'error';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manager that handles loading of the fonts
|
||||||
|
* Adds <link /> tags to <head />
|
||||||
|
* - Uses batch loading to reduce the number of requests
|
||||||
|
* - Uses a queue to prevent too many requests at once
|
||||||
|
* - Purges unused fonts after a certain time
|
||||||
|
*/
|
||||||
class AppliedFontsManager {
|
class AppliedFontsManager {
|
||||||
// Stores: slug -> timestamp of last visibility
|
// Stores: slug -> timestamp of last visibility
|
||||||
#usageTracker = new Map<string, number>();
|
#usageTracker = new Map<string, number>();
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
import { createEntityStore } from '$shared/lib';
|
import { createEntityStore } from '$shared/lib';
|
||||||
import type { UnifiedFont } from '../../types';
|
import type { UnifiedFont } from '../../types';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store that handles collection of selected fonts
|
||||||
|
*/
|
||||||
export const selectedFontsStore = createEntityStore<UnifiedFont>([]);
|
export const selectedFontsStore = createEntityStore<UnifiedFont>([]);
|
||||||
|
|||||||
@@ -1,19 +1,31 @@
|
|||||||
<!--
|
<!--
|
||||||
Component: FontApplicator
|
Component: FontApplicator
|
||||||
|
|
||||||
Loads fonts from fontshare with link tag
|
Loads fonts from fontshare with link tag
|
||||||
|
- Loads font only if it's not already applied
|
||||||
|
- Uses IntersectionObserver to detect when font is visible
|
||||||
|
- Adds smooth transition when font is loaded
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {
|
|
||||||
appliedFontsManager,
|
|
||||||
} from '$entities/Font/model/store/appliedFontsStore/appliedFontsStore.svelte';
|
|
||||||
import { cn } from '$shared/shadcn/utils/shadcn-utils';
|
import { cn } from '$shared/shadcn/utils/shadcn-utils';
|
||||||
import type { Snippet } from 'svelte';
|
import type { Snippet } from 'svelte';
|
||||||
|
import { appliedFontsManager } from '../../model';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
/**
|
||||||
|
* Font name to set
|
||||||
|
*/
|
||||||
name: string;
|
name: string;
|
||||||
|
/**
|
||||||
|
* Font id to load
|
||||||
|
*/
|
||||||
id: string;
|
id: string;
|
||||||
|
/**
|
||||||
|
* Additional classes
|
||||||
|
*/
|
||||||
className?: string;
|
className?: string;
|
||||||
|
/**
|
||||||
|
* Children
|
||||||
|
*/
|
||||||
children?: Snippet;
|
children?: Snippet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ import {
|
|||||||
import FontApplicator from '../FontApplicator/FontApplicator.svelte';
|
import FontApplicator from '../FontApplicator/FontApplicator.svelte';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
/**
|
||||||
|
* Object with information about font
|
||||||
|
*/
|
||||||
font: UnifiedFont;
|
font: UnifiedFont;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
|
<!--
|
||||||
|
Component: FontVirtualList
|
||||||
|
- Renders a virtualized list of fonts
|
||||||
|
- Handles font registration with the manager
|
||||||
|
-->
|
||||||
<script lang="ts" generics="T extends { id: string }">
|
<script lang="ts" generics="T extends { id: string }">
|
||||||
import { VirtualList } from '$shared/ui';
|
import { VirtualList } from '$shared/ui';
|
||||||
import type { ComponentProps } from 'svelte';
|
import type { ComponentProps } from 'svelte';
|
||||||
import { appliedFontsManager } from '../../model/store/appliedFontsStore/appliedFontsStore.svelte';
|
import { appliedFontsManager } from '../../model';
|
||||||
|
|
||||||
interface Props extends Omit<ComponentProps<typeof VirtualList<T>>, 'onVisibleItemsChange'> {
|
interface Props extends Omit<ComponentProps<typeof VirtualList<T>>, 'onVisibleItemsChange'> {
|
||||||
onVisibleItemsChange?: (items: T[]) => void;
|
onVisibleItemsChange?: (items: T[]) => void;
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import { selectedFontsStore } from '$entities/Font';
|
import { selectedFontsStore } from '$entities/Font';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store for displayed font samples
|
||||||
|
* - Handles shown text
|
||||||
|
* - Stores selected fonts for display
|
||||||
|
*/
|
||||||
export class DisplayedFontsStore {
|
export class DisplayedFontsStore {
|
||||||
#sampleText = $state('The quick brown fox jumps over the lazy dog');
|
#sampleText = $state('The quick brown fox jumps over the lazy dog');
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,17 @@ import {
|
|||||||
import { ContentEditable } from '$shared/ui';
|
import { ContentEditable } from '$shared/ui';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
/**
|
||||||
|
* Font info
|
||||||
|
*/
|
||||||
font: UnifiedFont;
|
font: UnifiedFont;
|
||||||
|
/**
|
||||||
|
* Text to display
|
||||||
|
*/
|
||||||
text: string;
|
text: string;
|
||||||
|
/**
|
||||||
|
* Font settings
|
||||||
|
*/
|
||||||
fontSize?: number;
|
fontSize?: number;
|
||||||
lineHeight?: number;
|
lineHeight?: number;
|
||||||
letterSpacing?: number;
|
letterSpacing?: number;
|
||||||
|
|||||||
@@ -4,6 +4,11 @@ import type { FilterConfig } from '../../model';
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a filter manager instance.
|
* Create a filter manager instance.
|
||||||
|
* - Uses debounce to update search query for better performance.
|
||||||
|
* - Manages filter instances for each group.
|
||||||
|
*
|
||||||
|
* @param config - Configuration for the filter manager.
|
||||||
|
* @returns - An instance of the filter manager.
|
||||||
*/
|
*/
|
||||||
export function createFilterManager<TValue extends string>(config: FilterConfig<TValue>) {
|
export function createFilterManager<TValue extends string>(config: FilterConfig<TValue>) {
|
||||||
const search = createDebouncedState(config.queryValue ?? '');
|
const search = createDebouncedState(config.queryValue ?? '');
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
import type { FontshareParams } from '$entities/Font';
|
import type { FontshareParams } from '$entities/Font';
|
||||||
import type { FilterManager } from '../filterManager/filterManager.svelte';
|
import type { FilterManager } from '../filterManager/filterManager.svelte';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps filter manager to fontshare params.
|
||||||
|
*
|
||||||
|
* @param manager - Filter manager instance.
|
||||||
|
* @returns - Partial fontshare params.
|
||||||
|
*/
|
||||||
export function mapManagerToParams(manager: FilterManager): Partial<FontshareParams> {
|
export function mapManagerToParams(manager: FilterManager): Partial<FontshareParams> {
|
||||||
return {
|
return {
|
||||||
q: manager.debouncedQueryValue,
|
q: manager.debouncedQueryValue,
|
||||||
|
|||||||
@@ -1,18 +1,8 @@
|
|||||||
|
<!--
|
||||||
|
Component: Filters
|
||||||
|
Renders a list of CheckboxFilter components for each filter group.
|
||||||
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
/**
|
|
||||||
* Filters Component
|
|
||||||
*
|
|
||||||
* Orchestrates all filter properties for the sidebar. Connects filter stores
|
|
||||||
* to CheckboxFilter components, organizing them by filter type:
|
|
||||||
*
|
|
||||||
* - Font provider: Google Fonts vs Fontshare
|
|
||||||
* - Font subset: Character subsets available (Latin, Latin Extended, etc.)
|
|
||||||
* - Font category: Serif, Sans-serif, Display, etc.
|
|
||||||
*
|
|
||||||
* This component handles reactive sync between filterManager selections
|
|
||||||
* and the unifiedFontStore using an $effect block to ensure filters are
|
|
||||||
* automatically synchronized whenever selections change.
|
|
||||||
*/
|
|
||||||
import { CheckboxFilter } from '$shared/ui';
|
import { CheckboxFilter } from '$shared/ui';
|
||||||
import { filterManager } from '../../model';
|
import { filterManager } from '../../model';
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
|
<!--
|
||||||
|
Component: FiltersControl
|
||||||
|
Renders a group of action buttons for filter operations.
|
||||||
|
- Reset: Clears all active filters (outline variant for secondary action)
|
||||||
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Button } from '$shared/shadcn/ui/button';
|
import { Button } from '$shared/shadcn/ui/button';
|
||||||
import { filterManager } from '../../model';
|
import { filterManager } from '../../model';
|
||||||
|
|
||||||
/**
|
|
||||||
* Controls Component
|
|
||||||
*
|
|
||||||
* Action button group for filter operations. Provides two buttons:
|
|
||||||
*
|
|
||||||
* - Reset: Clears all active filters (outline variant for secondary action)
|
|
||||||
*/
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex flex-row gap-2">
|
<div class="flex flex-row gap-2">
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
<!--
|
||||||
|
Component: SuggestedFonts
|
||||||
|
Renders a list of suggested fonts in a virtualized list to improve performance.
|
||||||
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {
|
import {
|
||||||
FontListItem,
|
FontListItem,
|
||||||
|
|||||||
@@ -3,6 +3,12 @@ import {
|
|||||||
createTypographyControl,
|
createTypographyControl,
|
||||||
} from '$shared/lib';
|
} from '$shared/lib';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a typography control manager that handles a collection of typography controls.
|
||||||
|
*
|
||||||
|
* @param configs - Array of control configurations.
|
||||||
|
* @returns - Typography control manager instance.
|
||||||
|
*/
|
||||||
export function createTypographyControlManager(configs: ControlModel[]) {
|
export function createTypographyControlManager(configs: ControlModel[]) {
|
||||||
const controls = $state(
|
const controls = $state(
|
||||||
configs.map(({ id, increaseLabel, decreaseLabel, controlLabel, ...config }) => ({
|
configs.map(({ id, increaseLabel, decreaseLabel, controlLabel, ...config }) => ({
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
|
<!--
|
||||||
|
Component: SetupFontMenu
|
||||||
|
Contains controls for setting up font properties.
|
||||||
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
/**
|
|
||||||
* Component containing controls for setting up font properties.
|
|
||||||
*/
|
|
||||||
import { Separator } from '$shared/shadcn/ui/separator/index';
|
import { Separator } from '$shared/shadcn/ui/separator/index';
|
||||||
import { Trigger as SidebarTrigger } from '$shared/shadcn/ui/sidebar';
|
import { Trigger as SidebarTrigger } from '$shared/shadcn/ui/sidebar';
|
||||||
import { ComboControl } from '$shared/ui';
|
import { ComboControl } from '$shared/ui';
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// Check if we are in a browser environment
|
// Check if we are in a browser environment
|
||||||
const isBrowser = typeof window !== 'undefined';
|
const isBrowser = typeof window !== 'undefined';
|
||||||
|
|
||||||
|
// A class to manage motion preference and provide a single instance for use everywhere
|
||||||
class MotionPreference {
|
class MotionPreference {
|
||||||
// Reactive state
|
// Reactive state
|
||||||
#reduced = $state(false);
|
#reduced = $state(false);
|
||||||
|
|||||||
@@ -75,6 +75,11 @@ export class EntityStore<T extends Entity> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new EntityStore instance with the given initial entities.
|
||||||
|
* @param initialEntities The initial entities to populate the store with.
|
||||||
|
* @returns - A new EntityStore instance.
|
||||||
|
*/
|
||||||
export function createEntityStore<T extends Entity>(initialEntities: T[] = []) {
|
export function createEntityStore<T extends Entity>(initialEntities: T[] = []) {
|
||||||
return new EntityStore<T>(initialEntities);
|
return new EntityStore<T>(initialEntities);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* Splits an array into two arrays based on a callback function.
|
||||||
|
* @param array The array to split.
|
||||||
|
* @param callback The callback function to determine which array to push each item to.
|
||||||
|
* @returns - An array containing two arrays, the first array contains items that passed the callback, the second array contains items that failed the callback.
|
||||||
|
*/
|
||||||
export function splitArray<T>(array: T[], callback: (item: T) => boolean) {
|
export function splitArray<T>(array: T[], callback: (item: T) => boolean) {
|
||||||
return array.reduce<[T[], T[]]>(
|
return array.reduce<[T[], T[]]>(
|
||||||
([pass, fail], item) => (
|
([pass, fail], item) => (
|
||||||
|
|||||||
@@ -1,3 +1,12 @@
|
|||||||
|
<!--
|
||||||
|
Component: CheckboxFilter
|
||||||
|
A collapsible property filter with checkboxes. Displate selected count as a badge
|
||||||
|
and supports reduced motion for accessibility.
|
||||||
|
- Open by default for immediate visibility and interaction
|
||||||
|
- Badge shown only when filters are active to reduce visual noise
|
||||||
|
- Transitions use cubicOut for natural deceleration
|
||||||
|
- Local transition prevents animation when component first renders
|
||||||
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Filter } from '$shared/lib';
|
import type { Filter } from '$shared/lib';
|
||||||
import { motion } from '$shared/lib';
|
import { motion } from '$shared/lib';
|
||||||
@@ -10,23 +19,9 @@ import {
|
|||||||
} from '$shared/shadcn/ui/collapsible';
|
} from '$shared/shadcn/ui/collapsible';
|
||||||
import { Label } from '$shared/shadcn/ui/label';
|
import { Label } from '$shared/shadcn/ui/label';
|
||||||
import ChevronDownIcon from '@lucide/svelte/icons/chevron-down';
|
import ChevronDownIcon from '@lucide/svelte/icons/chevron-down';
|
||||||
import { onMount } from 'svelte';
|
|
||||||
import { cubicOut } from 'svelte/easing';
|
import { cubicOut } from 'svelte/easing';
|
||||||
import { slide } from 'svelte/transition';
|
import { slide } from 'svelte/transition';
|
||||||
|
|
||||||
/**
|
|
||||||
* CheckboxFilter Component
|
|
||||||
*
|
|
||||||
* A collapsible property filter with checkboxes. Displays selected count as a badge
|
|
||||||
* and supports reduced motion for accessibility. Used in sidebar filtering UIs.
|
|
||||||
*
|
|
||||||
* Design choices:
|
|
||||||
* - Open by default for immediate visibility and interaction
|
|
||||||
* - Badge shown only when filters are active to reduce visual noise
|
|
||||||
* - Transitions use cubicOut for natural deceleration
|
|
||||||
* - Local transition prevents animation when component first renders
|
|
||||||
*/
|
|
||||||
|
|
||||||
interface PropertyFilterProps {
|
interface PropertyFilterProps {
|
||||||
/** Label for this filter group (e.g., "Properties", "Tags") */
|
/** Label for this filter group (e.g., "Properties", "Tags") */
|
||||||
displayedLabel: string;
|
displayedLabel: string;
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
|
<!--
|
||||||
|
Component: ComboControl
|
||||||
|
Provides multiple ways to change certain value
|
||||||
|
- via Increase/Decrease buttons
|
||||||
|
- via Slider
|
||||||
|
- via Input
|
||||||
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { TypographyControl } from '$shared/lib';
|
import type { TypographyControl } from '$shared/lib';
|
||||||
import { Button } from '$shared/shadcn/ui/button';
|
import { Button } from '$shared/shadcn/ui/button';
|
||||||
|
|||||||
Reference in New Issue
Block a user