UNPKG

15.2 kBJavaScriptView Raw
1'use client';
2
3import * as React from 'react';
4import PropTypes from 'prop-types';
5import clsx from 'clsx';
6import composeClasses from '@mui/utils/composeClasses';
7import useId from '@mui/utils/useId';
8import refType from '@mui/utils/refType';
9import { styled } from "../zero-styled/index.js";
10import { useDefaultProps } from "../DefaultPropsProvider/index.js";
11import Input from "../Input/index.js";
12import FilledInput from "../FilledInput/index.js";
13import OutlinedInput from "../OutlinedInput/index.js";
14import InputLabel from "../InputLabel/index.js";
15import FormControl from "../FormControl/index.js";
16import FormHelperText from "../FormHelperText/index.js";
17import Select from "../Select/index.js";
18import { getTextFieldUtilityClass } from "./textFieldClasses.js";
19import useSlot from "../utils/useSlot.js";
20import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
21const variantComponent = {
22 standard: Input,
23 filled: FilledInput,
24 outlined: OutlinedInput
25};
26const useUtilityClasses = ownerState => {
27 const {
28 classes
29 } = ownerState;
30 const slots = {
31 root: ['root']
32 };
33 return composeClasses(slots, getTextFieldUtilityClass, classes);
34};
35const TextFieldRoot = styled(FormControl, {
36 name: 'MuiTextField',
37 slot: 'Root',
38 overridesResolver: (props, styles) => styles.root
39})({});
40
41/**
42 * The `TextField` is a convenience wrapper for the most common cases (80%).
43 * It cannot be all things to all people, otherwise the API would grow out of control.
44 *
45 * ## Advanced Configuration
46 *
47 * It's important to understand that the text field is a simple abstraction
48 * on top of the following components:
49 *
50 * - [FormControl](/material-ui/api/form-control/)
51 * - [InputLabel](/material-ui/api/input-label/)
52 * - [FilledInput](/material-ui/api/filled-input/)
53 * - [OutlinedInput](/material-ui/api/outlined-input/)
54 * - [Input](/material-ui/api/input/)
55 * - [FormHelperText](/material-ui/api/form-helper-text/)
56 *
57 * If you wish to alter the props applied to the `input` element, you can do so as follows:
58 *
59 * ```jsx
60 * const inputProps = {
61 * step: 300,
62 * };
63 *
64 * return <TextField id="time" type="time" inputProps={inputProps} />;
65 * ```
66 *
67 * For advanced cases, please look at the source of TextField by clicking on the
68 * "Edit this page" button above. Consider either:
69 *
70 * - using the upper case props for passing values directly to the components
71 * - using the underlying components directly as shown in the demos
72 */
73const TextField = /*#__PURE__*/React.forwardRef(function TextField(inProps, ref) {
74 const props = useDefaultProps({
75 props: inProps,
76 name: 'MuiTextField'
77 });
78 const {
79 autoComplete,
80 autoFocus = false,
81 children,
82 className,
83 color = 'primary',
84 defaultValue,
85 disabled = false,
86 error = false,
87 FormHelperTextProps: FormHelperTextPropsProp,
88 fullWidth = false,
89 helperText,
90 id: idOverride,
91 InputLabelProps: InputLabelPropsProp,
92 inputProps: inputPropsProp,
93 InputProps: InputPropsProp,
94 inputRef,
95 label,
96 maxRows,
97 minRows,
98 multiline = false,
99 name,
100 onBlur,
101 onChange,
102 onFocus,
103 placeholder,
104 required = false,
105 rows,
106 select = false,
107 SelectProps: SelectPropsProp,
108 slots = {},
109 slotProps = {},
110 type,
111 value,
112 variant = 'outlined',
113 ...other
114 } = props;
115 const ownerState = {
116 ...props,
117 autoFocus,
118 color,
119 disabled,
120 error,
121 fullWidth,
122 multiline,
123 required,
124 select,
125 variant
126 };
127 const classes = useUtilityClasses(ownerState);
128 if (process.env.NODE_ENV !== 'production') {
129 if (select && !children) {
130 console.error('MUI: `children` must be passed when using the `TextField` component with `select`.');
131 }
132 }
133 const id = useId(idOverride);
134 const helperTextId = helperText && id ? `${id}-helper-text` : undefined;
135 const inputLabelId = label && id ? `${id}-label` : undefined;
136 const InputComponent = variantComponent[variant];
137 const externalForwardedProps = {
138 slots,
139 slotProps: {
140 input: InputPropsProp,
141 inputLabel: InputLabelPropsProp,
142 htmlInput: inputPropsProp,
143 formHelperText: FormHelperTextPropsProp,
144 select: SelectPropsProp,
145 ...slotProps
146 }
147 };
148 const inputAdditionalProps = {};
149 const inputLabelSlotProps = externalForwardedProps.slotProps.inputLabel;
150 if (variant === 'outlined') {
151 if (inputLabelSlotProps && typeof inputLabelSlotProps.shrink !== 'undefined') {
152 inputAdditionalProps.notched = inputLabelSlotProps.shrink;
153 }
154 inputAdditionalProps.label = label;
155 }
156 if (select) {
157 // unset defaults from textbox inputs
158 if (!SelectPropsProp || !SelectPropsProp.native) {
159 inputAdditionalProps.id = undefined;
160 }
161 inputAdditionalProps['aria-describedby'] = undefined;
162 }
163 const [InputSlot, inputProps] = useSlot('input', {
164 elementType: InputComponent,
165 externalForwardedProps,
166 additionalProps: inputAdditionalProps,
167 ownerState
168 });
169 const [InputLabelSlot, inputLabelProps] = useSlot('inputLabel', {
170 elementType: InputLabel,
171 externalForwardedProps,
172 ownerState
173 });
174 const [HtmlInputSlot, htmlInputProps] = useSlot('htmlInput', {
175 elementType: 'input',
176 externalForwardedProps,
177 ownerState
178 });
179 const [FormHelperTextSlot, formHelperTextProps] = useSlot('formHelperText', {
180 elementType: FormHelperText,
181 externalForwardedProps,
182 ownerState
183 });
184 const [SelectSlot, selectProps] = useSlot('select', {
185 elementType: Select,
186 externalForwardedProps,
187 ownerState
188 });
189 const InputElement = /*#__PURE__*/_jsx(InputSlot, {
190 "aria-describedby": helperTextId,
191 autoComplete: autoComplete,
192 autoFocus: autoFocus,
193 defaultValue: defaultValue,
194 fullWidth: fullWidth,
195 multiline: multiline,
196 name: name,
197 rows: rows,
198 maxRows: maxRows,
199 minRows: minRows,
200 type: type,
201 value: value,
202 id: id,
203 inputRef: inputRef,
204 onBlur: onBlur,
205 onChange: onChange,
206 onFocus: onFocus,
207 placeholder: placeholder,
208 inputProps: htmlInputProps,
209 slots: {
210 input: slots.htmlInput ? HtmlInputSlot : undefined
211 },
212 ...inputProps
213 });
214 return /*#__PURE__*/_jsxs(TextFieldRoot, {
215 className: clsx(classes.root, className),
216 disabled: disabled,
217 error: error,
218 fullWidth: fullWidth,
219 ref: ref,
220 required: required,
221 color: color,
222 variant: variant,
223 ownerState: ownerState,
224 ...other,
225 children: [label != null && label !== '' && /*#__PURE__*/_jsx(InputLabelSlot, {
226 htmlFor: id,
227 id: inputLabelId,
228 ...inputLabelProps,
229 children: label
230 }), select ? /*#__PURE__*/_jsx(SelectSlot, {
231 "aria-describedby": helperTextId,
232 id: id,
233 labelId: inputLabelId,
234 value: value,
235 input: InputElement,
236 ...selectProps,
237 children: children
238 }) : InputElement, helperText && /*#__PURE__*/_jsx(FormHelperTextSlot, {
239 id: helperTextId,
240 ...formHelperTextProps,
241 children: helperText
242 })]
243 });
244});
245process.env.NODE_ENV !== "production" ? TextField.propTypes /* remove-proptypes */ = {
246 // ┌────────────────────────────── Warning ──────────────────────────────┐
247 // │ These PropTypes are generated from the TypeScript type definitions. │
248 // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
249 // └─────────────────────────────────────────────────────────────────────┘
250 /**
251 * This prop helps users to fill forms faster, especially on mobile devices.
252 * The name can be confusing, as it's more like an autofill.
253 * You can learn more about it [following the specification](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill).
254 */
255 autoComplete: PropTypes.string,
256 /**
257 * If `true`, the `input` element is focused during the first mount.
258 * @default false
259 */
260 autoFocus: PropTypes.bool,
261 /**
262 * @ignore
263 */
264 children: PropTypes.node,
265 /**
266 * Override or extend the styles applied to the component.
267 */
268 classes: PropTypes.object,
269 /**
270 * @ignore
271 */
272 className: PropTypes.string,
273 /**
274 * The color of the component.
275 * It supports both default and custom theme colors, which can be added as shown in the
276 * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
277 * @default 'primary'
278 */
279 color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['primary', 'secondary', 'error', 'info', 'success', 'warning']), PropTypes.string]),
280 /**
281 * The default value. Use when the component is not controlled.
282 */
283 defaultValue: PropTypes.any,
284 /**
285 * If `true`, the component is disabled.
286 * @default false
287 */
288 disabled: PropTypes.bool,
289 /**
290 * If `true`, the label is displayed in an error state.
291 * @default false
292 */
293 error: PropTypes.bool,
294 /**
295 * Props applied to the [`FormHelperText`](https://mui.com/material-ui/api/form-helper-text/) element.
296 * @deprecated Use `slotProps.formHelperText` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details.
297 */
298 FormHelperTextProps: PropTypes.object,
299 /**
300 * If `true`, the input will take up the full width of its container.
301 * @default false
302 */
303 fullWidth: PropTypes.bool,
304 /**
305 * The helper text content.
306 */
307 helperText: PropTypes.node,
308 /**
309 * The id of the `input` element.
310 * Use this prop to make `label` and `helperText` accessible for screen readers.
311 */
312 id: PropTypes.string,
313 /**
314 * Props applied to the [`InputLabel`](https://mui.com/material-ui/api/input-label/) element.
315 * Pointer events like `onClick` are enabled if and only if `shrink` is `true`.
316 * @deprecated Use `slotProps.inputLabel` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details.
317 */
318 InputLabelProps: PropTypes.object,
319 /**
320 * [Attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Attributes) applied to the `input` element.
321 * @deprecated Use `slotProps.htmlInput` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details.
322 */
323 inputProps: PropTypes.object,
324 /**
325 * Props applied to the Input element.
326 * It will be a [`FilledInput`](https://mui.com/material-ui/api/filled-input/),
327 * [`OutlinedInput`](https://mui.com/material-ui/api/outlined-input/) or [`Input`](https://mui.com/material-ui/api/input/)
328 * component depending on the `variant` prop value.
329 * @deprecated Use `slotProps.input` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details.
330 */
331 InputProps: PropTypes.object,
332 /**
333 * Pass a ref to the `input` element.
334 */
335 inputRef: refType,
336 /**
337 * The label content.
338 */
339 label: PropTypes.node,
340 /**
341 * If `dense` or `normal`, will adjust vertical spacing of this and contained components.
342 * @default 'none'
343 */
344 margin: PropTypes.oneOf(['dense', 'none', 'normal']),
345 /**
346 * Maximum number of rows to display when multiline option is set to true.
347 */
348 maxRows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
349 /**
350 * Minimum number of rows to display when multiline option is set to true.
351 */
352 minRows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
353 /**
354 * If `true`, a `textarea` element is rendered instead of an input.
355 * @default false
356 */
357 multiline: PropTypes.bool,
358 /**
359 * Name attribute of the `input` element.
360 */
361 name: PropTypes.string,
362 /**
363 * @ignore
364 */
365 onBlur: PropTypes.func,
366 /**
367 * Callback fired when the value is changed.
368 *
369 * @param {object} event The event source of the callback.
370 * You can pull out the new value by accessing `event.target.value` (string).
371 */
372 onChange: PropTypes.func,
373 /**
374 * @ignore
375 */
376 onFocus: PropTypes.func,
377 /**
378 * The short hint displayed in the `input` before the user enters a value.
379 */
380 placeholder: PropTypes.string,
381 /**
382 * If `true`, the label is displayed as required and the `input` element is required.
383 * @default false
384 */
385 required: PropTypes.bool,
386 /**
387 * Number of rows to display when multiline option is set to true.
388 */
389 rows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
390 /**
391 * Render a [`Select`](https://mui.com/material-ui/api/select/) element while passing the Input element to `Select` as `input` parameter.
392 * If this option is set you must pass the options of the select as children.
393 * @default false
394 */
395 select: PropTypes.bool,
396 /**
397 * Props applied to the [`Select`](https://mui.com/material-ui/api/select/) element.
398 * @deprecated Use `slotProps.select` instead. This prop will be removed in v7. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details.
399 */
400 SelectProps: PropTypes.object,
401 /**
402 * The size of the component.
403 */
404 size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['medium', 'small']), PropTypes.string]),
405 /**
406 * The props used for each slot inside.
407 * @default {}
408 */
409 slotProps: PropTypes /* @typescript-to-proptypes-ignore */.shape({
410 formHelperText: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
411 htmlInput: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
412 input: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
413 inputLabel: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
414 select: PropTypes.oneOfType([PropTypes.func, PropTypes.object])
415 }),
416 /**
417 * The components used for each slot inside.
418 * @default {}
419 */
420 slots: PropTypes.shape({
421 formHelperText: PropTypes.elementType,
422 htmlInput: PropTypes.elementType,
423 input: PropTypes.elementType,
424 inputLabel: PropTypes.elementType,
425 select: PropTypes.elementType
426 }),
427 /**
428 * The system prop that allows defining system overrides as well as additional CSS styles.
429 */
430 sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
431 /**
432 * Type of the `input` element. It should be [a valid HTML5 input type](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Form_%3Cinput%3E_types).
433 */
434 type: PropTypes /* @typescript-to-proptypes-ignore */.string,
435 /**
436 * The value of the `input` element, required for a controlled component.
437 */
438 value: PropTypes.any,
439 /**
440 * The variant to use.
441 * @default 'outlined'
442 */
443 variant: PropTypes.oneOf(['filled', 'outlined', 'standard'])
444} : void 0;
445export default TextField;
\No newline at end of file