87 lines
2.0 KiB
TypeScript
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;
|