blakeblackshear.frigate/web/src/components/TextField.jsx

103 lines
2.7 KiB
React
Raw Normal View History

2021-02-02 05:28:25 +01:00
import { h } from 'preact';
import { useCallback, useEffect, useState } from 'preact/hooks';
export default function TextField({
helpText,
keyboardType = 'text',
inputRef,
label,
leadingIcon: LeadingIcon,
onBlur,
onChangeText,
onFocus,
readonly,
trailingIcon: TrailingIcon,
value: propValue = '',
...props
}) {
const [isFocused, setFocused] = useState(false);
const [value, setValue] = useState(propValue);
const handleFocus = useCallback(
(event) => {
setFocused(true);
onFocus && onFocus(event);
},
[onFocus]
);
const handleBlur = useCallback(
(event) => {
setFocused(false);
onBlur && onBlur(event);
},
[onBlur]
);
const handleChange = useCallback(
(event) => {
const { value } = event.target;
setValue(value);
onChangeText && onChangeText(value);
},
[onChangeText, setValue]
);
useEffect(() => {
if (propValue !== value) {
setValue(propValue);
}
// DO NOT include `value`
}, [propValue, setValue]); // eslint-disable-line react-hooks/exhaustive-deps
2021-02-02 05:28:25 +01:00
const labelMoved = isFocused || value !== '';
return (
<div className="w-full">
<div
className={`bg-gray-100 dark:bg-gray-700 rounded rounded-b-none border-gray-400 border-b p-1 pl-4 pr-3 ${
isFocused ? 'border-blue-500 dark:border-blue-500' : ''
}`}
ref={inputRef}
>
2021-02-14 16:56:10 +01:00
<label
className="flex space-x-2 items-center"
data-testid={`label-${label.toLowerCase().replace(/[^\w]+/g, '_')}`}
>
2021-02-05 00:19:47 +01:00
{LeadingIcon ? (
<div className="w-10 h-full">
2021-02-05 00:19:47 +01:00
<LeadingIcon />
</div>
) : null}
2021-02-02 05:28:25 +01:00
<div className="relative w-full">
<input
className="h-6 mt-6 w-full bg-transparent focus:outline-none focus:ring-0"
onBlur={handleBlur}
onFocus={handleFocus}
onInput={handleChange}
readOnly={readonly}
tabIndex="0"
2021-02-02 05:28:25 +01:00
type={keyboardType}
value={value}
{...props}
/>
<div
className={`absolute top-3 transition transform text-gray-600 dark:text-gray-400 ${
labelMoved ? 'text-xs -translate-y-2' : ''
} ${isFocused ? 'text-blue-500 dark:text-blue-500' : ''}`}
>
{label}
</div>
</div>
2021-02-05 00:19:47 +01:00
{TrailingIcon ? (
<div className="w-10 h-10">
2021-02-05 00:19:47 +01:00
<TrailingIcon />
</div>
) : null}
2021-02-02 05:28:25 +01:00
</label>
</div>
{helpText ? <div className="text-xs pl-3 pt-1">{helpText}</div> : null}
</div>
);
}