feat: add position9 field component

This commit is contained in:
2026-09-05 16:36:48 +05:00
parent 0c28925673
commit f24ccf9240
8 changed files with 289 additions and 4 deletions
+34
View File
@@ -11,6 +11,8 @@
// с полями `P`, а `Field<P[K]>` тип-проверялся на соответствие `P[K]`.
// Ошибки компилятора ловят расхождения между интерфейсом Params и схемой.
import type { Position9 } from "./core/textdraw";
export interface NumberSpec {
kind: "number";
default: number;
@@ -91,6 +93,27 @@ export interface OffsetSpec {
y: number;
}
/**
* 9-позиционная сетка (3×3): top/middle/bottom × left/center/right.
* Значение совпадает со строковым типом `Position9` из core/textdraw.
*/
export const POSITION9_VALUES = [
"top-left",
"top-center",
"top-right",
"middle-left",
"center",
"middle-right",
"bottom-left",
"bottom-center",
"bottom-right",
] as const;
export interface Position9Spec {
kind: "position9";
default: Position9;
}
/**
* «Объект as const» kind → спека поля. Единственный источник правды для
* перечня kinds: `FieldSpecKind` = ключи map, `FieldSpec` = значение по любому
@@ -107,6 +130,7 @@ export const fieldSpecs = {
dimension: {} as DimensionSpec,
"color-pair": {} as ColorPairSpec,
offset: {} as OffsetSpec,
position9: {} as Position9Spec,
} as const;
export type FieldSpecKind = keyof typeof fieldSpecs;
@@ -171,6 +195,9 @@ export const field = {
}): Field<Offset> => ({
spec: { kind: "offset", ...s },
}),
position9: (s: { default: Position9 }): Field<Position9> => ({
spec: { kind: "position9", ...s },
}),
};
/**
@@ -286,6 +313,13 @@ export function sanitizeSchemaParams<P>(
out[key] = { from, to };
break;
}
case "position9":
out[key] =
typeof raw === "string" &&
(POSITION9_VALUES as readonly string[]).includes(raw)
? (raw as Position9)
: spec.default;
break;
case "offset": {
const r =
typeof raw === "object" && raw !== null && "x" in raw && "y" in raw