119 lines
3.3 KiB
JavaScript
119 lines
3.3 KiB
JavaScript
'use client'
|
|
|
|
import { useCallback, useState } from 'react'
|
|
|
|
export default function QInput({ type, className, ref, id, readOnly = false, options = [], placeholder, value, onChange }) {
|
|
const [prevNum, setPrevNum] = useState('')
|
|
// options = options || [
|
|
// {
|
|
// id: 'one',
|
|
// name: 'Option 1',
|
|
// value: '111',
|
|
// },
|
|
// {
|
|
// id: 'two',
|
|
// name: 'Option 2',
|
|
// value: '222',
|
|
// },
|
|
// {
|
|
// id: 'three',
|
|
// name: 'Option 3',
|
|
// value: '333',
|
|
// },
|
|
// ]
|
|
|
|
const handleRadioCheckboxChange = useCallback(
|
|
(e, optionValue) => {
|
|
if (type === 'radio') {
|
|
onChange(e.target.value)
|
|
} else if (type === 'checkbox') {
|
|
const newValue = value.includes(optionValue) ? value.filter((v) => v !== optionValue) : [...value, optionValue]
|
|
onChange(newValue)
|
|
}
|
|
},
|
|
[type, value, onChange],
|
|
)
|
|
|
|
const handleTextNumberChange = useCallback(
|
|
(e) => {
|
|
onChange(e.target.value)
|
|
},
|
|
[onChange],
|
|
)
|
|
|
|
// type=number 정수 부호, 소수점 검사, 일부 키 허용
|
|
// const checkInputNumber = (e) => {
|
|
// const value = e.target.value
|
|
// const key = e.key
|
|
// const allowKeys = ['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'Home', 'End', 'Tab', 'Enter', 'Control'] // 'ArrowUp', 'ArrowDown',
|
|
// if (key >= '0' && key <= '9') {
|
|
// return
|
|
// }
|
|
// if (key === '.' && !value.includes('.') && value.length > 0 && !isNaN(Number(value))) {
|
|
// return
|
|
// }
|
|
// if (key === '-' && !value.includes('-') && value.length > 0) {
|
|
// return
|
|
// }
|
|
// if (allowKeys.includes(key)) {
|
|
// return
|
|
// }
|
|
// if (key === 'a' || key === 'c' || key === 'v' || key === 'x' || key === 'z') {
|
|
// return
|
|
// }
|
|
// e.preventDefault()
|
|
// }
|
|
// type=number 정수 부호, 소수점 검사
|
|
const checkInputNumber = (e) => {
|
|
const value = e.target.defaultValue
|
|
if (value === '') return
|
|
|
|
const regex = /^-?([1-9]\d*|\d)(\.\d*)?$/
|
|
if (regex.test(value)) {
|
|
setPrevNum(value)
|
|
} else {
|
|
onChange(prevNum)
|
|
}
|
|
}
|
|
|
|
// input type : text, number
|
|
const inputTextNumber = () => {
|
|
return (
|
|
<input
|
|
type="text"
|
|
className={`input-light ${className ? className : ''}`}
|
|
ref={ref}
|
|
id={id}
|
|
readOnly={readOnly ? true : false}
|
|
placeholder={placeholder}
|
|
value={value}
|
|
onChange={handleTextNumberChange}
|
|
onKeyUp={type === 'number' ? checkInputNumber : undefined}
|
|
/>
|
|
)
|
|
}
|
|
|
|
// input type : radio, checkbox
|
|
const inputRadioCheckbox = () => {
|
|
return (
|
|
<div className="flx">
|
|
{options?.map((option) => (
|
|
<div key={option.name} className={`d-${type}-radio light mr5`}>
|
|
<input
|
|
type={type}
|
|
name={type === 'radio' ? 'radioGroup' : 'checkboxGroup'}
|
|
value={option.value}
|
|
id={option.id}
|
|
checked={type === 'radio' ? value === option.value : value.includes(option.value)}
|
|
onChange={(e) => handleRadioCheckboxChange(e, option.value)}
|
|
/>
|
|
<label htmlFor={option.id}>{option.name}</label>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
return <>{type === 'text' || type === 'number' ? inputTextNumber() : type === 'radio' || type === 'checkbox' ? inputRadioCheckbox() : null}</>
|
|
}
|