chore: follow the general comments style
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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' });
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
},
|
||||
|
||||
@@ -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>();
|
||||
|
||||
/**
|
||||
|
||||
@@ -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>[];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/** @vitest-environment jsdom */
|
||||
/**
|
||||
* @vitest-environment jsdom
|
||||
*/
|
||||
import {
|
||||
afterEach,
|
||||
beforeEach,
|
||||
|
||||
@@ -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';
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
},
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/** @vitest-environment jsdom */
|
||||
/**
|
||||
* @vitest-environment jsdom
|
||||
*/
|
||||
import {
|
||||
afterEach,
|
||||
describe,
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/** @vitest-environment jsdom */
|
||||
/**
|
||||
* @vitest-environment jsdom
|
||||
*/
|
||||
import {
|
||||
afterEach,
|
||||
beforeEach,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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';
|
||||
|
||||
Reference in New Issue
Block a user