Refactor/reacrhitecture to fsd+ #49

Merged
ilia merged 70 commits from refactor/reacrhitecture-to-fsd+ into main 2026-06-03 09:55:47 +00:00
3 changed files with 1 additions and 229 deletions
Showing only changes of commit 907145c655 - Show all commits
@@ -1,200 +0,0 @@
/**
* Numeric control with bounded values and step precision
*
* Creates a reactive control for numeric values that enforces min/max bounds
* and rounds to a specific step increment. Commonly used for typography controls
* like font size, line height, and letter spacing.
*
* @example
* ```ts
* const fontSize = createTypographyControl({
* value: 16,
* min: 12,
* max: 72,
* step: 1
* });
*
* // Access current value
* fontSize.value; // 16
* fontSize.isAtMin; // false
*
* // Modify value (automatically clamped and rounded)
* fontSize.increase();
* fontSize.value = 100; // Will be clamped to max (72)
* ```
*/
import {
clampNumber,
roundToStepPrecision,
} from '$shared/lib/utils';
/**
* Core numeric control configuration
* Defines the bounds and stepping behavior for a control
*/
export interface ControlDataModel {
/**
* Initial or current numeric value
*/
value: number;
/**
* Lower inclusive bound
*/
min: number;
/**
* Upper inclusive bound
*/
max: number;
/**
* Precision for increment/decrement operations
*/
step: number;
}
/**
* Full control model including accessibility labels
*
* @template T - Type for the control identifier
*/
export interface ControlModel<T extends string = string> extends ControlDataModel {
/**
* Unique string identifier for the control
*/
id: T;
/**
* Label used by screen readers for the increase button
*/
increaseLabel?: string;
/**
* Label used by screen readers for the decrease button
*/
decreaseLabel?: string;
/**
* Overall label describing the control's purpose
*/
controlLabel?: string;
}
/**
* Creates a reactive numeric control with bounds and stepping
*
* The control automatically:
* - Clamps values to the min/max range
* - Rounds values to the step precision
* - Tracks whether at min/max bounds
*
* @param initialState - Initial value, bounds, and step configuration
* @returns Typography control instance with reactive state and methods
*
* @example
* ```ts
* // Font size control: 12-72px in 1px increments
* const fontSize = createTypographyControl({
* value: 16,
* min: 12,
* max: 72,
* step: 1
* });
*
* // Line height control: 1.0-2.0 in 0.1 increments
* const lineHeight = createTypographyControl({
* value: 1.5,
* min: 1.0,
* max: 2.0,
* step: 0.1
* });
*
* // Direct assignment (auto-clamped)
* fontSize.value = 100; // Becomes 72 (max)
* ```
*/
export function createTypographyControl<T extends ControlDataModel>(
initialState: T,
) {
let value = $state(initialState.value);
let max = $state(initialState.max);
let min = $state(initialState.min);
let step = $state(initialState.step);
// Derived state for boundary detection
const { isAtMax, isAtMin } = $derived({
isAtMax: value >= max,
isAtMin: value <= min,
});
return {
/**
* Clamped and rounded control value (reactive)
*/
get value() {
return value;
},
set value(newValue) {
const rounded = roundToStepPrecision(clampNumber(newValue, min, max), step);
if (value !== rounded) {
value = rounded;
}
},
/**
* Upper limit for the control value
*/
get max() {
return max;
},
/**
* Lower limit for the control value
*/
get min() {
return min;
},
/**
* Configured step increment
*/
get step() {
return step;
},
/**
* True if current value is equal to or greater than max
*/
get isAtMax() {
return isAtMax;
},
/**
* True if current value is equal to or less than min
*/
get isAtMin() {
return isAtMin;
},
/**
* Increase value by one step (clamped to max)
*/
increase() {
value = roundToStepPrecision(
clampNumber(value + step, min, max),
step,
);
},
/**
* Decrease value by one step (clamped to min)
*/
decrease() {
value = roundToStepPrecision(
clampNumber(value - step, min, max),
step,
);
},
};
}
/**
* Type representing a typography control instance
*/
export type TypographyControl = ReturnType<typeof createTypographyControl>;
+1 -25
View File
@@ -3,7 +3,6 @@
*
* Provides composable state management patterns for common UI needs:
* - Filter management with multi-selection
* - Typography controls with bounds and stepping
* - Virtual scrolling for large lists
* - Debounced state for search inputs
* - Entity stores with O(1) lookups
@@ -13,11 +12,10 @@
*
* @example
* ```ts
* import { createFilter, createVirtualizer, createTypographyControl } from '$shared/lib/helpers';
* import { createFilter, createVirtualizer } from '$shared/lib/helpers';
*
* const filter = createFilter({ properties: [...] });
* const virtualizer = createVirtualizer(() => ({ count: 1000, estimateSize: () => 50 }));
* const control = createTypographyControl({ value: 16, min: 12, max: 72, step: 1 });
* ```
*/
@@ -43,28 +41,6 @@ export {
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
*/
-4
View File
@@ -5,15 +5,12 @@
*/
export {
type ControlDataModel,
type ControlModel,
createDebouncedState,
createEntityStore,
createFilter,
createPersistentStore,
createPerspectiveManager,
createResponsiveManager,
createTypographyControl,
createVirtualizer,
type Entity,
type EntityStore,
@@ -24,7 +21,6 @@ export {
type Property,
type ResponsiveManager,
responsiveManager,
type TypographyControl,
type VirtualItem,
type Virtualizer,
type VirtualizerOptions,