UNPKG

22.1 kBJavaScriptView Raw
1"use strict";
2
3var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
4
5var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
6
7Object.defineProperty(exports, "__esModule", {
8 value: true
9});
10exports.default = exports.styles = void 0;
11
12var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
13
14var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
15
16var _utils = require("@material-ui/utils");
17
18var React = _interopRequireWildcard(require("react"));
19
20var _propTypes = _interopRequireDefault(require("prop-types"));
21
22var _clsx = _interopRequireDefault(require("clsx"));
23
24var _formControlState = _interopRequireDefault(require("../FormControl/formControlState"));
25
26var _FormControlContext = _interopRequireWildcard(require("../FormControl/FormControlContext"));
27
28var _withStyles = _interopRequireDefault(require("../styles/withStyles"));
29
30var _capitalize = _interopRequireDefault(require("../utils/capitalize"));
31
32var _useForkRef = _interopRequireDefault(require("../utils/useForkRef"));
33
34var _TextareaAutosize = _interopRequireDefault(require("../TextareaAutosize"));
35
36var _utils2 = require("./utils");
37
38/* eslint-disable jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */
39var styles = function styles(theme) {
40 var light = theme.palette.type === 'light';
41 var placeholder = {
42 color: 'currentColor',
43 opacity: light ? 0.42 : 0.5,
44 transition: theme.transitions.create('opacity', {
45 duration: theme.transitions.duration.shorter
46 })
47 };
48 var placeholderHidden = {
49 opacity: '0 !important'
50 };
51 var placeholderVisible = {
52 opacity: light ? 0.42 : 0.5
53 };
54 return {
55 '@global': {
56 '@keyframes mui-auto-fill': {},
57 '@keyframes mui-auto-fill-cancel': {}
58 },
59
60 /* Styles applied to the root element. */
61 root: (0, _extends2.default)({}, theme.typography.body1, {
62 color: theme.palette.text.primary,
63 lineHeight: '1.1876em',
64 // Reset (19px), match the native input line-height
65 boxSizing: 'border-box',
66 // Prevent padding issue with fullWidth.
67 position: 'relative',
68 cursor: 'text',
69 display: 'inline-flex',
70 alignItems: 'center',
71 '&$disabled': {
72 color: theme.palette.text.disabled,
73 cursor: 'default'
74 }
75 }),
76
77 /* Styles applied to the root element if the component is a descendant of `FormControl`. */
78 formControl: {},
79
80 /* Styles applied to the root element if the component is focused. */
81 focused: {},
82
83 /* Styles applied to the root element if `disabled={true}`. */
84 disabled: {},
85
86 /* Styles applied to the root element if `startAdornment` is provided. */
87 adornedStart: {},
88
89 /* Styles applied to the root element if `endAdornment` is provided. */
90 adornedEnd: {},
91
92 /* Pseudo-class applied to the root element if `error={true}`. */
93 error: {},
94
95 /* Styles applied to the `input` element if `margin="dense"`. */
96 marginDense: {},
97
98 /* Styles applied to the root element if `multiline={true}`. */
99 multiline: {
100 padding: "".concat(8 - 2, "px 0 ").concat(8 - 1, "px"),
101 '&$marginDense': {
102 paddingTop: 4 - 1
103 }
104 },
105
106 /* Styles applied to the root element if the color is secondary. */
107 colorSecondary: {},
108
109 /* Styles applied to the root element if `fullWidth={true}`. */
110 fullWidth: {
111 width: '100%'
112 },
113
114 /* Styles applied to the `input` element. */
115 input: {
116 font: 'inherit',
117 letterSpacing: 'inherit',
118 color: 'currentColor',
119 padding: "".concat(8 - 2, "px 0 ").concat(8 - 1, "px"),
120 border: 0,
121 boxSizing: 'content-box',
122 background: 'none',
123 height: '1.1876em',
124 // Reset (19px), match the native input line-height
125 margin: 0,
126 // Reset for Safari
127 WebkitTapHighlightColor: 'transparent',
128 display: 'block',
129 // Make the flex item shrink with Firefox
130 minWidth: 0,
131 width: '100%',
132 // Fix IE 11 width issue
133 animationName: 'mui-auto-fill-cancel',
134 animationDuration: '10ms',
135 '&::-webkit-input-placeholder': placeholder,
136 '&::-moz-placeholder': placeholder,
137 // Firefox 19+
138 '&:-ms-input-placeholder': placeholder,
139 // IE 11
140 '&::-ms-input-placeholder': placeholder,
141 // Edge
142 '&:focus': {
143 outline: 0
144 },
145 // Reset Firefox invalid required input style
146 '&:invalid': {
147 boxShadow: 'none'
148 },
149 '&::-webkit-search-decoration': {
150 // Remove the padding when type=search.
151 '-webkit-appearance': 'none'
152 },
153 // Show and hide the placeholder logic
154 'label[data-shrink=false] + $formControl &': {
155 '&::-webkit-input-placeholder': placeholderHidden,
156 '&::-moz-placeholder': placeholderHidden,
157 // Firefox 19+
158 '&:-ms-input-placeholder': placeholderHidden,
159 // IE 11
160 '&::-ms-input-placeholder': placeholderHidden,
161 // Edge
162 '&:focus::-webkit-input-placeholder': placeholderVisible,
163 '&:focus::-moz-placeholder': placeholderVisible,
164 // Firefox 19+
165 '&:focus:-ms-input-placeholder': placeholderVisible,
166 // IE 11
167 '&:focus::-ms-input-placeholder': placeholderVisible // Edge
168
169 },
170 '&$disabled': {
171 opacity: 1 // Reset iOS opacity
172
173 },
174 '&:-webkit-autofill': {
175 animationDuration: '5000s',
176 animationName: 'mui-auto-fill'
177 }
178 },
179
180 /* Styles applied to the `input` element if `margin="dense"`. */
181 inputMarginDense: {
182 paddingTop: 4 - 1
183 },
184
185 /* Styles applied to the `input` element if `multiline={true}`. */
186 inputMultiline: {
187 height: 'auto',
188 resize: 'none',
189 padding: 0
190 },
191
192 /* Styles applied to the `input` element if `type="search"`. */
193 inputTypeSearch: {
194 // Improve type search style.
195 '-moz-appearance': 'textfield',
196 '-webkit-appearance': 'textfield'
197 },
198
199 /* Styles applied to the `input` element if `startAdornment` is provided. */
200 inputAdornedStart: {},
201
202 /* Styles applied to the `input` element if `endAdornment` is provided. */
203 inputAdornedEnd: {},
204
205 /* Styles applied to the `input` element if `hiddenLabel={true}`. */
206 inputHiddenLabel: {}
207 };
208};
209
210exports.styles = styles;
211var useEnhancedEffect = typeof window === 'undefined' ? React.useEffect : React.useLayoutEffect;
212/**
213 * `InputBase` contains as few styles as possible.
214 * It aims to be a simple building block for creating an input.
215 * It contains a load of style reset and some state logic.
216 */
217
218var InputBase = /*#__PURE__*/React.forwardRef(function InputBase(props, ref) {
219 var ariaDescribedby = props['aria-describedby'],
220 autoComplete = props.autoComplete,
221 autoFocus = props.autoFocus,
222 classes = props.classes,
223 className = props.className,
224 color = props.color,
225 defaultValue = props.defaultValue,
226 disabled = props.disabled,
227 endAdornment = props.endAdornment,
228 error = props.error,
229 _props$fullWidth = props.fullWidth,
230 fullWidth = _props$fullWidth === void 0 ? false : _props$fullWidth,
231 id = props.id,
232 _props$inputComponent = props.inputComponent,
233 inputComponent = _props$inputComponent === void 0 ? 'input' : _props$inputComponent,
234 _props$inputProps = props.inputProps,
235 inputPropsProp = _props$inputProps === void 0 ? {} : _props$inputProps,
236 inputRefProp = props.inputRef,
237 margin = props.margin,
238 _props$multiline = props.multiline,
239 multiline = _props$multiline === void 0 ? false : _props$multiline,
240 name = props.name,
241 onBlur = props.onBlur,
242 onChange = props.onChange,
243 onClick = props.onClick,
244 onFocus = props.onFocus,
245 onKeyDown = props.onKeyDown,
246 onKeyUp = props.onKeyUp,
247 placeholder = props.placeholder,
248 readOnly = props.readOnly,
249 renderSuffix = props.renderSuffix,
250 rows = props.rows,
251 rowsMax = props.rowsMax,
252 rowsMin = props.rowsMin,
253 maxRows = props.maxRows,
254 minRows = props.minRows,
255 startAdornment = props.startAdornment,
256 _props$type = props.type,
257 type = _props$type === void 0 ? 'text' : _props$type,
258 valueProp = props.value,
259 other = (0, _objectWithoutProperties2.default)(props, ["aria-describedby", "autoComplete", "autoFocus", "classes", "className", "color", "defaultValue", "disabled", "endAdornment", "error", "fullWidth", "id", "inputComponent", "inputProps", "inputRef", "margin", "multiline", "name", "onBlur", "onChange", "onClick", "onFocus", "onKeyDown", "onKeyUp", "placeholder", "readOnly", "renderSuffix", "rows", "rowsMax", "rowsMin", "maxRows", "minRows", "startAdornment", "type", "value"]);
260 var value = inputPropsProp.value != null ? inputPropsProp.value : valueProp;
261
262 var _React$useRef = React.useRef(value != null),
263 isControlled = _React$useRef.current;
264
265 var inputRef = React.useRef();
266 var handleInputRefWarning = React.useCallback(function (instance) {
267 if (process.env.NODE_ENV !== 'production') {
268 if (instance && instance.nodeName !== 'INPUT' && !instance.focus) {
269 console.error(['Material-UI: You have provided a `inputComponent` to the input component', 'that does not correctly handle the `inputRef` prop.', 'Make sure the `inputRef` prop is called with a HTMLInputElement.'].join('\n'));
270 }
271 }
272 }, []);
273 var handleInputPropsRefProp = (0, _useForkRef.default)(inputPropsProp.ref, handleInputRefWarning);
274 var handleInputRefProp = (0, _useForkRef.default)(inputRefProp, handleInputPropsRefProp);
275 var handleInputRef = (0, _useForkRef.default)(inputRef, handleInputRefProp);
276
277 var _React$useState = React.useState(false),
278 focused = _React$useState[0],
279 setFocused = _React$useState[1];
280
281 var muiFormControl = (0, _FormControlContext.useFormControl)();
282
283 if (process.env.NODE_ENV !== 'production') {
284 // eslint-disable-next-line react-hooks/rules-of-hooks
285 React.useEffect(function () {
286 if (muiFormControl) {
287 return muiFormControl.registerEffect();
288 }
289
290 return undefined;
291 }, [muiFormControl]);
292 }
293
294 var fcs = (0, _formControlState.default)({
295 props: props,
296 muiFormControl: muiFormControl,
297 states: ['color', 'disabled', 'error', 'hiddenLabel', 'margin', 'required', 'filled']
298 });
299 fcs.focused = muiFormControl ? muiFormControl.focused : focused; // The blur won't fire when the disabled state is set on a focused input.
300 // We need to book keep the focused state manually.
301
302 React.useEffect(function () {
303 if (!muiFormControl && disabled && focused) {
304 setFocused(false);
305
306 if (onBlur) {
307 onBlur();
308 }
309 }
310 }, [muiFormControl, disabled, focused, onBlur]);
311 var onFilled = muiFormControl && muiFormControl.onFilled;
312 var onEmpty = muiFormControl && muiFormControl.onEmpty;
313 var checkDirty = React.useCallback(function (obj) {
314 if ((0, _utils2.isFilled)(obj)) {
315 if (onFilled) {
316 onFilled();
317 }
318 } else if (onEmpty) {
319 onEmpty();
320 }
321 }, [onFilled, onEmpty]);
322 useEnhancedEffect(function () {
323 if (isControlled) {
324 checkDirty({
325 value: value
326 });
327 }
328 }, [value, checkDirty, isControlled]);
329
330 var handleFocus = function handleFocus(event) {
331 // Fix a bug with IE 11 where the focus/blur events are triggered
332 // while the input is disabled.
333 if (fcs.disabled) {
334 event.stopPropagation();
335 return;
336 }
337
338 if (onFocus) {
339 onFocus(event);
340 }
341
342 if (inputPropsProp.onFocus) {
343 inputPropsProp.onFocus(event);
344 }
345
346 if (muiFormControl && muiFormControl.onFocus) {
347 muiFormControl.onFocus(event);
348 } else {
349 setFocused(true);
350 }
351 };
352
353 var handleBlur = function handleBlur(event) {
354 if (onBlur) {
355 onBlur(event);
356 }
357
358 if (inputPropsProp.onBlur) {
359 inputPropsProp.onBlur(event);
360 }
361
362 if (muiFormControl && muiFormControl.onBlur) {
363 muiFormControl.onBlur(event);
364 } else {
365 setFocused(false);
366 }
367 };
368
369 var handleChange = function handleChange(event) {
370 if (!isControlled) {
371 var element = event.target || inputRef.current;
372
373 if (element == null) {
374 throw new Error(process.env.NODE_ENV !== "production" ? "Material-UI: Expected valid input target. Did you use a custom `inputComponent` and forget to forward refs? See https://mui.com/r/input-component-ref-interface for more info." : (0, _utils.formatMuiErrorMessage)(1));
375 }
376
377 checkDirty({
378 value: element.value
379 });
380 }
381
382 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
383 args[_key - 1] = arguments[_key];
384 }
385
386 if (inputPropsProp.onChange) {
387 inputPropsProp.onChange.apply(inputPropsProp, [event].concat(args));
388 } // Perform in the willUpdate
389
390
391 if (onChange) {
392 onChange.apply(void 0, [event].concat(args));
393 }
394 }; // Check the input state on mount, in case it was filled by the user
395 // or auto filled by the browser before the hydration (for SSR).
396
397
398 React.useEffect(function () {
399 checkDirty(inputRef.current);
400 }, []); // eslint-disable-line react-hooks/exhaustive-deps
401
402 var handleClick = function handleClick(event) {
403 if (inputRef.current && event.currentTarget === event.target) {
404 inputRef.current.focus();
405 }
406
407 if (onClick) {
408 onClick(event);
409 }
410 };
411
412 var InputComponent = inputComponent;
413 var inputProps = (0, _extends2.default)({}, inputPropsProp, {
414 ref: handleInputRef
415 });
416
417 if (typeof InputComponent !== 'string') {
418 inputProps = (0, _extends2.default)({
419 // Rename ref to inputRef as we don't know the
420 // provided `inputComponent` structure.
421 inputRef: handleInputRef,
422 type: type
423 }, inputProps, {
424 ref: null
425 });
426 } else if (multiline) {
427 if (rows && !maxRows && !minRows && !rowsMax && !rowsMin) {
428 InputComponent = 'textarea';
429 } else {
430 inputProps = (0, _extends2.default)({
431 minRows: rows || minRows,
432 rowsMax: rowsMax,
433 maxRows: maxRows
434 }, inputProps);
435 InputComponent = _TextareaAutosize.default;
436 }
437 } else {
438 inputProps = (0, _extends2.default)({
439 type: type
440 }, inputProps);
441 }
442
443 var handleAutoFill = function handleAutoFill(event) {
444 // Provide a fake value as Chrome might not let you access it for security reasons.
445 checkDirty(event.animationName === 'mui-auto-fill-cancel' ? inputRef.current : {
446 value: 'x'
447 });
448 };
449
450 React.useEffect(function () {
451 if (muiFormControl) {
452 muiFormControl.setAdornedStart(Boolean(startAdornment));
453 }
454 }, [muiFormControl, startAdornment]);
455 return /*#__PURE__*/React.createElement("div", (0, _extends2.default)({
456 className: (0, _clsx.default)(classes.root, classes["color".concat((0, _capitalize.default)(fcs.color || 'primary'))], className, fcs.disabled && classes.disabled, fcs.error && classes.error, fullWidth && classes.fullWidth, fcs.focused && classes.focused, muiFormControl && classes.formControl, multiline && classes.multiline, startAdornment && classes.adornedStart, endAdornment && classes.adornedEnd, fcs.margin === 'dense' && classes.marginDense),
457 onClick: handleClick,
458 ref: ref
459 }, other), startAdornment, /*#__PURE__*/React.createElement(_FormControlContext.default.Provider, {
460 value: null
461 }, /*#__PURE__*/React.createElement(InputComponent, (0, _extends2.default)({
462 "aria-invalid": fcs.error,
463 "aria-describedby": ariaDescribedby,
464 autoComplete: autoComplete,
465 autoFocus: autoFocus,
466 defaultValue: defaultValue,
467 disabled: fcs.disabled,
468 id: id,
469 onAnimationStart: handleAutoFill,
470 name: name,
471 placeholder: placeholder,
472 readOnly: readOnly,
473 required: fcs.required,
474 rows: rows,
475 value: value,
476 onKeyDown: onKeyDown,
477 onKeyUp: onKeyUp
478 }, inputProps, {
479 className: (0, _clsx.default)(classes.input, inputPropsProp.className, fcs.disabled && classes.disabled, multiline && classes.inputMultiline, fcs.hiddenLabel && classes.inputHiddenLabel, startAdornment && classes.inputAdornedStart, endAdornment && classes.inputAdornedEnd, type === 'search' && classes.inputTypeSearch, fcs.margin === 'dense' && classes.inputMarginDense),
480 onBlur: handleBlur,
481 onChange: handleChange,
482 onFocus: handleFocus
483 }))), endAdornment, renderSuffix ? renderSuffix((0, _extends2.default)({}, fcs, {
484 startAdornment: startAdornment
485 })) : null);
486});
487process.env.NODE_ENV !== "production" ? InputBase.propTypes = {
488 // ----------------------------- Warning --------------------------------
489 // | These PropTypes are generated from the TypeScript type definitions |
490 // | To update them edit the d.ts file and run "yarn proptypes" |
491 // ----------------------------------------------------------------------
492
493 /**
494 * @ignore
495 */
496 'aria-describedby': _propTypes.default.string,
497
498 /**
499 * This prop helps users to fill forms faster, especially on mobile devices.
500 * The name can be confusing, as it's more like an autofill.
501 * You can learn more about it [following the specification](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill).
502 */
503 autoComplete: _propTypes.default.string,
504
505 /**
506 * If `true`, the `input` element will be focused during the first mount.
507 */
508 autoFocus: _propTypes.default.bool,
509
510 /**
511 * Override or extend the styles applied to the component.
512 * See [CSS API](#css) below for more details.
513 */
514 classes: _propTypes.default.object,
515
516 /**
517 * @ignore
518 */
519 className: _propTypes.default.string,
520
521 /**
522 * The color of the component. It supports those theme colors that make sense for this component.
523 */
524 color: _propTypes.default.oneOf(['primary', 'secondary']),
525
526 /**
527 * The default `input` element value. Use when the component is not controlled.
528 */
529 defaultValue: _propTypes.default.any,
530
531 /**
532 * If `true`, the `input` element will be disabled.
533 */
534 disabled: _propTypes.default.bool,
535
536 /**
537 * End `InputAdornment` for this component.
538 */
539 endAdornment: _propTypes.default.node,
540
541 /**
542 * If `true`, the input will indicate an error. This is normally obtained via context from
543 * FormControl.
544 */
545 error: _propTypes.default.bool,
546
547 /**
548 * If `true`, the input will take up the full width of its container.
549 */
550 fullWidth: _propTypes.default.bool,
551
552 /**
553 * The id of the `input` element.
554 */
555 id: _propTypes.default.string,
556
557 /**
558 * The component used for the `input` element.
559 * Either a string to use a HTML element or a component.
560 */
561 inputComponent: _propTypes.default.elementType,
562
563 /**
564 * [Attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Attributes) applied to the `input` element.
565 */
566 inputProps: _propTypes.default.object,
567
568 /**
569 * Pass a ref to the `input` element.
570 */
571 inputRef: _utils.refType,
572
573 /**
574 * If `dense`, will adjust vertical spacing. This is normally obtained via context from
575 * FormControl.
576 */
577 margin: _propTypes.default.oneOf(['dense', 'none']),
578
579 /**
580 * Maximum number of rows to display when multiline option is set to true.
581 */
582 maxRows: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]),
583
584 /**
585 * Minimum number of rows to display when multiline option is set to true.
586 */
587 minRows: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]),
588
589 /**
590 * If `true`, a textarea element will be rendered.
591 */
592 multiline: _propTypes.default.bool,
593
594 /**
595 * Name attribute of the `input` element.
596 */
597 name: _propTypes.default.string,
598
599 /**
600 * Callback fired when the input is blurred.
601 *
602 * Notice that the first argument (event) might be undefined.
603 */
604 onBlur: _propTypes.default.func,
605
606 /**
607 * Callback fired when the value is changed.
608 *
609 * @param {object} event The event source of the callback.
610 * You can pull out the new value by accessing `event.target.value` (string).
611 */
612 onChange: _propTypes.default.func,
613
614 /**
615 * @ignore
616 */
617 onClick: _propTypes.default.func,
618
619 /**
620 * @ignore
621 */
622 onFocus: _propTypes.default.func,
623
624 /**
625 * @ignore
626 */
627 onKeyDown: _propTypes.default.func,
628
629 /**
630 * @ignore
631 */
632 onKeyUp: _propTypes.default.func,
633
634 /**
635 * The short hint displayed in the input before the user enters a value.
636 */
637 placeholder: _propTypes.default.string,
638
639 /**
640 * It prevents the user from changing the value of the field
641 * (not from interacting with the field).
642 */
643 readOnly: _propTypes.default.bool,
644
645 /**
646 * @ignore
647 */
648 renderSuffix: _propTypes.default.func,
649
650 /**
651 * If `true`, the `input` element will be required.
652 */
653 required: _propTypes.default.bool,
654
655 /**
656 * Number of rows to display when multiline option is set to true.
657 */
658 rows: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]),
659
660 /**
661 * Maximum number of rows to display.
662 * @deprecated Use `maxRows` instead.
663 */
664 rowsMax: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]),
665
666 /**
667 * Minimum number of rows to display.
668 * @deprecated Use `minRows` instead.
669 */
670 rowsMin: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]),
671
672 /**
673 * Start `InputAdornment` for this component.
674 */
675 startAdornment: _propTypes.default.node,
676
677 /**
678 * 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).
679 */
680 type: _propTypes.default.string,
681
682 /**
683 * The value of the `input` element, required for a controlled component.
684 */
685 value: _propTypes.default.any
686} : void 0;
687
688var _default = (0, _withStyles.default)(styles, {
689 name: 'MuiInputBase'
690})(InputBase);
691
692exports.default = _default;
\No newline at end of file