import type BezierEasing from "bezier-easing"; import type { BooleanCtrl } from "./ctrl-boolean"; import type { DualRangeValue, DualRangeCtrl } from "./ctrl-dual-range"; import type { Easing, EasingCtrl } from "./ctrl-easing"; import type { RadioCtrl } from "./ctrl-radio"; import type { RangeCtrl } from "./ctrl-range"; import type { SeedCtrl } from "./ctrl-seed"; import type { FileCtrl } from "./ctrl-file"; export interface PRNG { (): number; } export type HashItem = { id: string; value: unknown; }; export type CtrlControlType = "boolean" | "range" | "radio" | "seed" | "easing" | "dual-range" | "file"; export type CtrlItemType = CtrlControlType | "group" | "html"; export type CtrlChangeHandler = (control: CtrlComponent) => void; export type CtrlConfig = { type: CtrlItemType; id?: string; name: string; accept?: string; group?: string; label?: string; defaultValue?: T; isRandomizationDisabled?: boolean; }; export interface Ctrl { id: string; group?: string; name: string; label?: string; type: CtrlItemType; isRandomizationDisabled: boolean; onChange: CtrlChangeHandler; parse: (value: string) => T; getRandomValue: () => T; getDefaultValue: () => T; buildUI: () => unknown; valueToString: (value?: T) => string; update: (value: T) => void; element: HTMLElement; } export interface CtrlTypeMap { boolean: { value: boolean; }; range: { value: number; min: number; max: number; step?: number; }; radio: { value: string; items: Record; columns?: 1 | 2 | 3 | 4 | 5; }; seed: { value: string; }; easing: { value: Easing; presets?: Record; }; "dual-range": { value: DualRangeValue; min: number; max: number; step?: number; }; group: { value: Record; controls: readonly TypedControlConfig[]; isRandomizationDisabled?: boolean; }; html: { html: HTMLElement; }; file: { value: File | null; accept?: string; }; } export type TypedControlConfig = { [K in CtrlControlType]: { type: K; id?: string; name: string; group?: string; label?: string; defaultValue?: CtrlTypeMap[K]["value"]; isRandomizationDisabled?: boolean; } & Omit; }[CtrlControlType]; export type GroupConfig = { type: "group"; name: string; label?: string; controls: readonly TypedControlConfig[]; isCollapsed?: boolean; }; export type HTMLConfig = { type: "html"; name: string; label?: string; html: HTMLElement; }; export type ConfigItem = TypedControlConfig | GroupConfig | HTMLConfig; export type ConfigFor = Extract; type ExtractValues = { [C in Extract as C["name"]]: CtrlTypeMap[C["type"]]["value"]; } & { [C in Extract as C["name"]]: OptionsMap; }; type DerivedProps = { [C in Extract as `${C["name"]}Easing`]: ReturnType; } & { [C in Extract as `${C["name"]}Rng`]: PRNG; } & { [C in Extract as C["name"]]: DerivedProps; }; export type OptionsMap = ExtractValues & DerivedProps; export type ControlsOptions = { showRandomizeButton?: boolean; storage?: "hash" | "none"; theme?: "system" | "light" | "dark"; parent?: Element; title?: string; }; export type CtrlComponent = BooleanCtrl | RangeCtrl | RadioCtrl | SeedCtrl | EasingCtrl | DualRangeCtrl | FileCtrl; export type ControlConstructor = new (...args: any[]) => T; export {};