Input.tsx 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import type { FC } from 'react'
  2. import { CheckCircle } from '@/app/components/base/icons/src/vender/solid/general'
  3. type InputProps = {
  4. value?: string
  5. onChange: (v: string) => void
  6. onFocus?: () => void
  7. placeholder?: string
  8. validated?: boolean
  9. className?: string
  10. disabled?: boolean
  11. type?: string
  12. min?: number
  13. max?: number
  14. }
  15. const Input: FC<InputProps> = ({
  16. value,
  17. onChange,
  18. onFocus,
  19. placeholder,
  20. validated,
  21. className,
  22. disabled,
  23. type = 'text',
  24. min,
  25. max,
  26. }) => {
  27. const toLimit = (v: string) => {
  28. const minNum = parseFloat(`${min}`)
  29. const maxNum = parseFloat(`${max}`)
  30. if (!isNaN(minNum) && parseFloat(v) < minNum) {
  31. onChange(`${min}`)
  32. return
  33. }
  34. if (!isNaN(maxNum) && parseFloat(v) > maxNum)
  35. onChange(`${max}`)
  36. }
  37. return (
  38. <div className='relative'>
  39. <input
  40. tabIndex={0}
  41. className={`
  42. block px-3 w-full h-9 bg-gray-100 text-sm rounded-lg border border-transparent
  43. appearance-none outline-none caret-primary-600
  44. hover:border-[rgba(0,0,0,0.08)] hover:bg-gray-50
  45. focus:bg-white focus:border-gray-300 focus:shadow-xs
  46. placeholder:text-sm placeholder:text-gray-400
  47. ${validated && 'pr-[30px]'}
  48. ${className}
  49. `}
  50. placeholder={placeholder || ''}
  51. onChange={e => onChange(e.target.value)}
  52. onBlur={e => toLimit(e.target.value)}
  53. onFocus={onFocus}
  54. value={value}
  55. disabled={disabled}
  56. type={type}
  57. min={min}
  58. max={max}
  59. />
  60. {
  61. validated && (
  62. <div className='absolute top-2.5 right-2.5'>
  63. <CheckCircle className='w-4 h-4 text-[#039855]' />
  64. </div>
  65. )
  66. }
  67. </div>
  68. )
  69. }
  70. export default Input