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>, templateColorway: PlotlyColorway, isDarkTheme?: boolean, @@ -134,6 +135,7 @@ export const getColor = ( export const getSchemaColors = ( colorway: string[] | undefined, colors: PieColors | Color | Color[] | string | null | undefined, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, isDarkTheme?: boolean, isDonut?: boolean, @@ -170,6 +172,7 @@ export const extractColor = ( colorway: string[] | undefined, colorwayType: ColorwayType, colors: PieColors | Color | Color[] | string | null | undefined, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, isDarkTheme?: boolean, isDonut?: boolean, @@ -183,6 +186,7 @@ export const resolveColor = ( extractedColors: string[] | string | null | undefined, index: number, legend: string, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorway: string[] | undefined, isDarkTheme?: boolean, diff --git a/packages/charts/react-charting/src/components/DeclarativeChart/PlotlySchemaAdapter.ts b/packages/charts/react-charting/src/components/DeclarativeChart/PlotlySchemaAdapter.ts index 89a83db41c7f92..4212563b6b0704 100644 --- a/packages/charts/react-charting/src/components/DeclarativeChart/PlotlySchemaAdapter.ts +++ b/packages/charts/react-charting/src/components/DeclarativeChart/PlotlySchemaAdapter.ts @@ -328,6 +328,7 @@ export const _getGaugeAxisColor = ( colorway: string[] | undefined, colorwayType: ColorwayType, color: Color | undefined, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, isDarkTheme?: boolean, ): string => { @@ -1123,6 +1124,7 @@ export const normalizeObjectArrayForGVBC = ( export const transformPlotlyJsonToAnnotationChartProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated _colorMap: React.MutableRefObject>, _colorwayType: ColorwayType, _isDarkTheme?: boolean, @@ -1160,6 +1162,7 @@ export const transformPlotlyJsonToAnnotationChartProps = ( export const transformPlotlyJsonToDonutProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -1263,6 +1266,7 @@ export const transformPlotlyJsonToDonutProps = ( export const transformPlotlyJsonToVSBCProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -1454,6 +1458,7 @@ export const transformPlotlyJsonToVSBCProps = ( export const transformPlotlyJsonToGVBCProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -1627,6 +1632,7 @@ export const transformPlotlyJsonToGVBCProps = ( export const transformPlotlyJsonToVBCProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -1736,6 +1742,7 @@ export const transformPlotlyJsonToVBCProps = ( export const transformPlotlyJsonToAreaChartProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -1753,6 +1760,7 @@ export const transformPlotlyJsonToAreaChartProps = ( export const transformPlotlyJsonToLineChartProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -1770,6 +1778,7 @@ export const transformPlotlyJsonToLineChartProps = ( export const transformPlotlyJsonToScatterChartProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -1808,6 +1817,7 @@ const transformPlotlyJsonToScatterTraceProps = ( input: PlotlySchema, isMultiPlot: boolean, chartType: ScatterChartTypes, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -2038,6 +2048,7 @@ const transformPlotlyJsonToScatterTraceProps = ( export const transformPlotlyJsonToHorizontalBarWithAxisProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -2117,6 +2128,7 @@ export const transformPlotlyJsonToHorizontalBarWithAxisProps = ( export const transformPlotlyJsonToGanttChartProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -2218,6 +2230,7 @@ export const transformPlotlyJsonToGanttChartProps = ( export const transformPlotlyJsonToHeatmapProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -2380,6 +2393,7 @@ export const transformPlotlyJsonToHeatmapProps = ( export const transformPlotlyJsonToSankeyProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -2454,6 +2468,7 @@ export const transformPlotlyJsonToSankeyProps = ( export const transformPlotlyJsonToGaugeProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -2642,6 +2657,7 @@ function mergeCells(tableCells?: TableData['cells'], templateCells?: TableData[' export const transformPlotlyJsonToChartTableProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -2790,6 +2806,7 @@ function getCategoriesAndValues(series: Partial): { export const transformPlotlyJsonToFunnelChartProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -3265,6 +3282,7 @@ const getLegendShape = (series: Partial): ILegend['shape'] => { export const getAllupLegendsProps = ( input: PlotlySchema, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, traceInfo: TraceInfo[], diff --git a/packages/charts/react-charting/src/components/DeclarativeChart/__snapshots__/DeclarativeChartRTL.test.tsx.snap b/packages/charts/react-charting/src/components/DeclarativeChart/__snapshots__/DeclarativeChartRTL.test.tsx.snap index 5b0a756b85687d..f2f9f5b15f7ee1 100644 --- a/packages/charts/react-charting/src/components/DeclarativeChart/__snapshots__/DeclarativeChartRTL.test.tsx.snap +++ b/packages/charts/react-charting/src/components/DeclarativeChart/__snapshots__/DeclarativeChartRTL.test.tsx.snap @@ -20425,14 +20425,14 @@ exports[`DeclarativeChart Should render sankeychart in DeclarativeChart 1`] = ` } > ; + private _legendsRef: React.RefObject; public static getDerivedStateFromProps( nextProps: Readonly, @@ -141,7 +141,9 @@ export class DonutChartBase extends React.Component (this._rootElem = rootElem)} + ref={(rootElem: HTMLElement | null) => { + this._rootElem = rootElem; + }} onMouseLeave={this._handleChartMouseLeave} > {this.props.xAxisAnnotation && ( diff --git a/packages/charts/react-charting/src/components/FunnelChart/FunnelChart.base.tsx b/packages/charts/react-charting/src/components/FunnelChart/FunnelChart.base.tsx index 03324f7500f1c8..2f82a0466b04ab 100644 --- a/packages/charts/react-charting/src/components/FunnelChart/FunnelChart.base.tsx +++ b/packages/charts/react-charting/src/components/FunnelChart/FunnelChart.base.tsx @@ -28,7 +28,7 @@ const getClassNames = classNamesFunction = React.forwardRef< HTMLDivElement, IFunnelChartProps ->((props, forwardedRef) => { +>(({ orientation = 'vertical', ...props }, forwardedRef) => { const _tooltipId: string = getId('FunnelChartTooltipId_'); const _emptyChartId: string = getId('_FunnelChart_empty'); const isRTL = getRTL(); @@ -248,7 +248,7 @@ export const FunnelChartBase: React.FunctionComponent = React return data.map((d, i) => { const geometryProps = - props.orientation === 'vertical' + orientation === 'vertical' ? getVerticalFunnelSegmentGeometry({ d, i, data, funnelWidth, funnelHeight, isRTL }) : getHorizontalFunnelSegmentGeometry({ d, i, data, funnelWidth, funnelHeight, isRTL }); @@ -302,7 +302,7 @@ export const FunnelChartBase: React.FunctionComponent = React })); const geom = - props.orientation === 'vertical' + orientation === 'vertical' ? getStackedVerticalFunnelSegmentGeometry({ ...geometryParams, stages: stagesWithSubValues, @@ -493,7 +493,3 @@ export const FunnelChartBase: React.FunctionComponent = React ); }); FunnelChartBase.displayName = 'FunnelChart'; -// eslint-disable-next-line @typescript-eslint/no-deprecated -FunnelChartBase.defaultProps = { - orientation: 'vertical', -}; diff --git a/packages/charts/react-charting/src/components/GaugeChart/GaugeChart.base.tsx b/packages/charts/react-charting/src/components/GaugeChart/GaugeChart.base.tsx index c3f2d2e07d8606..5281c14def7d2f 100644 --- a/packages/charts/react-charting/src/components/GaugeChart/GaugeChart.base.tsx +++ b/packages/charts/react-charting/src/components/GaugeChart/GaugeChart.base.tsx @@ -135,7 +135,7 @@ export class GaugeChartBase extends React.Component; + private _legendsRef: React.RefObject; constructor(props: IGaugeChartProps) { super(props); @@ -203,7 +203,12 @@ export class GaugeChartBase extends React.Component (this._rootElem = el)}> +
{ + this._rootElem = el; + }} + > ; - private _legendsRef: React.RefObject; + private _cartesianChartRef: React.RefObject; + private _legendsRef: React.RefObject; private _legendColorMap: Record = {}; private readonly Y_ORIGIN: number = 0; - private _rectRef: React.RefObject; + private _rectRef: React.RefObject; private _uniqDotId = getId('gvbc_dot_'); public constructor(props: IGroupedVerticalBarChartProps) { diff --git a/packages/charts/react-charting/src/components/HeatMapChart/HeatMapChart.base.tsx b/packages/charts/react-charting/src/components/HeatMapChart/HeatMapChart.base.tsx index 1ab80d09b85298..7e04c36d914c89 100644 --- a/packages/charts/react-charting/src/components/HeatMapChart/HeatMapChart.base.tsx +++ b/packages/charts/react-charting/src/components/HeatMapChart/HeatMapChart.base.tsx @@ -136,8 +136,8 @@ export class HeatMapChartBase extends React.Component; - private _legendsRef: React.RefObject; + private _cartesianChartRef: React.RefObject; + private _legendsRef: React.RefObject; public constructor(props: IHeatMapChartProps) { super(props); diff --git a/packages/charts/react-charting/src/components/HorizontalBarChart/HorizontalBarChart.base.tsx b/packages/charts/react-charting/src/components/HorizontalBarChart/HorizontalBarChart.base.tsx index b2abcb966414bc..5b5a914d47dbf7 100644 --- a/packages/charts/react-charting/src/components/HorizontalBarChart/HorizontalBarChart.base.tsx +++ b/packages/charts/react-charting/src/components/HorizontalBarChart/HorizontalBarChart.base.tsx @@ -47,7 +47,7 @@ export class HorizontalBarChartBase extends React.Component; + private barChartSvgRef: React.RefObject; private _emptyChartId: string; constructor(props: IHorizontalBarChartProps) { diff --git a/packages/charts/react-charting/src/components/HorizontalBarChartWithAxis/HorizontalBarChartWithAxis.base.tsx b/packages/charts/react-charting/src/components/HorizontalBarChartWithAxis/HorizontalBarChartWithAxis.base.tsx index 93700c75a46e63..74a053bc02f5f2 100644 --- a/packages/charts/react-charting/src/components/HorizontalBarChartWithAxis/HorizontalBarChartWithAxis.base.tsx +++ b/packages/charts/react-charting/src/components/HorizontalBarChartWithAxis/HorizontalBarChartWithAxis.base.tsx @@ -91,8 +91,8 @@ export class HorizontalBarChartWithAxisBase private _xAxisType: XAxisTypes; private _yAxisType: YAxisType; private _calloutAnchorPoint: IHorizontalBarChartWithAxisDataPoint | null; - private _cartesianChartRef: React.RefObject; - private _legendsRef: React.RefObject; + private _cartesianChartRef: React.RefObject; + private _legendsRef: React.RefObject; private _longestBarPositiveTotalValue: number; private _longestBarNegativeTotalValue: number; private readonly X_ORIGIN: number = 0; diff --git a/packages/charts/react-charting/src/components/Legends/Legends.base.tsx b/packages/charts/react-charting/src/components/Legends/Legends.base.tsx index 1f65d1b64d070a..3898b094104f3a 100644 --- a/packages/charts/react-charting/src/components/Legends/Legends.base.tsx +++ b/packages/charts/react-charting/src/components/Legends/Legends.base.tsx @@ -109,7 +109,12 @@ export class LegendsBase extends React.Component im this._isLegendSelected = Object.keys(this.state.selectedLegends).length > 0; const dataToRender = this._generateData(); return ( -
(this._rootElem = el)}> +
{ + this._rootElem = el; + }} + > {this.props.enabledWrapLines ? ( this._onRenderData(dataToRender) ) : ( @@ -344,7 +349,9 @@ export class LegendsBase extends React.Component im
(this._hoverCardRef = rootElem)} + ref={(rootElem: HTMLDivElement) => { + this._hoverCardRef = rootElem; + }} {...(allowFocusOnLegends && { role: 'button', 'aria-expanded': this.state.isHoverCardVisible, diff --git a/packages/charts/react-charting/src/components/LineChart/LineChart.base.tsx b/packages/charts/react-charting/src/components/LineChart/LineChart.base.tsx index d188b799e782c5..b69203cfe50ef6 100644 --- a/packages/charts/react-charting/src/components/LineChart/LineChart.base.tsx +++ b/packages/charts/react-charting/src/components/LineChart/LineChart.base.tsx @@ -208,8 +208,8 @@ export class LineChartBase extends React.Component; - private _legendsRef: React.RefObject; + private _cartesianChartRef: React.RefObject; + private _legendsRef: React.RefObject; private _yScaleSecondary: ScaleLinear | undefined; private _hasMarkersMode: boolean = false; private _isXAxisDateType: boolean = false; diff --git a/packages/charts/react-charting/src/components/LineChart/eventAnnotation/Textbox.tsx b/packages/charts/react-charting/src/components/LineChart/eventAnnotation/Textbox.tsx index 14f77f7462ca69..329054a3c594aa 100644 --- a/packages/charts/react-charting/src/components/LineChart/eventAnnotation/Textbox.tsx +++ b/packages/charts/react-charting/src/components/LineChart/eventAnnotation/Textbox.tsx @@ -14,7 +14,7 @@ interface ITextboxProps { } export const Textbox: React.FunctionComponent = props => { - const textElementRef: React.RefObject = React.useRef(null); + const textElementRef: React.RefObject = React.useRef(null); const wrapWords = () => { if (!textElementRef.current) { diff --git a/packages/charts/react-charting/src/components/ResponsiveContainer/ResponsiveContainer.tsx b/packages/charts/react-charting/src/components/ResponsiveContainer/ResponsiveContainer.tsx index 2437012dbcdc7f..76e781e29d4542 100644 --- a/packages/charts/react-charting/src/components/ResponsiveContainer/ResponsiveContainer.tsx +++ b/packages/charts/react-charting/src/components/ResponsiveContainer/ResponsiveContainer.tsx @@ -8,7 +8,7 @@ import { IResponsiveChildProps, IResponsiveContainerProps } from './ResponsiveCo */ export const ResponsiveContainer: React.FC = props => { const containerRef = React.useRef(null); - const onResizeRef = React.useRef(); + const onResizeRef = React.useRef(undefined); const [size, setSize] = React.useState<{ containerWidth?: number; containerHeight?: number }>({}); diff --git a/packages/charts/react-charting/src/components/SankeyChart/SankeyChart.base.tsx b/packages/charts/react-charting/src/components/SankeyChart/SankeyChart.base.tsx index 0eead6aef93a29..76cb2bb1833ebe 100644 --- a/packages/charts/react-charting/src/components/SankeyChart/SankeyChart.base.tsx +++ b/packages/charts/react-charting/src/components/SankeyChart/SankeyChart.base.tsx @@ -843,7 +843,9 @@ export class SankeyChartBase extends React.Component (this.chartContainer = rootElem)} + ref={(rootElem: HTMLDivElement) => { + this.chartContainer = rootElem; + }} onMouseLeave={this._onCloseCallout} > {/* diff --git a/packages/charts/react-charting/src/components/StackedBarChart/MultiStackedBarChart.base.tsx b/packages/charts/react-charting/src/components/StackedBarChart/MultiStackedBarChart.base.tsx index 950f03165abc16..5cac2122ab6548 100644 --- a/packages/charts/react-charting/src/components/StackedBarChart/MultiStackedBarChart.base.tsx +++ b/packages/charts/react-charting/src/components/StackedBarChart/MultiStackedBarChart.base.tsx @@ -59,7 +59,7 @@ export class MultiStackedBarChartBase extends React.Component; + private barChartSvgRef: React.RefObject; private _emptyChartId: string; private _barId: string; private _barIdPlaceholderPartToWhole: string; diff --git a/packages/charts/react-charting/src/components/StackedBarChart/StackedBarChart.base.tsx b/packages/charts/react-charting/src/components/StackedBarChart/StackedBarChart.base.tsx index b384f37d9698b4..97ff25536b6b3d 100644 --- a/packages/charts/react-charting/src/components/StackedBarChart/StackedBarChart.base.tsx +++ b/packages/charts/react-charting/src/components/StackedBarChart/StackedBarChart.base.tsx @@ -40,7 +40,7 @@ export class StackedBarChartBase extends React.Component; + private barChartSvgRef: React.RefObject; private _isRTL = getRTL(); public constructor(props: IStackedBarChartProps) { diff --git a/packages/charts/react-charting/src/components/VerticalBarChart/VerticalBarChart.base.tsx b/packages/charts/react-charting/src/components/VerticalBarChart/VerticalBarChart.base.tsx index 67b5445b702d54..6a84e1e9026df5 100644 --- a/packages/charts/react-charting/src/components/VerticalBarChart/VerticalBarChart.base.tsx +++ b/packages/charts/react-charting/src/components/VerticalBarChart/VerticalBarChart.base.tsx @@ -118,8 +118,8 @@ export class VerticalBarChartBase private _emptyChartId: string; private _xAxisInnerPadding: number; private _xAxisOuterPadding: number; - private _cartesianChartRef: React.RefObject; - private _legendsRef: React.RefObject; + private _cartesianChartRef: React.RefObject; + private _legendsRef: React.RefObject; public constructor(props: IVerticalBarChartProps) { super(props); @@ -406,7 +406,9 @@ export class VerticalBarChartBase // at the same x-axis point in the stack callout. So to prevent an increase in focusable elements // and avoid conveying duplicate info, make these line points non-focusable. data-is-focusable={this._legendHighlighted(lineLegendText!)} - ref={e => (circleRef.refElement = e)} + ref={e => { + circleRef.refElement = e; + }} onFocus={this._lineFocus.bind(this, item.point, circleRef)} onBlur={this._handleChartMouseLeave} /> diff --git a/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChart.base.tsx b/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChart.base.tsx index 79b97edc333489..f38d064fe2dac3 100644 --- a/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChart.base.tsx +++ b/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChart.base.tsx @@ -141,8 +141,8 @@ export class VerticalStackedBarChartBase private _emptyChartId: string; private _xAxisInnerPadding: number; private _xAxisOuterPadding: number; - private _cartesianChartRef: React.RefObject; - private _legendsRef: React.RefObject; + private _cartesianChartRef: React.RefObject; + private _legendsRef: React.RefObject; private readonly Y_ORIGIN: number = 0; private _yAxisType: YAxisType; private _yAxisLabels: string[] = []; @@ -516,7 +516,9 @@ export class VerticalStackedBarChartBase // For more information, see https://fuzzbomb.github.io/accessibility-demos/visually-hidden-focus-test.html opacity={this._getCircleOpacityAndRadius(circlePoint.xItem.xAxisPoint, circlePoint.legend).opacity} transform={`translate(${xScaleBandwidthTranslate}, ${yScaleBandwidthTranslate})`} - ref={e => (circleRef.refElement = e)} + ref={e => { + circleRef.refElement = e; + }} {...(noBarsActive && (this._noLegendHighlighted() || this._isLegendHighlighted(item)) ? { 'data-is-focusable': !this.props.hideTooltip, @@ -1086,7 +1088,9 @@ export class VerticalStackedBarChartBase `} fill={this.props.enableGradient ? `url(#${gradientId})` : startColor} rx={this.props.roundCorners ? 3 : 0} - ref={e => (ref.refElement = e)} + ref={e => { + ref.refElement = e; + }} transform={`translate(${xScaleBandwidthTranslate}, 0)`} {...rectFocusProps} /> @@ -1114,7 +1118,9 @@ export class VerticalStackedBarChartBase height={barHeight} fill={this.props.enableGradient ? `url(#${gradientId})` : startColor} rx={this.props.roundCorners ? 3 : 0} - ref={e => (ref.refElement = e)} + ref={e => { + ref.refElement = e; + }} {...rectFocusProps} transform={`translate(${xScaleBandwidthTranslate}, 0)`} /> @@ -1158,7 +1164,13 @@ export class VerticalStackedBarChartBase } return ( - (groupRef.refElement = e)} {...stackFocusProps}> + { + groupRef.refElement = e; + }} + {...stackFocusProps} + > {singleBar} {/* diff --git a/packages/charts/react-charts/library/etc/react-charts.api.md b/packages/charts/react-charts/library/etc/react-charts.api.md index e2bb736449a19b..e73e591c67e290 100644 --- a/packages/charts/react-charts/library/etc/react-charts.api.md +++ b/packages/charts/react-charts/library/etc/react-charts.api.md @@ -154,7 +154,7 @@ export interface CartesianChartProps { calloutProps?: Partial; calloutPropsPerDataPoint?: (dataPointCalloutProps: any) => ChartPopoverProps; className?: string; - componentRef?: React_2.RefObject; + componentRef?: React_2.RefObject; customDateTimeFormatter?: (dateTime: Date) => string; dateLocalizeOptions?: Intl.DateTimeFormatOptions; enabledLegendsWrapLines?: boolean; @@ -1082,7 +1082,7 @@ export interface LegendsProps { defaultSelectedLegend?: string; defaultSelectedLegends?: string[]; enabledWrapLines?: boolean; - legendRef?: React_2.RefObject; + legendRef?: React_2.RefObject; legends: Legend[]; onChange?: (selectedLegends: string[], event: React_2.MouseEvent, currentLegend?: Legend) => void; overflowStyles?: React_2.CSSProperties; diff --git a/packages/charts/react-charts/library/src/components/AreaChart/__snapshots__/AreaChart.test.tsx.snap b/packages/charts/react-charts/library/src/components/AreaChart/__snapshots__/AreaChart.test.tsx.snap index 39dd78cc2e30cf..b2d4ee4cf96a0c 100644 --- a/packages/charts/react-charts/library/src/components/AreaChart/__snapshots__/AreaChart.test.tsx.snap +++ b/packages/charts/react-charts/library/src/components/AreaChart/__snapshots__/AreaChart.test.tsx.snap @@ -337,7 +337,7 @@ exports[`Area chart rendering Should render the Area Chart with negative y value @@ -345,7 +345,7 @@ exports[`Area chart rendering Should render the Area Chart with negative y value @@ -1203,7 +1203,7 @@ exports[`Area chart rendering Should render the Area Chart with tozeroy mode 1`] @@ -2173,7 +2173,7 @@ exports[`Area chart rendering Should render the Area chart with secondary Y axis @@ -3031,7 +3031,7 @@ exports[`Area chart rendering Should render the area chart with numeric x-axis d `; +exports[`Area chart rendering with date x-axis data Should render the area chart with date x-axis data 1`] = ` +
+ +
+`; + exports[`Area chart rendering with duplicate values Should return the correct dataset for duplicate values 1`] = `null`; exports[`Area chart rendering with duplicate values Should return the correct dataset for duplicate values 2`] = `null`; @@ -3560,7 +4103,7 @@ Object { >
@@ -3899,7 +4442,7 @@ Object { @@ -3907,7 +4450,7 @@ Object { @@ -4763,7 +5306,7 @@ Object {
@@ -5675,7 +6218,7 @@ Object { @@ -5683,7 +6226,7 @@ Object { @@ -6539,7 +7082,7 @@ Object {
@@ -7451,7 +7994,7 @@ Object { @@ -7459,7 +8002,7 @@ Object { @@ -8315,7 +8858,7 @@ Object { @@ -9230,7 +9773,7 @@ Object { @@ -9716,7 +10259,7 @@ Object { @@ -10261,7 +10804,7 @@ Object { @@ -11117,7 +11660,7 @@ Object { @@ -12032,7 +12575,7 @@ Object { @@ -12888,7 +13431,7 @@ Object { @@ -13632,7 +14175,7 @@ Object { @@ -13893,7 +14436,7 @@ Object { @@ -14384,7 +14927,7 @@ Object { @@ -15250,7 +15793,7 @@ Object { @@ -16175,7 +16718,7 @@ Object { @@ -16957,7 +17500,7 @@ Object { @@ -17798,7 +18341,7 @@ Object { @@ -18654,7 +19197,7 @@ Object { @@ -19709,7 +20252,7 @@ Object {
, @@ -20702,7 +21245,7 @@ Object { @@ -20710,7 +21253,7 @@ Object {
@@ -21702,7 +22245,7 @@ Object { @@ -21710,7 +22253,7 @@ Object { @@ -22646,7 +23189,7 @@ Object { @@ -23561,7 +24104,7 @@ Object { @@ -24417,7 +24960,7 @@ Object { @@ -25232,7 +25775,7 @@ exports[`Screen resolution Should remain unchanged on zoom in 1`] = ` @@ -25995,7 +26538,7 @@ exports[`Screen resolution Should remain unchanged on zoom out 1`] = ` = React.forwar return (
(_rootElem.current = el)} + ref={el => { + _rootElem.current = el; + }} className={classes.root as string} style={{ height: height ? `${height}px` : '650px', overflow: 'hidden' }} > diff --git a/packages/charts/react-charts/library/src/components/CommonComponents/CartesianChart.tsx b/packages/charts/react-charts/library/src/components/CommonComponents/CartesianChart.tsx index 7023a5ac648683..e1b14d4f063cf5 100644 --- a/packages/charts/react-charts/library/src/components/CommonComponents/CartesianChart.tsx +++ b/packages/charts/react-charts/library/src/components/CommonComponents/CartesianChart.tsx @@ -38,13 +38,13 @@ import { useFocusableGroup, useArrowNavigationGroup } from '@fluentui/react-tabs export const CartesianChart: React.FunctionComponent = React.forwardRef< HTMLDivElement, ModifiedCartesianChartProps ->((props, forwardedRef) => { - const chartContainer = React.useRef(); +>(({ hideTickOverlap = true, ...props }, forwardedRef) => { + const chartContainer = React.useRef(null); let legendContainer: HTMLDivElement; const minLegendContainerHeight: number = 40; - const xAxisElement = React.useRef(); - const yAxisElement = React.useRef(); - const yAxisElementSecondary = React.useRef(); + const xAxisElement = React.useRef(null); + const yAxisElement = React.useRef(null); + const yAxisElementSecondary = React.useRef(null); let margins: IMargins; const idForGraph: string = 'chart_'; let _reqID: number | undefined; @@ -69,7 +69,8 @@ export const CartesianChart: React.FunctionComponent(0); const [containerHeight, setContainerHeight] = React.useState(0); const [startFromX, setStartFromX] = React.useState(0); - const [prevProps, setPrevProps] = React.useState(null); + const prevWidthRef = React.useRef(undefined); + const prevHeightRef = React.useRef(undefined); const chartTypesWithStringYAxis = [ ChartTypes.HorizontalBarChartWithAxis, @@ -129,9 +130,6 @@ export const CartesianChart: React.FunctionComponent { _fitParentContainer(); - if (props !== null) { - setPrevProps(props); - } if ( chartTypesWithStringYAxis.includes(props.chartType) && props.showYAxisLables && @@ -154,11 +152,18 @@ export const CartesianChart: React.FunctionComponent { - if (prevProps) { - if (prevProps.height !== props.height || prevProps.width !== props.width) { - _fitParentContainer(); - } + // Check if height or width changed + if ( + prevWidthRef.current !== undefined && + prevHeightRef.current !== undefined && + (prevWidthRef.current !== props.width || prevHeightRef.current !== props.height) + ) { + _fitParentContainer(); } + // Update refs with current values + prevWidthRef.current = props.width; + prevHeightRef.current = props.height; + if ( chartTypesWithStringYAxis.includes(props.chartType) && props.showYAxisLables && @@ -172,7 +177,7 @@ export const CartesianChart: React.FunctionComponent (chartContainer.current = rootElem)} + ref={(rootElem: HTMLDivElement) => { + chartContainer.current = rootElem; + }} onMouseLeave={_onChartLeave} >
@@ -789,7 +796,12 @@ export const CartesianChart: React.FunctionComponent {!props.hideLegend && ( -
(legendContainer = e)} className={classes.legendContainer}> +
{ + legendContainer = e; + }} + className={classes.legendContainer} + > {props.legendBars}
)} @@ -799,6 +811,3 @@ export const CartesianChart: React.FunctionComponent; + componentRef?: React.RefObject; /** * Prop to set the x axis annotation. Used to display additional information on the x-axis. diff --git a/packages/charts/react-charts/library/src/components/DeclarativeChart/PlotlyColorAdapter.ts b/packages/charts/react-charts/library/src/components/DeclarativeChart/PlotlyColorAdapter.ts index 511d01d4633fa5..9c18e83bd1caa6 100644 --- a/packages/charts/react-charts/library/src/components/DeclarativeChart/PlotlyColorAdapter.ts +++ b/packages/charts/react-charts/library/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>, templateColorway: PlotlyColorway, isDarkTheme?: boolean, @@ -134,6 +135,7 @@ export const getColor = ( export const getSchemaColors = ( colorway: string[] | undefined, colors: PieColors | Color | Color[] | string | null | undefined, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, isDarkTheme?: boolean, isDonut?: boolean, @@ -170,6 +172,7 @@ export const extractColor = ( colorway: string[] | undefined, colorwayType: ColorwayType, colors: PieColors | Color | Color[] | string | null | undefined, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, isDarkTheme?: boolean, isDonut?: boolean, @@ -183,6 +186,7 @@ export const resolveColor = ( extractedColors: string[] | string | null | undefined, index: number, legend: string, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorway: string[] | undefined, isDarkTheme?: boolean, diff --git a/packages/charts/react-charts/library/src/components/DeclarativeChart/PlotlySchemaAdapter.ts b/packages/charts/react-charts/library/src/components/DeclarativeChart/PlotlySchemaAdapter.ts index b326fb9d7076a1..dde2c88dfd340d 100644 --- a/packages/charts/react-charts/library/src/components/DeclarativeChart/PlotlySchemaAdapter.ts +++ b/packages/charts/react-charts/library/src/components/DeclarativeChart/PlotlySchemaAdapter.ts @@ -319,6 +319,7 @@ export const _getGaugeAxisColor = ( colorway: string[] | undefined, colorwayType: ColorwayType, color: Color | undefined, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, isDarkTheme?: boolean, ): string => { @@ -488,6 +489,7 @@ export const normalizeObjectArrayForGVBC = ( export const transformPlotlyJsonToDonutProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -593,6 +595,7 @@ export const transformPlotlyJsonToDonutProps = ( export const transformPlotlyJsonToVSBCProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -810,6 +813,7 @@ export const transformPlotlyJsonToVSBCProps = ( export const transformPlotlyJsonToGVBCProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -980,6 +984,7 @@ export const transformPlotlyJsonToGVBCProps = ( export const transformPlotlyJsonToVBCProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -1084,6 +1089,7 @@ export const transformPlotlyJsonToVBCProps = ( export const transformPlotlyJsonToAreaChartProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -1101,6 +1107,7 @@ export const transformPlotlyJsonToAreaChartProps = ( export const transformPlotlyJsonToLineChartProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -1118,6 +1125,7 @@ export const transformPlotlyJsonToLineChartProps = ( export const transformPlotlyJsonToScatterChartProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -1156,6 +1164,7 @@ const transformPlotlyJsonToScatterTraceProps = ( input: PlotlySchema, isMultiPlot: boolean, chartType: ScatterChartTypes, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -1381,6 +1390,7 @@ const transformPlotlyJsonToScatterTraceProps = ( export const transformPlotlyJsonToHorizontalBarWithAxisProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -1460,6 +1470,7 @@ export const transformPlotlyJsonToHorizontalBarWithAxisProps = ( export const transformPlotlyJsonToGanttChartProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -1561,6 +1572,7 @@ export const transformPlotlyJsonToGanttChartProps = ( export const transformPlotlyJsonToHeatmapProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -1724,6 +1736,7 @@ export const transformPlotlyJsonToHeatmapProps = ( export const transformPlotlyJsonToSankeyProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -1799,6 +1812,7 @@ export const transformPlotlyJsonToSankeyProps = ( export const transformPlotlyJsonToGaugeProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -1989,6 +2003,7 @@ function mergeCells(tableCells?: TableData['cells'], templateCells?: TableData[' export const transformPlotlyJsonToChartTableProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -2137,6 +2152,7 @@ function getCategoriesAndValues(series: Partial): { export const transformPlotlyJsonToFunnelChartProps = ( input: PlotlySchema, isMultiPlot: boolean, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, isDarkTheme?: boolean, @@ -2607,6 +2623,7 @@ const getLegendShape = (series: Partial): Legend['shape'] => { export const getAllupLegendsProps = ( input: PlotlySchema, + // eslint-disable-next-line @typescript-eslint/no-deprecated colorMap: React.MutableRefObject>, colorwayType: ColorwayType, traceInfo: TraceInfo[], diff --git a/packages/charts/react-charts/library/src/components/DonutChart/DonutChart.tsx b/packages/charts/react-charts/library/src/components/DonutChart/DonutChart.tsx index 69259dcfcc8d94..17ca943e54a0c7 100644 --- a/packages/charts/react-charts/library/src/components/DonutChart/DonutChart.tsx +++ b/packages/charts/react-charts/library/src/components/DonutChart/DonutChart.tsx @@ -24,7 +24,8 @@ const MIN_LEGEND_CONTAINER_HEIGHT = 40; * {@docCategory DonutChart} */ export const DonutChart: React.FunctionComponent = React.forwardRef( - (props, forwardedRef) => { + ({ innerRadius = 0, hideLabels = true, ...restProps }, forwardedRef) => { + const props = { innerRadius, hideLabels, ...restProps }; const _rootElem = React.useRef(null); const _uniqText: string = useId('_Pie_'); /* eslint-disable @typescript-eslint/no-explicit-any */ @@ -321,7 +322,9 @@ export const DonutChart: React.FunctionComponent = React.forwar return !_isChartEmpty() ? (
(_rootElem.current = rootElem)} + ref={(rootElem: HTMLDivElement | null) => { + _rootElem.current = rootElem; + }} onMouseLeave={_handleChartMouseLeave} > {props.xAxisAnnotation && ( @@ -376,7 +379,12 @@ export const DonutChart: React.FunctionComponent = React.forwar isCartesian={false} /> {!hideLegend && ( -
(legendContainer.current = e)} className={classes.legendContainer}> +
{ + legendContainer.current = e; + }} + className={classes.legendContainer} + > {legendBars}
)} @@ -388,7 +396,3 @@ export const DonutChart: React.FunctionComponent = React.forwar ); DonutChart.displayName = 'DonutChart'; -DonutChart.defaultProps = { - innerRadius: 0, - hideLabels: true, -}; diff --git a/packages/charts/react-charts/library/src/components/DonutChart/__snapshots__/DonutChart.test.tsx.snap b/packages/charts/react-charts/library/src/components/DonutChart/__snapshots__/DonutChart.test.tsx.snap index 6ffaa075def90c..ce091106185626 100644 --- a/packages/charts/react-charts/library/src/components/DonutChart/__snapshots__/DonutChart.test.tsx.snap +++ b/packages/charts/react-charts/library/src/components/DonutChart/__snapshots__/DonutChart.test.tsx.snap @@ -23,7 +23,7 @@ exports[`Donut chart interactions Should hide callout on mouse leave 1`] = ` aria-label="2020/04/30, 20000." class="fui-donut-arc__root" d="M0.55,-54.997A55,55,0,0,1,51.396,-19.582L0,0Z" - id="_Pie_r0first20000" + id="_Pie__r_0_first20000" opacity="1" role="img" style="fill: #E5E5E5; cursor: default;" @@ -35,7 +35,7 @@ exports[`Donut chart interactions Should hide callout on mouse leave 1`] = ` aria-label="2020/04/20, 39000." class="fui-donut-arc__root" d="M51.777,-18.551A55,55,0,0,1,-22.37,50.245L0,0Z" - id="_Pie_r0second39000" + id="_Pie__r_0_second39000" opacity="1" role="img" style="fill: #0078D4; cursor: default;" @@ -47,7 +47,7 @@ exports[`Donut chart interactions Should hide callout on mouse leave 1`] = ` aria-label="2020/04/25, 45000." class="fui-donut-arc__root" d="M-23.37,49.788A55,55,0,0,1,-0.55,-54.997L0,0Z" - id="_Pie_r0third45000" + id="_Pie__r_0_third45000" opacity="1" role="img" style="fill: #DADADA; cursor: default;" @@ -59,7 +59,7 @@ exports[`Donut chart interactions Should hide callout on mouse leave 1`] = `