Files
goldenChart/frontend/src/components/SmaPeriodInput.tsx
T
2026-05-23 15:11:48 +09:00

87 lines
2.0 KiB
TypeScript

/**
* SMA MA1~11 기간 입력 — 프리셋 드롭다운 없이 직접 숫자 편집 (포커스 유지)
*/
import React, { useState, useEffect, useRef, useCallback } from 'react';
const MIN = 1;
const MAX = 500;
interface SmaPeriodInputProps {
value: number;
disabled?: boolean;
onCommit: (v: number) => void;
}
const SmaPeriodInput: React.FC<SmaPeriodInputProps> = ({
value,
disabled = false,
onCommit,
}) => {
const [text, setText] = useState(() => String(value));
const editingRef = useRef(false);
const committedRef = useRef(value);
useEffect(() => {
if (editingRef.current) return;
if (value !== committedRef.current) {
committedRef.current = value;
setText(String(value));
}
}, [value]);
const commit = useCallback((raw: string) => {
const trimmed = raw.trim();
if (trimmed === '') {
setText(String(committedRef.current));
return;
}
const n = parseInt(trimmed, 10);
if (isNaN(n)) {
setText(String(committedRef.current));
return;
}
const clamped = Math.max(MIN, Math.min(MAX, n));
committedRef.current = clamped;
setText(String(clamped));
onCommit(clamped);
}, [onCommit]);
return (
<input
type="text"
inputMode="numeric"
className="ism-input ism-narrow ism-sma-period-input"
value={text}
disabled={disabled}
autoComplete="off"
spellCheck={false}
onMouseDown={e => {
e.stopPropagation();
}}
onPointerDown={e => {
e.stopPropagation();
}}
onClick={e => e.stopPropagation()}
onFocus={e => {
e.stopPropagation();
editingRef.current = true;
}}
onChange={e => {
const s = e.target.value.replace(/[^\d]/g, '');
setText(s);
}}
onBlur={e => {
editingRef.current = false;
commit(e.target.value);
}}
onKeyDown={e => {
if (e.key === 'Enter') {
(e.target as HTMLInputElement).blur();
}
}}
/>
);
};
export default SmaPeriodInput;