diff --git a/components/molecules/text-field/form-text-field.tsx b/components/molecules/text-field/form-text-field.tsx index 823ed33d..1a117158 100644 --- a/components/molecules/text-field/form-text-field.tsx +++ b/components/molecules/text-field/form-text-field.tsx @@ -1,9 +1,9 @@ 'use client'; -import React, { ChangeEvent, forwardRef } from 'react'; +import React, { ChangeEvent, forwardRef, KeyboardEvent } from 'react'; import { css, cx } from '@/styled-system/css'; -import { preventMinus } from '@/utils'; +import { preventCharacters } from '@/utils'; import { absoluteStyles, @@ -43,6 +43,7 @@ export const FormTextField = forwardRef( subText, placeholder, unit, + preventDecimal, className, maxLength, wrapperClassName, @@ -66,6 +67,10 @@ export const FormTextField = forwardRef( } else void onChange(event); }; + const handleKeyDown = (event: KeyboardEvent) => { + preventCharacters(event, ['-', preventDecimal ? '.' : '']); + }; + return ( ( maxLength={maxLength} onFocus={() => handlers.onChangeFocus(true)} onBlur={() => handlers.onChangeFocus(false)} - onKeyDown={inputType === 'number' ? preventMinus : undefined} + onKeyDown={inputType === 'number' ? handleKeyDown : undefined} onChange={handleInputChange} className={cx( css( diff --git a/components/molecules/text-field/text-field.tsx b/components/molecules/text-field/text-field.tsx index 17fa33e3..b91f392b 100644 --- a/components/molecules/text-field/text-field.tsx +++ b/components/molecules/text-field/text-field.tsx @@ -1,9 +1,9 @@ 'use client'; -import { ChangeEvent } from 'react'; +import { ChangeEvent, KeyboardEvent } from 'react'; import { css, cx } from '@/styled-system/css'; -import { preventMinus } from '@/utils'; +import { preventCharacters } from '@/utils'; import { absoluteStyles, @@ -24,6 +24,7 @@ import { useTextField } from './use-text-field'; * @param subText 추가 설명 텍스트 * @param placeholder placeholder 값 * @param unit 입력값 단위 + * @param step 소수점 단위 제한 * @param maxLength input의 최대길이 * @param className input태그 추가 스타일 * @param wrapperClassName text-field-wrapper 컴포넌트 추가 스타일 부여 @@ -39,6 +40,8 @@ export function TextField({ subText, placeholder, unit, + step, + preventDecimal, maxLength, className, wrapperClassName, @@ -52,11 +55,28 @@ export function TextField({ const handleInputChange = (event: ChangeEvent) => { let newValue = event.target.value; + let numValue = parseFloat(event.target.value); - if (maxLength && newValue.length >= maxLength) { - newValue = newValue.slice(0, maxLength); - void onChange?.(newValue); - } else void onChange?.(newValue); + //소수점 단위가 제한되어 있을 때 + if (step && numValue % step !== 0) { + numValue = Math.round(numValue * 2) / 2; + newValue = numValue.toString(); + } + + const lengthWithoutDecimal = newValue.replace('.', '').length; + + //소수점도 고려한 maxLength 적용 + if (maxLength && lengthWithoutDecimal >= maxLength) { + newValue = newValue.slice( + 0, + maxLength + (newValue.includes('.') ? 2 : 0), + ); + } + void onChange?.(newValue); + }; + + const handleKeyDown = (event: KeyboardEvent) => { + preventCharacters(event, ['-', preventDecimal ? '.' : '']); }; return ( @@ -78,7 +98,7 @@ export function TextField({ onChange={handleInputChange} onFocus={() => handlers.onChangeFocus(true)} onBlur={() => handlers.onChangeFocus(false)} - onKeyDown={inputType === 'number' ? preventMinus : undefined} + onKeyDown={inputType === 'number' ? handleKeyDown : undefined} className={cx( css( shouldEmphasize diff --git a/components/molecules/text-field/type.ts b/components/molecules/text-field/type.ts index f8bcde02..2427b745 100644 --- a/components/molecules/text-field/type.ts +++ b/components/molecules/text-field/type.ts @@ -10,6 +10,8 @@ export interface TextFieldProps { placeholder?: string; unit?: string; maxLength?: number; + step?: number; + preventDecimal?: boolean; className?: string; wrapperClassName?: string; absoluteClassName?: string; diff --git a/features/record/components/molecules/distance-field-with-badge.tsx b/features/record/components/molecules/distance-field-with-badge.tsx index acad1717..9302d07e 100644 --- a/features/record/components/molecules/distance-field-with-badge.tsx +++ b/features/record/components/molecules/distance-field-with-badge.tsx @@ -47,6 +47,8 @@ export function DistanceFieldWithBadge({ , + blockedChars: string[], +) => { + if (blockedChars.includes(event.key)) { + event.preventDefault(); + } +}; diff --git a/utils/input/prevent-minus.ts b/utils/input/prevent-minus.ts deleted file mode 100644 index 812260b1..00000000 --- a/utils/input/prevent-minus.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { KeyboardEvent } from 'react'; - -export const preventMinus = (event: KeyboardEvent) => { - if (event.key === '-') { - event.preventDefault(); - } -};