|
1 |
| -import classNames from 'classnames'; |
2 |
| -import React, { |
3 |
| - InputHTMLAttributes, |
4 |
| - TextareaHTMLAttributes, |
5 |
| - forwardRef, |
6 |
| - useEffect, |
7 |
| - useState, |
8 |
| -} from 'react'; |
| 1 | +import React, { forwardRef, useContext } from 'react'; |
| 2 | +import { FormContext } from './Form'; |
| 3 | +import { REGULAR_INPUT_CLASSNAMES } from './regularInputClassnames'; |
9 | 4 |
|
10 |
| -type FormControlProps<T extends 'input' | 'textarea'> = T extends 'input' |
11 |
| - ? InputHTMLAttributes<HTMLInputElement> |
12 |
| - : T extends 'textarea' |
13 |
| - ? TextareaHTMLAttributes<HTMLTextAreaElement> |
14 |
| - : never; |
| 5 | +type InputProps = React.DetailedHTMLProps< |
| 6 | + React.InputHTMLAttributes<HTMLInputElement>, |
| 7 | + HTMLInputElement |
| 8 | +>; |
15 | 9 |
|
16 |
| -interface FormInputBaseProps<T extends 'input' | 'textarea'> { |
17 |
| - label?: string; |
18 |
| - hint?: string; |
19 |
| - suffixText?: string; |
20 |
| - noEndMargin?: boolean; |
21 |
| - as?: T; |
22 |
| -} |
| 10 | +export interface FormInputProps extends InputProps {} |
23 | 11 |
|
24 |
| -type InputProps = FormInputBaseProps<'input'> & FormControlProps<'input'>; |
25 |
| -type TextareaProps = FormInputBaseProps<'textarea'> & FormControlProps<'textarea'>; |
26 |
| -type FormInputProps = InputProps | TextareaProps; |
27 |
| - |
28 |
| -const FormInput = forwardRef(function TextInput( |
29 |
| - { label, hint, suffixText, as, noEndMargin, ...props }: FormInputProps, |
30 |
| - ref: any, |
31 |
| -) { |
32 |
| - const [focused, setFocused] = useState(false); |
33 |
| - |
34 |
| - if (props.readOnly) { |
35 |
| - props.disabled = true; |
36 |
| - } |
37 |
| - |
38 |
| - useEffect(() => { |
39 |
| - if (props.disabled) { |
40 |
| - setFocused(false); |
41 |
| - } |
42 |
| - }, [props.disabled]); |
43 |
| - |
44 |
| - const element = React.createElement(as || 'input', { |
45 |
| - ...props, |
46 |
| - ref, |
47 |
| - onFocus: () => setFocused(true), |
48 |
| - onBlur: () => setFocused(false), |
49 |
| - className: classNames( |
50 |
| - 'flex flex-1 bg-inherit px-4 py-2 outline-none disabled:bg-gray-100 ', |
51 |
| - 'rounded-md text-muted', |
52 |
| - ), |
53 |
| - }); |
| 12 | +const FormInput = forwardRef(function FromInput(props: FormInputProps, ref: any) { |
| 13 | + const { formLoading: formDisabled } = useContext(FormContext); |
54 | 14 |
|
55 | 15 | return (
|
56 |
| - <div className={classNames('relative', !noEndMargin && 'my-6')}> |
57 |
| - <div className="mb-2 ms-1"> |
58 |
| - <label className="flex gap-1"> |
59 |
| - {label} |
60 |
| - {hint ? <span className="text-muted">({hint})</span> : null} |
61 |
| - {props.required ? <span>*</span> : null} |
62 |
| - </label> |
63 |
| - </div> |
64 |
| - |
65 |
| - <div className="flex items-center gap-4"> |
66 |
| - <div |
67 |
| - className={classNames( |
68 |
| - 'flex flex-1 rounded-md border transition-colors', |
69 |
| - focused ? 'border-primary' : 'border-gray-300', |
70 |
| - )} |
71 |
| - > |
72 |
| - {element} |
73 |
| - </div> |
74 |
| - {suffixText ? <span>{suffixText}</span> : null} |
75 |
| - </div> |
76 |
| - </div> |
| 16 | + <input |
| 17 | + {...props} |
| 18 | + ref={ref} |
| 19 | + disabled={formDisabled || props.readOnly || props.disabled} |
| 20 | + className={REGULAR_INPUT_CLASSNAMES} |
| 21 | + /> |
77 | 22 | );
|
78 | 23 | });
|
79 | 24 |
|
|
0 commit comments