Files
frontend-svelte/src/shared/lib/helpers/createTypographyControl/createTypographyControl.svelte.ts
T

98 lines
2.0 KiB
TypeScript
Raw Normal View History

import {
clampNumber,
roundToStepPrecision,
} from '$shared/lib/utils';
export interface ControlDataModel {
2026-01-09 16:13:47 +03:00
/**
* Control value
*/
value: number;
2026-01-09 16:13:47 +03:00
/**
* Minimal possible value
*/
min: number;
2026-01-09 16:13:47 +03:00
/**
* Maximal possible value
*/
max: number;
2026-01-09 16:13:47 +03:00
/**
* Step size for increase/decrease
*/
step: number;
}
export interface ControlModel extends ControlDataModel {
2026-01-09 16:13:47 +03:00
/**
* Control identifier
*/
id: string;
2026-01-09 16:13:47 +03:00
/**
* Area label for increase button
*/
increaseLabel: string;
2026-01-09 16:13:47 +03:00
/**
* Area label for decrease button
*/
decreaseLabel: string;
2026-01-09 16:13:47 +03:00
/**
* Control area label
*/
controlLabel: string;
}
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);
const { isAtMax, isAtMin } = $derived({
isAtMax: value >= max,
isAtMin: value <= min,
});
return {
get value() {
return value;
},
set value(newValue) {
value = roundToStepPrecision(
clampNumber(newValue, min, max),
step,
);
},
get max() {
return max;
},
get min() {
return min;
},
get step() {
return step;
},
get isAtMax() {
return isAtMax;
},
get isAtMin() {
return isAtMin;
},
increase() {
value = roundToStepPrecision(
clampNumber(value + step, min, max),
step,
);
},
decrease() {
value = roundToStepPrecision(
clampNumber(value - step, min, max),
step,
);
},
};
}
export type TypographyControl = ReturnType<typeof createTypographyControl>;