diff --git a/.changelog/5955-fix-react-19-support.md b/.changelog/5955-fix-react-19-support.md new file mode 100644 index 0000000000..0a180f6e1d --- /dev/null +++ b/.changelog/5955-fix-react-19-support.md @@ -0,0 +1,13 @@ +### Added + +- Added [#5552](https://github.com/microsoft/BotFramework-WebChat/issues/5552) and [#5850](https://github.com/microsoft/BotFramework-WebChat/issues/5850), support for React 19, in PR [#5955](https://github.com/microsoft/BotFramework-WebChat/pull/5955), by [@OEvgeny](https://github.com/OEvgeny) +- 👷🏻 Pull request validation: added type definitions tests with `@types/react@19`, in PR [#5955](https://github.com/microsoft/BotFramework-WebChat/pull/5955), by [@OEvgeny](https://github.com/OEvgeny) + +### Removed + +- Components: removed the remaining `propTypes` and the `prop-types` dependency, React 19 ignores them, in PR [#5955](https://github.com/microsoft/BotFramework-WebChat/pull/5955), by [@OEvgeny](https://github.com/OEvgeny) + +### Fixed + +- Fixed Adaptive Cards submitting empty inputs in Strict Mode on React 19, in PR [#5955](https://github.com/microsoft/BotFramework-WebChat/pull/5955), by [@OEvgeny](https://github.com/OEvgeny) +- Fixed `Composer` of the full bundle not calling a `children` function with `extraStyleSet`, in PR [#5955](https://github.com/microsoft/BotFramework-WebChat/pull/5955), by [@OEvgeny](https://github.com/OEvgeny) diff --git a/.github/workflows/pull-request-validation.yml b/.github/workflows/pull-request-validation.yml index 87ad9a7cd7..5ac684813c 100644 --- a/.github/workflows/pull-request-validation.yml +++ b/.github/workflows/pull-request-validation.yml @@ -281,6 +281,15 @@ jobs: run: ../../node_modules/.bin/tsd -t ./dist/botframework-webchat-core.d.mts working-directory: ./packages/core + # The steps above use @types/react@16 (our baseline), check with the types of the latest React too. + # In every workspace: packages that declare @types/react@16 would otherwise keep their own copy. + - name: Install @types/react@19 and @types/react-dom@19 + run: npm install --no-save --workspaces --include-workspace-root @types/react@19 @types/react-dom@19 + + - name: Run tsd under packages/bundle with @types/react@19 + run: ../../node_modules/.bin/tsd -t ./dist/botframework-webchat.d.mts + working-directory: ./packages/bundle + bundler-test: name: Bundler test (${{ matrix.bundler }}, React ${{ matrix.react }}) needs: diff --git a/__tests__/html2/react19/asset/reactDOMWithoutRender.js b/__tests__/html2/react19/asset/reactDOMWithoutRender.js deleted file mode 100644 index 03bedf7469..0000000000 --- a/__tests__/html2/react19/asset/reactDOMWithoutRender.js +++ /dev/null @@ -1,9 +0,0 @@ -// Emulates "react-dom" of React 19, where `ReactDOM.render()` was removed, on top of React 18. -// Named exports are kept: react-film, bundled in the static build, imports `render` by name (spyip/react-film#110). -import ReactDOM from '/__dist__/packages/bundle/static/react-dom.js'; - -export * from '/__dist__/packages/bundle/static/react-dom.js'; - -const { render: _render, ...ReactDOMWithoutRender } = ReactDOM; - -export default Object.freeze(ReactDOMWithoutRender); diff --git a/__tests__/html2/react19/renderWebChat.esm.html b/__tests__/html2/react19/renderWebChat.esm.html index 708d95f68c..dea7926f7a 100644 --- a/__tests__/html2/react19/renderWebChat.esm.html +++ b/__tests__/html2/react19/renderWebChat.esm.html @@ -1,23 +1,19 @@ - renderWebChat() renders with the root passed when ReactDOM.render() is unavailable (ESM build) + React 19: renderWebChat() of the ESM build renders with the root passed
- @@ -37,8 +33,8 @@ const { directLine, store } = testHelpers.createDirectLineEmulator(); const webChatElement = document.getElementById('webchat'); - // GIVEN: "react-dom" of React 18 without `ReactDOM.render()`, like React 19. - expect(ReactDOM.version).toEqual(expect.stringMatching(/^18\./u)); // React 18 underneath the emulation, see the import map. + // GIVEN: React 19, which no longer has `ReactDOM.render()`. + expect(ReactDOM.version).toBe('19.3.1'); expect(ReactDOM.render).toBeUndefined(); // WHEN: Web Chat is rendered by renderWebChat() into the element. diff --git a/__tests__/html2/react19/strictMode.adaptiveCard.submit.html b/__tests__/html2/react19/strictMode.adaptiveCard.submit.html new file mode 100644 index 0000000000..3b131769eb --- /dev/null +++ b/__tests__/html2/react19/strictMode.adaptiveCard.submit.html @@ -0,0 +1,98 @@ + + + + React 19: submits the typed value of an Adaptive Card in Strict Mode + + + +
+ + + + diff --git a/__tests__/html2/react19/strictMode.adaptiveCard.submit.html.snap-1.png b/__tests__/html2/react19/strictMode.adaptiveCard.submit.html.snap-1.png new file mode 100644 index 0000000000..42d3b6c48d Binary files /dev/null and b/__tests__/html2/react19/strictMode.adaptiveCard.submit.html.snap-1.png differ diff --git a/__tests__/html2/react19/strictMode.esm.html b/__tests__/html2/react19/strictMode.esm.html new file mode 100644 index 0000000000..28ae00b4f4 --- /dev/null +++ b/__tests__/html2/react19/strictMode.esm.html @@ -0,0 +1,198 @@ + + + + React 19 in Strict Mode (ESM build): message, carousel, suggested action and Adaptive Card + + + +
+ + + + diff --git a/__tests__/html2/react19/strictMode.esm.html.snap-1.png b/__tests__/html2/react19/strictMode.esm.html.snap-1.png new file mode 100644 index 0000000000..fafb644575 Binary files /dev/null and b/__tests__/html2/react19/strictMode.esm.html.snap-1.png differ diff --git a/__tests__/html2/react19/strictMode.esm.html.snap-2.png b/__tests__/html2/react19/strictMode.esm.html.snap-2.png new file mode 100644 index 0000000000..24d28e598b Binary files /dev/null and b/__tests__/html2/react19/strictMode.esm.html.snap-2.png differ diff --git a/__tests__/html2/react19/strictMode.esm.html.snap-3.png b/__tests__/html2/react19/strictMode.esm.html.snap-3.png new file mode 100644 index 0000000000..e2c1afef69 Binary files /dev/null and b/__tests__/html2/react19/strictMode.esm.html.snap-3.png differ diff --git a/__tests__/html2/react19/strictMode.esm.html.snap-4.png b/__tests__/html2/react19/strictMode.esm.html.snap-4.png new file mode 100644 index 0000000000..c80814681f Binary files /dev/null and b/__tests__/html2/react19/strictMode.esm.html.snap-4.png differ diff --git a/__tests__/html2/strictMode/adaptiveCard.submit.html b/__tests__/html2/strictMode/adaptiveCard.submit.html new file mode 100644 index 0000000000..523956d52f --- /dev/null +++ b/__tests__/html2/strictMode/adaptiveCard.submit.html @@ -0,0 +1,98 @@ + + + + Strict Mode: submits the typed value of an Adaptive Card on React 18 + + + +
+ + + + diff --git a/__tests__/html2/strictMode/adaptiveCard.submit.html.snap-1.png b/__tests__/html2/strictMode/adaptiveCard.submit.html.snap-1.png new file mode 100644 index 0000000000..42d3b6c48d Binary files /dev/null and b/__tests__/html2/strictMode/adaptiveCard.submit.html.snap-1.png differ diff --git a/docs/HOSTING.md b/docs/HOSTING.md index b100dabca3..d4d9d913b9 100644 --- a/docs/HOSTING.md +++ b/docs/HOSTING.md @@ -87,12 +87,12 @@ Serving Web Chat code from your own service is recommended for these environment For React web apps, it is important to have all React components rendered with the same version and instance of the React runtime. -To choose between different version of React runtime, modify the import map and reference the version of your choice. React runtime must be loaded as ES Modules (ESM) instead of UMD. You may need to use a smart CDN service to load React runtime as ESM. +Web Chat supports React 16.8.6 to 19. To choose between different version of React runtime, modify the import map and reference the version of your choice. React runtime must be loaded as ES Modules (ESM) instead of UMD. You may need to use a smart CDN service to load React runtime as ESM. -When deploying to locked down environment, clients may not have access to smart CDN service. For conveniences, Web Chat repacked React 16.8.6 (baseline) and React 18 (latest supported) as ESM under the `/static/` directory. +When deploying to locked down environment, clients may not have access to smart CDN service. For conveniences, Web Chat repacked React 16.8.6 (baseline) and React 18 as ESM under the `/static/` directory.
-For React (latest supported) +For React 18 ```html