diff --git a/.github/workflows/pr-vrt.yml b/.github/workflows/pr-vrt.yml
index 6e14013b20a5bb..f2ed427b93bfe4 100644
--- a/.github/workflows/pr-vrt.yml
+++ b/.github/workflows/pr-vrt.yml
@@ -24,6 +24,7 @@ jobs:
if: ${{ github.repository_owner == 'microsoft' }}
runs-on: macos-14-xlarge
name: Generate screenshots
+ timeout-minutes: 60
steps:
- uses: actions/checkout@v4
with:
diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
index b33584bb52d87a..94b31e35dd7f09 100644
--- a/.github/workflows/pr.yml
+++ b/.github/workflows/pr.yml
@@ -104,17 +104,17 @@ jobs:
- run: |
yarn install --frozen-lockfile
yarn rit --react 17 --install-deps
- yarn rit --react 19 --install-deps
+ yarn rit --react 18 --install-deps
- - name: Verify Cypress installs from RIT temp workspaces (React 17 -> v13, React 19 -> v14)
+ - name: Verify Cypress installs from RIT temp workspaces (React 17 -> v13, React 18 -> v14)
run: |
"$GITHUB_WORKSPACE"/tmp/rit/react-17/node_modules/.bin/cypress verify
- "$GITHUB_WORKSPACE"/tmp/rit/react-19/node_modules/.bin/cypress verify
+ "$GITHUB_WORKSPACE"/tmp/rit/react-18/node_modules/.bin/cypress verify
- - name: React Versions Integration Tests (17,19) - E2E
+ - name: React Versions Integration Tests (17,18) - E2E
id: e2e
run: |
- yarn nx affected -t test-rit--17--e2e,test-rit--19--e2e --exclude='react-19-tests-v9,react-charting,react'
+ yarn nx affected -t test-rit--17--e2e,test-rit--18--e2e --exclude='react-19-tests-v9,react-charting,react'
- name: Upload Cypress screenshots if exist
uses: actions/upload-artifact@v4
@@ -125,40 +125,9 @@ jobs:
tmp/rit/**/cypress/screenshots/**/*.png
retention-days: 1
- - name: React Versions Integration Tests (17,19) - Type-check & Test
+ - name: React Versions Integration Tests (17,18) - Type-check & Test
run: |
- FLUENT_JEST_WORKER=2 yarn nx affected -t test-rit--17--type-check,test-rit--19--type-check,test-rit--17--test,test-rit--19--test --exclude='react-19-tests-v9'
-
- react_19_v9_source_code_typecheck:
- if: ${{ github.repository_owner == 'microsoft' }}
- runs-on: ubuntu-latest
- permissions:
- contents: 'read'
- actions: 'read'
- name: v9 source code type-check against React 19
- steps:
- - uses: actions/checkout@v4
- with:
- fetch-depth: 0
-
- - name: Derive appropriate SHAs for base and head for `nx affected` commands
- uses: nrwl/nx-set-shas@826660b82addbef3abff5fa871492ebad618c9e1 # v4.3.3
- with:
- main-branch-name: 'master'
-
- - uses: actions/setup-node@v4
- with:
- cache: 'yarn'
- node-version: '22'
-
- - run: echo number of CPUs "$(getconf _NPROCESSORS_ONLN)"
-
- - run: |
- yarn install --frozen-lockfile
- yarn rit --react 19 --install-deps
-
- - run: |
- yarn nx affected -t test-rit--19--type-check --exclude='*,!react-19-tests-v9'
+ FLUENT_JEST_WORKER=2 yarn nx affected -t test-rit--17--type-check,test-rit--18--type-check,test-rit--17--test,test-rit--18--test --exclude='react-19-tests-v9'
e2e:
if: ${{ github.repository_owner == 'microsoft' }}
diff --git a/apps/chart-docsite/package.json b/apps/chart-docsite/package.json
index 7a09079879cad2..272d0720b31702 100644
--- a/apps/chart-docsite/package.json
+++ b/apps/chart-docsite/package.json
@@ -29,8 +29,8 @@
"@fluentui/react-charts": "*",
"@fluentui/react-storybook-addon": "*",
"@fluentui/react-storybook-addon-export-to-sandbox": "*",
- "react": "18.3.1",
- "react-dom": "18.3.1",
+ "react": "19.2.0",
+ "react-dom": "19.2.0",
"tslib": "^2.1.0"
}
}
diff --git a/apps/perf-test-react-components/package.json b/apps/perf-test-react-components/package.json
index 9e4ea9f4808cfb..157e2b384c1c12 100644
--- a/apps/perf-test-react-components/package.json
+++ b/apps/perf-test-react-components/package.json
@@ -29,8 +29,8 @@
"@fluentui/react-theme": "*",
"@griffel/core": "^1.16.0",
"@microsoft/load-themed-styles": "^1.10.26",
- "react": "18.3.1",
- "react-dom": "18.3.1",
+ "react": "19.2.0",
+ "react-dom": "19.2.0",
"tslib": "^2.1.0"
}
}
diff --git a/apps/perf-test/package.json b/apps/perf-test/package.json
index 8303b0913bb566..f6b4e09190c414 100644
--- a/apps/perf-test/package.json
+++ b/apps/perf-test/package.json
@@ -22,8 +22,8 @@
"@fluentui/example-data": "*",
"@fluentui/react": "*",
"@microsoft/load-themed-styles": "^1.10.26",
- "react": "18.3.1",
- "react-dom": "18.3.1",
+ "react": "19.2.0",
+ "react-dom": "19.2.0",
"tslib": "^2.1.0"
}
}
diff --git a/apps/public-docsite-resources/package.json b/apps/public-docsite-resources/package.json
index 83d2c737eaa06c..20098f3bb5a919 100644
--- a/apps/public-docsite-resources/package.json
+++ b/apps/public-docsite-resources/package.json
@@ -46,8 +46,8 @@
"@fluentui/theme-samples": "*",
"@fluentui/react-monaco-editor": "*",
"office-ui-fabric-core": "^11.0.0",
- "react": "18.3.1",
- "react-dom": "18.3.1",
+ "react": "19.2.0",
+ "react-dom": "19.2.0",
"tslib": "^2.1.0"
}
}
diff --git a/apps/public-docsite-v9/package.json b/apps/public-docsite-v9/package.json
index d5d8737dce2a7f..bdc18dc3c502df 100644
--- a/apps/public-docsite-v9/package.json
+++ b/apps/public-docsite-v9/package.json
@@ -40,8 +40,8 @@
"@fluentui/react-timepicker-compat": "*",
"@griffel/react": "^1.5.22",
"@microsoft/applicationinsights-web": "^3",
- "react": "18.3.1",
- "react-dom": "18.3.1",
+ "react": "19.2.0",
+ "react-dom": "19.2.0",
"react-window": "^1.8.6",
"tslib": "^2.1.0",
"react-hook-form": "^5.7.2",
diff --git a/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Components/Flex/utils.stories.test.tsx b/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Components/Flex/utils.stories.test.tsx
index f2383c04f013b5..5499e15b43a488 100644
--- a/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Components/Flex/utils.stories.test.tsx
+++ b/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Components/Flex/utils.stories.test.tsx
@@ -1,9 +1,22 @@
-/* eslint-disable react/jsx-key */
+/* eslint-disable @typescript-eslint/naming-convention */
+
import * as React from 'react';
-import { Source } from '@storybook/addon-docs';
-import { createRenderer } from 'react-test-renderer/shallow';
+import { render } from '@testing-library/react';
+
import { CodeExample } from './utils.stories';
+// Mock the Source component to verify it receives correct props
+const mockSource = jest.fn(({ code, language }: { code: string; language: string }) => (
+
+ {code}
+
+));
+
+// `Source` wont be available in the test environment, so we need to mock it to test the code output
+jest.mock('@storybook/addon-docs', () => ({
+ Source: (props: { code: string; language: string }) => mockSource(props),
+}));
+
function mockMDXSourceCodeBlock(source: string) {
return {
props: {
@@ -16,23 +29,22 @@ function mockMDXSourceCodeBlock(source: string) {
} as React.ReactElement;
}
+beforeEach(() => {
+ mockSource.mockClear();
+});
+
test('renders children', () => {
- const renderer = createRenderer();
- renderer.render(
+ const { container } = render(
Child
,
);
- const result = renderer.getRenderOutput();
- expect(result.props).toEqual({
- children: 'Child',
- });
+ expect(container.textContent).toBe('Child');
});
test('renders Markdown source blocks', () => {
- const renderer = createRenderer();
- renderer.render(
+ const { getByRole, getByTestId } = render(
{mockMDXSourceCodeBlock(`\`\`\`js
function test() {
@@ -41,43 +53,51 @@ test('renders Markdown source blocks', () => {
\`\`\``)}
,
);
- const result = renderer.getRenderOutput();
- expect(result.props).toEqual({
- children: [
- JavaScript
,
- ,
- ],
- });
+ }`,
+ language: 'jsextra',
+ }),
+ );
+
+ // Verify Source component rendered correctly
+ const sourceElement = getByTestId('source');
+ expect(sourceElement.getAttribute('data-language')).toBe('jsextra');
+ expect(sourceElement.textContent).toContain('function test()');
});
test('uses JSX for no header JSX source code blocks', () => {
- const renderer = createRenderer();
- renderer.render(
+ const { getByRole, getByTestId } = render(
{mockMDXSourceCodeBlock(`
`)}
,
);
- const result = renderer.getRenderOutput();
- expect(result.props).toEqual({
- children: [
- React
,
-
+ const heading = getByRole('heading', { level: 3 });
+ expect(heading.textContent).toBe('React');
+
+ // Verify Source component was called with JSX language
+ expect(mockSource).toHaveBeenCalledWith(
+ expect.objectContaining({
+ code: `
-
`}
- language="jsx"
- />,
- ],
- });
+ `,
+ language: 'jsx',
+ }),
+ );
+
+ const sourceElement = getByTestId('source');
+ expect(sourceElement.getAttribute('data-language')).toBe('jsx');
});
test.each([
@@ -85,9 +105,8 @@ test.each([
['css', 'CSS'],
['js', 'JavaScript'],
['jsx', 'React'],
-] as const)('for language %s uses the header %s', (language, expectedHeader) => {
- const renderer = createRenderer();
- renderer.render(
+])('for language %s uses the header %s', (language, expectedHeader) => {
+ const { getByRole, getByTestId } = render(
{mockMDXSourceCodeBlock(`
\`\`\`${language}
@@ -96,16 +115,27 @@ test.each([
`)}
,
);
- const result = renderer.getRenderOutput();
- expect(result.props).toEqual({
- children: [{expectedHeader}
, ],
- });
+ const resolvedLanguage = language === 'js' ? 'jsextra' : language;
+
+ const heading = getByRole('heading', { level: 3 });
+ expect(heading.textContent).toBe(expectedHeader);
+
+ // Verify Source component was called with correct language
+ expect(mockSource).toHaveBeenCalledWith(
+ expect.objectContaining({
+ code: 'Code',
+ language: resolvedLanguage,
+ }),
+ );
+
+ const sourceElement = getByTestId('source');
+ expect(sourceElement.getAttribute('data-language')).toBe(resolvedLanguage);
+ expect(sourceElement.textContent).toBe('Code');
});
test('overrides the default title', () => {
- const renderer = createRenderer();
- renderer.render(
+ const { getByRole, getByTestId } = render(
{mockMDXSourceCodeBlock(`
\`\`\`js
@@ -114,9 +144,18 @@ test('overrides the default title', () => {
`)}
,
);
- const result = renderer.getRenderOutput();
- expect(result.props).toEqual({
- children: [Custom title
, ],
- });
+ const heading = getByRole('heading', { level: 3 });
+ expect(heading.textContent).toBe('Custom title');
+
+ // Verify Source component still receives correct code and language
+ expect(mockSource).toHaveBeenCalledWith(
+ expect.objectContaining({
+ code: 'Code',
+ language: 'jsextra',
+ }),
+ );
+
+ const sourceElement = getByTestId('source');
+ expect(sourceElement.getAttribute('data-language')).toBe('jsextra');
});
diff --git a/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Components/Flex/utils.stories.tsx b/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Components/Flex/utils.stories.tsx
index fd536bff6c733e..b7c5ca62717e1e 100644
--- a/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Components/Flex/utils.stories.tsx
+++ b/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Components/Flex/utils.stories.tsx
@@ -30,7 +30,7 @@ const codeLanguages = {
js: 'JavaScript',
jsx: 'React',
};
-export const CodeExample = (props: { title?: string; children: React.ReactElement }) => {
+export const CodeExample = (props: { title?: string; children?: React.ReactElement }) => {
const { title, children } = props;
// Access the raw values from the markdown source code block
const markdownCodeBlockValue: string | undefined = children?.props?.children?.props?.children;
diff --git a/apps/public-docsite/package.json b/apps/public-docsite/package.json
index 87c7cbbbe12398..84a013c8e8fac3 100644
--- a/apps/public-docsite/package.json
+++ b/apps/public-docsite/package.json
@@ -48,8 +48,8 @@
"@fluentui/utilities": "*",
"@microsoft/load-themed-styles": "^1.10.26",
"office-ui-fabric-core": "^11.0.0",
- "react": "18.3.1",
- "react-dom": "18.3.1",
+ "react": "19.2.0",
+ "react-dom": "19.2.0",
"tslib": "^2.1.0",
"whatwg-fetch": "2.0.4"
}
diff --git a/apps/public-docsite/src/components/IconGrid/IconGrid.tsx b/apps/public-docsite/src/components/IconGrid/IconGrid.tsx
index 6a35e2b8192a52..66f5b173c170d3 100644
--- a/apps/public-docsite/src/components/IconGrid/IconGrid.tsx
+++ b/apps/public-docsite/src/components/IconGrid/IconGrid.tsx
@@ -31,7 +31,7 @@ export type IIconGridProps = IFontIconGridProps | ISvgIconGridProps;
interface IFontIconDefinition {
name: string;
- ref: React.RefObject;
+ ref: React.RefObject;
iconType: 'core-font' | 'react-font';
}
diff --git a/apps/public-docsite/src/components/Nav/Nav.tsx b/apps/public-docsite/src/components/Nav/Nav.tsx
index fcbd71c6ba9e37..7ef520abc8712b 100644
--- a/apps/public-docsite/src/components/Nav/Nav.tsx
+++ b/apps/public-docsite/src/components/Nav/Nav.tsx
@@ -100,7 +100,7 @@ export class Nav extends React.Component {
);
}
- private _renderLinkList = (pages: INavPage[], isSubMenu: boolean): React.ReactElement => {
+ private _renderLinkList = (pages: INavPage[], isSubMenu: boolean): React.ReactElement => {
const { searchablePageTitle } = this.props;
const { sortState } = this.state;
diff --git a/apps/public-docsite/webpack.serve.config.js b/apps/public-docsite/webpack.serve.config.js
index 85503202fa1af7..cce8db4e0afd69 100644
--- a/apps/public-docsite/webpack.serve.config.js
+++ b/apps/public-docsite/webpack.serve.config.js
@@ -61,7 +61,8 @@ module.exports = [
resolve: {
alias: {
- ...getResolveAlias(), // react-monaco-editor dynamically loads @types/react via proprietary webpack require.ensure,
+ ...getResolveAlias(),
+ // react-monaco-editor dynamically loads @types/react via proprietary webpack require.ensure,
// this doesn't work starting @types/react@17.0.48 as the types package introduced Export Maps
'@types/react/index.d.ts': path.resolve(__dirname, '../../node_modules/@types/react/index.d.ts'),
},
diff --git a/apps/react-19-tests-v9/.swcrc b/apps/react-19-tests-v9/.swcrc
deleted file mode 100644
index b4ffa86dee3067..00000000000000
--- a/apps/react-19-tests-v9/.swcrc
+++ /dev/null
@@ -1,30 +0,0 @@
-{
- "$schema": "https://json.schemastore.org/swcrc",
- "exclude": [
- "/testing",
- "/**/*.cy.ts",
- "/**/*.cy.tsx",
- "/**/*.spec.ts",
- "/**/*.spec.tsx",
- "/**/*.test.ts",
- "/**/*.test.tsx"
- ],
- "jsc": {
- "parser": {
- "syntax": "typescript",
- "tsx": true,
- "decorators": false,
- "dynamicImport": false
- },
- "externalHelpers": true,
- "transform": {
- "react": {
- "runtime": "classic",
- "useSpread": true
- }
- },
- "target": "es2019"
- },
- "minify": false,
- "sourceMaps": true
-}
diff --git a/apps/react-19-tests-v9/README.md b/apps/react-19-tests-v9/README.md
deleted file mode 100644
index 490ba688b52ff9..00000000000000
--- a/apps/react-19-tests-v9/README.md
+++ /dev/null
@@ -1,59 +0,0 @@
-# @fluentui/react-19-tests-v9
-
-**Tests for React 19 compatibility in [Fluent UI React v9](https://react.fluentui.dev)**.
-
-## Usage
-
-### React 19 integration tests against all v9 code in monorepo
-
-Following Targets are used:
-
-#### type-check:integration
-
-`yarn nx run react-19-tests-v9:type-check:integration`
-
-runs `tsc` against all monorepo v9 stories with properly pinned `@types/react@18`
-
-_Note:_ react-migration-v8-v9, react-migration-v0-v9 and any `react-*-compat` are excluded from this check
-
-#### e2e:integration
-
-`yarn nx run react-19-tests-v9:e2e:integration`
-
-runs `cypress` against all monorepo v9 `*.cy.tsx?` with properly pinned `react18` runtime deps
-
-### `start`
-
-```shell
-# yarn start
-```
-
-This app has a simple CRA style `App.tsx` file to allow testing and triaging Fluent UI components in a React 19 environment. Please do not commit any new content to this file that isn't useful for everyone else.
-
-This file and process will be replaced with Storybook once we are able to get storybook working in React 19 in our mono-repo.
-
-### `test`
-
-```shell
-# yarn test
-```
-
-Add test files for React 19 issues that have been triaged and resolved so that we do not regress.
-
-### `type-check`
-
-To be able to type-check cross React versions we need all v9 libraries build up front so we don't type check all v9 implementation rather public API surface.
-
-For that purpose we use `tsconfig.react-compat-check.json` as target for `type-check` npm script task, which disables path aliases and forces `tsc` to consume linked monorepo build packages.
-
-**Local machine flow:**
-
-```sh
-yarn nx run react-19-tests-v9:build
-
-yarn nx run react-19-tests-v9:type-check
-```
-
-**CI:**
-
-nx defines `build` targets to be executed prior to `type-check`.
diff --git a/apps/react-19-tests-v9/package.json b/apps/react-19-tests-v9/package.json
deleted file mode 100644
index 35a4f863099039..00000000000000
--- a/apps/react-19-tests-v9/package.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "name": "@fluentui/react-19-tests-v9",
- "description": "React 19 type-check against v9 source files",
- "version": "1.0.0",
- "private": true,
- "scripts": {
- "format": "prettier -w . --ignore-path ../.prettierignore",
- "format:check": "yarn format -c"
- },
- "devDependencies": {
- "@fluentui/eslint-plugin": "*"
- },
- "dependencies": {
- "@fluentui/react-components": "*",
- "@fluentui/react-calendar-compat": "*",
- "@fluentui/react-datepicker-compat": "*",
- "@fluentui/react-timepicker-compat": "*",
- "@fluentui/react-migration-v8-v9": "*",
- "@fluentui/react-menu-grid-preview": "*",
- "tslib": "^2.1.0"
- }
-}
diff --git a/apps/react-19-tests-v9/project.json b/apps/react-19-tests-v9/project.json
deleted file mode 100644
index cdb226fd38ab67..00000000000000
--- a/apps/react-19-tests-v9/project.json
+++ /dev/null
@@ -1,98 +0,0 @@
-{
- "name": "react-19-tests-v9",
- "$schema": "../../node_modules/nx/schemas/project-schema.json",
- "projectType": "application",
- "implicitDependencies": [],
- "tags": ["vNext"],
- "metadata": {
- "targetGroups": {
- "React Integration Tester": ["test-rit--19--prepare", "test-rit--19--type-check", "test-rit"]
- }
- },
- "targets": {
- "test-rit--19--prepare": {
- "options": {
- "cwd": "{projectRoot}",
- "command": "yarn rit --prepare-only --no-install --project-id ci --react 19 --verbose"
- },
- "cache": true,
- "inputs": [
- "default",
- "production",
- "^production",
- "{workspaceRoot}/jest.preset.js",
- "{workspaceRoot}/tools/react-integration-testing/**"
- ],
- "outputs": ["{workspaceRoot}/tmp/rit/react-19/rit-tests-v9-react-19-ci"],
- "dependsOn": ["^build"],
- "metadata": {
- "technologies": ["react-integration-tester"],
- "description": "Run react integration tests against React 19",
- "help": {
- "command": "yarn rit --help",
- "example": {}
- }
- },
- "executor": "nx:run-commands",
- "configurations": {},
- "parallelism": true
- },
- "test-rit--19--type-check": {
- "options": {
- "cwd": "{projectRoot}",
- "command": "yarn rit --project-id ci --react 19 --run type-check --verbose"
- },
- "cache": true,
- "inputs": [
- "default",
- "production",
- "^production",
- "{workspaceRoot}/jest.preset.js",
- "{workspaceRoot}/tools/react-integration-testing/**"
- ],
- "outputs": [],
- "dependsOn": ["test-rit--19--prepare"],
- "metadata": {
- "technologies": ["react-integration-tester"],
- "description": "Run react integration tests against React 19",
- "help": {
- "command": "yarn rit --help",
- "example": {}
- }
- },
- "executor": "nx:run-commands",
- "configurations": {},
- "parallelism": true
- },
- "test-rit": {
- "executor": "nx:noop",
- "cache": true,
- "dependsOn": [
- {
- "target": "test-rit--19--type-check",
- "projects": "self",
- "params": "forward"
- }
- ],
- "inputs": [
- "default",
- "production",
- "^production",
- "{workspaceRoot}/jest.preset.js",
- "{workspaceRoot}/tools/react-integration-testing/**"
- ],
- "outputs": [],
- "metadata": {
- "technologies": ["react-integration-tester"],
- "description": "Run react integration tests against React 19",
- "help": {
- "command": "yarn rit --help",
- "example": {}
- }
- },
- "configurations": {},
- "options": {},
- "parallelism": true
- }
- }
-}
diff --git a/apps/react-19-tests-v9/src/index.ts b/apps/react-19-tests-v9/src/index.ts
deleted file mode 100644
index cb0ff5c3b541f6..00000000000000
--- a/apps/react-19-tests-v9/src/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export {};
diff --git a/apps/react-19-tests-v9/tsconfig.json b/apps/react-19-tests-v9/tsconfig.json
deleted file mode 100644
index 9cf5fafb90afb5..00000000000000
--- a/apps/react-19-tests-v9/tsconfig.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "extends": "../../tsconfig.base.json",
- "compilerOptions": {
- "module": "CommonJS",
- "target": "ES2019",
- "noEmit": true,
- "isolatedModules": true,
- "importHelpers": true,
- "jsx": "react",
- "noUnusedLocals": true,
- "preserveConstEnums": true,
- "skipLibCheck": true
- },
- "include": [],
- "files": [],
- "references": [
- {
- "path": "./tsconfig.lib.json"
- }
- ]
-}
diff --git a/apps/react-19-tests-v9/tsconfig.lib.json b/apps/react-19-tests-v9/tsconfig.lib.json
deleted file mode 100644
index c0d322adf8cb3b..00000000000000
--- a/apps/react-19-tests-v9/tsconfig.lib.json
+++ /dev/null
@@ -1,37 +0,0 @@
-{
- "compilerOptions": {
- "target": "ES2019",
- "module": "esnext",
- "moduleResolution": "node",
- "lib": ["ES2019", "ES2020.Intl", "dom"],
- "sourceMap": true,
- "strict": true,
- "pretty": true,
- "noEmit": true,
- "isolatedModules": true,
- "importHelpers": true,
- "jsx": "react",
- "noUnusedLocals": true,
- "preserveConstEnums": true,
- "skipLibCheck": true,
- "types": []
- },
- "exclude": [
- "../../packages/react-components/react-migration-v0-v9/**",
- "../../packages/react-components/react-migration-v8-v9/**",
- "../../packages/react-components/react-conformance-griffel/**",
- "../../packages/react-components/**/*.stories.tsx",
- "../../packages/react-components/**/*.stories.ts",
- "../../packages/react-components/**/*.test.tsx",
- "../../packages/react-components/**/*.test.ts",
- "../../packages/react-components/**/*.spec.tsx",
- "../../packages/react-components/**/*.spec.ts",
- "../../packages/react-components/**/*.cy.tsx",
- "../../packages/react-components/**/*.cy.ts"
- ],
- "include": [
- "../../packages/react-components/react-*/library/src/*.tsx",
- "../../packages/react-components/react-*/library/src/*.ts"
- ],
- "files": ["../../typings/static-assets/index.d.ts", "../../typings/environment/index.d.ts"]
-}
diff --git a/apps/rit-tests-v9/.eslintrc.json b/apps/rit-tests-v9/.eslintrc.json
index ed692bcfff2a6d..55ebed399e939c 100644
--- a/apps/rit-tests-v9/.eslintrc.json
+++ b/apps/rit-tests-v9/.eslintrc.json
@@ -1,7 +1,7 @@
{
"extends": ["plugin:@fluentui/eslint-plugin/react"],
"root": true,
- "ignorePatterns": ["!**/*", "src/react-19/**/*", "src/react-17/**/*"],
+ "ignorePatterns": ["!**/*", "src/react-18/**/*", "src/react-17/**/*"],
"rules": {
"@nx/workspace-enforce-use-client": "off",
"@nx/workspace-no-restricted-globals": "off",
diff --git a/apps/rit-tests-v9/tsconfig.lib.json b/apps/rit-tests-v9/tsconfig.lib.json
index 92ff0c3a802067..70c29fa2bc42f5 100644
--- a/apps/rit-tests-v9/tsconfig.lib.json
+++ b/apps/rit-tests-v9/tsconfig.lib.json
@@ -18,5 +18,5 @@
"**/*.cy.ts",
"**/*.cy.tsx"
],
- "include": ["src/index.ts", "./src/react-18/", "./src/shared/**/*.ts", "./src/shared/**/*.tsx"]
+ "include": ["src/index.ts", "./src/react-19/", "./src/shared/**/*.ts", "./src/shared/**/*.tsx"]
}
diff --git a/apps/ssr-tests/test/test.js b/apps/ssr-tests/test/test.js
index b3fc5871131f9f..1152b0245e6cf6 100644
--- a/apps/ssr-tests/test/test.js
+++ b/apps/ssr-tests/test/test.js
@@ -61,17 +61,36 @@ describe('Utilities', () => {
/**
*
* @param {string} componentName
- * @param {React.ComponentClass | (() => JSX.Element)} component
+ * @param {React.ComponentClass | (() => React.ReactElement)} component
*/
function testRender(componentName, component) {
- it(`${componentName} can render in a server environment`, done => {
- let elem = React.createElement(component);
+ it(`${componentName} can render in a server environment`, function () {
+ // Increase timeout for components that may take longer (like Calendar)
+ this.timeout(10000);
+ let elem;
try {
- ReactDOMServer.renderToString(elem);
- done();
+ elem = React.createElement(component);
} catch (/** @type {any} */ e) {
- done(new Error(e));
+ throw new Error(`${componentName} failed to create element: ${e.message || e}`);
+ }
+
+ try {
+ const result = ReactDOMServer.renderToString(elem);
+
+ // Basic sanity check that something was rendered
+ if (typeof result !== 'string') {
+ throw new Error(`${componentName} rendered a non-string result: ${typeof result}`);
+ }
+
+ if (result.length === 0) {
+ throw new Error(`${componentName} rendered an empty string`);
+ }
+ } catch (/** @type {any} */ e) {
+ // Re-throw with better context
+ const message = e.message || String(e);
+ console.error(`${componentName} failed to render: ${message}`);
+ throw new Error(e);
}
});
}
diff --git a/apps/ssr-tests/webpack.config.js b/apps/ssr-tests/webpack.config.js
index 04c561116b2373..1aa27a6432f689 100644
--- a/apps/ssr-tests/webpack.config.js
+++ b/apps/ssr-tests/webpack.config.js
@@ -1,3 +1,4 @@
+const path = require('node:path');
const { getResolveAlias, resources } = require('@fluentui/scripts-webpack');
module.exports = resources.createConfig('ssr-tests', false, {
@@ -10,7 +11,12 @@ module.exports = resources.createConfig('ssr-tests', false, {
target: 'node',
resolve: {
- alias: getResolveAlias(true /*useLib*/),
+ alias: {
+ ...getResolveAlias(true /*useLib*/),
+ // react-monaco-editor dynamically loads @types/react via proprietary webpack require.ensure,
+ // this doesn't work starting @types/react@17.0.48 as the types package introduced Export Maps
+ '@types/react/index.d.ts': path.resolve(__dirname, '../../node_modules/@types/react/index.d.ts'),
+ },
},
plugins: [
diff --git a/apps/theming-designer/package.json b/apps/theming-designer/package.json
index b3ebde3f52c7aa..04d48211888c4c 100644
--- a/apps/theming-designer/package.json
+++ b/apps/theming-designer/package.json
@@ -25,8 +25,8 @@
"@fluentui/set-version": "*",
"@fluentui/font-icons-mdl2": "*",
"@microsoft/load-themed-styles": "^1.10.26",
- "react": "18.3.1",
- "react-dom": "18.3.1",
+ "react": "19.2.0",
+ "react-dom": "19.2.0",
"tslib": "^2.1.0"
}
}
diff --git a/apps/vr-tests-react-components/package.json b/apps/vr-tests-react-components/package.json
index 15f2c39ce7b373..c9e9c033d6ec6f 100644
--- a/apps/vr-tests-react-components/package.json
+++ b/apps/vr-tests-react-components/package.json
@@ -71,8 +71,8 @@
"@fluentui/react-tree": "*",
"@fluentui/react-utilities": "*",
"@griffel/react": "^1.5.22",
- "react": "18.3.1",
- "react-dom": "18.3.1",
+ "react": "19.2.0",
+ "react-dom": "19.2.0",
"tslib": "^2.1.0",
"@fluentui/react-breadcrumb": "*",
"@fluentui/react-rating": "*",
diff --git a/apps/vr-tests-react-components/src/stories/Positioning/PositioningScrollJumps.stories.tsx b/apps/vr-tests-react-components/src/stories/Positioning/PositioningScrollJumps.stories.tsx
index 770c8392693f02..6008df59436362 100644
--- a/apps/vr-tests-react-components/src/stories/Positioning/PositioningScrollJumps.stories.tsx
+++ b/apps/vr-tests-react-components/src/stories/Positioning/PositioningScrollJumps.stories.tsx
@@ -186,7 +186,7 @@ const Target: React.FC<{ children?: React.ReactNode }> = props => {
const setOpen = useContextSelector(Context, v => v!.setOpen);
const targetRef = useContextSelector(Context, v => v!.targetRef);
- return React.cloneElement(props.children as React.ReactElement, {
+ return React.cloneElement(props.children as React.ReactElement, {
'aria-expanded': `${open}`,
onClick: () => setOpen(true),
ref: targetRef,
diff --git a/apps/vr-tests-web-components/package.json b/apps/vr-tests-web-components/package.json
index aea1e9733b3361..93440686885691 100644
--- a/apps/vr-tests-web-components/package.json
+++ b/apps/vr-tests-web-components/package.json
@@ -13,8 +13,8 @@
"test-vr": "storywright --browsers chromium --url dist/storybook --destpath dist/screenshots --waitTimeScreenshot 500 --concurrency 4 --headless true --stepsApi parameters"
},
"dependencies": {
- "react": "18.3.1",
- "react-dom": "18.3.1",
+ "react": "19.2.0",
+ "react-dom": "19.2.0",
"html-react-parser": "4.0.0",
"@fluentui/tokens": ">=1.0.0-alpha",
"@fluentui/web-components": ">=3.0.0-alpha",
diff --git a/apps/vr-tests-web-components/src/utilities/WCThemeDecorator.tsx b/apps/vr-tests-web-components/src/utilities/WCThemeDecorator.tsx
index 1c53979f65eaf8..9aa76cd9542057 100644
--- a/apps/vr-tests-web-components/src/utilities/WCThemeDecorator.tsx
+++ b/apps/vr-tests-web-components/src/utilities/WCThemeDecorator.tsx
@@ -59,7 +59,7 @@ function getStoryName(story: StoryFn) {
return story.name?.replace(/([a-z])([A-Z])/g, '$1 $2');
}
-export const getStoryVariant = (story: () => string | JSX.Element | JSX.Element[], variant: Variant) => {
+export const getStoryVariant = (story: () => string | React.ReactElement | React.ReactElement[], variant: Variant) => {
return {
...story,
render: story,
diff --git a/apps/vr-tests/package.json b/apps/vr-tests/package.json
index 5e16dbfe435345..4e42b542a11241 100644
--- a/apps/vr-tests/package.json
+++ b/apps/vr-tests/package.json
@@ -28,8 +28,8 @@
"@fluentui/storybook": "*",
"@fluentui/react-charting": "*",
"@fluentui/theme-samples": "*",
- "react": "18.3.1",
- "react-dom": "18.3.1",
+ "react": "19.2.0",
+ "react-dom": "19.2.0",
"tslib": "^2.1.0"
}
}
diff --git a/change/@fluentui-react-7bd30384-1944-4b2e-82e7-3a9ca9cf00a2.json b/change/@fluentui-react-7bd30384-1944-4b2e-82e7-3a9ca9cf00a2.json
new file mode 100644
index 00000000000000..d53e21a758e3fb
--- /dev/null
+++ b/change/@fluentui-react-7bd30384-1944-4b2e-82e7-3a9ca9cf00a2.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-aria-4f20499b-bdbb-4173-bb3d-3354e1865af6.json b/change/@fluentui-react-aria-4f20499b-bdbb-4173-bb3d-3354e1865af6.json
new file mode 100644
index 00000000000000..4d346e2e1094f8
--- /dev/null
+++ b/change/@fluentui-react-aria-4f20499b-bdbb-4173-bb3d-3354e1865af6.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-aria",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-calendar-compat-9f1fad8f-bc75-42b2-8ed1-08faeda7e26d.json b/change/@fluentui-react-calendar-compat-9f1fad8f-bc75-42b2-8ed1-08faeda7e26d.json
new file mode 100644
index 00000000000000..9c18cbe179cacf
--- /dev/null
+++ b/change/@fluentui-react-calendar-compat-9f1fad8f-bc75-42b2-8ed1-08faeda7e26d.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-calendar-compat",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-charting-d811cd0a-72aa-409d-b825-f8be9db8aaf1.json b/change/@fluentui-react-charting-d811cd0a-72aa-409d-b825-f8be9db8aaf1.json
new file mode 100644
index 00000000000000..9a9e73180a6b3e
--- /dev/null
+++ b/change/@fluentui-react-charting-d811cd0a-72aa-409d-b825-f8be9db8aaf1.json
@@ -0,0 +1,7 @@
+{
+ "type": "none",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-charting",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "none"
+}
diff --git a/change/@fluentui-react-charts-4f4d2082-d4f4-4c13-b632-2e9271b1d869.json b/change/@fluentui-react-charts-4f4d2082-d4f4-4c13-b632-2e9271b1d869.json
new file mode 100644
index 00000000000000..d2913ad6751758
--- /dev/null
+++ b/change/@fluentui-react-charts-4f4d2082-d4f4-4c13-b632-2e9271b1d869.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-charts",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-combobox-411145bf-5451-46f2-8923-d84dfe726246.json b/change/@fluentui-react-combobox-411145bf-5451-46f2-8923-d84dfe726246.json
new file mode 100644
index 00000000000000..e3d0618ec0d99c
--- /dev/null
+++ b/change/@fluentui-react-combobox-411145bf-5451-46f2-8923-d84dfe726246.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-combobox",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-conformance-griffel-90873251-569e-4385-af6b-081b55097b0b.json b/change/@fluentui-react-conformance-griffel-90873251-569e-4385-af6b-081b55097b0b.json
new file mode 100644
index 00000000000000..ec142aa36ed844
--- /dev/null
+++ b/change/@fluentui-react-conformance-griffel-90873251-569e-4385-af6b-081b55097b0b.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-conformance-griffel",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-context-selector-a81bfe45-d38d-4510-8352-e63250770172.json b/change/@fluentui-react-context-selector-a81bfe45-d38d-4510-8352-e63250770172.json
new file mode 100644
index 00000000000000..4f4de4281f37e4
--- /dev/null
+++ b/change/@fluentui-react-context-selector-a81bfe45-d38d-4510-8352-e63250770172.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-context-selector",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-datepicker-compat-f71f503f-ff8e-495d-85a8-52252d3a8f77.json b/change/@fluentui-react-datepicker-compat-f71f503f-ff8e-495d-85a8-52252d3a8f77.json
new file mode 100644
index 00000000000000..15d6d264d0d339
--- /dev/null
+++ b/change/@fluentui-react-datepicker-compat-f71f503f-ff8e-495d-85a8-52252d3a8f77.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-datepicker-compat",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-docsite-components-82baf1ea-cd01-43b1-b486-81142b83c54b.json b/change/@fluentui-react-docsite-components-82baf1ea-cd01-43b1-b486-81142b83c54b.json
new file mode 100644
index 00000000000000..e778ff1c2aa568
--- /dev/null
+++ b/change/@fluentui-react-docsite-components-82baf1ea-cd01-43b1-b486-81142b83c54b.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-docsite-components",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-experiments-661291cc-c0ad-41cc-b854-0df5e1a3135c.json b/change/@fluentui-react-experiments-661291cc-c0ad-41cc-b854-0df5e1a3135c.json
new file mode 100644
index 00000000000000..819f2b9617dbd0
--- /dev/null
+++ b/change/@fluentui-react-experiments-661291cc-c0ad-41cc-b854-0df5e1a3135c.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-experiments",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-focus-363768e0-b8a1-4a05-b016-0deb074b5b45.json b/change/@fluentui-react-focus-363768e0-b8a1-4a05-b016-0deb074b5b45.json
new file mode 100644
index 00000000000000..4c3a7e3cd4bb23
--- /dev/null
+++ b/change/@fluentui-react-focus-363768e0-b8a1-4a05-b016-0deb074b5b45.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-focus",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-hooks-37bb3c6b-9743-4055-bb81-c7d42b241bfa.json b/change/@fluentui-react-hooks-37bb3c6b-9743-4055-bb81-c7d42b241bfa.json
new file mode 100644
index 00000000000000..c02eb7e322f0ae
--- /dev/null
+++ b/change/@fluentui-react-hooks-37bb3c6b-9743-4055-bb81-c7d42b241bfa.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-hooks",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-infobutton-d61dae32-bae5-4560-a05f-2880d5c190bd.json b/change/@fluentui-react-infobutton-d61dae32-bae5-4560-a05f-2880d5c190bd.json
new file mode 100644
index 00000000000000..bd36241abd7081
--- /dev/null
+++ b/change/@fluentui-react-infobutton-d61dae32-bae5-4560-a05f-2880d5c190bd.json
@@ -0,0 +1,7 @@
+{
+ "type": "prerelease",
+ "comment": "fix: mitigate native popover prop dts clash from public API exposed by React 19",
+ "packageName": "@fluentui/react-infobutton",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-jsx-runtime-418b7d0f-858c-4ecf-b873-cee512e9aa90.json b/change/@fluentui-react-jsx-runtime-418b7d0f-858c-4ecf-b873-cee512e9aa90.json
new file mode 100644
index 00000000000000..0d52d64af32a8a
--- /dev/null
+++ b/change/@fluentui-react-jsx-runtime-418b7d0f-858c-4ecf-b873-cee512e9aa90.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-jsx-runtime",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-menu-794babc6-5254-4a68-87fa-eb9943097ae2.json b/change/@fluentui-react-menu-794babc6-5254-4a68-87fa-eb9943097ae2.json
new file mode 100644
index 00000000000000..abd8c5612d75cc
--- /dev/null
+++ b/change/@fluentui-react-menu-794babc6-5254-4a68-87fa-eb9943097ae2.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-menu",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-message-bar-54e95d71-37f1-445f-af99-e9ae1c830028.json b/change/@fluentui-react-message-bar-54e95d71-37f1-445f-af99-e9ae1c830028.json
new file mode 100644
index 00000000000000..2cff228e78cef0
--- /dev/null
+++ b/change/@fluentui-react-message-bar-54e95d71-37f1-445f-af99-e9ae1c830028.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-message-bar",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-migration-v0-v9-da90228a-bafd-4cdc-bf83-3bb6f922c856.json b/change/@fluentui-react-migration-v0-v9-da90228a-bafd-4cdc-bf83-3bb6f922c856.json
new file mode 100644
index 00000000000000..09c782a9ba5cb1
--- /dev/null
+++ b/change/@fluentui-react-migration-v0-v9-da90228a-bafd-4cdc-bf83-3bb6f922c856.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-migration-v0-v9",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-migration-v8-v9-f778b39d-6b62-464b-939b-65b670d16b2e.json b/change/@fluentui-react-migration-v8-v9-f778b39d-6b62-464b-939b-65b670d16b2e.json
new file mode 100644
index 00000000000000..4fbe15722ca8cc
--- /dev/null
+++ b/change/@fluentui-react-migration-v8-v9-f778b39d-6b62-464b-939b-65b670d16b2e.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-migration-v8-v9",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-monaco-editor-b33c4086-5997-4aa5-96dc-f4f83e408268.json b/change/@fluentui-react-monaco-editor-b33c4086-5997-4aa5-96dc-f4f83e408268.json
new file mode 100644
index 00000000000000..cc4a89b61d31bd
--- /dev/null
+++ b/change/@fluentui-react-monaco-editor-b33c4086-5997-4aa5-96dc-f4f83e408268.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-monaco-editor",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-motion-676152ce-cae3-4dba-936b-586d0629d4be.json b/change/@fluentui-react-motion-676152ce-cae3-4dba-936b-586d0629d4be.json
new file mode 100644
index 00000000000000..aac5c965f97591
--- /dev/null
+++ b/change/@fluentui-react-motion-676152ce-cae3-4dba-936b-586d0629d4be.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-motion",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-overflow-638b0100-6cd4-4c54-a558-f9de0cf2a2ec.json b/change/@fluentui-react-overflow-638b0100-6cd4-4c54-a558-f9de0cf2a2ec.json
new file mode 100644
index 00000000000000..8982c4af91b49c
--- /dev/null
+++ b/change/@fluentui-react-overflow-638b0100-6cd4-4c54-a558-f9de0cf2a2ec.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-overflow",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-popover-799b70f1-6520-4c6f-867c-dd58af4ccf63.json b/change/@fluentui-react-popover-799b70f1-6520-4c6f-867c-dd58af4ccf63.json
new file mode 100644
index 00000000000000..01946cf160bc57
--- /dev/null
+++ b/change/@fluentui-react-popover-799b70f1-6520-4c6f-867c-dd58af4ccf63.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-popover",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-portal-e2b145ab-c3a9-40d3-b616-2f3bec6b842b.json b/change/@fluentui-react-portal-e2b145ab-c3a9-40d3-b616-2f3bec6b842b.json
new file mode 100644
index 00000000000000..450fbae574de1d
--- /dev/null
+++ b/change/@fluentui-react-portal-e2b145ab-c3a9-40d3-b616-2f3bec6b842b.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-portal",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-positioning-a7f793e1-af83-4082-98a1-5f8646271a40.json b/change/@fluentui-react-positioning-a7f793e1-af83-4082-98a1-5f8646271a40.json
new file mode 100644
index 00000000000000..c1237091277c38
--- /dev/null
+++ b/change/@fluentui-react-positioning-a7f793e1-af83-4082-98a1-5f8646271a40.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-positioning",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-storybook-addon-0b1ed82f-94e3-42b2-ab31-7dd198e08519.json b/change/@fluentui-react-storybook-addon-0b1ed82f-94e3-42b2-ab31-7dd198e08519.json
new file mode 100644
index 00000000000000..dcc03e23443a16
--- /dev/null
+++ b/change/@fluentui-react-storybook-addon-0b1ed82f-94e3-42b2-ab31-7dd198e08519.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-storybook-addon",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-tabster-13e213e3-9574-4e21-b282-5d12d6a2c56a.json b/change/@fluentui-react-tabster-13e213e3-9574-4e21-b282-5d12d6a2c56a.json
new file mode 100644
index 00000000000000..001554ecb7cc4b
--- /dev/null
+++ b/change/@fluentui-react-tabster-13e213e3-9574-4e21-b282-5d12d6a2c56a.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-tabster",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-tooltip-c9c36ee9-012e-416e-8ad4-7a0a87d82c2c.json b/change/@fluentui-react-tooltip-c9c36ee9-012e-416e-8ad4-7a0a87d82c2c.json
new file mode 100644
index 00000000000000..6dfd486f140abb
--- /dev/null
+++ b/change/@fluentui-react-tooltip-c9c36ee9-012e-416e-8ad4-7a0a87d82c2c.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-tooltip",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-tree-8abfcb1c-d95b-4961-93dc-d9152b2a246a.json b/change/@fluentui-react-tree-8abfcb1c-d95b-4961-93dc-d9152b2a246a.json
new file mode 100644
index 00000000000000..150363e48462b8
--- /dev/null
+++ b/change/@fluentui-react-tree-8abfcb1c-d95b-4961-93dc-d9152b2a246a.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-tree",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-utilities-f12ed59e-5467-457a-b942-a30e1bbb2d1d.json b/change/@fluentui-react-utilities-f12ed59e-5467-457a-b942-a30e1bbb2d1d.json
new file mode 100644
index 00000000000000..ea7ccd6f118068
--- /dev/null
+++ b/change/@fluentui-react-utilities-f12ed59e-5467-457a-b942-a30e1bbb2d1d.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-utilities",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-react-virtualizer-4fcf4754-814f-4e78-af89-af5e11d33f3c.json b/change/@fluentui-react-virtualizer-4fcf4754-814f-4e78-af89-af5e11d33f3c.json
new file mode 100644
index 00000000000000..7eceb819a24d8c
--- /dev/null
+++ b/change/@fluentui-react-virtualizer-4fcf4754-814f-4e78-af89-af5e11d33f3c.json
@@ -0,0 +1,7 @@
+{
+ "type": "none",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/react-virtualizer",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "none"
+}
diff --git a/change/@fluentui-test-utilities-66434ad4-300c-4542-98bc-5436670d6e4d.json b/change/@fluentui-test-utilities-66434ad4-300c-4542-98bc-5436670d6e4d.json
new file mode 100644
index 00000000000000..83eea5900070c0
--- /dev/null
+++ b/change/@fluentui-test-utilities-66434ad4-300c-4542-98bc-5436670d6e4d.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/test-utilities",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-utilities-8fc63979-80aa-4e21-bad9-188c1e862eba.json b/change/@fluentui-utilities-8fc63979-80aa-4e21-bad9-188c1e862eba.json
new file mode 100644
index 00000000000000..7e5a3972899823
--- /dev/null
+++ b/change/@fluentui-utilities-8fc63979-80aa-4e21-bad9-188c1e862eba.json
@@ -0,0 +1,7 @@
+{
+ "type": "patch",
+ "comment": "chore: migrate source to react 19",
+ "packageName": "@fluentui/utilities",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/change/@fluentui-web-components-498ceae2-ca99-49a6-ad41-d1be1f215be8.json b/change/@fluentui-web-components-498ceae2-ca99-49a6-ad41-d1be1f215be8.json
new file mode 100644
index 00000000000000..8374a12de6b47a
--- /dev/null
+++ b/change/@fluentui-web-components-498ceae2-ca99-49a6-ad41-d1be1f215be8.json
@@ -0,0 +1,7 @@
+{
+ "type": "prerelease",
+ "comment": "fix: avoid global type leaks into production assets compilation",
+ "packageName": "@fluentui/web-components",
+ "email": "martinhochel@microsoft.com",
+ "dependentChangeType": "patch"
+}
diff --git a/nx.json b/nx.json
index 62606d448a3e35..90d09457b3ec9e 100644
--- a/nx.json
+++ b/nx.json
@@ -149,7 +149,7 @@
},
"reactIntegrationTesting": {
"targetName": "test-rit",
- "reactVersions": ["17", "19"],
+ "reactVersions": ["17", "18"],
"exclude": [
"react-theme-sass",
"babel-preset-global-context",
diff --git a/package.json b/package.json
index c7aab82be82ce8..690f92f04ff9d6 100644
--- a/package.json
+++ b/package.json
@@ -148,11 +148,11 @@
"@types/node": "^22.0.0",
"@types/prettier": "2.7.2",
"@types/progress": "2.0.5",
- "@types/react": "18.3.20",
- "@types/react-dom": "18.3.6",
+ "@types/react": "19.2.2",
+ "@types/react-dom": "19.2.2",
"@types/react-frame-component": "4.1.1",
- "@types/react-is": "18.3.1",
- "@types/react-test-renderer": "18.3.1",
+ "@types/react-is": "19.2.0",
+ "@types/react-test-renderer": "19.1.0",
"@types/react-transition-group": "4.4.6",
"@types/react-window": "^1.8.2",
"@types/scheduler": "0.16.2",
@@ -275,13 +275,13 @@
"progress": "2.0.3",
"puppeteer": "19.6.3",
"raw-loader": "4.0.2",
- "react": "18.3.1",
+ "react": "19.2.0",
"react-app-polyfill": "2.0.0",
- "react-dom": "18.3.1",
+ "react-dom": "19.2.0",
"react-frame-component": "4.1.1",
- "react-is": "18.3.1",
+ "react-is": "19.2.0",
"react-shadow": "20.3.0",
- "react-test-renderer": "18.3.1",
+ "react-test-renderer": "19.2.0",
"react-window": "^1.8.6",
"read-pkg-up": "7.0.1",
"replace-in-file": "6.1.0",
@@ -296,7 +296,7 @@
"sass": "1.49.11",
"sass-loader": "12.4.0",
"satisfied": "^1.1.1",
- "scheduler": "0.20.2",
+ "scheduler": "0.27.0",
"schema-utils": "3.1.1",
"semver": "^6.2.0",
"source-map-loader": "4.0.0",
diff --git a/packages/charts/react-charting/src/components/AreaChart/AreaChart.base.tsx b/packages/charts/react-charting/src/components/AreaChart/AreaChart.base.tsx
index 913f2abb8763e7..ea3779ccd1ace5 100644
--- a/packages/charts/react-charting/src/components/AreaChart/AreaChart.base.tsx
+++ b/packages/charts/react-charting/src/components/AreaChart/AreaChart.base.tsx
@@ -147,8 +147,8 @@ export class AreaChartBase extends React.Component;
- private _legendsRef: React.RefObject;
+ private _cartesianChartRef: React.RefObject;
+ private _legendsRef: React.RefObject;
private _containsSecondaryYAxis = false;
private _hasDuplicateXValues = false;
private _hasMissingXValues = false;
diff --git a/packages/charts/react-charting/src/components/ChartTable/ChartTable.base.tsx b/packages/charts/react-charting/src/components/ChartTable/ChartTable.base.tsx
index 90effc54e84ae1..6678b3123be56f 100644
--- a/packages/charts/react-charting/src/components/ChartTable/ChartTable.base.tsx
+++ b/packages/charts/react-charting/src/components/ChartTable/ChartTable.base.tsx
@@ -111,7 +111,9 @@ export class ChartTableBase extends React.Component {
return (
(this._rootElem = el)}
+ ref={el => {
+ this._rootElem = el;
+ }}
className={classNames.root}
style={{ height: height ? `${height}px` : '650px', overflow: 'hidden' }}
>
diff --git a/packages/charts/react-charting/src/components/CommonComponents/CartesianChart.base.tsx b/packages/charts/react-charting/src/components/CommonComponents/CartesianChart.base.tsx
index 26a53b8cf5b4b5..091880b62e38af 100644
--- a/packages/charts/react-charting/src/components/CommonComponents/CartesianChart.base.tsx
+++ b/packages/charts/react-charting/src/components/CommonComponents/CartesianChart.base.tsx
@@ -590,7 +590,9 @@ export class CartesianChartBase
(this.chartContainer = rootElem)}
+ ref={(rootElem: HTMLDivElement) => {
+ this.chartContainer = rootElem;
+ }}
onMouseLeave={this._onChartLeave}
>
{!this._isFirstRender &&
}
@@ -754,7 +756,12 @@ export class CartesianChartBase
{!this.props.hideLegend && (
-
(this.legendContainer = e)} className={this._classNames.legendContainer}>
+
{
+ this.legendContainer = e;
+ }}
+ className={this._classNames.legendContainer}
+ >
{this.props.legendBars}
)}
diff --git a/packages/charts/react-charting/src/components/DeclarativeChart/PlotlyColorAdapter.ts b/packages/charts/react-charting/src/components/DeclarativeChart/PlotlyColorAdapter.ts
index 511d01d4633fa5..9c18e83bd1caa6 100644
--- a/packages/charts/react-charting/src/components/DeclarativeChart/PlotlyColorAdapter.ts
+++ b/packages/charts/react-charting/src/components/DeclarativeChart/PlotlyColorAdapter.ts
@@ -106,6 +106,7 @@ function tryMapFluentDataViz(
export const getColor = (
legendLabel: string,
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
colorMap: React.MutableRefObject