1 | import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
|
2 | import _extends from "@babel/runtime/helpers/esm/extends";
|
3 | import { formatMuiErrorMessage as _formatMuiErrorMessage } from "@material-ui/utils";
|
4 |
|
5 |
|
6 | import * as React from 'react';
|
7 | import PropTypes from 'prop-types';
|
8 | import clsx from 'clsx';
|
9 | import { refType } from '@material-ui/utils';
|
10 | import formControlState from '../FormControl/formControlState';
|
11 | import FormControlContext, { useFormControl } from '../FormControl/FormControlContext';
|
12 | import withStyles from '../styles/withStyles';
|
13 | import capitalize from '../utils/capitalize';
|
14 | import useForkRef from '../utils/useForkRef';
|
15 | import TextareaAutosize from '../TextareaAutosize';
|
16 | import { isFilled } from './utils';
|
17 | export const styles = theme => {
|
18 | const light = theme.palette.type === 'light';
|
19 | const placeholder = {
|
20 | color: 'currentColor',
|
21 | opacity: light ? 0.42 : 0.5,
|
22 | transition: theme.transitions.create('opacity', {
|
23 | duration: theme.transitions.duration.shorter
|
24 | })
|
25 | };
|
26 | const placeholderHidden = {
|
27 | opacity: '0 !important'
|
28 | };
|
29 | const placeholderVisible = {
|
30 | opacity: light ? 0.42 : 0.5
|
31 | };
|
32 | return {
|
33 | '@global': {
|
34 | '@keyframes mui-auto-fill': {},
|
35 | '@keyframes mui-auto-fill-cancel': {}
|
36 | },
|
37 |
|
38 |
|
39 | root: _extends({}, theme.typography.body1, {
|
40 | color: theme.palette.text.primary,
|
41 | lineHeight: '1.1876em',
|
42 |
|
43 | boxSizing: 'border-box',
|
44 |
|
45 | position: 'relative',
|
46 | cursor: 'text',
|
47 | display: 'inline-flex',
|
48 | alignItems: 'center',
|
49 | '&$disabled': {
|
50 | color: theme.palette.text.disabled,
|
51 | cursor: 'default'
|
52 | }
|
53 | }),
|
54 |
|
55 |
|
56 | formControl: {},
|
57 |
|
58 |
|
59 | focused: {},
|
60 |
|
61 |
|
62 | disabled: {},
|
63 |
|
64 |
|
65 | adornedStart: {},
|
66 |
|
67 |
|
68 | adornedEnd: {},
|
69 |
|
70 |
|
71 | error: {},
|
72 |
|
73 |
|
74 | marginDense: {},
|
75 |
|
76 |
|
77 | multiline: {
|
78 | padding: `${8 - 2}px 0 ${8 - 1}px`,
|
79 | '&$marginDense': {
|
80 | paddingTop: 4 - 1
|
81 | }
|
82 | },
|
83 |
|
84 |
|
85 | colorSecondary: {},
|
86 |
|
87 |
|
88 | fullWidth: {
|
89 | width: '100%'
|
90 | },
|
91 |
|
92 |
|
93 | input: {
|
94 | font: 'inherit',
|
95 | letterSpacing: 'inherit',
|
96 | color: 'currentColor',
|
97 | padding: `${8 - 2}px 0 ${8 - 1}px`,
|
98 | border: 0,
|
99 | boxSizing: 'content-box',
|
100 | background: 'none',
|
101 | height: '1.1876em',
|
102 |
|
103 | margin: 0,
|
104 |
|
105 | WebkitTapHighlightColor: 'transparent',
|
106 | display: 'block',
|
107 |
|
108 | minWidth: 0,
|
109 | width: '100%',
|
110 |
|
111 | animationName: 'mui-auto-fill-cancel',
|
112 | animationDuration: '10ms',
|
113 | '&::-webkit-input-placeholder': placeholder,
|
114 | '&::-moz-placeholder': placeholder,
|
115 |
|
116 | '&:-ms-input-placeholder': placeholder,
|
117 |
|
118 | '&::-ms-input-placeholder': placeholder,
|
119 |
|
120 | '&:focus': {
|
121 | outline: 0
|
122 | },
|
123 |
|
124 | '&:invalid': {
|
125 | boxShadow: 'none'
|
126 | },
|
127 | '&::-webkit-search-decoration': {
|
128 |
|
129 | '-webkit-appearance': 'none'
|
130 | },
|
131 |
|
132 | 'label[data-shrink=false] + $formControl &': {
|
133 | '&::-webkit-input-placeholder': placeholderHidden,
|
134 | '&::-moz-placeholder': placeholderHidden,
|
135 |
|
136 | '&:-ms-input-placeholder': placeholderHidden,
|
137 |
|
138 | '&::-ms-input-placeholder': placeholderHidden,
|
139 |
|
140 | '&:focus::-webkit-input-placeholder': placeholderVisible,
|
141 | '&:focus::-moz-placeholder': placeholderVisible,
|
142 |
|
143 | '&:focus:-ms-input-placeholder': placeholderVisible,
|
144 |
|
145 | '&:focus::-ms-input-placeholder': placeholderVisible
|
146 |
|
147 | },
|
148 | '&$disabled': {
|
149 | opacity: 1
|
150 |
|
151 | },
|
152 | '&:-webkit-autofill': {
|
153 | animationDuration: '5000s',
|
154 | animationName: 'mui-auto-fill'
|
155 | }
|
156 | },
|
157 |
|
158 |
|
159 | inputMarginDense: {
|
160 | paddingTop: 4 - 1
|
161 | },
|
162 |
|
163 |
|
164 | inputMultiline: {
|
165 | height: 'auto',
|
166 | resize: 'none',
|
167 | padding: 0
|
168 | },
|
169 |
|
170 |
|
171 | inputTypeSearch: {
|
172 |
|
173 | '-moz-appearance': 'textfield',
|
174 | '-webkit-appearance': 'textfield'
|
175 | },
|
176 |
|
177 |
|
178 | inputAdornedStart: {},
|
179 |
|
180 |
|
181 | inputAdornedEnd: {},
|
182 |
|
183 |
|
184 | inputHiddenLabel: {}
|
185 | };
|
186 | };
|
187 | const useEnhancedEffect = typeof window === 'undefined' ? React.useEffect : React.useLayoutEffect;
|
188 |
|
189 |
|
190 |
|
191 |
|
192 |
|
193 |
|
194 | const InputBase = React.forwardRef(function InputBase(props, ref) {
|
195 | const {
|
196 | 'aria-describedby': ariaDescribedby,
|
197 | autoComplete,
|
198 | autoFocus,
|
199 | classes,
|
200 | className,
|
201 | defaultValue,
|
202 | disabled,
|
203 | endAdornment,
|
204 | fullWidth = false,
|
205 | id,
|
206 | inputComponent = 'input',
|
207 | inputProps: inputPropsProp = {},
|
208 | inputRef: inputRefProp,
|
209 | multiline = false,
|
210 | name,
|
211 | onBlur,
|
212 | onChange,
|
213 | onClick,
|
214 | onFocus,
|
215 | onKeyDown,
|
216 | onKeyUp,
|
217 | placeholder,
|
218 | readOnly,
|
219 | renderSuffix,
|
220 | rows,
|
221 | rowsMax,
|
222 | rowsMin,
|
223 | maxRows,
|
224 | minRows,
|
225 | startAdornment,
|
226 | type = 'text',
|
227 | value: valueProp
|
228 | } = props,
|
229 | other = _objectWithoutPropertiesLoose(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"]);
|
230 |
|
231 | const value = inputPropsProp.value != null ? inputPropsProp.value : valueProp;
|
232 | const {
|
233 | current: isControlled
|
234 | } = React.useRef(value != null);
|
235 | const inputRef = React.useRef();
|
236 | const handleInputRefWarning = React.useCallback(instance => {
|
237 | if (process.env.NODE_ENV !== 'production') {
|
238 | if (instance && instance.nodeName !== 'INPUT' && !instance.focus) {
|
239 | 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'));
|
240 | }
|
241 | }
|
242 | }, []);
|
243 | const handleInputPropsRefProp = useForkRef(inputPropsProp.ref, handleInputRefWarning);
|
244 | const handleInputRefProp = useForkRef(inputRefProp, handleInputPropsRefProp);
|
245 | const handleInputRef = useForkRef(inputRef, handleInputRefProp);
|
246 | const [focused, setFocused] = React.useState(false);
|
247 | const muiFormControl = useFormControl();
|
248 |
|
249 | if (process.env.NODE_ENV !== 'production') {
|
250 |
|
251 | React.useEffect(() => {
|
252 | if (muiFormControl) {
|
253 | return muiFormControl.registerEffect();
|
254 | }
|
255 |
|
256 | return undefined;
|
257 | }, [muiFormControl]);
|
258 | }
|
259 |
|
260 | const fcs = formControlState({
|
261 | props,
|
262 | muiFormControl,
|
263 | states: ['color', 'disabled', 'error', 'hiddenLabel', 'margin', 'required', 'filled']
|
264 | });
|
265 | fcs.focused = muiFormControl ? muiFormControl.focused : focused;
|
266 |
|
267 |
|
268 | React.useEffect(() => {
|
269 | if (!muiFormControl && disabled && focused) {
|
270 | setFocused(false);
|
271 |
|
272 | if (onBlur) {
|
273 | onBlur();
|
274 | }
|
275 | }
|
276 | }, [muiFormControl, disabled, focused, onBlur]);
|
277 | const onFilled = muiFormControl && muiFormControl.onFilled;
|
278 | const onEmpty = muiFormControl && muiFormControl.onEmpty;
|
279 | const checkDirty = React.useCallback(obj => {
|
280 | if (isFilled(obj)) {
|
281 | if (onFilled) {
|
282 | onFilled();
|
283 | }
|
284 | } else if (onEmpty) {
|
285 | onEmpty();
|
286 | }
|
287 | }, [onFilled, onEmpty]);
|
288 | useEnhancedEffect(() => {
|
289 | if (isControlled) {
|
290 | checkDirty({
|
291 | value
|
292 | });
|
293 | }
|
294 | }, [value, checkDirty, isControlled]);
|
295 |
|
296 | const handleFocus = event => {
|
297 |
|
298 |
|
299 | if (fcs.disabled) {
|
300 | event.stopPropagation();
|
301 | return;
|
302 | }
|
303 |
|
304 | if (onFocus) {
|
305 | onFocus(event);
|
306 | }
|
307 |
|
308 | if (inputPropsProp.onFocus) {
|
309 | inputPropsProp.onFocus(event);
|
310 | }
|
311 |
|
312 | if (muiFormControl && muiFormControl.onFocus) {
|
313 | muiFormControl.onFocus(event);
|
314 | } else {
|
315 | setFocused(true);
|
316 | }
|
317 | };
|
318 |
|
319 | const handleBlur = event => {
|
320 | if (onBlur) {
|
321 | onBlur(event);
|
322 | }
|
323 |
|
324 | if (inputPropsProp.onBlur) {
|
325 | inputPropsProp.onBlur(event);
|
326 | }
|
327 |
|
328 | if (muiFormControl && muiFormControl.onBlur) {
|
329 | muiFormControl.onBlur(event);
|
330 | } else {
|
331 | setFocused(false);
|
332 | }
|
333 | };
|
334 |
|
335 | const handleChange = (event, ...args) => {
|
336 | if (!isControlled) {
|
337 | const element = event.target || inputRef.current;
|
338 |
|
339 | if (element == null) {
|
340 | 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://material-ui.com/r/input-component-ref-interface for more info.` : _formatMuiErrorMessage(1));
|
341 | }
|
342 |
|
343 | checkDirty({
|
344 | value: element.value
|
345 | });
|
346 | }
|
347 |
|
348 | if (inputPropsProp.onChange) {
|
349 | inputPropsProp.onChange(event, ...args);
|
350 | }
|
351 |
|
352 |
|
353 | if (onChange) {
|
354 | onChange(event, ...args);
|
355 | }
|
356 | };
|
357 |
|
358 |
|
359 |
|
360 | React.useEffect(() => {
|
361 | checkDirty(inputRef.current);
|
362 | }, []);
|
363 |
|
364 | const handleClick = event => {
|
365 | if (inputRef.current && event.currentTarget === event.target) {
|
366 | inputRef.current.focus();
|
367 | }
|
368 |
|
369 | if (onClick) {
|
370 | onClick(event);
|
371 | }
|
372 | };
|
373 |
|
374 | let InputComponent = inputComponent;
|
375 |
|
376 | let inputProps = _extends({}, inputPropsProp, {
|
377 | ref: handleInputRef
|
378 | });
|
379 |
|
380 | if (typeof InputComponent !== 'string') {
|
381 | inputProps = _extends({
|
382 |
|
383 |
|
384 | inputRef: handleInputRef,
|
385 | type
|
386 | }, inputProps, {
|
387 | ref: null
|
388 | });
|
389 | } else if (multiline) {
|
390 | if (rows && !maxRows && !minRows && !rowsMax && !rowsMin) {
|
391 | InputComponent = 'textarea';
|
392 | } else {
|
393 | inputProps = _extends({
|
394 | minRows: rows || minRows,
|
395 | rowsMax,
|
396 | maxRows
|
397 | }, inputProps);
|
398 | InputComponent = TextareaAutosize;
|
399 | }
|
400 | } else {
|
401 | inputProps = _extends({
|
402 | type
|
403 | }, inputProps);
|
404 | }
|
405 |
|
406 | const handleAutoFill = event => {
|
407 |
|
408 | checkDirty(event.animationName === 'mui-auto-fill-cancel' ? inputRef.current : {
|
409 | value: 'x'
|
410 | });
|
411 | };
|
412 |
|
413 | React.useEffect(() => {
|
414 | if (muiFormControl) {
|
415 | muiFormControl.setAdornedStart(Boolean(startAdornment));
|
416 | }
|
417 | }, [muiFormControl, startAdornment]);
|
418 | return React.createElement("div", _extends({
|
419 | className: clsx(classes.root, classes[`color${capitalize(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),
|
420 | onClick: handleClick,
|
421 | ref: ref
|
422 | }, other), startAdornment, React.createElement(FormControlContext.Provider, {
|
423 | value: null
|
424 | }, React.createElement(InputComponent, _extends({
|
425 | "aria-invalid": fcs.error,
|
426 | "aria-describedby": ariaDescribedby,
|
427 | autoComplete: autoComplete,
|
428 | autoFocus: autoFocus,
|
429 | defaultValue: defaultValue,
|
430 | disabled: fcs.disabled,
|
431 | id: id,
|
432 | onAnimationStart: handleAutoFill,
|
433 | name: name,
|
434 | placeholder: placeholder,
|
435 | readOnly: readOnly,
|
436 | required: fcs.required,
|
437 | rows: rows,
|
438 | value: value,
|
439 | onKeyDown: onKeyDown,
|
440 | onKeyUp: onKeyUp
|
441 | }, inputProps, {
|
442 | className: clsx(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),
|
443 | onBlur: handleBlur,
|
444 | onChange: handleChange,
|
445 | onFocus: handleFocus
|
446 | }))), endAdornment, renderSuffix ? renderSuffix(_extends({}, fcs, {
|
447 | startAdornment
|
448 | })) : null);
|
449 | });
|
450 | process.env.NODE_ENV !== "production" ? InputBase.propTypes = {
|
451 |
|
452 |
|
453 |
|
454 |
|
455 |
|
456 | |
457 |
|
458 |
|
459 | 'aria-describedby': PropTypes.string,
|
460 |
|
461 | |
462 |
|
463 |
|
464 |
|
465 |
|
466 | autoComplete: PropTypes.string,
|
467 |
|
468 | |
469 |
|
470 |
|
471 | autoFocus: PropTypes.bool,
|
472 |
|
473 | |
474 |
|
475 |
|
476 |
|
477 | classes: PropTypes.object,
|
478 |
|
479 | |
480 |
|
481 |
|
482 | className: PropTypes.string,
|
483 |
|
484 | |
485 |
|
486 |
|
487 | color: PropTypes.oneOf(['primary', 'secondary']),
|
488 |
|
489 | |
490 |
|
491 |
|
492 | defaultValue: PropTypes.any,
|
493 |
|
494 | |
495 |
|
496 |
|
497 | disabled: PropTypes.bool,
|
498 |
|
499 | |
500 |
|
501 |
|
502 | endAdornment: PropTypes.node,
|
503 |
|
504 | |
505 |
|
506 |
|
507 |
|
508 | error: PropTypes.bool,
|
509 |
|
510 | |
511 |
|
512 |
|
513 | fullWidth: PropTypes.bool,
|
514 |
|
515 | |
516 |
|
517 |
|
518 | id: PropTypes.string,
|
519 |
|
520 | |
521 |
|
522 |
|
523 |
|
524 | inputComponent: PropTypes.elementType,
|
525 |
|
526 | |
527 |
|
528 |
|
529 | inputProps: PropTypes.object,
|
530 |
|
531 | |
532 |
|
533 |
|
534 | inputRef: refType,
|
535 |
|
536 | |
537 |
|
538 |
|
539 |
|
540 | margin: PropTypes.oneOf(['dense', 'none']),
|
541 |
|
542 | |
543 |
|
544 |
|
545 | maxRows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
546 |
|
547 | |
548 |
|
549 |
|
550 | minRows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
551 |
|
552 | |
553 |
|
554 |
|
555 | multiline: PropTypes.bool,
|
556 |
|
557 | |
558 |
|
559 |
|
560 | name: PropTypes.string,
|
561 |
|
562 | |
563 |
|
564 |
|
565 |
|
566 |
|
567 | onBlur: PropTypes.func,
|
568 |
|
569 | |
570 |
|
571 |
|
572 |
|
573 |
|
574 |
|
575 | onChange: PropTypes.func,
|
576 |
|
577 | |
578 |
|
579 |
|
580 | onClick: PropTypes.func,
|
581 |
|
582 | |
583 |
|
584 |
|
585 | onFocus: PropTypes.func,
|
586 |
|
587 | |
588 |
|
589 |
|
590 | onKeyDown: PropTypes.func,
|
591 |
|
592 | |
593 |
|
594 |
|
595 | onKeyUp: PropTypes.func,
|
596 |
|
597 | |
598 |
|
599 |
|
600 | placeholder: PropTypes.string,
|
601 |
|
602 | |
603 |
|
604 |
|
605 |
|
606 | readOnly: PropTypes.bool,
|
607 |
|
608 | |
609 |
|
610 |
|
611 | renderSuffix: PropTypes.func,
|
612 |
|
613 | |
614 |
|
615 |
|
616 | required: PropTypes.bool,
|
617 |
|
618 | |
619 |
|
620 |
|
621 | rows: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
622 |
|
623 | |
624 |
|
625 |
|
626 |
|
627 | rowsMax: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
628 |
|
629 | |
630 |
|
631 |
|
632 |
|
633 | rowsMin: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
634 |
|
635 | |
636 |
|
637 |
|
638 | startAdornment: PropTypes.node,
|
639 |
|
640 | |
641 |
|
642 |
|
643 | type: PropTypes.string,
|
644 |
|
645 | |
646 |
|
647 |
|
648 | value: PropTypes.any
|
649 | } : void 0;
|
650 | export default withStyles(styles, {
|
651 | name: 'MuiInputBase'
|
652 | })(InputBase); |
\ | No newline at end of file |