@@ -23,6 +23,7 @@ interface IProps {
2323 setIsVisible : ( value : TIsVisible ) => void ;
2424 viewDate : string ;
2525 setViewDate : ( value : string ) => void ;
26+ disabled : boolean ;
2627}
2728
2829// Function to select text
@@ -65,6 +66,7 @@ function InputUnit({
6566 setIsVisible,
6667 viewDate,
6768 setViewDate,
69+ disabled,
6870} : IProps ) {
6971 const inputRef = useRef < HTMLDivElement > ( null ) ;
7072 const nextRef = useRef < HTMLElement > ( ) ;
@@ -87,10 +89,6 @@ function InputUnit({
8789 } , [ type , dateValue , timeValue ] ) ;
8890 const [ text , setText ] = useState < string > ( displayUnit ) ;
8991
90- useEffect ( ( ) => {
91- setText ( displayUnit ) ;
92- } , [ displayUnit ] ) ;
93-
9492 const utilSetDateValue = ( {
9593 year,
9694 month,
@@ -147,43 +145,8 @@ function InputUnit({
147145 }
148146 } ;
149147
150- // Text의 변화를 감지하여 Value에 최종 저장
151- useEffect ( ( ) => {
152- if ( ! isNumeric ( text as string ) ) return ;
153-
154- switch ( type ) {
155- case 'YYYY' :
156- utilSetDateValue ( { ...dateValue , year : Number ( text ) } ) ;
157- setViewDate (
158- `${ text } -${ viewDate . split ( '-' ) [ 1 ] } -${ viewDate . split ( '-' ) [ 2 ] } `
159- ) ;
160- return ;
161- case 'MM' :
162- utilSetDateValue ( { ...dateValue , month : Number ( text ) - 1 } ) ;
163- setViewDate (
164- `${ viewDate . split ( '-' ) [ 0 ] } -${ text } -${ viewDate . split ( '-' ) [ 2 ] } `
165- ) ;
166- return ;
167- case 'DD' :
168- utilSetDateValue ( { ...dateValue , date : Number ( text ) } ) ;
169- return ;
170- case 'hh' :
171- utilSetTimeValue ( { ...timeValue , hour : Number ( text ) } ) ;
172- return ;
173- case 'mm' :
174- utilSetTimeValue ( { ...timeValue , minute : Number ( text ) } ) ;
175- return ;
176- case 'ss' :
177- utilSetTimeValue ( { ...timeValue , second : Number ( text ) } ) ;
178- return ;
179- default :
180- return ;
181- }
182- // eslint-disable-next-line react-hooks/exhaustive-deps
183- } , [ text ] ) ;
184-
185148 // Type마다 특정 자리수 입력 시 다음 Input으로 focusing
186- const handleInput = ( e : FormEvent < HTMLDivElement > ) => {
149+ const inputHandler = ( e : FormEvent < HTMLDivElement > ) => {
187150 const target = e . target as HTMLDivElement ;
188151 const count = target . textContent ?. length || 0 ;
189152 const value = Number ( target . textContent ) ;
@@ -256,17 +219,6 @@ function InputUnit({
256219 }
257220 } ;
258221
259- // 다음 Input Unit을 nextRef에 저장.
260- useEffect ( ( ) => {
261- if ( inputRef . current ) {
262- const nextSiblings = getNextSiblingsWithDataValueTrue ( inputRef . current ) ;
263-
264- if ( nextSiblings . length ) {
265- nextRef . current = nextSiblings [ 0 ] ;
266- }
267- }
268- } , [ ] ) ;
269-
270222 // 허용된 입력 외 prevent
271223 const numberChecker = ( e : KeyboardEvent ) => {
272224 const allowKeys = [
@@ -283,31 +235,95 @@ function InputUnit({
283235 }
284236 } ;
285237
238+ const focusHandler = ( e : React . FocusEvent < HTMLDivElement > ) => {
239+ if ( disabled ) return ;
240+ setIsVisible ( visibleType ) ;
241+ setTimeout ( ( ) => {
242+ selectText ( e . target ) ;
243+ } , 10 ) ;
244+ } ;
245+
246+ const clickHandler = ( e : React . MouseEvent < HTMLDivElement > ) => {
247+ if ( disabled ) return ;
248+ if ( ! isValue ) {
249+ if ( nextRef . current ) {
250+ nextRef . current . focus ( ) ;
251+ }
252+ } else {
253+ const target = e . target as HTMLElement ;
254+ selectText ( target ) ;
255+ }
256+ } ;
257+
258+ const blurHandler = ( e : React . FocusEvent < HTMLDivElement > ) => {
259+ if ( disabled ) return ;
260+ setValue ( e . target ) ;
261+ } ;
262+
263+ useEffect ( ( ) => {
264+ setText ( displayUnit ) ;
265+ } , [ displayUnit ] ) ;
266+
267+ // Text의 변화를 감지하여 Value에 최종 저장
268+ useEffect ( ( ) => {
269+ if ( ! isNumeric ( text as string ) ) return ;
270+
271+ switch ( type ) {
272+ case 'YYYY' :
273+ utilSetDateValue ( { ...dateValue , year : Number ( text ) } ) ;
274+ setViewDate (
275+ `${ text } -${ viewDate . split ( '-' ) [ 1 ] } -${ viewDate . split ( '-' ) [ 2 ] } `
276+ ) ;
277+ return ;
278+ case 'MM' :
279+ utilSetDateValue ( { ...dateValue , month : Number ( text ) - 1 } ) ;
280+ setViewDate (
281+ `${ viewDate . split ( '-' ) [ 0 ] } -${ text } -${ viewDate . split ( '-' ) [ 2 ] } `
282+ ) ;
283+ return ;
284+ case 'DD' :
285+ utilSetDateValue ( { ...dateValue , date : Number ( text ) } ) ;
286+ return ;
287+ case 'hh' :
288+ utilSetTimeValue ( { ...timeValue , hour : Number ( text ) } ) ;
289+ return ;
290+ case 'mm' :
291+ utilSetTimeValue ( { ...timeValue , minute : Number ( text ) } ) ;
292+ return ;
293+ case 'ss' :
294+ utilSetTimeValue ( { ...timeValue , second : Number ( text ) } ) ;
295+ return ;
296+ default :
297+ return ;
298+ }
299+ // eslint-disable-next-line react-hooks/exhaustive-deps
300+ } , [ text ] ) ;
301+
302+ // 다음 Input Unit을 nextRef에 저장.
303+ useEffect ( ( ) => {
304+ if ( inputRef . current ) {
305+ const nextSiblings = getNextSiblingsWithDataValueTrue ( inputRef . current ) ;
306+
307+ if ( nextSiblings . length ) {
308+ nextRef . current = nextSiblings [ 0 ] ;
309+ }
310+ }
311+ } , [ ] ) ;
312+
286313 return (
287314 < div
288315 role = "presentation"
289316 ref = { inputRef }
290317 data-value = { isValue }
291318 className = { `${ NAME_SPACE } __input-unit` }
292319 dangerouslySetInnerHTML = { { __html : text } }
293- contentEditable = { isValue }
320+ contentEditable = { isValue && ! disabled }
294321 suppressContentEditableWarning = { true }
295- onFocus = { ( e ) => {
296- setIsVisible ( visibleType ) ;
297- setTimeout ( ( ) => {
298- selectText ( e . target ) ;
299- } , 10 ) ;
300- } }
301- onClick = { ( e ) => {
302- if ( ! isValue ) return ;
303- const target = e . target as HTMLElement ;
304- selectText ( target ) ;
305- } }
306- onInput = { handleInput }
322+ onFocus = { focusHandler }
323+ onClick = { clickHandler }
324+ onInput = { inputHandler }
307325 onKeyDown = { numberChecker }
308- onBlur = { ( e ) => {
309- setValue ( e . target ) ;
310- } }
326+ onBlur = { blurHandler }
311327 inputMode = "numeric"
312328 />
313329 ) ;
0 commit comments