/** * This component is a template for an input component that wraps the application style */ import React, { BaseSyntheticEvent, ReactNode, useCallback, useState } from 'react'; import { debounce as _debounce } from 'lodash'; interface FabInputProps { id: string, onChange?: (event: BaseSyntheticEvent) => void, 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 = ({ id, onChange, value, icon, className, disabled, type, required, debounce, addOn, addOnClassName }) => { const [inputValue, setInputValue] = useState(value); /** * 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 */ const handleChange = (e: BaseSyntheticEvent): void => { setInputValue(e.target.value); if (typeof onChange === 'function') { if (debounce) { handler(e); } else { onChange(e); } } } return (
{hasIcon() && {icon}} {hasAddOn() && {addOn}}
); } FabInput.defaultProps = { type: 'text', debounce: 0 };