From 3e191df3dd43dcdd5a5f717166d4db9834340a2b Mon Sep 17 00:00:00 2001 From: Sean Perkins Date: Thu, 8 Jun 2023 14:35:25 -0400 Subject: [PATCH] fix(react): onDoubleClick fires on components (#27611) Issue number: Resolves #21320 --------- ## What is the current behavior? `onDoubleClick` bindings on Ionic components do not fire when the element is double clicked. ## What is the new behavior? - `onDoubleClick` fires on Ionic components - Fixed the unit testing set-up for the react test apps ## Does this introduce a breaking change? - [ ] Yes - [x] No ## Other information --- core/package-lock.json | 14 +++++++------- core/package.json | 2 +- .../react-component-lib/utils/attachProps.ts | 13 ++++++++++++- packages/react/test/apps/react17/package.json | 2 +- packages/react/test/apps/react18/package.json | 2 +- packages/react/test/base/src/OutputTarget.test.tsx | 14 ++++++++++++++ packages/react/test/base/src/setupTests.ts | 12 +++++++----- 7 files changed, 43 insertions(+), 16 deletions(-) create mode 100644 packages/react/test/base/src/OutputTarget.test.tsx diff --git a/core/package-lock.json b/core/package-lock.json index 22c9ac7ae8..4a01996e83 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -22,7 +22,7 @@ "@rollup/plugin-node-resolve": "^8.4.0", "@rollup/plugin-virtual": "^2.0.3", "@stencil/angular-output-target": "^0.7.1", - "@stencil/react-output-target": "^0.5.1", + "@stencil/react-output-target": "^0.5.3", "@stencil/sass": "^3.0.4", "@stencil/vue-output-target": "^0.8.6", "@types/jest": "^27.5.2", @@ -1606,9 +1606,9 @@ } }, "node_modules/@stencil/react-output-target": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@stencil/react-output-target/-/react-output-target-0.5.1.tgz", - "integrity": "sha512-mEwJaFrNXn/neRQJU7m5H98nJR8B3w0QPv8ijBXDtWh+lD2NA49/FO4bwyDtgkdadp+o5obqJZ4/RcwvzyDLvQ==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@stencil/react-output-target/-/react-output-target-0.5.3.tgz", + "integrity": "sha512-68jwRp35CjAcwhTJ9yFD/3n+jrHOqvEH2jreVuPVvZK+4tkhPlYlwz0d1E1RlF3jyifUSfdkWUGgXIEy8Fo3yw==", "dev": true, "peerDependencies": { "@stencil/core": ">=2.0.0 || >=3 || >= 4.0.0-beta.0 || >= 4.0.0" @@ -11455,9 +11455,9 @@ "integrity": "sha512-I+660Oe9OMLiU+thjV1GgcI27dcvrSpF3xisHWBOU/4mzRtho3YW0cI8lSjcqyB1KirGTA6QeQ0Xif5UHqn8hw==" }, "@stencil/react-output-target": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@stencil/react-output-target/-/react-output-target-0.5.1.tgz", - "integrity": "sha512-mEwJaFrNXn/neRQJU7m5H98nJR8B3w0QPv8ijBXDtWh+lD2NA49/FO4bwyDtgkdadp+o5obqJZ4/RcwvzyDLvQ==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@stencil/react-output-target/-/react-output-target-0.5.3.tgz", + "integrity": "sha512-68jwRp35CjAcwhTJ9yFD/3n+jrHOqvEH2jreVuPVvZK+4tkhPlYlwz0d1E1RlF3jyifUSfdkWUGgXIEy8Fo3yw==", "dev": true, "requires": {} }, diff --git a/core/package.json b/core/package.json index ace538c617..bb47c3f9df 100644 --- a/core/package.json +++ b/core/package.json @@ -44,7 +44,7 @@ "@rollup/plugin-node-resolve": "^8.4.0", "@rollup/plugin-virtual": "^2.0.3", "@stencil/angular-output-target": "^0.7.1", - "@stencil/react-output-target": "^0.5.1", + "@stencil/react-output-target": "^0.5.3", "@stencil/sass": "^3.0.4", "@stencil/vue-output-target": "^0.8.6", "@types/jest": "^27.5.2", diff --git a/packages/react/src/components/react-component-lib/utils/attachProps.ts b/packages/react/src/components/react-component-lib/utils/attachProps.ts index de2cc499b2..9a1825f54f 100644 --- a/packages/react/src/components/react-component-lib/utils/attachProps.ts +++ b/packages/react/src/components/react-component-lib/utils/attachProps.ts @@ -62,6 +62,17 @@ export const getClassName = (classList: DOMTokenList, newProps: any, oldProps: a return finalClassNames.join(' '); }; +/** + * Transforms a React event name to a browser event name. + */ +export const transformReactEventName = (eventNameSuffix: string) => { + switch (eventNameSuffix) { + case 'doubleclick': + return 'dblclick'; + } + return eventNameSuffix; +}; + /** * Checks if an event is supported in the current execution environment. * @license Modernizr 3.0.0pre (Custom Build) | MIT @@ -70,7 +81,7 @@ export const isCoveredByReact = (eventNameSuffix: string) => { if (typeof document === 'undefined') { return true; } else { - const eventName = 'on' + eventNameSuffix; + const eventName = 'on' + transformReactEventName(eventNameSuffix); let isSupported = eventName in document; if (!isSupported) { diff --git a/packages/react/test/apps/react17/package.json b/packages/react/test/apps/react17/package.json index 9343678502..65aaa80e0b 100644 --- a/packages/react/test/apps/react17/package.json +++ b/packages/react/test/apps/react17/package.json @@ -20,7 +20,7 @@ "scripts": { "start": "react-scripts start", "build": "react-scripts build", - "test": "react-scripts test", + "test": "react-scripts test --env=jsdom --transformIgnorePatterns 'node_modules/(?!(@ionic/react|@ionic/react-router|@ionic/core|@stencil/core|ionicons)/)'", "eject": "react-scripts eject", "sync": "sh ./scripts/sync.sh", "cypress": "cypress run --headless --browser chrome", diff --git a/packages/react/test/apps/react18/package.json b/packages/react/test/apps/react18/package.json index 0ff0037ecd..0517114668 100644 --- a/packages/react/test/apps/react18/package.json +++ b/packages/react/test/apps/react18/package.json @@ -20,7 +20,7 @@ "scripts": { "start": "react-scripts start", "build": "react-scripts build", - "test": "react-scripts test", + "test": "react-scripts test --env=jsdom --transformIgnorePatterns 'node_modules/(?!(@ionic/react|@ionic/react-router|@ionic/core|@stencil/core|ionicons)/)'", "eject": "react-scripts eject", "sync": "sh ./scripts/sync.sh", "cypress": "cypress run --headless --browser chrome", diff --git a/packages/react/test/base/src/OutputTarget.test.tsx b/packages/react/test/base/src/OutputTarget.test.tsx new file mode 100644 index 0000000000..8829b3bc35 --- /dev/null +++ b/packages/react/test/base/src/OutputTarget.test.tsx @@ -0,0 +1,14 @@ +import { IonButton } from '@ionic/react'; +import { fireEvent, render, screen } from '@testing-library/react'; +import React from 'react'; + +test('should support onDoubleClick bindings', () => { + const mockFn = jest.fn(); + + render(Click me); + + // Simulate a double click on the button + fireEvent.dblClick(screen.getByText('Click me')); + + expect(mockFn).toBeCalled(); +}); diff --git a/packages/react/test/base/src/setupTests.ts b/packages/react/test/base/src/setupTests.ts index 87988d6bde..f55d048292 100644 --- a/packages/react/test/base/src/setupTests.ts +++ b/packages/react/test/base/src/setupTests.ts @@ -2,13 +2,15 @@ // allows you to do things like: // expect(element).toHaveTextContent(/react/i) // learn more: https://github.com/testing-library/jest-dom -import '@testing-library/jest-dom/extend-expect'; +import { setupIonicReact } from '@ionic/react'; + +setupIonicReact(); // Mock matchmedia -window.matchMedia = window.matchMedia || function() { +window.matchMedia = window.matchMedia || function () { return { - matches: false, - addListener: function() {}, - removeListener: function() {} + matches: false, + addListener: function () { }, + removeListener: function () { } }; };