2026-01-07 16:53:17 +03:00
|
|
|
import {
|
|
|
|
|
clampNumber,
|
|
|
|
|
roundToStepPrecision,
|
|
|
|
|
} from '$shared/lib/utils';
|
|
|
|
|
|
|
|
|
|
export interface ControlDataModel {
|
2026-01-09 16:13:47 +03:00
|
|
|
/**
|
|
|
|
|
* Control value
|
|
|
|
|
*/
|
2026-01-07 16:53:17 +03:00
|
|
|
value: number;
|
2026-01-09 16:13:47 +03:00
|
|
|
/**
|
|
|
|
|
* Minimal possible value
|
|
|
|
|
*/
|
2026-01-07 16:53:17 +03:00
|
|
|
min: number;
|
2026-01-09 16:13:47 +03:00
|
|
|
/**
|
|
|
|
|
* Maximal possible value
|
|
|
|
|
*/
|
2026-01-07 16:53:17 +03:00
|
|
|
max: number;
|
2026-01-09 16:13:47 +03:00
|
|
|
/**
|
|
|
|
|
* Step size for increase/decrease
|
|
|
|
|
*/
|
2026-01-07 16:53:17 +03:00
|
|
|
step: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ControlModel extends ControlDataModel {
|
2026-01-09 16:13:47 +03:00
|
|
|
/**
|
|
|
|
|
* Control identifier
|
|
|
|
|
*/
|
2026-01-07 16:53:17 +03:00
|
|
|
id: string;
|
2026-01-09 16:13:47 +03:00
|
|
|
/**
|
|
|
|
|
* Area label for increase button
|
|
|
|
|
*/
|
2026-01-07 16:53:17 +03:00
|
|
|
increaseLabel: string;
|
2026-01-09 16:13:47 +03:00
|
|
|
/**
|
|
|
|
|
* Area label for decrease button
|
|
|
|
|
*/
|
2026-01-07 16:53:17 +03:00
|
|
|
decreaseLabel: string;
|
2026-01-09 16:13:47 +03:00
|
|
|
/**
|
|
|
|
|
* Control area label
|
|
|
|
|
*/
|
2026-01-07 16:53:17 +03:00
|
|
|
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>;
|