Skip to content
38 changes: 31 additions & 7 deletions packages/mui-material/src/InputBase/InputBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -455,14 +455,38 @@ const InputBase = React.forwardRef(function InputBase(inProps, ref) {
}, []);

const handleClick = (event) => {
if (inputRef.current && event.currentTarget === event.target) {
inputRef.current.focus();
}
const input = inputRef.current;

if (
input &&
event.currentTarget === event.target &&
(input.nodeName === 'INPUT' || input.nodeName === 'TEXTAREA')
) {
const pos =
typeof input.selectionStart === 'number'
? input.selectionStart
: input.value.length;

input.focus();

requestAnimationFrame(() => {
const restorePos =
pos === 0 && event.target === event.currentTarget
? input.value.length
: pos;

if (typeof input.setSelectionRange === 'function') {
input.setSelectionRange(restorePos, restorePos);
}
});
}

if (onClick) {
onClick(event);
}
};


if (onClick) {
onClick(event);
}
};
let InputComponent = inputComponent;
let inputProps = inputPropsProp;

Expand Down
28 changes: 27 additions & 1 deletion packages/mui-material/src/InputBase/InputBase.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { expect } from 'chai';
import { spy } from 'sinon';
import sinon, { spy } from 'sinon';
import { act, createRenderer, fireEvent, screen, reactMajor } from '@mui/internal-test-utils';
import { ThemeProvider } from '@emotion/react';
import FormControl, { useFormControl } from '@mui/material/FormControl';
Expand Down Expand Up @@ -694,6 +694,32 @@ describe('<InputBase />', () => {
});
});

describe('caret behavior', () => {
it('should preserve caret position when clicking on the Root wrapper', () => {
const clock = sinon.useFakeTimers();

const { container } = render(<InputBase defaultValue="hello" />);
const input = container.querySelector('input');

act(() => {
input.setSelectionRange(2, 2);
});

const wrapper = input.parentElement;

fireEvent.click(wrapper);

act(() => {
clock.runAll();
});

expect(input.selectionStart).to.equal(2);
expect(input.selectionEnd).to.equal(2);

clock.restore();
});
});

describe('prop: focused', () => {
it('should render correct border color with `ThemeProvider` imported from `@emotion/react`', function test() {
if (window.navigator.userAgent.includes('jsdom')) {
Expand Down
Loading