diff --git a/src/features/AdjustTypography/index.ts b/src/features/AdjustTypography/index.ts index da1afb9..2ff571d 100644 --- a/src/features/AdjustTypography/index.ts +++ b/src/features/AdjustTypography/index.ts @@ -1,5 +1,8 @@ export { createTypographySettingsStore, + MULTIPLIER_L, + MULTIPLIER_M, + MULTIPLIER_S, type TypographySettingsStore, typographySettingsStore, } from './model'; diff --git a/src/features/AdjustTypography/model/const/const.ts b/src/features/AdjustTypography/model/const/const.ts new file mode 100644 index 0000000..bd2680c --- /dev/null +++ b/src/features/AdjustTypography/model/const/const.ts @@ -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[] = [ + { + 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', + }, +]; diff --git a/src/features/AdjustTypography/model/index.ts b/src/features/AdjustTypography/model/index.ts index 67419fd..4543ff8 100644 --- a/src/features/AdjustTypography/model/index.ts +++ b/src/features/AdjustTypography/model/index.ts @@ -1,3 +1,8 @@ +export { + MULTIPLIER_L, + MULTIPLIER_M, + MULTIPLIER_S, +} from './const/const'; export { createTypographySettingsStore, type TypographySettingsStore, diff --git a/src/features/AdjustTypography/model/types/typography.ts b/src/features/AdjustTypography/model/types/typography.ts new file mode 100644 index 0000000..4b89019 --- /dev/null +++ b/src/features/AdjustTypography/model/types/typography.ts @@ -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 = + & Pick + & ControlLabels + & { + /** + * Unique identifier for the control + */ + id: T; + }; diff --git a/src/features/AdjustTypography/model/typographyControl/createTypographyControl.svelte.ts b/src/features/AdjustTypography/model/typographyControl/createTypographyControl.svelte.ts new file mode 100644 index 0000000..452ea33 --- /dev/null +++ b/src/features/AdjustTypography/model/typographyControl/createTypographyControl.svelte.ts @@ -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; + +/** + * 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); + }, + }; +} diff --git a/src/shared/lib/helpers/createTypographyControl/createTypographyControl.test.ts b/src/features/AdjustTypography/model/typographyControl/createTypographyControl.test.ts similarity index 98% rename from src/shared/lib/helpers/createTypographyControl/createTypographyControl.test.ts rename to src/features/AdjustTypography/model/typographyControl/createTypographyControl.test.ts index 31ca633..85d683a 100644 --- a/src/shared/lib/helpers/createTypographyControl/createTypographyControl.test.ts +++ b/src/features/AdjustTypography/model/typographyControl/createTypographyControl.test.ts @@ -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,