From 113429c777a739b2f0218997d4f03fe52eb2aea3 Mon Sep 17 00:00:00 2001 From: Lukas Date: Mon, 14 Aug 2023 10:57:47 +0300 Subject: [PATCH] [TextField] Fix to handle `onClick` on root element (#38072) --- .../mui-material/src/TextField/TextField.js | 12 +++++++++++- .../src/TextField/TextField.test.js | 9 +++++++++ .../fixtures/TextField/TextFieldWithOnClick.tsx | 17 +++++++++++++++++ test/e2e/index.test.ts | 10 ++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 test/e2e/fixtures/TextField/TextFieldWithOnClick.tsx diff --git a/packages/mui-material/src/TextField/TextField.js b/packages/mui-material/src/TextField/TextField.js index 32fe23de23958e..2448ce22274d89 100644 --- a/packages/mui-material/src/TextField/TextField.js +++ b/packages/mui-material/src/TextField/TextField.js @@ -147,6 +147,15 @@ const TextField = React.forwardRef(function TextField(inProps, ref) { InputMore['aria-describedby'] = undefined; } + const handleClick = (event) => { + if (!disabled && onClick) { + // The `onClick` is registered both on the root and the input elements. + // Without stopping the propagation, the event could be triggered twice. + event.stopPropagation(); + onClick(event); + } + }; + const id = useId(idOverride); const helperTextId = helperText && id ? `${id}-helper-text` : undefined; const inputLabelId = label && id ? `${id}-label` : undefined; @@ -170,7 +179,7 @@ const TextField = React.forwardRef(function TextField(inProps, ref) { onBlur={onBlur} onChange={onChange} onFocus={onFocus} - onClick={onClick} + onClick={handleClick} placeholder={placeholder} inputProps={inputProps} {...InputMore} @@ -189,6 +198,7 @@ const TextField = React.forwardRef(function TextField(inProps, ref) { color={color} variant={variant} ownerState={ownerState} + onClick={handleClick} {...other} > {label != null && label !== '' && ( diff --git a/packages/mui-material/src/TextField/TextField.test.js b/packages/mui-material/src/TextField/TextField.test.js index 1891e41b9df46b..18b3b0e5d61829 100644 --- a/packages/mui-material/src/TextField/TextField.test.js +++ b/packages/mui-material/src/TextField/TextField.test.js @@ -243,4 +243,13 @@ describe('', () => { expect(getByRole('button')).toHaveAccessibleDescription('Foo bar'); }); }); + + it('should trigger `onClick` only once', () => { + const handleClick = spy(); + const { getByRole } = render( + , + ); + fireEvent.click(getByRole('textbox')); + expect(handleClick.callCount).to.equal(1); + }); }); diff --git a/test/e2e/fixtures/TextField/TextFieldWithOnClick.tsx b/test/e2e/fixtures/TextField/TextFieldWithOnClick.tsx new file mode 100644 index 00000000000000..935d316c40fd98 --- /dev/null +++ b/test/e2e/fixtures/TextField/TextFieldWithOnClick.tsx @@ -0,0 +1,17 @@ +import * as React from 'react'; +import TextField from '@mui/material/TextField'; + +export default function TextFieldWithOnClick() { + const [isClicked, setIsClicked] = React.useState(false); + return ( + { + setIsClicked(true); + }} + /> + ); +} diff --git a/test/e2e/index.test.ts b/test/e2e/index.test.ts index 41ee58e532f1d8..0ead9450c22cbc 100644 --- a/test/e2e/index.test.ts +++ b/test/e2e/index.test.ts @@ -254,4 +254,14 @@ describe('e2e', () => { expect(pageErrors.length).to.equal(0); }); }); + + describe('', () => { + it('should handle `onClick` when clicking on the focused label position', async () => { + await renderFixture('TextField/TextFieldWithOnClick'); + + // execute the click on the focused label position + await page.getByRole('textbox').click({ position: { x: 10, y: 10 } }); + await page.waitForSelector('.MuiInputBase-root.Mui-error'); + }); + }); });