UNPKG

5.96 kBJavaScriptView Raw
1import _extends from "@babel/runtime/helpers/esm/extends";
2import { formatMuiErrorMessage as _formatMuiErrorMessage } from "@mui/utils";
3import * as React from 'react';
4import { unstable_useForkRef as useForkRef } from '@mui/utils';
5import useFormControl from '../FormControlUnstyled/useFormControl';
6import extractEventHandlers from '../utils/extractEventHandlers';
7export default function useInput(props, inputRef) {
8 const {
9 defaultValue,
10 disabled: disabledProp = false,
11 error: errorProp = false,
12 onBlur,
13 onChange,
14 onFocus,
15 required: requiredProp = false,
16 value: valueProp
17 } = props;
18 const formControlContext = useFormControl();
19 let value;
20 let required;
21 let disabled;
22 let error;
23
24 if (formControlContext) {
25 var _formControlContext$d, _formControlContext$r, _formControlContext$e;
26
27 value = formControlContext.value;
28 disabled = (_formControlContext$d = formControlContext.disabled) != null ? _formControlContext$d : false;
29 required = (_formControlContext$r = formControlContext.required) != null ? _formControlContext$r : false;
30 error = (_formControlContext$e = formControlContext.error) != null ? _formControlContext$e : false;
31 } else {
32 value = valueProp;
33 disabled = disabledProp;
34 required = requiredProp;
35 error = errorProp;
36 }
37
38 const {
39 current: isControlled
40 } = React.useRef(value != null);
41 const handleInputRefWarning = React.useCallback(instance => {
42 if (process.env.NODE_ENV !== 'production') {
43 if (instance && instance.nodeName !== 'INPUT' && !instance.focus) {
44 console.error(['MUI: You have provided a `components.Input` to the input component', 'that does not correctly handle the `ref` prop.', 'Make sure the `ref` prop is called with a HTMLInputElement.'].join('\n'));
45 }
46 }
47 }, []);
48 const internalInputRef = React.useRef(null);
49 const handleIncomingRef = useForkRef(inputRef, handleInputRefWarning);
50 const handleInputRef = useForkRef(internalInputRef, handleIncomingRef);
51 const [focused, setFocused] = React.useState(false); // The blur won't fire when the disabled state is set on a focused input.
52 // We need to book keep the focused state manually.
53
54 React.useEffect(() => {
55 if (!formControlContext && disabled && focused) {
56 setFocused(false); // @ts-ignore
57
58 onBlur == null ? void 0 : onBlur();
59 }
60 }, [formControlContext, disabled, focused, onBlur]);
61
62 const handleFocus = otherHandlers => event => {
63 var _otherHandlers$onFocu;
64
65 // Fix a bug with IE11 where the focus/blur events are triggered
66 // while the component is disabled.
67 if (formControlContext != null && formControlContext.disabled) {
68 event.stopPropagation();
69 return;
70 }
71
72 (_otherHandlers$onFocu = otherHandlers.onFocus) == null ? void 0 : _otherHandlers$onFocu.call(otherHandlers, event);
73
74 if (formControlContext && formControlContext.onFocus) {
75 var _formControlContext$o;
76
77 formControlContext == null ? void 0 : (_formControlContext$o = formControlContext.onFocus) == null ? void 0 : _formControlContext$o.call(formControlContext);
78 } else {
79 setFocused(true);
80 }
81 };
82
83 const handleBlur = otherHandlers => event => {
84 var _otherHandlers$onBlur;
85
86 (_otherHandlers$onBlur = otherHandlers.onBlur) == null ? void 0 : _otherHandlers$onBlur.call(otherHandlers, event);
87
88 if (formControlContext && formControlContext.onBlur) {
89 formControlContext.onBlur();
90 } else {
91 setFocused(false);
92 }
93 };
94
95 const handleChange = otherHandlers => (event, ...args) => {
96 var _formControlContext$o2, _otherHandlers$onChan;
97
98 if (!isControlled) {
99 const element = event.target || internalInputRef.current;
100
101 if (element == null) {
102 throw new Error(process.env.NODE_ENV !== "production" ? `MUI: Expected valid input target. Did you use a custom \`components.Input\` and forget to forward refs? See https://mui.com/r/input-component-ref-interface for more info.` : _formatMuiErrorMessage(17));
103 }
104 }
105
106 formControlContext == null ? void 0 : (_formControlContext$o2 = formControlContext.onChange) == null ? void 0 : _formControlContext$o2.call(formControlContext, event); // @ts-ignore
107
108 (_otherHandlers$onChan = otherHandlers.onChange) == null ? void 0 : _otherHandlers$onChan.call(otherHandlers, event, ...args);
109 };
110
111 const handleClick = otherHandlers => event => {
112 var _otherHandlers$onClic;
113
114 if (internalInputRef.current && event.currentTarget === event.target) {
115 internalInputRef.current.focus();
116 }
117
118 (_otherHandlers$onClic = otherHandlers.onClick) == null ? void 0 : _otherHandlers$onClic.call(otherHandlers, event);
119 };
120
121 const getRootProps = externalProps => {
122 // onBlur, onChange and onFocus are forwarded to the input slot.
123 const propsEventHandlers = extractEventHandlers(props, ['onBlur', 'onChange', 'onFocus']);
124
125 const externalEventHandlers = _extends({}, propsEventHandlers, extractEventHandlers(externalProps));
126
127 return _extends({}, externalProps, externalEventHandlers, {
128 onClick: handleClick(externalEventHandlers)
129 });
130 };
131
132 const getInputProps = externalProps => {
133 const propsEventHandlers = {
134 onBlur,
135 onChange,
136 onFocus
137 };
138
139 const externalEventHandlers = _extends({}, propsEventHandlers, extractEventHandlers(externalProps));
140
141 const mergedEventHandlers = _extends({}, externalProps, externalEventHandlers, {
142 onBlur: handleBlur(externalEventHandlers),
143 onChange: handleChange(externalEventHandlers),
144 onFocus: handleFocus(externalEventHandlers)
145 });
146
147 return _extends({}, mergedEventHandlers, {
148 'aria-invalid': error || undefined,
149 defaultValue: defaultValue,
150 ref: handleInputRef,
151 value: value,
152 required,
153 disabled
154 });
155 };
156
157 return {
158 disabled,
159 error,
160 focused,
161 formControlContext,
162 getInputProps,
163 getRootProps,
164 required,
165 value
166 };
167}
\No newline at end of file