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

View File

@@ -41,10 +41,14 @@ export class ApiError extends Error {
* @param response - Original fetch Response object
*/
constructor(
/** HTTP status code */
/**
* HTTP status code
*/
public status: number,
message: string,
/** Original Response object for inspection */
/**
* Original Response object for inspection
*/
public response?: Response,
) {
super(message);

View File

@@ -15,15 +15,25 @@ import { QueryClient } from '@tanstack/query-core';
export const queryClient = new QueryClient({
defaultOptions: {
queries: {
/** Data remains fresh for 5 minutes after fetch */
/**
* Data remains fresh for 5 minutes after fetch
*/
staleTime: 5 * 60 * 1000,
/** Unused cache entries are removed after 10 minutes */
/**
* Unused cache entries are removed after 10 minutes
*/
gcTime: 10 * 60 * 1000,
/** Don't refetch when window regains focus */
/**
* Don't refetch when window regains focus
*/
refetchOnWindowFocus: false,
/** Refetch on mount if data is stale */
/**
* Refetch on mount if data is stale
*/
refetchOnMount: true,
/** Retry failed requests up to 3 times */
/**
* Retry failed requests up to 3 times
*/
retry: 3,
/**
* Exponential backoff for retries

View File

@@ -3,21 +3,35 @@
* Ensures consistent serialization for batch requests by sorting IDs.
*/
export const fontKeys = {
/** Base key for all font queries */
/**
* Base key for all font queries
*/
all: ['fonts'] as const,
/** Keys for font list queries */
/**
* Keys for font list queries
*/
lists: () => [...fontKeys.all, 'list'] as const,
/** Specific font list key with filter parameters */
/**
* Specific font list key with filter parameters
*/
list: (params: object) => [...fontKeys.lists(), params] as const,
/** Keys for font batch queries */
/**
* Keys for font batch queries
*/
batches: () => [...fontKeys.all, 'batch'] as const,
/** Specific batch key, sorted for stability */
/**
* Specific batch key, sorted for stability
*/
batch: (ids: string[]) => [...fontKeys.batches(), [...ids].sort()] as const,
/** Keys for font detail queries */
/**
* Keys for font detail queries
*/
details: () => [...fontKeys.all, 'detail'] as const,
/** Specific font detail key by ID */
/**
* Specific font detail key by ID
*/
detail: (id: string) => [...fontKeys.details(), id] as const,
} as const;

View File

@@ -12,20 +12,37 @@ import {
* each font's actual advance widths independently.
*/
export interface ComparisonLine {
/** Full text of this line as returned by pretext. */
/**
* Full text of this line as returned by pretext.
*/
text: string;
/** Rendered width of this line in pixels — maximum across font A and font B. */
/**
* Rendered width of this line in pixels — maximum across font A and font B.
*/
width: number;
/**
* Individual character metadata for both fonts in this line
*/
chars: Array<{
/** The grapheme cluster string (may be >1 code unit for emoji, etc.). */
/**
* The grapheme cluster string (may be >1 code unit for emoji, etc.).
*/
char: string;
/** X offset from the start of the line in font A, in pixels. */
/**
* X offset from the start of the line in font A, in pixels.
*/
xA: number;
/** Advance width of this grapheme in font A, in pixels. */
/**
* Advance width of this grapheme in font A, in pixels.
*/
widthA: number;
/** X offset from the start of the line in font B, in pixels. */
/**
* X offset from the start of the line in font B, in pixels.
*/
xB: number;
/** Advance width of this grapheme in font B, in pixels. */
/**
* Advance width of this grapheme in font B, in pixels.
*/
widthB: number;
}>;
}
@@ -34,9 +51,13 @@ export interface ComparisonLine {
* Aggregated output of a dual-font layout pass.
*/
export interface ComparisonResult {
/** Per-line grapheme data for both fonts. Empty when input text is empty. */
/**
* Per-line grapheme data for both fonts. Empty when input text is empty.
*/
lines: ComparisonLine[];
/** Total height in pixels. Equals `lines.length * lineHeight` (pretext guarantee). */
/**
* Total height in pixels. Equals `lines.length * lineHeight` (pretext guarantee).
*/
totalHeight: number;
}

View File

@@ -28,8 +28,6 @@ describe('CharacterComparisonEngine', () => {
engine = new CharacterComparisonEngine();
});
// --- layout() ---
it('returns empty result for empty string', () => {
const result = engine.layout('', '400 16px "FontA"', '400 16px "FontB"', 500, 20);
expect(result.lines).toHaveLength(0);
@@ -111,8 +109,6 @@ describe('CharacterComparisonEngine', () => {
expect(r2).not.toBe(r1);
});
// --- getCharState() ---
it('getCharState returns proximity 1 when slider is exactly over char center', () => {
// 'A' only: FontA width=10. Container=500px. Line centered.
// lineXOffset = (500 - maxWidth) / 2. maxWidth = max(10, 15) = 15 (FontB is wider).

View File

@@ -10,16 +10,29 @@ import {
* sequences and combining characters each produce exactly one entry.
*/
export interface LayoutLine {
/** Full text of this line as returned by pretext. */
/**
* Full text of this line as returned by pretext.
*/
text: string;
/** Rendered width of this line in pixels. */
/**
* Rendered width of this line in pixels.
*/
width: number;
/**
* Individual character metadata for this line
*/
chars: Array<{
/** The grapheme cluster string (may be >1 code unit for emoji, etc.). */
/**
* The grapheme cluster string (may be >1 code unit for emoji, etc.).
*/
char: string;
/** X offset from the start of the line, in pixels. */
/**
* X offset from the start of the line, in pixels.
*/
x: number;
/** Advance width of this grapheme, in pixels. */
/**
* Advance width of this grapheme, in pixels.
*/
width: number;
}>;
}
@@ -28,9 +41,13 @@ export interface LayoutLine {
* Aggregated output of a single-font layout pass.
*/
export interface LayoutResult {
/** Per-line grapheme data. Empty when input text is empty. */
/**
* Per-line grapheme data. Empty when input text is empty.
*/
lines: LayoutLine[];
/** Total height in pixels. Equals `lines.length * lineHeight` (pretext guarantee). */
/**
* Total height in pixels. Equals `lines.length * lineHeight` (pretext guarantee).
*/
totalHeight: number;
}
@@ -65,7 +82,9 @@ export class TextLayoutEngine {
*/
#segmenter: Intl.Segmenter;
/** @param locale BCP 47 language tag passed to Intl.Segmenter. Defaults to the runtime locale. */
/**
* @param locale BCP 47 language tag passed to Intl.Segmenter. Defaults to the runtime locale.
*/
constructor(locale?: string) {
this.#segmenter = new Intl.Segmenter(locale, { granularity: 'grapheme' });
}

View File

@@ -32,7 +32,9 @@ export function createDebouncedState<T>(initialValue: T, wait: number = 300) {
}, wait);
return {
/** Current value with immediate updates (for UI binding) */
/**
* Current value with immediate updates (for UI binding)
*/
get immediate() {
return immediate;
},
@@ -41,7 +43,9 @@ export function createDebouncedState<T>(initialValue: T, wait: number = 300) {
// Manually trigger the debounce on write
updateDebounced(value);
},
/** Current value with debounced updates (for logic/operations) */
/**
* Current value with debounced updates (for logic/operations)
*/
get debounced() {
return debounced;
},

View File

@@ -28,7 +28,9 @@ import { SvelteMap } from 'svelte/reactivity';
* Base entity interface requiring an ID field
*/
export interface Entity {
/** Unique identifier for the entity */
/**
* Unique identifier for the entity
*/
id: string;
}
@@ -39,7 +41,9 @@ export interface Entity {
* triggers updates when entities are added, removed, or modified.
*/
export class EntityStore<T extends Entity> {
/** Reactive map of entities keyed by ID */
/**
* Reactive map of entities keyed by ID
*/
#entities = new SvelteMap<string, T>();
/**

View File

@@ -29,13 +29,21 @@
* @template TValue - The type of the property value (typically string)
*/
export interface Property<TValue extends string> {
/** Unique identifier for the property */
/**
* Unique string identifier for the filterable property
*/
id: string;
/** Human-readable display name */
/**
* Human-readable label for UI display
*/
name: string;
/** Underlying value for filtering logic */
/**
* Underlying machine-readable value used for filtering logic
*/
value: TValue;
/** Whether the property is currently selected */
/**
* Current selection status (reactive)
*/
selected?: boolean;
}
@@ -45,7 +53,9 @@ export interface Property<TValue extends string> {
* @template TValue - The type of property values
*/
export interface FilterModel<TValue extends string> {
/** Array of filterable properties */
/**
* Collection of properties that can be toggled in this filter
*/
properties: Property<TValue>[];
}

View File

@@ -1,4 +1,6 @@
/** @vitest-environment jsdom */
/**
* @vitest-environment jsdom
*/
import {
afterEach,
beforeEach,

View File

@@ -32,19 +32,33 @@ import { Spring } from 'svelte/motion';
* Configuration options for perspective effects
*/
export interface PerspectiveConfig {
/** Z-axis translation per level in pixels */
/**
* Z-axis translation per level in pixels
*/
depthStep?: number;
/** Scale reduction per level (0-1) */
/**
* Scale reduction per level (0-1)
*/
scaleStep?: number;
/** Blur amount per level in pixels */
/**
* Blur amount per level in pixels
*/
blurStep?: number;
/** Opacity reduction per level (0-1) */
/**
* Opacity reduction per level (0-1)
*/
opacityStep?: number;
/** Parallax movement intensity per level */
/**
* Parallax movement intensity per level
*/
parallaxIntensity?: number;
/** Horizontal offset - positive for right, negative for left */
/**
* Horizontal offset - positive for right, negative for left
*/
horizontalOffset?: number;
/** Layout mode: 'center' for centered, 'split' for side-by-side */
/**
* Layout mode: 'center' for centered, 'split' for side-by-side
*/
layoutMode?: 'center' | 'split';
}

View File

@@ -39,15 +39,25 @@
* Customize to match your design system's breakpoints.
*/
export interface Breakpoints {
/** Mobile devices - default 640px */
/**
* Mobile devices - default 640px
*/
mobile: number;
/** Tablet portrait - default 768px */
/**
* Tablet portrait - default 768px
*/
tabletPortrait: number;
/** Tablet landscape - default 1024px */
/**
* Tablet landscape - default 1024px
*/
tablet: number;
/** Desktop - default 1280px */
/**
* Desktop - default 1280px
*/
desktop: number;
/** Large desktop - default 1536px */
/**
* Large desktop - default 1536px
*/
desktopLarge: number;
}
@@ -206,66 +216,108 @@ export function createResponsiveManager(customBreakpoints?: Partial<Breakpoints>
);
return {
/** Viewport width in pixels */
/**
* Current viewport width in pixels (reactive)
*/
get width() {
return width;
},
/** Viewport height in pixels */
/**
* Current viewport height in pixels (reactive)
*/
get height() {
return height;
},
// Standard breakpoints
/**
* True if viewport width is below the mobile threshold
*/
get isMobile() {
return isMobile;
},
/**
* True if viewport width is between mobile and tablet portrait thresholds
*/
get isTabletPortrait() {
return isTabletPortrait;
},
/**
* True if viewport width is between tablet portrait and desktop thresholds
*/
get isTablet() {
return isTablet;
},
/**
* True if viewport width is between desktop and large desktop thresholds
*/
get isDesktop() {
return isDesktop;
},
/**
* True if viewport width is at or above the large desktop threshold
*/
get isDesktopLarge() {
return isDesktopLarge;
},
// Convenience groupings
/**
* True if viewport width is below the desktop threshold
*/
get isMobileOrTablet() {
return isMobileOrTablet;
},
/**
* True if viewport width is at or above the tablet portrait threshold
*/
get isTabletOrDesktop() {
return isTabletOrDesktop;
},
// Orientation
/**
* Current screen orientation (portrait | landscape)
*/
get orientation() {
return orientation;
},
/**
* True if screen height is greater than width
*/
get isPortrait() {
return isPortrait;
},
/**
* True if screen width is greater than height
*/
get isLandscape() {
return isLandscape;
},
// Device capabilities
/**
* True if the device supports touch interaction
*/
get isTouchDevice() {
return isTouchDevice;
},
// Current breakpoint
/**
* Name of the currently active breakpoint (reactive)
*/
get currentBreakpoint() {
return currentBreakpoint;
},
// Methods
/**
* Initialization function to start event listeners
*/
init,
/**
* Helper to check for custom width ranges
*/
matches,
// Breakpoint values (for custom logic)
/**
* Underlying breakpoint pixel values
*/
breakpoints,
};
}

View File

@@ -34,13 +34,21 @@ import {
* Defines the bounds and stepping behavior for a control
*/
export interface ControlDataModel {
/** Current numeric value */
/**
* Initial or current numeric value
*/
value: number;
/** Minimum allowed value (inclusive) */
/**
* Lower inclusive bound
*/
min: number;
/** Maximum allowed value (inclusive) */
/**
* Upper inclusive bound
*/
max: number;
/** Step size for increment/decrement operations */
/**
* Precision for increment/decrement operations
*/
step: number;
}
@@ -50,13 +58,21 @@ export interface ControlDataModel {
* @template T - Type for the control identifier
*/
export interface ControlModel<T extends string = string> extends ControlDataModel {
/** Unique identifier for the control */
/**
* Unique string identifier for the control
*/
id: T;
/** ARIA label for the increase button */
/**
* Label used by screen readers for the increase button
*/
increaseLabel?: string;
/** ARIA label for the decrease button */
/**
* Label used by screen readers for the decrease button
*/
decreaseLabel?: string;
/** ARIA label for the control area */
/**
* Overall label describing the control's purpose
*/
controlLabel?: string;
}
@@ -109,8 +125,7 @@ export function createTypographyControl<T extends ControlDataModel>(
return {
/**
* Current control value (getter/setter)
* Setting automatically clamps to bounds and rounds to step precision
* Clamped and rounded control value (reactive)
*/
get value() {
return value;
@@ -122,27 +137,37 @@ export function createTypographyControl<T extends ControlDataModel>(
}
},
/** Maximum allowed value */
/**
* Upper limit for the control value
*/
get max() {
return max;
},
/** Minimum allowed value */
/**
* Lower limit for the control value
*/
get min() {
return min;
},
/** Step increment size */
/**
* Configured step increment
*/
get step() {
return step;
},
/** Whether the value is at or exceeds the maximum */
/**
* True if current value is equal to or greater than max
*/
get isAtMax() {
return isAtMax;
},
/** Whether the value is at or below the minimum */
/**
* True if current value is equal to or less than min
*/
get isAtMin() {
return isAtMin;
},

View File

@@ -45,7 +45,9 @@ export interface VirtualItem {
* Options are reactive - pass them through a function getter to enable updates.
*/
export interface VirtualizerOptions {
/** Total number of items in the data array */
/**
* Total number of items in the underlying data array
*/
count: number;
/**
* Function to estimate the size of an item at a given index.
@@ -60,7 +62,10 @@ export interface VirtualizerOptions {
* as fonts finish loading, eliminating the DOM-measurement snap on load.
*/
estimateSize: (index: number) => number;
/** Number of extra items to render outside viewport for smoother scrolling (default: 5) */
/**
* Number of extra items to render outside viewport for smoother scrolling
* @default 5
*/
overscan?: number;
/**
* Function to get the key of an item at a given index.
@@ -464,27 +469,45 @@ export function createVirtualizer<T>(
}
return {
/**
* Current vertical scroll position in pixels (reactive)
*/
get scrollOffset() {
return scrollOffset;
},
/**
* Measured height of the visible container area (reactive)
*/
get containerHeight() {
return containerHeight;
},
/** Computed array of visible items to render (reactive) */
/**
* Computed array of visible items to render (reactive)
*/
get items() {
return items;
},
/** Total height of all items in pixels (reactive) */
/**
* Total height of all items in pixels (reactive)
*/
get totalSize() {
return totalSize;
},
/** Svelte action for the scrollable container element */
/**
* Svelte action for the scrollable container element
*/
container,
/** Svelte action for measuring individual item elements */
/**
* Svelte action for measuring individual item elements
*/
measureElement,
/** Programmatic scroll method to scroll to a specific item */
/**
* Programmatic scroll method to scroll to a specific item
*/
scrollToIndex,
/** Programmatic scroll method to scroll to a specific pixel offset */
/**
* Programmatic scroll method to scroll to a specific pixel offset
*/
scrollToOffset,
};
}

View File

@@ -1,4 +1,6 @@
/** @vitest-environment jsdom */
/**
* @vitest-environment jsdom
*/
import {
afterEach,
describe,

View File

@@ -22,59 +22,178 @@
* ```
*/
/**
* Filter management
*/
export {
/**
* Reactive filter factory
*/
createFilter,
/**
* Filter instance type
*/
type Filter,
/**
* Initial state model
*/
type FilterModel,
/**
* Filterable property definition
*/
type Property,
} from './createFilter/createFilter.svelte';
/**
* Bounded numeric controls
*/
export {
/**
* Base numeric configuration
*/
type ControlDataModel,
/**
* Extended model with labels
*/
type ControlModel,
/**
* Reactive control factory
*/
createTypographyControl,
/**
* Control instance type
*/
type TypographyControl,
} from './createTypographyControl/createTypographyControl.svelte';
/**
* List virtualization
*/
export {
/**
* Reactive virtualizer factory
*/
createVirtualizer,
/**
* Rendered item layout data
*/
type VirtualItem,
/**
* Virtualizer instance type
*/
type Virtualizer,
/**
* Configuration options
*/
type VirtualizerOptions,
} from './createVirtualizer/createVirtualizer.svelte';
export { createDebouncedState } from './createDebouncedState/createDebouncedState.svelte';
/**
* UI State
*/
export {
/**
* Immediate/debounced state factory
*/
createDebouncedState,
} from './createDebouncedState/createDebouncedState.svelte';
/**
* Entity collections
*/
export {
/**
* Reactive entity store factory
*/
createEntityStore,
/**
* Base entity requirement
*/
type Entity,
/**
* Entity store instance type
*/
type EntityStore,
} from './createEntityStore/createEntityStore.svelte';
/**
* Comparison logic
*/
export {
/**
* Character-by-character comparison utility
*/
CharacterComparisonEngine,
/**
* Single line of comparison results
*/
type ComparisonLine,
/**
* Full comparison output
*/
type ComparisonResult,
} from './CharacterComparisonEngine/CharacterComparisonEngine.svelte';
/**
* Text layout
*/
export {
/**
* Single line layout information
*/
type LayoutLine as TextLayoutLine,
/**
* Full multi-line layout information
*/
type LayoutResult as TextLayoutResult,
/**
* High-level text measurement engine
*/
TextLayoutEngine,
} from './TextLayoutEngine/TextLayoutEngine.svelte';
/**
* Persistence
*/
export {
/**
* LocalStorage-backed reactive store factory
*/
createPersistentStore,
/**
* Persistent store instance type
*/
type PersistentStore,
} from './createPersistentStore/createPersistentStore.svelte';
/**
* Responsive design
*/
export {
/**
* Breakpoint tracking factory
*/
createResponsiveManager,
/**
* Responsive manager instance type
*/
type ResponsiveManager,
/**
* Singleton manager for global usage
*/
responsiveManager,
} from './createResponsiveManager/createResponsiveManager.svelte';
/**
* 3D Perspectives
*/
export {
/**
* Motion-aware perspective factory
*/
createPerspectiveManager,
/**
* Perspective manager instance type
*/
type PerspectiveManager,
} from './createPerspectiveManager/createPerspectiveManager.svelte';

View File

@@ -1,4 +1,6 @@
/** @vitest-environment jsdom */
/**
* @vitest-environment jsdom
*/
import {
afterEach,
beforeEach,

View File

@@ -7,8 +7,12 @@
* @template T - Type of the response data
*/
export interface ApiResponse<T> {
/** Response payload data */
/**
* Primary data payload returned by the server
*/
data: T;
/** HTTP status code */
/**
* HTTP status code (e.g. 200, 404, 500)
*/
status: number;
}

View File

@@ -3,7 +3,9 @@ import type {
InputVariant,
} from './types';
/** Size-specific layout classes: padding, text size, height, and clear-icon pixel size. */
/**
* Size-specific layout classes: padding, text size, height, and clear-icon pixel size.
*/
export const inputSizeConfig: Record<InputSize, { input: string; text: string; height: string; clearIcon: number }> = {
sm: { input: 'px-3 py-1.5', text: 'text-sm', height: 'h-8', clearIcon: 12 },
md: { input: 'px-4 py-2', text: 'text-base', height: 'h-10', clearIcon: 14 },
@@ -11,7 +13,9 @@ export const inputSizeConfig: Record<InputSize, { input: string; text: string; h
xl: { input: 'px-4 py-3', text: 'text-xl md:text-2xl', height: 'h-14', clearIcon: 18 },
};
/** Variant-specific classes: base background/border, focus ring, and error state. */
/**
* Variant-specific classes: base background/border, focus ring, and error state.
*/
export const inputVariantConfig: Record<InputVariant, { base: string; focus: string; error: string }> = {
default: {
base: 'bg-paper dark:bg-paper border border-subtle',

View File

@@ -1,6 +1,8 @@
export type InputVariant = 'default' | 'underline' | 'filled';
export type InputSize = 'sm' | 'md' | 'lg' | 'xl';
/** Convenience map for consumers sizing icons to match the input. */
/**
* Convenience map for consumers sizing icons to match the input.
*/
export const inputIconSize: Record<InputSize, number> = {
sm: 14,
md: 16,

View File

@@ -1,28 +1,150 @@
export { default as Badge } from './Badge/Badge.svelte';
export {
/**
* Pill-shaped status indicator
*/
default as Badge,
} from './Badge/Badge.svelte';
export {
/**
* Main action trigger
*/
Button,
/**
* Horizontal layout for related buttons
*/
ButtonGroup,
/**
* Button optimized for single-icon display
*/
IconButton,
/**
* State-aware toggle switch
*/
ToggleButton,
} from './Button';
export { default as ComboControl } from './ComboControl/ComboControl.svelte';
export { default as ContentEditable } from './ContentEditable/ContentEditable.svelte';
export { default as ControlGroup } from './ControlGroup/ControlGroup.svelte';
export { default as Divider } from './Divider/Divider.svelte';
export { default as FilterGroup } from './FilterGroup/FilterGroup.svelte';
export { default as Footnote } from './Footnote/Footnote.svelte';
export { default as Input } from './Input/Input.svelte';
export { default as Label } from './Label/Label.svelte';
export { default as Loader } from './Loader/Loader.svelte';
export { default as Logo } from './Logo/Logo.svelte';
export { default as PerspectivePlan } from './PerspectivePlan/PerspectivePlan.svelte';
export { default as SearchBar } from './SearchBar/SearchBar.svelte';
export { default as Section } from './Section/Section.svelte';
export type { TitleStatusChangeHandler } from './Section/types';
export { default as SidebarContainer } from './SidebarContainer/SidebarContainer.svelte';
export { default as Skeleton } from './Skeleton/Skeleton.svelte';
export { default as Slider } from './Slider/Slider.svelte';
export { default as Stat } from './Stat/Stat.svelte';
export { default as StatGroup } from './Stat/StatGroup.svelte';
export { default as TechText } from './TechText/TechText.svelte';
export { default as VirtualList } from './VirtualList/VirtualList.svelte';
export {
/**
* Input with associated increment/decrement controls
*/
default as ComboControl,
} from './ComboControl/ComboControl.svelte';
export {
/**
* Rich text input using contenteditable attribute
*/
default as ContentEditable,
} from './ContentEditable/ContentEditable.svelte';
export {
/**
* Semantic grouping for related UI controls
*/
default as ControlGroup,
} from './ControlGroup/ControlGroup.svelte';
export {
/**
* Simple horizontal line separator
*/
default as Divider,
} from './Divider/Divider.svelte';
export {
/**
* Filterable property set with selection logic
*/
default as FilterGroup,
} from './FilterGroup/FilterGroup.svelte';
export {
/**
* Small text for secondary meta-information
*/
default as Footnote,
} from './Footnote/Footnote.svelte';
export {
/**
* Design-system standard text input
*/
default as Input,
} from './Input/Input.svelte';
export {
/**
* Text label for input fields
*/
default as Label,
} from './Label/Label.svelte';
export {
/**
* Full-page or component-level progress spinner
*/
default as Loader,
} from './Loader/Loader.svelte';
export {
/**
* Main application logo
*/
default as Logo,
} from './Logo/Logo.svelte';
export {
/**
* 3D perspective background/container
*/
default as PerspectivePlan,
} from './PerspectivePlan/PerspectivePlan.svelte';
export {
/**
* Specialized input with search icon and clear state
*/
default as SearchBar,
} from './SearchBar/SearchBar.svelte';
export {
/**
* Content section with header and optional title tracking
*/
default as Section,
} from './Section/Section.svelte';
export {
/**
* Callback for section visibility status changes
*/
type TitleStatusChangeHandler,
} from './Section/types';
export {
/**
* Structural sidebar component
*/
default as SidebarContainer,
} from './SidebarContainer/SidebarContainer.svelte';
export {
/**
* Loading placeholder with pulsing animation
*/
default as Skeleton,
} from './Skeleton/Skeleton.svelte';
export {
/**
* Range selector with numeric feedback
*/
default as Slider,
} from './Slider/Slider.svelte';
export {
/**
* Individual numeric statistic display
*/
default as Stat,
} from './Stat/Stat.svelte';
export {
/**
* Grouping for multiple statistics
*/
default as StatGroup,
} from './Stat/StatGroup.svelte';
export {
/**
* Mono-spaced technical/metadata text
*/
default as TechText,
} from './TechText/TechText.svelte';
export {
/**
* High-performance list renderer for large datasets
*/
default as VirtualList,
} from './VirtualList/VirtualList.svelte';