import type { AriaAttributes, FormEvent, InputHTMLAttributes, ReactNode, } from 'react' import React, { forwardRef, useImperativeHandle, useRef } from 'react' import { Icon, IconButton, Input } from '../..' type InputProps = Omit, 'onSubmit'> type ButtonProps = { onClick?: () => void testId?: string 'aria-label'?: string } export interface SearchInputFieldProps extends InputProps { /** * ID to find this component in testing tools (e.g.: cypress, testing library, and jest). */ testId?: string /** * Props for the submit button inside the input. */ buttonProps?: ButtonProps /** * A React component that will be rendered as an icon (submit button). * @default */ buttonIcon?: ReactNode /** * Whether to show the attachment button. * @default false */ showAttachmentButton?: boolean /** * Props for the paperclip button inside the input. */ attachmentButtonProps?: ButtonProps /** * Aria-label for the attachment button (e.g. from CMS). */ attachmentButtonAriaLabel?: string /** * Aria-label for the submit button (e.g. from CMS). */ submitButtonAriaLabel?: string /** * A React component that will be rendered as an icon (attachment button). * @default */ attachmentButtonIcon?: ReactNode /** * Aria-label for the search input (e.g. from CMS). */ 'aria-label'?: AriaAttributes['aria-label'] /** * Callback function when submitted. */ onSubmit: (value: string) => void } export interface SearchInputFieldRef { inputRef?: HTMLInputElement | null formRef?: HTMLFormElement | null } const SearchInputField = forwardRef< SearchInputFieldRef | null, SearchInputFieldProps >(function SearchInputField( { onSubmit, buttonIcon, showAttachmentButton = false, attachmentButtonAriaLabel, attachmentButtonIcon, attachmentButtonProps, submitButtonAriaLabel, 'aria-label': ariaLabel, testId = 'fs-search-input', buttonProps, ...otherProps }, ref ) { const inputRef = useRef(null) const formRef = useRef(null) const handleSubmit = (event: FormEvent) => { event.preventDefault() if (inputRef.current?.value !== '') { onSubmit(inputRef.current!.value) } } const { 'aria-label': buttonAriaLabel, ...otherButtonProps } = buttonProps ?? {} useImperativeHandle(ref, () => ({ inputRef: inputRef.current, formRef: formRef.current, })) return (
{showAttachmentButton && ( <> } size="small" {...attachmentButtonProps} /> )} } size="small" {...otherButtonProps} />
) }) export default SearchInputField