import cx from "classnames"; import React from "react"; const CLASS_ROOT = "text-input"; export type TextInputSize = "default" | "large"; export type TextInputWidth = "3ch" | "8ch" | "12ch" | "default" | "fullwidth"; export type TextInputType = | "email" | "hidden" | "password" | "search" | "tel" | "number" | "text" | "url"; export type TextInputSearchIcon = "none" | "transient" | "persistent"; export interface TextInputProps extends Omit, "size"> { /** Input html type. */ htmlType?: TextInputType; /** Html id attribute. */ id: string; /** Disabled state. */ isDisabled?: boolean; /** Invalid state */ isInvalid?: boolean; /** Readonly state. */ isReadonly?: boolean; /** Valid state */ isValid?: boolean; /** Html name attribute. If not present, id is used.*/ name?: string; /** Placeholder text */ placeholder?: string; /** Size of element. */ size?: TextInputSize; /** Input value. */ value?: string; /** Input width */ width?: TextInputWidth; /** Additional CSS classes */ className?: string; /** Search icon mode. `transient` shows icon only on empty unfocused input, `persistent` keeps it visible with placeholder. */ searchIcon?: TextInputSearchIcon; } const defaultProps = { htmlType: "text" as TextInputType, size: "default" as TextInputSize, width: "default" as TextInputWidth, searchIcon: "none" as TextInputSearchIcon, }; const TextInput = React.forwardRef( ( { className, id, isDisabled, isInvalid, isValid, isReadonly, placeholder, size = defaultProps.size, htmlType = defaultProps.htmlType, width = defaultProps.width, searchIcon = defaultProps.searchIcon, name, ...other }, ref, ) => { const hasSearchIcon = searchIcon === "transient"; const hasSearchIconWithPlaceholder = searchIcon === "persistent"; const classes = cx( CLASS_ROOT, { "is-invalid": isInvalid, "is-valid": isValid, [`${CLASS_ROOT}--${size}`]: size !== defaultProps.size, [`${CLASS_ROOT}--${width}`]: width !== defaultProps.width, }, className, ); const inputName = name || id; const inputElement = ( ); if (hasSearchIcon || hasSearchIconWithPlaceholder) { return ( {inputElement} ); } return inputElement; }, ); TextInput.displayName = "TextInput"; export { TextInput };