File size: 1,771 Bytes
f0743f4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import React from 'react';
import type { ControllerRenderProps, FieldValues, FieldPath } from 'react-hook-form';
import { Label } from './Label';
import { Input } from './Input';
import { cn } from '~/utils';

export default function FormInput<
  TFieldValues extends FieldValues = FieldValues,
  TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
>({
  field,
  label,
  labelClass,
  inputClass,
  containerClass,
  labelAdjacent,
  placeholder = '',
  type = 'string',
}: {
  field: ControllerRenderProps<TFieldValues, TName>;
  label: string;
  labelClass?: string;
  inputClass?: string;
  placeholder?: string;
  containerClass?: string;
  type?: 'string' | 'number';
  labelAdjacent?: React.ReactNode;
}) {
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;

    if (type !== 'number') {
      field.onChange(value);
      return;
    }

    if (value === '') {
      field.onChange(value);
    } else if (!isNaN(Number(value))) {
      field.onChange(Number(value));
    }
  };

  return (
    <div className={cn('flex w-full flex-col items-center gap-2', containerClass)}>
      <div className="flex w-full items-center justify-start gap-2">
        <Label
          htmlFor={`${field.name}-input`}
          className={cn('text-left text-sm font-semibold text-text-primary', labelClass)}
        >
          {label}
        </Label>
        {labelAdjacent}
      </div>
      <Input
        id={`${field.name}-input`}
        value={field.value ?? ''}
        onChange={handleChange}
        placeholder={placeholder}
        className={cn(
          'flex h-10 max-h-10 w-full resize-none border-none bg-surface-secondary px-3 py-2',
          inputClass,
        )}
      />
    </div>
  );
}