Skip to content

Commit 1e77b3f

Browse files
committed
[TextField] Handle Chrome autofill
1 parent e9f26fc commit 1e77b3f

File tree

2 files changed

+37
-15
lines changed

2 files changed

+37
-15
lines changed

packages/material-ui/src/FormControl/FormControl.js

+10-10
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,14 @@ const FormControl = React.forwardRef(function FormControl(props, ref) {
143143
};
144144
}
145145

146+
const onFilled = React.useCallback(() => {
147+
setFilled(true);
148+
}, []);
149+
150+
const onEmpty = React.useCallback(() => {
151+
setFilled(false);
152+
}, []);
153+
146154
const childContext = {
147155
adornedStart,
148156
disabled,
@@ -154,16 +162,8 @@ const FormControl = React.forwardRef(function FormControl(props, ref) {
154162
onBlur: () => {
155163
setFocused(false);
156164
},
157-
onEmpty: () => {
158-
if (filled) {
159-
setFilled(false);
160-
}
161-
},
162-
onFilled: () => {
163-
if (!filled) {
164-
setFilled(true);
165-
}
166-
},
165+
onEmpty,
166+
onFilled,
167167
onFocus: () => {
168168
setFocused(true);
169169
},

packages/material-ui/src/InputBase/InputBase.js

+27-5
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,13 @@ export const styles = theme => {
115115
'&$disabled': {
116116
opacity: 1, // Reset iOS opacity
117117
},
118+
'&:-webkit-autofill': {
119+
animationDuration: '5000s',
120+
animationName: '$auto-fill',
121+
},
122+
},
123+
'@keyframes auto-fill': {
124+
from: {},
118125
},
119126
/* Styles applied to the `input` element if `margin="dense"`. */
120127
inputMarginDense: {
@@ -241,17 +248,20 @@ const InputBase = React.forwardRef(function InputBase(props, ref) {
241248
}
242249
}, [muiFormControl, disabled, focused, onBlur]);
243250

251+
const onFilled = muiFormControl && muiFormControl.onFilled;
252+
const onEmpty = muiFormControl && muiFormControl.onEmpty;
253+
244254
const checkDirty = React.useCallback(
245255
obj => {
246256
if (isFilled(obj)) {
247-
if (muiFormControl && muiFormControl.onFilled) {
248-
muiFormControl.onFilled();
257+
if (onFilled) {
258+
onFilled();
249259
}
250-
} else if (muiFormControl && muiFormControl.onEmpty) {
251-
muiFormControl.onEmpty();
260+
} else if (onEmpty) {
261+
onEmpty();
252262
}
253263
},
254-
[muiFormControl],
264+
[onFilled, onEmpty],
255265
);
256266

257267
useEnhancedEffect(() => {
@@ -313,6 +323,12 @@ const InputBase = React.forwardRef(function InputBase(props, ref) {
313323
}
314324
};
315325

326+
// Check the input state on mount, in case it was filled by the user
327+
// or auto filled by the browser before the hydration (for SSR).
328+
React.useEffect(() => {
329+
checkDirty(inputRef.current);
330+
}, []); // eslint-disable-line react-hooks/exhaustive-deps
331+
316332
const handleClick = event => {
317333
if (inputRef.current && event.currentTarget === event.target) {
318334
inputRef.current.focus();
@@ -356,6 +372,11 @@ const InputBase = React.forwardRef(function InputBase(props, ref) {
356372
};
357373
}
358374

375+
const handleAutoFill = () => {
376+
// Provide a fake value as Chrome might not let you access it for security reasons.
377+
checkDirty({ value: 'x' });
378+
};
379+
359380
return (
360381
<div
361382
className={clsx(
@@ -401,6 +422,7 @@ const InputBase = React.forwardRef(function InputBase(props, ref) {
401422
defaultValue={defaultValue}
402423
disabled={fcs.disabled}
403424
id={id}
425+
onAnimationStart={handleAutoFill}
404426
name={name}
405427
onBlur={handleBlur}
406428
onChange={handleChange}

0 commit comments

Comments
 (0)