'use client'; import { bool, oneOf, string } from 'prop-types'; import React, { FocusEvent, forwardRef, useState } from 'react'; import { TextFieldInterface } from './text-field.types'; export const TextField = forwardRef<HTMLInputElement, TextFieldInterface>( ( { variant = 'filled', withAfterIcon, withBeforeIcon, supportingText, ...props }, ref, ) => { const [raised, setRaised] = useState<boolean>(!!props.placeholder); const callback = (e: FocusEvent<HTMLInputElement>): void => { if ( e.type === 'blur' && e.target.value.length === 0 && !props.placeholder ) { setRaised(false); } else if (e.type === 'focus') { setRaised(true); } }; const iconStyles = withBeforeIcon && withAfterIcon ? 'with-before-icon with-after-icon' : withBeforeIcon ? 'with-before-icon' : withAfterIcon ? 'with-after-icon' : ''; return ( <span> <div className={`m3 m3-text-field ${variant}`.trimEnd()}> {variant === 'outlined' && ( <fieldset> <legend className={raised && 'raised'}> <span>Label</span> </legend> </fieldset> )} {withBeforeIcon && ( <span className={'m3-icon icon-before'}> {withBeforeIcon && 'search'} </span> )} <input ref={ref} {...props} className={`${props.className ?? ''} ${iconStyles}`.trim()} onBlur={event => { callback(event); if (props.onBlur) { props.onBlur(event); } }} onFocus={event => { callback(event); if (props.onFocus) { props.onFocus(event); } }} /> <label className={raised ? 'raised' : ''}> {props.children ?? 'Label'} </label> <span className={'m3-text-field-state-layer'} /> {withAfterIcon && ( <span className={'m3-icon'}> {withAfterIcon && 'cancel'} </span> )} </div> {supportingText !== '' && ( <span className={'m3-text-field-supporting-text'}> {supportingText} </span> )} </span> ); }, ); TextField.propTypes = { children: string, className: string, placeholder: string, withAfterIcon: bool, withBeforeIcon: bool, supportingText: string, variant: oneOf(['filled', 'outlined']), };