refactor(AdjustTypography): add typography-control module (factory, types, constants)
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
export {
|
||||
createTypographySettingsStore,
|
||||
MULTIPLIER_L,
|
||||
MULTIPLIER_M,
|
||||
MULTIPLIER_S,
|
||||
type TypographySettingsStore,
|
||||
typographySettingsStore,
|
||||
} from './model';
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
import {
|
||||
DEFAULT_FONT_SIZE,
|
||||
DEFAULT_FONT_WEIGHT,
|
||||
DEFAULT_LETTER_SPACING,
|
||||
DEFAULT_LINE_HEIGHT,
|
||||
FONT_SIZE_STEP,
|
||||
FONT_WEIGHT_STEP,
|
||||
LETTER_SPACING_STEP,
|
||||
LINE_HEIGHT_STEP,
|
||||
MAX_FONT_SIZE,
|
||||
MAX_FONT_WEIGHT,
|
||||
MAX_LETTER_SPACING,
|
||||
MAX_LINE_HEIGHT,
|
||||
MIN_FONT_SIZE,
|
||||
MIN_FONT_WEIGHT,
|
||||
MIN_LETTER_SPACING,
|
||||
MIN_LINE_HEIGHT,
|
||||
} from '$entities/Font';
|
||||
import type {
|
||||
ControlId,
|
||||
ControlModel,
|
||||
} from '../types/typography';
|
||||
|
||||
/**
|
||||
* Responsive font-size scaling factors applied by typographySettingsStore.
|
||||
*/
|
||||
export const MULTIPLIER_S = 0.5;
|
||||
export const MULTIPLIER_M = 0.75;
|
||||
export const MULTIPLIER_L = 1;
|
||||
|
||||
/**
|
||||
* Default control definitions seeding the typography settings store.
|
||||
* Composed from the font-render ranges/defaults owned by the Font entity.
|
||||
*/
|
||||
export const DEFAULT_TYPOGRAPHY_CONTROLS_DATA: ControlModel<ControlId>[] = [
|
||||
{
|
||||
id: 'font_size',
|
||||
value: DEFAULT_FONT_SIZE,
|
||||
max: MAX_FONT_SIZE,
|
||||
min: MIN_FONT_SIZE,
|
||||
step: FONT_SIZE_STEP,
|
||||
increaseLabel: 'Increase Font Size',
|
||||
decreaseLabel: 'Decrease Font Size',
|
||||
controlLabel: 'Size',
|
||||
},
|
||||
{
|
||||
id: 'font_weight',
|
||||
value: DEFAULT_FONT_WEIGHT,
|
||||
max: MAX_FONT_WEIGHT,
|
||||
min: MIN_FONT_WEIGHT,
|
||||
step: FONT_WEIGHT_STEP,
|
||||
increaseLabel: 'Increase Font Weight',
|
||||
decreaseLabel: 'Decrease Font Weight',
|
||||
controlLabel: 'Weight',
|
||||
},
|
||||
{
|
||||
id: 'line_height',
|
||||
value: DEFAULT_LINE_HEIGHT,
|
||||
max: MAX_LINE_HEIGHT,
|
||||
min: MIN_LINE_HEIGHT,
|
||||
step: LINE_HEIGHT_STEP,
|
||||
increaseLabel: 'Increase Line Height',
|
||||
decreaseLabel: 'Decrease Line Height',
|
||||
controlLabel: 'Leading',
|
||||
},
|
||||
{
|
||||
id: 'letter_spacing',
|
||||
value: DEFAULT_LETTER_SPACING,
|
||||
max: MAX_LETTER_SPACING,
|
||||
min: MIN_LETTER_SPACING,
|
||||
step: LETTER_SPACING_STEP,
|
||||
increaseLabel: 'Increase Letter Spacing',
|
||||
decreaseLabel: 'Decrease Letter Spacing',
|
||||
controlLabel: 'Tracking',
|
||||
},
|
||||
];
|
||||
@@ -1,3 +1,8 @@
|
||||
export {
|
||||
MULTIPLIER_L,
|
||||
MULTIPLIER_M,
|
||||
MULTIPLIER_S,
|
||||
} from './const/const';
|
||||
export {
|
||||
createTypographySettingsStore,
|
||||
type TypographySettingsStore,
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import type {
|
||||
ControlLabels,
|
||||
NumericControl,
|
||||
} from '$shared/ui';
|
||||
|
||||
/**
|
||||
* Identifiers for the adjustable typography axes
|
||||
*/
|
||||
export type ControlId = 'font_size' | 'font_weight' | 'line_height' | 'letter_spacing';
|
||||
|
||||
/**
|
||||
* Static configuration for one typography control.
|
||||
*
|
||||
* Derived from the SSOT contract types — declares no fields of its own beyond
|
||||
* the domain `id`. Bounds come from NumericControl, labels from ControlLabels.
|
||||
*
|
||||
* @template T - Control identifier type
|
||||
*/
|
||||
export type ControlModel<T extends string = string> =
|
||||
& Pick<NumericControl, 'value' | 'min' | 'max' | 'step'>
|
||||
& ControlLabels
|
||||
& {
|
||||
/**
|
||||
* Unique identifier for the control
|
||||
*/
|
||||
id: T;
|
||||
};
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Bounded numeric control for typography settings.
|
||||
*
|
||||
* Produces a reactive control that clamps to [min, max] and rounds to step.
|
||||
* Implements the NumericControl contract that ComboControl renders.
|
||||
*/
|
||||
import {
|
||||
clampNumber,
|
||||
roundToStepPrecision,
|
||||
} from '$shared/lib/utils';
|
||||
import type { NumericControl } from '$shared/ui';
|
||||
|
||||
/**
|
||||
* Bounds + initial value seed for a control
|
||||
*/
|
||||
type ControlSeed = Pick<NumericControl, 'value' | 'min' | 'max' | 'step'>;
|
||||
|
||||
/**
|
||||
* Create a reactive bounded numeric control.
|
||||
*
|
||||
* @param initialState - Initial value and bounds
|
||||
* @returns A NumericControl whose value is always clamped and step-rounded
|
||||
*/
|
||||
export function createTypographyControl(initialState: ControlSeed): NumericControl {
|
||||
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) {
|
||||
const rounded = roundToStepPrecision(clampNumber(newValue, min, max), step);
|
||||
if (value !== rounded) {
|
||||
value = rounded;
|
||||
}
|
||||
},
|
||||
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);
|
||||
},
|
||||
};
|
||||
}
|
||||
+3
-5
@@ -1,12 +1,10 @@
|
||||
import {
|
||||
type TypographyControl,
|
||||
createTypographyControl,
|
||||
} from '$shared/lib';
|
||||
import type { NumericControl } from '$shared/ui';
|
||||
import {
|
||||
describe,
|
||||
expect,
|
||||
it,
|
||||
} from 'vitest';
|
||||
import { createTypographyControl } from './createTypographyControl.svelte';
|
||||
|
||||
/**
|
||||
* Test Strategy for createTypographyControl Helper
|
||||
@@ -34,7 +32,7 @@ describe('createTypographyControl - Unit Tests', () => {
|
||||
min?: number;
|
||||
max?: number;
|
||||
step?: number;
|
||||
}): TypographyControl {
|
||||
}): NumericControl {
|
||||
return createTypographyControl({
|
||||
value: initialValue,
|
||||
min: options?.min ?? 0,
|
||||
Reference in New Issue
Block a user