"use client"; import * as React from "react"; import { ControlFieldLabel } from "../../control-layout"; import { Field, Input } from "../../primitives"; import { type ControlValueChangeHandler } from "../control-types"; import { cn } from "../../../lib/utils"; export type RangeInputControlProps = { defaultValue?: { end: string; start: string }; end: string; name: string; onValueChange?: ControlValueChangeHandler<{ start: string; end: string }>; showLabel?: boolean; start: string; }; const RANGE_FULL_WIDTH_VALUE_LENGTH = 7; function shouldUseFullWidthRangeInputs(start: string, end: string): boolean { return Math.max(start.length, end.length) > RANGE_FULL_WIDTH_VALUE_LENGTH; } function RangeInputs({ className, end, name, onCancel, onCommit, onDraftChange, start, }: RangeInputControlProps & { className?: string; onCancel: () => void; onCommit: () => void; onDraftChange: (nextValue: { start: string; end: string }) => void; }): React.JSX.Element { function handleKeyDown(event: React.KeyboardEvent): void { if (event.key === "Enter") { event.preventDefault(); onCommit(); event.currentTarget.blur(); return; } if (event.key === "Escape") { event.preventDefault(); onCancel(); event.currentTarget.blur(); } } return (
onDraftChange({ end, start: event.target.value }) } onKeyDown={handleKeyDown} size="default" value={start} /> onDraftChange({ end: event.target.value, start }) } onKeyDown={handleKeyDown} size="default" value={end} />
); } export function RangeInputControl({ defaultValue, end, name, onValueChange, showLabel = true, start, }: RangeInputControlProps): React.JSX.Element { const [currentValue, setCurrentValue] = React.useState({ end, start }); const committedValueRef = React.useRef({ end, start }); const defaultValueRef = React.useRef(defaultValue ?? { end, start }); React.useEffect(() => { committedValueRef.current = { end, start }; setCurrentValue({ end, start }); }, [end, start]); React.useEffect(() => { defaultValueRef.current = defaultValue ?? { end, start }; }, [defaultValue, end, start]); function updateDraft(nextValue: { start: string; end: string }): void { setCurrentValue(nextValue); } function getCommittedValue(): { start: string; end: string } { const nextValue = { end: currentValue.end.trim() === "" ? defaultValueRef.current.end : currentValue.end, start: currentValue.start.trim() === "" ? defaultValueRef.current.start : currentValue.start, }; return nextValue; } function commitValue(): void { const nextValue = getCommittedValue(); setCurrentValue(nextValue); if ( nextValue.start !== committedValueRef.current.start || nextValue.end !== committedValueRef.current.end ) { onValueChange?.(nextValue); } } function cancelDraft(): void { setCurrentValue(committedValueRef.current); } if (shouldUseFullWidthRangeInputs(start, end)) { return ( {showLabel ? {name} : null} ); } return ( {showLabel ? {name} : null} ); }