2021-03-24 17:31:50 +01:00
|
|
|
/**
|
|
|
|
* This component is a template for an input component that wraps the application style
|
|
|
|
*/
|
|
|
|
|
2021-03-30 11:26:47 +02:00
|
|
|
import React, { BaseSyntheticEvent, ReactNode, useCallback, useState } from 'react';
|
2021-03-24 17:31:50 +01:00
|
|
|
import { debounce as _debounce } from 'lodash';
|
|
|
|
|
|
|
|
interface FabInputProps {
|
|
|
|
id: string,
|
2021-03-30 11:26:47 +02:00
|
|
|
onChange?: (event: BaseSyntheticEvent) => void,
|
2021-03-24 17:31:50 +01:00
|
|
|
value: any,
|
|
|
|
icon?: ReactNode,
|
|
|
|
addOn?: ReactNode,
|
|
|
|
addOnClassName?: string,
|
|
|
|
className?: string,
|
|
|
|
disabled?: boolean,
|
|
|
|
required?: boolean,
|
|
|
|
debounce?: number,
|
|
|
|
type?: 'text' | 'date' | 'password' | 'url' | 'time' | 'tel' | 'search' | 'number' | 'month' | 'email' | 'datetime-local' | 'week',
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const FabInput: React.FC<FabInputProps> = ({ id, onChange, value, icon, className, disabled, type, required, debounce, addOn, addOnClassName }) => {
|
2021-03-30 11:26:47 +02:00
|
|
|
const [inputValue, setInputValue] = useState<any>(value);
|
|
|
|
|
2021-03-24 17:31:50 +01:00
|
|
|
/**
|
|
|
|
* Check if the current component was provided an icon to display
|
|
|
|
*/
|
|
|
|
const hasIcon = (): boolean => {
|
|
|
|
return !!icon;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if the current component was provided an add-on element to display, at the end of the input
|
|
|
|
*/
|
|
|
|
const hasAddOn = (): boolean => {
|
|
|
|
return !!addOn;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Debounced (ie. temporised) version of the 'on change' callback.
|
|
|
|
*/
|
|
|
|
const handler = useCallback(_debounce(onChange, debounce), []);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handle the action of the button
|
|
|
|
*/
|
2021-03-30 11:26:47 +02:00
|
|
|
const handleChange = (e: BaseSyntheticEvent): void => {
|
|
|
|
setInputValue(e.target.value);
|
2021-03-24 17:31:50 +01:00
|
|
|
if (typeof onChange === 'function') {
|
2021-03-30 11:26:47 +02:00
|
|
|
if (debounce) {
|
|
|
|
handler(e);
|
|
|
|
} else {
|
|
|
|
onChange(e);
|
|
|
|
}
|
2021-03-24 17:31:50 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div className={`fab-input ${className ? className : ''}`}>
|
|
|
|
{hasIcon() && <span className="fab-input--icon">{icon}</span>}
|
2021-03-30 11:26:47 +02:00
|
|
|
<input id={id} type={type} className="fab-input--input" value={inputValue} onChange={handleChange} disabled={disabled} required={required} />
|
2021-03-24 17:31:50 +01:00
|
|
|
{hasAddOn() && <span className={`fab-input--addon ${addOnClassName ? addOnClassName : ''}`}>{addOn}</span>}
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
FabInput.defaultProps = { type: 'text', debounce: 0 };
|
|
|
|
|