import { type CSSProperties, type HTMLAttributes, type InputHTMLAttributes, type ReactElement, type Ref, } from "react"; import { type PropsWithRef } from "../types.js"; import { useEnsuredId } from "../useEnsuredId.js"; import { FormMessageContainer } from "./FormMessageContainer.js"; import { Label } from "./Label.js"; import { TextFieldContainer } from "./TextFieldContainer.js"; import { textField } from "./textFieldStyles.js"; import { type FormFieldOptions, type UserAgentAutocompleteProps, } from "./types.js"; /** * These are all the "supported" input types for react-md so that they at least * render reasonably well by default. There is no built-in validation or * anything adding onto existing browser functionality for these types. * * @since 2.5.0 - `"search"` was added * @since 6.0.0 Dropped support for `"week"` and `"month"` input types since * they are not available in Firefox and Safari at this time. */ export type SupportedInputTypes = | "text" | "password" | "number" | "tel" | "email" | "date" | "time" | "datetime-local" | "url" | "color" | "search"; /** * @since 6.0.0 Renamed from `TextFieldAttributes` to * `TextFieldInputAttributes` */ export type TextFieldInputAttributes = Omit< InputHTMLAttributes, "type" >; /** * @since 6.0.0 Removed the `containerRef` prop. */ export interface TextFieldProps extends TextFieldInputAttributes, UserAgentAutocompleteProps, FormFieldOptions { ref?: Ref; /** * @defaultValue `"text-field-" + useId()` */ id?: string; /** * Optional placeholder text to display in the text field. * * @defaultValue `label ? " " : ""` */ placeholder?: string; /** * Any optional inline styles to set on the input. */ inputStyle?: CSSProperties; /** * An optional `className` to add to the input. */ inputClassName?: string; /** * The text field type. * * @defaultValue `"text"` */ type?: SupportedInputTypes; /** * Optional props to provide to the {@link TextFieldContainer} component. * There probably isn't any real use for this prop other than if you need to * add a `ref` for some DOM behavior. */ containerProps?: PropsWithRef>; } /** * The structure for this component is: * @example Component Structure * ```tsx * * * * * * ``` * * @example Simple Example * ```tsx * import { TextField } from "@react-md/core/form/TextField"; * import type { ReactElement } from "react"; * * function Example(): ReactElement { * return ( * * ); * } * ``` * * @see {@link https://react-md.dev/components/textfield | TextField Demos} */ export function TextField(props: TextFieldProps): ReactElement { const { ref, id: propId, style, className, type = "text", label, labelProps, labelStyle, labelClassName, autoCompleteValue, autoComplete = autoCompleteValue, name = autoCompleteValue, dense, error, active, inline, leftAddon, leftAddonProps, rightAddon, rightAddonProps, disableLeftAddonStyles, disableRightAddonStyles, inputStyle, inputClassName, theme, underlineDirection, messageProps, messageContainerProps, containerProps, ...remaining } = props; const { disabled, readOnly } = props; const id = useEnsuredId(propId, "text-field"); let { placeholder = "" } = props; if (label && !placeholder) { // See the placeholder type definition comments for information placeholder = " "; } return ( {label && ( )} ); }