import { type FormEvent } from 'react'; import type { CheatSchema } from '../../../protocol/messages'; import { resolveOption } from '../model/values'; import { formatNumber, numericValue } from './format-number'; import { SliderTrack, type ControlInternalProps } from './shared'; export const ScalarControl = ({ cheat, value, disabled, onChange }: ControlInternalProps) => { const numericOptions = getNumericOptions(cheat.args.options ?? []); const min = cheat.args.min ?? numericOptions[0] ?? 0; const max = cheat.args.max ?? numericOptions[numericOptions.length - 1] ?? 100; const step = cheat.args.step ?? inferStep(numericOptions) ?? 1; const currentValue = numericValue(value, min); const handleInput = (event: FormEvent) => onChange(Number(event.currentTarget.value)); return (
{formatNumber(currentValue, step)}{cheat.args.postfix ?? ''}
{min}{cheat.args.postfix ?? ''} {max}{cheat.args.postfix ?? ''}
); }; function getNumericOptions(options: NonNullable): number[] { return options .map(resolveOption) .map((option) => numericValue(option.value, Number.NaN)) .filter((option) => Number.isFinite(option)) .sort((left, right) => left - right); } function inferStep(options: number[]): number | null { if (options.length < 2) { return null; } const steps = options .slice(1) .map((option, index) => Math.abs(option - options[index])) .filter((option) => option > 0); return steps.length > 0 ? Math.min(...steps) : null; }