74 lines
1.6 KiB
TypeScript
74 lines
1.6 KiB
TypeScript
|
|
import {
|
||
|
|
clampNumber,
|
||
|
|
roundToStepPrecision,
|
||
|
|
} from '$shared/lib/utils';
|
||
|
|
|
||
|
|
export interface ControlDataModel {
|
||
|
|
value: number;
|
||
|
|
min: number;
|
||
|
|
max: number;
|
||
|
|
step: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface ControlModel extends ControlDataModel {
|
||
|
|
id: string;
|
||
|
|
increaseLabel: string;
|
||
|
|
decreaseLabel: string;
|
||
|
|
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>;
|