diff --git a/.github/ISSUE_TEMPLATE/01-react-components-bug-report.yml b/.github/ISSUE_TEMPLATE/01-react-components-bug-report.yml index fa2b5be3bc0082..3ac9d7de51cab4 100644 --- a/.github/ISSUE_TEMPLATE/01-react-components-bug-report.yml +++ b/.github/ISSUE_TEMPLATE/01-react-components-bug-report.yml @@ -26,8 +26,15 @@ body: - Breadcrumb - Button - Card + - CardFooter + - CardHeader + - CardPreview + - Carousel + - CarouselNav - Checkbox - Combobox + - CompoundButton + - Counter Badge - DataGrid - Dialog - Divider @@ -38,14 +45,19 @@ body: - Image - InfoLabel - Input + - InteractionTag - Label - Link + - List - Menu + - MenuButton + - MenuList - MessageBar - Overflow - Persona - Popover - Portal + - PresenceBadge - ProgressBar - RadioGroup - Rating @@ -56,32 +68,37 @@ body: - Slider - SpinButton - Spinner + - SplitButton - SwatchPicker - Switch - - Table - TabList + - Table - Tag + - TagGroup - TagPicker - TeachingPopover - Text - Textarea - Toast + - ToggleButton - Toolbar - Tooltip - Tree + - ColorPicker (Preview) + - Nav (Preview) + - Virtualizer (Preview) + - VirtualizerScrollView (Preview) + - VirtualizerScrollViewDynamic (Preview) - Calendar (Compat) - DatePicker (Compat) - TimePicker (Compat) - - Carousel (Preview) - - List (Preview) - - Nav (Preview) - - Virtualizer (Preview) - - Motion - Icons - - Theme/Tokens - - Utilities (utilities we provide besides Components, e.g. apis from react-utilities) - - Migration Shims v0 - - Migration Shims v8 + - Migration Shims V0 + - Migration Shims V8 + - Motion + - Theme + - Tokens + - Utilities - Other... validations: required: true diff --git a/.github/workflows/pr-vrt-comment.yml b/.github/workflows/pr-vrt-comment.yml index 39f8960881ce12..cea6491dd5114c 100644 --- a/.github/workflows/pr-vrt-comment.yml +++ b/.github/workflows/pr-vrt-comment.yml @@ -4,6 +4,10 @@ on: workflows: ['VRT CI'] types: - completed + branches: + - master + # remove following once CRT testing is done + - vrt-gha-testing concurrency: # see https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#example-only-cancel-in-progress-jobs-or-runs-for-the-current-workflow diff --git a/.github/workflows/pr-vrt.yml b/.github/workflows/pr-vrt.yml index 344a1783f9f858..7cb8853eb8e604 100644 --- a/.github/workflows/pr-vrt.yml +++ b/.github/workflows/pr-vrt.yml @@ -1,6 +1,8 @@ name: VRT CI on: - pull_request: + # TODO: once testing is done enable pull_request trigger again + # pull_request: + workflow_dispatch: concurrency: # see https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#example-only-cancel-in-progress-jobs-or-runs-for-the-current-workflow diff --git a/README.md b/README.md index ce78d0bfa950d5..c2bffa8e5ced88 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,8 @@ The following table will help you navigate the 3 projects and understand their d | **Used By** | Microsoft 365 | Office | Edge | | **Read Me** | [README.md](/packages/react-components/react-components/README.md) | [README.md](/packages/react/README.md)| [README.md](/packages/web-components/README.md) | | **Changelog** | [CHANGELOG.md](/packages/react-components/react-components/CHANGELOG.md) | [CHANGELOG.md](/packages/react/CHANGELOG.md) | [CHANGELOG.md](/packages/web-components/CHANGELOG.md) | -| **Repo** | [packages/react-components](/packages/react-components/react-components/CHANGELOG.md) | [./packages/react](/packages/react) | [./packages/web-components](/packages/web-components) | -| **Quick Start** | [Quick Start](https://react.fluentui.dev/?path=/docs/concepts-developer-quick-start--page) | [Quick Start](https://developer.microsoft.com/en-us/fluentui#/get-started/web) | [See README.md](https://github.com/microsoft/fluentui/tree/master/packages/web-components/README.md) | +| **Repo** | [packages/react-components](/packages/react-components/react-components) | [./packages/react](/packages/react) | [./packages/web-components](/packages/web-components) | +| **Quick Start** | [Quick Start](https://react.fluentui.dev/?path=/docs/concepts-developer-quick-start--docs) | [Quick Start](https://developer.microsoft.com/en-us/fluentui#/get-started/web) | [See README.md](https://github.com/microsoft/fluentui/tree/master/packages/web-components/README.md) | | **Docs** | [https://react.fluentui.dev/](https://react.fluentui.dev/) | [aka.ms/fluentui-react](https://aka.ms/fluentui-react) | [aka.ms/fluentui-web-components](https://aka.ms/fluentui-web-components) | | **NPM** | `@fluentui/react-components` | `@fluentui/react`| `@fluentui/web-components` | | **Version** | [![npm version](https://img.shields.io/npm/v/@fluentui/react-components?style=flat-square)](https://www.npmjs.com/package/@fluentui/react-components) | [![npm version](https://img.shields.io/npm/v/@fluentui/react?style=flat-square)](https://www.npmjs.com/package/@fluentui/react) | [![npm version](https://img.shields.io/npm/v/@fluentui/web-components/beta?style=flat-square)](https://www.npmjs.com/package/@fluentui/web-components/v/3.0.0-beta.15) | diff --git a/apps/chart-docsite/.eslintrc.json b/apps/chart-docsite/.eslintrc.json index 45462ffe5954dc..a75719fd243047 100644 --- a/apps/chart-docsite/.eslintrc.json +++ b/apps/chart-docsite/.eslintrc.json @@ -4,7 +4,7 @@ "rules": { "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/jsx-no-bind": "off", - "deprecation/deprecation": "off", + "@typescript-eslint/no-deprecated": "off", "import/no-extraneous-dependencies": ["error", { "packageDir": [".", "../.."] }] } } diff --git a/apps/public-docsite-resources/.eslintrc.json b/apps/public-docsite-resources/.eslintrc.json index b9cc959897e9b2..9fc74280fa19bb 100644 --- a/apps/public-docsite-resources/.eslintrc.json +++ b/apps/public-docsite-resources/.eslintrc.json @@ -5,7 +5,7 @@ "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/explicit-member-accessibility": "off", "@typescript-eslint/member-ordering": "off", - "deprecation/deprecation": "off", - "no-restricted-globals": "off" + "no-restricted-globals": "off", + "@typescript-eslint/no-deprecated": "off" } } diff --git a/apps/public-docsite-v9/.eslintrc.json b/apps/public-docsite-v9/.eslintrc.json index 45462ffe5954dc..21b3d1e6a45479 100644 --- a/apps/public-docsite-v9/.eslintrc.json +++ b/apps/public-docsite-v9/.eslintrc.json @@ -4,7 +4,7 @@ "rules": { "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/jsx-no-bind": "off", - "deprecation/deprecation": "off", - "import/no-extraneous-dependencies": ["error", { "packageDir": [".", "../.."] }] + "import/no-extraneous-dependencies": ["error", { "packageDir": [".", "../.."] }], + "@typescript-eslint/no-deprecated": "off" } } diff --git a/apps/public-docsite-v9/src/Concepts/Theming.stories.mdx b/apps/public-docsite-v9/src/Concepts/Theming.stories.mdx index c79f39c86363bf..aae124ac7f8146 100644 --- a/apps/public-docsite-v9/src/Concepts/Theming.stories.mdx +++ b/apps/public-docsite-v9/src/Concepts/Theming.stories.mdx @@ -22,7 +22,7 @@ No matter what theme is used, the component styles are always the same. The only Those tokens are resolved to CSS variables. The `FluentProvider` component is responsible for setting the values of the CSS variables in DOM and changing them when the theme changes. When the theme is switched, only the variables are changed, all styles remain the same. -Place a `` at the root of your app and pass a theme to the `theme` prop. The provider will render a `div` and set all tokens as CSS variables on that element. The provider also propagates CCS variables to React portals created with [Portal component](?path=/docs/components-portal--default). +Place a `` at the root of your app and pass a theme to the `theme` prop. The provider will render a `div` and set all tokens as CSS variables on that element. The provider also propagates CSS variables to React portals created with [Portal component](?path=/docs/components-portal--default). ```jsx import { FluentProvider, teamsLightTheme } from '@fluentui/react-components'; diff --git a/apps/public-docsite/.eslintrc.json b/apps/public-docsite/.eslintrc.json index 4a1010d7c11d98..6a0ccc21bb36a8 100644 --- a/apps/public-docsite/.eslintrc.json +++ b/apps/public-docsite/.eslintrc.json @@ -3,10 +3,10 @@ "root": true, "rules": { "@typescript-eslint/no-explicit-any": "off", - "deprecation/deprecation": "off", "import/no-webpack-loader-syntax": "off", // ok in this project "prefer-const": "off", "react/jsx-no-bind": "off", - "no-restricted-globals": "off" + "no-restricted-globals": "off", + "@typescript-eslint/no-deprecated": "off" } } diff --git a/apps/theming-designer/.eslintrc.json b/apps/theming-designer/.eslintrc.json index 0d9ca4c10f823d..5ad87795c4a5b2 100644 --- a/apps/theming-designer/.eslintrc.json +++ b/apps/theming-designer/.eslintrc.json @@ -3,8 +3,8 @@ "root": true, "rules": { "@typescript-eslint/no-explicit-any": "off", - "deprecation/deprecation": "off", "prefer-const": "off", - "no-restricted-globals": "off" + "no-restricted-globals": "off", + "@typescript-eslint/no-deprecated": "off" } } diff --git a/apps/vr-tests-react-components/.eslintrc.json b/apps/vr-tests-react-components/.eslintrc.json index 3301180702eb44..deda75964dbfd1 100644 --- a/apps/vr-tests-react-components/.eslintrc.json +++ b/apps/vr-tests-react-components/.eslintrc.json @@ -7,8 +7,8 @@ "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/naming-convention": "off", "@typescript-eslint/jsx-no-bind": "off", - "deprecation/deprecation": "off", "import/no-extraneous-dependencies": ["error", { "packageDir": [".", "../.."] }], - "@nx/workspace-no-restricted-globals": "off" + "@nx/workspace-no-restricted-globals": "off", + "@typescript-eslint/no-deprecated": "off" } } diff --git a/apps/vr-tests/.eslintrc.json b/apps/vr-tests/.eslintrc.json index 54ac641d7b3bfc..5f50754feeb77e 100644 --- a/apps/vr-tests/.eslintrc.json +++ b/apps/vr-tests/.eslintrc.json @@ -4,8 +4,8 @@ "rules": { "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/jsx-no-bind": "off", - "deprecation/deprecation": "off", "import/no-extraneous-dependencies": ["error", { "packageDir": [".", "../.."] }], - "no-restricted-globals": "off" + "no-restricted-globals": "off", + "@typescript-eslint/no-deprecated": "off" } } diff --git a/azure-pipelines.release.web-components.yml b/azure-pipelines.release.web-components.yml index 7ff0c44032afa9..e3817f7116627a 100644 --- a/azure-pipelines.release.web-components.yml +++ b/azure-pipelines.release.web-components.yml @@ -69,7 +69,7 @@ extends: displayName: yarn - script: | - yarn nx run-many -t format:check lint test build -p web-components --nxBail + yarn nx run-many -t format:check lint test build -p tag:web-components --exclude vr-tests-web-components --nxBail displayName: Build, Test, Lint - script: | diff --git a/change/@fluentui-chart-web-components-dfff0cf0-8ca6-4c11-aacb-bdd0e7090bbb.json b/change/@fluentui-chart-web-components-dfff0cf0-8ca6-4c11-aacb-bdd0e7090bbb.json deleted file mode 100644 index c610fda40decf5..00000000000000 --- a/change/@fluentui-chart-web-components-dfff0cf0-8ca6-4c11-aacb-bdd0e7090bbb.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "Create chart web components. Includes donut chart and horizontal bar chart", - "packageName": "@fluentui/chart-web-components", - "email": "98592573+AtishayMsft@users.noreply.github.com", - "dependentChangeType": "patch" -} diff --git a/change/@fluentui-eslint-plugin-fa5bccc0-99d9-46ae-8cc6-5fbdd18360cb.json b/change/@fluentui-eslint-plugin-fa5bccc0-99d9-46ae-8cc6-5fbdd18360cb.json new file mode 100644 index 00000000000000..ddfba557f6a9a4 --- /dev/null +++ b/change/@fluentui-eslint-plugin-fa5bccc0-99d9-46ae-8cc6-5fbdd18360cb.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/eslint-plugin", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-1b776c96-e0cd-4c27-a7a5-b8b53dc322d2.json b/change/@fluentui-react-1b776c96-e0cd-4c27-a7a5-b8b53dc322d2.json new file mode 100644 index 00000000000000..0b41cf5900b414 --- /dev/null +++ b/change/@fluentui-react-1b776c96-e0cd-4c27-a7a5-b8b53dc322d2.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Async dispose to release references", + "packageName": "@fluentui/react", + "email": "706967+KevinTCoughlin@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-accordion-b082df99-c014-4ba8-8523-fdc134b25bcb.json b/change/@fluentui-react-accordion-b082df99-c014-4ba8-8523-fdc134b25bcb.json new file mode 100644 index 00000000000000..ae55ba19bba18f --- /dev/null +++ b/change/@fluentui-react-accordion-b082df99-c014-4ba8-8523-fdc134b25bcb.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-accordion", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-aria-ece4e8b8-ef6f-487c-a209-1a55c9dc6bfb.json b/change/@fluentui-react-aria-ece4e8b8-ef6f-487c-a209-1a55c9dc6bfb.json new file mode 100644 index 00000000000000..dc9f1971ad978a --- /dev/null +++ b/change/@fluentui-react-aria-ece4e8b8-ef6f-487c-a209-1a55c9dc6bfb.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-aria", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-avatar-9cab8d3a-1bcd-4c03-8138-82520de36649.json b/change/@fluentui-react-avatar-9cab8d3a-1bcd-4c03-8138-82520de36649.json new file mode 100644 index 00000000000000..9d3bbebf5cb5e1 --- /dev/null +++ b/change/@fluentui-react-avatar-9cab8d3a-1bcd-4c03-8138-82520de36649.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-avatar", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-color-picker-preview-1411f212-27ea-4335-bcd3-b210359b0bd1.json b/change/@fluentui-react-color-picker-preview-1411f212-27ea-4335-bcd3-b210359b0bd1.json new file mode 100644 index 00000000000000..6e323e0af85625 --- /dev/null +++ b/change/@fluentui-react-color-picker-preview-1411f212-27ea-4335-bcd3-b210359b0bd1.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-color-picker-preview", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-color-picker-preview-c30cb79c-aed3-4e9b-ad55-b1f946c8c691.json b/change/@fluentui-react-color-picker-preview-c30cb79c-aed3-4e9b-ad55-b1f946c8c691.json new file mode 100644 index 00000000000000..659240a99245b9 --- /dev/null +++ b/change/@fluentui-react-color-picker-preview-c30cb79c-aed3-4e9b-ad55-b1f946c8c691.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "fix: focus jumps to inputY instead of next element", + "packageName": "@fluentui/react-color-picker-preview", + "email": "vkozlova@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-color-picker-preview-d36c4ad2-9cc0-4131-bdee-dd557b75c0bb.json b/change/@fluentui-react-color-picker-preview-d36c4ad2-9cc0-4131-bdee-dd557b75c0bb.json new file mode 100644 index 00000000000000..f30eab37953f98 --- /dev/null +++ b/change/@fluentui-react-color-picker-preview-d36c4ad2-9cc0-4131-bdee-dd557b75c0bb.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "feat: Added `transparent` option to the AlphaSlider", + "packageName": "@fluentui/react-color-picker-preview", + "email": "v.kozlova13@gmail.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-combobox-6b28f16b-50a6-4ea3-8afc-d21e6b99bc5e.json b/change/@fluentui-react-combobox-6b28f16b-50a6-4ea3-8afc-d21e6b99bc5e.json new file mode 100644 index 00000000000000..793132b08fa9f9 --- /dev/null +++ b/change/@fluentui-react-combobox-6b28f16b-50a6-4ea3-8afc-d21e6b99bc5e.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-combobox", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-components-2c418aac-078d-45dc-ad47-4bf796a2e600.json b/change/@fluentui-react-components-2c418aac-078d-45dc-ad47-4bf796a2e600.json new file mode 100644 index 00000000000000..d1657869b81f19 --- /dev/null +++ b/change/@fluentui-react-components-2c418aac-078d-45dc-ad47-4bf796a2e600.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "feature: re-export react-tag-picker context", + "packageName": "@fluentui/react-components", + "email": "bernardo.sunderhus@gmail.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-components-8e070f58-09e6-4a66-bd63-bbd13b27db88.json b/change/@fluentui-react-components-8e070f58-09e6-4a66-bd63-bbd13b27db88.json new file mode 100644 index 00000000000000..ddc6a6c41d1080 --- /dev/null +++ b/change/@fluentui-react-components-8e070f58-09e6-4a66-bd63-bbd13b27db88.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "feature: TreeRootReset component", + "packageName": "@fluentui/react-components", + "email": "bernardo.sunderhus@gmail.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-components-a1ed2f9c-dd8c-4d5c-82ae-295a90a26772.json b/change/@fluentui-react-components-a1ed2f9c-dd8c-4d5c-82ae-295a90a26772.json new file mode 100644 index 00000000000000..6c9209a8e0effa --- /dev/null +++ b/change/@fluentui-react-components-a1ed2f9c-dd8c-4d5c-82ae-295a90a26772.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-components", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-conformance-4944bee5-948a-4649-87a1-8362f68d4635.json b/change/@fluentui-react-conformance-4944bee5-948a-4649-87a1-8362f68d4635.json new file mode 100644 index 00000000000000..58fe9ad666bf04 --- /dev/null +++ b/change/@fluentui-react-conformance-4944bee5-948a-4649-87a1-8362f68d4635.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-conformance", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-icons-compat-d79ea04c-0316-4c1e-9c1e-96710298947a.json b/change/@fluentui-react-icons-compat-d79ea04c-0316-4c1e-9c1e-96710298947a.json new file mode 100644 index 00000000000000..3fb672d36efa9b --- /dev/null +++ b/change/@fluentui-react-icons-compat-d79ea04c-0316-4c1e-9c1e-96710298947a.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-icons-compat", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-link-3fcc87af-d93e-43d3-8c48-d38b192fd9ac.json b/change/@fluentui-react-link-3fcc87af-d93e-43d3-8c48-d38b192fd9ac.json new file mode 100644 index 00000000000000..c77906f88a7d1f --- /dev/null +++ b/change/@fluentui-react-link-3fcc87af-d93e-43d3-8c48-d38b192fd9ac.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "fix: support Enter and Space interaction, if rendered as span", + "packageName": "@fluentui/react-link", + "email": "vgenaev@gmail.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-menu-51e8bb80-2224-47a8-8a42-282214bcee42.json b/change/@fluentui-react-menu-51e8bb80-2224-47a8-8a42-282214bcee42.json new file mode 100644 index 00000000000000..369c63a243bb20 --- /dev/null +++ b/change/@fluentui-react-menu-51e8bb80-2224-47a8-8a42-282214bcee42.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-menu", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-message-bar-045b67fd-ae48-4ed9-abbd-669235409ead.json b/change/@fluentui-react-message-bar-045b67fd-ae48-4ed9-abbd-669235409ead.json new file mode 100644 index 00000000000000..f62fce2bae66b0 --- /dev/null +++ b/change/@fluentui-react-message-bar-045b67fd-ae48-4ed9-abbd-669235409ead.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-message-bar", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-motion-32b72aa4-8d6a-42e7-8adc-3d0eb8162c7a.json b/change/@fluentui-react-motion-32b72aa4-8d6a-42e7-8adc-3d0eb8162c7a.json new file mode 100644 index 00000000000000..57cfdd1c1b62b2 --- /dev/null +++ b/change/@fluentui-react-motion-32b72aa4-8d6a-42e7-8adc-3d0eb8162c7a.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-motion", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-motion-components-preview-67537ce1-b461-4bec-bbcb-61d9202e6632.json b/change/@fluentui-react-motion-components-preview-67537ce1-b461-4bec-bbcb-61d9202e6632.json new file mode 100644 index 00000000000000..970d564c51cda6 --- /dev/null +++ b/change/@fluentui-react-motion-components-preview-67537ce1-b461-4bec-bbcb-61d9202e6632.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "refactor(Collapse): streamline motion atom functions", + "packageName": "@fluentui/react-motion-components-preview", + "email": "robertpenner@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-motion-components-preview-7795f18a-df86-480a-8546-efca47ef6069.json b/change/@fluentui-react-motion-components-preview-7795f18a-df86-480a-8546-efca47ef6069.json new file mode 100644 index 00000000000000..36a3d3b7e344cc --- /dev/null +++ b/change/@fluentui-react-motion-components-preview-7795f18a-df86-480a-8546-efca47ef6069.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-motion-components-preview", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-motion-f4c1433b-f36e-4b2c-a9bd-9b16f37489fc.json b/change/@fluentui-react-motion-f4c1433b-f36e-4b2c-a9bd-9b16f37489fc.json new file mode 100644 index 00000000000000..cba37e60ef3fdd --- /dev/null +++ b/change/@fluentui-react-motion-f4c1433b-f36e-4b2c-a9bd-9b16f37489fc.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "feat: add extended support for reduced motion", + "packageName": "@fluentui/react-motion", + "email": "olfedias@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-popover-02147114-2b1f-427d-a369-c495dcc060f7.json b/change/@fluentui-react-popover-02147114-2b1f-427d-a369-c495dcc060f7.json new file mode 100644 index 00000000000000..7c818960694aea --- /dev/null +++ b/change/@fluentui-react-popover-02147114-2b1f-427d-a369-c495dcc060f7.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-popover", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-positioning-7ff1890e-77cb-4078-be01-2673bb29a80b.json b/change/@fluentui-react-positioning-7ff1890e-77cb-4078-be01-2673bb29a80b.json new file mode 100644 index 00000000000000..fa917f363eb6e0 --- /dev/null +++ b/change/@fluentui-react-positioning-7ff1890e-77cb-4078-be01-2673bb29a80b.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-positioning", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-provider-9f506bc2-b69a-4140-b85e-67b97c87e955.json b/change/@fluentui-react-provider-9f506bc2-b69a-4140-b85e-67b97c87e955.json new file mode 100644 index 00000000000000..c7f52f2deb033f --- /dev/null +++ b/change/@fluentui-react-provider-9f506bc2-b69a-4140-b85e-67b97c87e955.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "fix: Updating FluentProvider types to avoid implicit import in API definition.", + "packageName": "@fluentui/react-provider", + "email": "makotom@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-radio-59106324-2e52-43e5-b407-87f41706faa5.json b/change/@fluentui-react-radio-59106324-2e52-43e5-b407-87f41706faa5.json new file mode 100644 index 00000000000000..85b8c6c078c718 --- /dev/null +++ b/change/@fluentui-react-radio-59106324-2e52-43e5-b407-87f41706faa5.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-radio", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-spinbutton-a56360e5-91b4-443c-90d7-d16c9a672862.json b/change/@fluentui-react-spinbutton-a56360e5-91b4-443c-90d7-d16c9a672862.json new file mode 100644 index 00000000000000..3f61d17745a214 --- /dev/null +++ b/change/@fluentui-react-spinbutton-a56360e5-91b4-443c-90d7-d16c9a672862.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "fix spinbutton test", + "packageName": "@fluentui/react-spinbutton", + "email": "carla.muntean@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-switch-eef105b5-30ee-4c92-bac3-3eb2f1db9980.json b/change/@fluentui-react-switch-eef105b5-30ee-4c92-bac3-3eb2f1db9980.json new file mode 100644 index 00000000000000..e6327946c49fac --- /dev/null +++ b/change/@fluentui-react-switch-eef105b5-30ee-4c92-bac3-3eb2f1db9980.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-switch", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-table-041ffd34-f086-4af7-a72a-66dbbd56617b.json b/change/@fluentui-react-table-041ffd34-f086-4af7-a72a-66dbbd56617b.json new file mode 100644 index 00000000000000..9855003d9f9cca --- /dev/null +++ b/change/@fluentui-react-table-041ffd34-f086-4af7-a72a-66dbbd56617b.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-table", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-tabs-c489edef-c7ee-4bf0-8f32-8565edccb381.json b/change/@fluentui-react-tabs-c489edef-c7ee-4bf0-8f32-8565edccb381.json new file mode 100644 index 00000000000000..add9f9f3024781 --- /dev/null +++ b/change/@fluentui-react-tabs-c489edef-c7ee-4bf0-8f32-8565edccb381.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-tabs", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-tabster-a4a177a3-0514-4657-9fdd-a0e90d44e813.json b/change/@fluentui-react-tabster-a4a177a3-0514-4657-9fdd-a0e90d44e813.json new file mode 100644 index 00000000000000..8e5d56c1248819 --- /dev/null +++ b/change/@fluentui-react-tabster-a4a177a3-0514-4657-9fdd-a0e90d44e813.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-tabster", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-tag-picker-7ed3243d-60b5-4678-9762-f1b1722ca0fe.json b/change/@fluentui-react-tag-picker-7ed3243d-60b5-4678-9762-f1b1722ca0fe.json new file mode 100644 index 00000000000000..9060ffa1cb620a --- /dev/null +++ b/change/@fluentui-react-tag-picker-7ed3243d-60b5-4678-9762-f1b1722ca0fe.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "feature: single line layout", + "packageName": "@fluentui/react-tag-picker", + "email": "bernardo.sunderhus@gmail.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-tag-picker-f788c84a-933e-4291-9111-2a6187517663.json b/change/@fluentui-react-tag-picker-f788c84a-933e-4291-9111-2a6187517663.json new file mode 100644 index 00000000000000..3f3abb7239db9f --- /dev/null +++ b/change/@fluentui-react-tag-picker-f788c84a-933e-4291-9111-2a6187517663.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "bugfix: secondaryContent not displaying properly", + "packageName": "@fluentui/react-tag-picker", + "email": "bernardo.sunderhus@gmail.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-tooltip-058754b5-d9ec-459a-acc5-ba9ff587c4e3.json b/change/@fluentui-react-tooltip-058754b5-d9ec-459a-acc5-ba9ff587c4e3.json new file mode 100644 index 00000000000000..c1ea720b6a9e45 --- /dev/null +++ b/change/@fluentui-react-tooltip-058754b5-d9ec-459a-acc5-ba9ff587c4e3.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-tooltip", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-tooltip-4088de96-b20d-4c18-9567-9987be622dbf.json b/change/@fluentui-react-tooltip-4088de96-b20d-4c18-9567-9987be622dbf.json new file mode 100644 index 00000000000000..d8e0b5362d896c --- /dev/null +++ b/change/@fluentui-react-tooltip-4088de96-b20d-4c18-9567-9987be622dbf.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "fix: wrong call of useIsNavigatingWithKeyboard", + "packageName": "@fluentui/react-tooltip", + "email": "viktorgenaev@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-tree-287da350-699b-410f-bd97-7cb590731302.json b/change/@fluentui-react-tree-287da350-699b-410f-bd97-7cb590731302.json new file mode 100644 index 00000000000000..712df07693df6e --- /dev/null +++ b/change/@fluentui-react-tree-287da350-699b-410f-bd97-7cb590731302.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-tree", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-tree-69773403-5633-414b-866a-f20aedf4bc0c.json b/change/@fluentui-react-tree-69773403-5633-414b-866a-f20aedf4bc0c.json new file mode 100644 index 00000000000000..299a1892740844 --- /dev/null +++ b/change/@fluentui-react-tree-69773403-5633-414b-866a-f20aedf4bc0c.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "feature: introduces navigationMode property", + "packageName": "@fluentui/react-tree", + "email": "bernardo.sunderhus@gmail.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-tree-b452026f-0282-4a88-a922-34c2a983c77c.json b/change/@fluentui-react-tree-b452026f-0282-4a88-a922-34c2a983c77c.json new file mode 100644 index 00000000000000..7e09b55e865d5d --- /dev/null +++ b/change/@fluentui-react-tree-b452026f-0282-4a88-a922-34c2a983c77c.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "feature: TreeRootReset component", + "packageName": "@fluentui/react-tree", + "email": "bernardo.sunderhus@gmail.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-utilities-0b333279-3531-4fce-a0ee-8e9c05d6f830.json b/change/@fluentui-react-utilities-0b333279-3531-4fce-a0ee-8e9c05d6f830.json new file mode 100644 index 00000000000000..050e7fdba7a165 --- /dev/null +++ b/change/@fluentui-react-utilities-0b333279-3531-4fce-a0ee-8e9c05d6f830.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "fix: add autoCorrect and minLength input properties support to getNativeProps utility", + "packageName": "@fluentui/react-utilities", + "email": "dmytrokirpa@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-utilities-82544042-02b6-4262-91cd-e7f9fe24bad2.json b/change/@fluentui-react-utilities-82544042-02b6-4262-91cd-e7f9fe24bad2.json new file mode 100644 index 00000000000000..6b1ae1f1853dd9 --- /dev/null +++ b/change/@fluentui-react-utilities-82544042-02b6-4262-91cd-e7f9fe24bad2.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-utilities", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/change/@fluentui-react-virtualizer-00dd23f0-89d0-486d-844f-30a880feb0f5.json b/change/@fluentui-react-virtualizer-00dd23f0-89d0-486d-844f-30a880feb0f5.json new file mode 100644 index 00000000000000..556a8a1950726c --- /dev/null +++ b/change/@fluentui-react-virtualizer-00dd23f0-89d0-486d-844f-30a880feb0f5.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule", + "packageName": "@fluentui/react-virtualizer", + "email": "vgenaev@gmail.com", + "dependentChangeType": "none" +} diff --git a/docs/react-v9/contributing/rfcs/react-components/styles-handbook.md b/docs/react-v9/contributing/rfcs/react-components/styles-handbook.md index 749b39684ef147..2b9cf9e008790c 100644 --- a/docs/react-v9/contributing/rfcs/react-components/styles-handbook.md +++ b/docs/react-v9/contributing/rfcs/react-components/styles-handbook.md @@ -962,7 +962,7 @@ function Checkbox(props) { } ``` -[fluent-colors]: https://react.fluentui.dev/?path=/docs/theme-colors--page +[fluent-colors]: https://react.fluentui.dev/?path=/docs/theme-colors--docs [griffel]: https://griffel.js.org [griffel-aot]: https://griffel.js.org/react/ahead-of-time-compilation/introduction [griffel-atomic-css]: https://griffel.js.org/react/guides/atomic-css diff --git a/package.json b/package.json index c50f53823e2ddb..b05c90218db7e1 100644 --- a/package.json +++ b/package.json @@ -75,14 +75,14 @@ "@microsoft/load-themed-styles": "1.10.26", "@microsoft/loader-load-themed-styles": "2.0.17", "@microsoft/tsdoc": "0.14.2", - "@nx/devkit": "19.8.4", - "@nx/eslint": "19.8.4", - "@nx/eslint-plugin": "19.8.4", - "@nx/jest": "19.8.4", - "@nx/js": "19.8.4", - "@nx/node": "19.8.4", - "@nx/plugin": "19.8.4", - "@nx/workspace": "19.8.4", + "@nx/devkit": "19.8.14", + "@nx/eslint": "19.8.14", + "@nx/eslint-plugin": "19.8.14", + "@nx/jest": "19.8.14", + "@nx/js": "19.8.14", + "@nx/node": "19.8.14", + "@nx/plugin": "19.8.14", + "@nx/workspace": "19.8.14", "@octokit/rest": "18.12.0", "@oddbird/css-anchor-positioning": "0.4.0", "@phenomnomnominal/tsquery": "6.1.3", @@ -231,7 +231,6 @@ "eslint-config-airbnb": "18.2.1", "eslint-config-prettier": "8.3.0", "eslint-import-resolver-typescript": "3.6.1", - "eslint-plugin-deprecation": "3.0.0", "eslint-plugin-es": "4.1.0", "eslint-plugin-import": "2.29.1", "eslint-plugin-jest": "28.8.0", @@ -282,7 +281,7 @@ "monosize-bundler-webpack": "0.1.5", "monosize-storage-azure": "0.0.15", "node-plop": "0.25.0", - "nx": "19.8.4", + "nx": "19.8.14", "p-queue": "6.6.2", "parse-diff": "0.7.1", "path-browserify": "1.0.1", @@ -335,7 +334,7 @@ "terser-webpack-plugin": "5.3.10", "through2": "4.0.2", "tmp": "0.2.1", - "ts-jest": "29.1.1", + "ts-jest": "29.2.5", "ts-loader": "9.4.2", "ts-node": "10.9.2", "tsconfig-paths": "4.2.0", diff --git a/packages/azure-themes/CHANGELOG.json b/packages/azure-themes/CHANGELOG.json index 4aaf5704766b85..d422a264bc9375 100644 --- a/packages/azure-themes/CHANGELOG.json +++ b/packages/azure-themes/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/azure-themes", "entries": [ + { + "date": "Fri, 17 Jan 2025 07:21:32 GMT", + "tag": "@fluentui/azure-themes_v8.6.120", + "version": "8.6.120", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/azure-themes", + "comment": "Bump @fluentui/react to v8.122.7", + "commit": "baf887d95f91874c814a7cae749c20e797f828be" + } + ] + } + }, { "date": "Mon, 13 Jan 2025 07:21:23 GMT", "tag": "@fluentui/azure-themes_v8.6.119", diff --git a/packages/azure-themes/CHANGELOG.md b/packages/azure-themes/CHANGELOG.md index c5e0dc641af2fe..5599d162f0a4ee 100644 --- a/packages/azure-themes/CHANGELOG.md +++ b/packages/azure-themes/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/azure-themes -This log was last generated on Mon, 13 Jan 2025 07:21:23 GMT and should not be manually modified. +This log was last generated on Fri, 17 Jan 2025 07:21:32 GMT and should not be manually modified. +## [8.6.120](https://github.com/microsoft/fluentui/tree/@fluentui/azure-themes_v8.6.120) + +Fri, 17 Jan 2025 07:21:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/azure-themes_v8.6.119..@fluentui/azure-themes_v8.6.120) + +### Patches + +- Bump @fluentui/react to v8.122.7 ([commit](https://github.com/microsoft/fluentui/commit/baf887d95f91874c814a7cae749c20e797f828be) by beachball) + ## [8.6.119](https://github.com/microsoft/fluentui/tree/@fluentui/azure-themes_v8.6.119) Mon, 13 Jan 2025 07:21:23 GMT diff --git a/packages/azure-themes/package.json b/packages/azure-themes/package.json index 49ed3c4f1ba138..b6a061aef01ccc 100644 --- a/packages/azure-themes/package.json +++ b/packages/azure-themes/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/azure-themes", - "version": "8.6.119", + "version": "8.6.120", "description": "Azure themes for Fluent UI React", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -27,7 +27,7 @@ "@fluentui/scripts-webpack": "*" }, "dependencies": { - "@fluentui/react": "^8.122.6", + "@fluentui/react": "^8.122.7", "@fluentui/set-version": "^8.2.23", "tslib": "^2.1.0" } diff --git a/packages/charts/chart-web-components/CHANGELOG.json b/packages/charts/chart-web-components/CHANGELOG.json new file mode 100644 index 00000000000000..0824e940714c8e --- /dev/null +++ b/packages/charts/chart-web-components/CHANGELOG.json @@ -0,0 +1,55 @@ +{ + "name": "@fluentui/chart-web-components", + "entries": [ + { + "date": "Fri, 17 Jan 2025 04:07:40 GMT", + "tag": "@fluentui/chart-web-components_v0.0.0", + "version": "0.0.0", + "comments": { + "none": [ + { + "author": "martinhochel@microsoft.com", + "package": "@fluentui/chart-web-components", + "commit": "408fe44060b746844a9c76c67391b18d76d1f26e", + "comment": "chore: sync failed release pipeline with git" + } + ], + "patch": [ + { + "author": "beachball", + "package": "@fluentui/chart-web-components", + "comment": "Bump @fluentui/web-components to v3.0.0-beta.77", + "commit": "24bd1b2e8063db6c121ee02425db564fbb762f5a" + } + ] + } + }, + { + "date": "Tue, 14 Jan 2025 14:42:14 GMT", + "tag": "@fluentui/chart-web-components_v0.0.0-alpha.2", + "version": "0.0.0-alpha.2", + "comments": { + "prerelease": [ + { + "author": "98592573+AtishayMsft@users.noreply.github.com", + "package": "@fluentui/chart-web-components", + "commit": "5964b11d0ac272f2ae10e1081b8f0d1e17497eef", + "comment": "Create chart web components. Includes donut chart and horizontal bar chart" + }, + { + "author": "beachball", + "package": "@fluentui/chart-web-components", + "comment": "Bump @fluentui/tokens to v1.0.0-alpha.21", + "commit": "8cf401d626def27ad679f9e53928533df9f9ef52" + }, + { + "author": "beachball", + "package": "@fluentui/chart-web-components", + "comment": "Bump @fluentui/web-components to v3.0.0-beta.76", + "commit": "8cf401d626def27ad679f9e53928533df9f9ef52" + } + ] + } + } + ] +} diff --git a/packages/charts/chart-web-components/CHANGELOG.md b/packages/charts/chart-web-components/CHANGELOG.md new file mode 100644 index 00000000000000..c5f2184dfb5e5b --- /dev/null +++ b/packages/charts/chart-web-components/CHANGELOG.md @@ -0,0 +1,24 @@ +# Change Log - @fluentui/chart-web-components + +This log was last generated on Fri, 17 Jan 2025 04:07:40 GMT and should not be manually modified. + + + +## [0.0.0](https://github.com/microsoft/fluentui/tree/@fluentui/chart-web-components_v0.0.0) + +Fri, 17 Jan 2025 04:07:40 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/chart-web-components_v0.0.0-alpha.2..@fluentui/chart-web-components_v0.0.0) + +### Patches + +- Bump @fluentui/web-components to v3.0.0-beta.77 ([PR #33679](https://github.com/microsoft/fluentui/pull/33679) by beachball) + +## [0.0.0-alpha.2](https://github.com/microsoft/fluentui/tree/@fluentui/chart-web-components_v0.0.0-alpha.2) + +Tue, 14 Jan 2025 14:42:14 GMT + +### Changes + +- Create chart web components. Includes donut chart and horizontal bar chart ([PR #33084](https://github.com/microsoft/fluentui/pull/33084) by 98592573+AtishayMsft@users.noreply.github.com) +- Bump @fluentui/tokens to v1.0.0-alpha.21 ([PR #33642](https://github.com/microsoft/fluentui/pull/33642) by beachball) +- Bump @fluentui/web-components to v3.0.0-beta.76 ([PR #33642](https://github.com/microsoft/fluentui/pull/33642) by beachball) diff --git a/packages/charts/chart-web-components/package.json b/packages/charts/chart-web-components/package.json index fe15d6d133e168..1ad8f593736763 100644 --- a/packages/charts/chart-web-components/package.json +++ b/packages/charts/chart-web-components/package.json @@ -1,7 +1,7 @@ { "name": "@fluentui/chart-web-components", "description": "A library of Fluent Chart Web Components", - "version": "0.0.0-alpha.1", + "version": "0.0.0", "author": { "name": "Microsoft" }, @@ -97,8 +97,8 @@ }, "dependencies": { "@microsoft/fast-web-utilities": "^6.0.0", - "@fluentui/tokens": "^1.0.0-alpha", - "@fluentui/web-components": "^3.0.0-beta", + "@fluentui/tokens": "^1.0.0-alpha.21", + "@fluentui/web-components": "^3.0.0-beta.77", "@types/d3-selection": "^3.0.0", "@types/d3-shape": "^3.0.0", "d3-selection": "^3.0.0", diff --git a/packages/charts/react-charting/CHANGELOG.json b/packages/charts/react-charting/CHANGELOG.json index 39fddc4b97a2dc..ff4f3f3b32a70a 100644 --- a/packages/charts/react-charting/CHANGELOG.json +++ b/packages/charts/react-charting/CHANGELOG.json @@ -1,6 +1,101 @@ { "name": "@fluentui/react-charting", "entries": [ + { + "date": "Tue, 21 Jan 2025 07:13:50 GMT", + "tag": "@fluentui/react-charting_v5.23.43", + "version": "5.23.43", + "comments": { + "patch": [ + { + "author": "110246001+krkshitij@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "08575f8e7d2362e9b986bccee516546f88fe562a", + "comment": "fix: resolve overlapping bars issue in histogram" + }, + { + "author": "120183316+srmukher@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "b929a867df391be107630afe2de281c5d06594e7", + "comment": "Adding fallback and fixes for test app crashes for 12 schema data " + }, + { + "author": "98592573+AtishayMsft@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "b929a867df391be107630afe2de281c5d06594e7", + "comment": "Use strongly typed interfaces for plotly schema" + }, + { + "author": "110246001+krkshitij@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "b929a867df391be107630afe2de281c5d06594e7", + "comment": "fix: resolve bugs in declarative chart" + }, + { + "author": "74965306+Anush2303@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "b929a867df391be107630afe2de281c5d06594e7", + "comment": "StronglyType plotly schema bug fix" + } + ] + } + }, + { + "date": "Mon, 20 Jan 2025 07:21:43 GMT", + "tag": "@fluentui/react-charting_v5.23.42", + "version": "5.23.42", + "comments": { + "patch": [ + { + "author": "120183316+srmukher@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "556fc8e7b9a921cedbb07c2f0670dfabcf8ec0ed", + "comment": "Support tozeroy mode for Area Charts" + }, + { + "author": "74965306+Anush2303@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "dc365b11fcca7eb0077460510eb78d93d3315ecd", + "comment": "Declarative chart bug fixes" + } + ], + "none": [ + { + "author": "vgenaev@gmail.com", + "package": "@fluentui/react-charting", + "commit": "fd420e1e0b66e04c8a423cff3eea6d21d9434d2d", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule" + } + ] + } + }, + { + "date": "Fri, 17 Jan 2025 07:21:32 GMT", + "tag": "@fluentui/react-charting_v5.23.41", + "version": "5.23.41", + "comments": { + "patch": [ + { + "author": "74965306+Anush2303@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "c26be3e3a85258c61111cf2dd5c19798d3a4e936", + "comment": "Make Dark mode text visible" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/theme-samples to v8.7.196", + "commit": "baf887d95f91874c814a7cae749c20e797f828be" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/react to v8.122.7", + "commit": "baf887d95f91874c814a7cae749c20e797f828be" + } + ] + } + }, { "date": "Mon, 13 Jan 2025 07:21:22 GMT", "tag": "@fluentui/react-charting_v5.23.40", diff --git a/packages/charts/react-charting/CHANGELOG.md b/packages/charts/react-charting/CHANGELOG.md index 42e32365cd9654..178ccd9991cebf 100644 --- a/packages/charts/react-charting/CHANGELOG.md +++ b/packages/charts/react-charting/CHANGELOG.md @@ -1,9 +1,43 @@ # Change Log - @fluentui/react-charting -This log was last generated on Mon, 13 Jan 2025 07:21:22 GMT and should not be manually modified. +This log was last generated on Tue, 21 Jan 2025 07:13:50 GMT and should not be manually modified. +## [5.23.43](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.43) + +Tue, 21 Jan 2025 07:13:50 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.42..@fluentui/react-charting_v5.23.43) + +### Patches + +- fix: resolve overlapping bars issue in histogram ([PR #33695](https://github.com/microsoft/fluentui/pull/33695) by 110246001+krkshitij@users.noreply.github.com) +- Adding fallback and fixes for test app crashes for 12 schema data ([PR #33621](https://github.com/microsoft/fluentui/pull/33621) by 120183316+srmukher@users.noreply.github.com) +- Use strongly typed interfaces for plotly schema ([PR #33621](https://github.com/microsoft/fluentui/pull/33621) by 98592573+AtishayMsft@users.noreply.github.com) +- fix: resolve bugs in declarative chart ([PR #33621](https://github.com/microsoft/fluentui/pull/33621) by 110246001+krkshitij@users.noreply.github.com) +- StronglyType plotly schema bug fix ([PR #33621](https://github.com/microsoft/fluentui/pull/33621) by 74965306+Anush2303@users.noreply.github.com) + +## [5.23.42](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.42) + +Mon, 20 Jan 2025 07:21:43 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.41..@fluentui/react-charting_v5.23.42) + +### Patches + +- Support tozeroy mode for Area Charts ([PR #33581](https://github.com/microsoft/fluentui/pull/33581) by 120183316+srmukher@users.noreply.github.com) +- Declarative chart bug fixes ([PR #33567](https://github.com/microsoft/fluentui/pull/33567) by 74965306+Anush2303@users.noreply.github.com) + +## [5.23.41](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.41) + +Fri, 17 Jan 2025 07:21:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.40..@fluentui/react-charting_v5.23.41) + +### Patches + +- Make Dark mode text visible ([PR #33671](https://github.com/microsoft/fluentui/pull/33671) by 74965306+Anush2303@users.noreply.github.com) +- Bump @fluentui/theme-samples to v8.7.196 ([commit](https://github.com/microsoft/fluentui/commit/baf887d95f91874c814a7cae749c20e797f828be) by beachball) +- Bump @fluentui/react to v8.122.7 ([commit](https://github.com/microsoft/fluentui/commit/baf887d95f91874c814a7cae749c20e797f828be) by beachball) + ## [5.23.40](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.40) Mon, 13 Jan 2025 07:21:22 GMT diff --git a/packages/charts/react-charting/bundle-size/DeclarativeChart.fixture.js b/packages/charts/react-charting/bundle-size/DeclarativeChart.fixture.js new file mode 100644 index 00000000000000..ce50de1aed3848 --- /dev/null +++ b/packages/charts/react-charting/bundle-size/DeclarativeChart.fixture.js @@ -0,0 +1,7 @@ +import { DeclarativeChart } from '@fluentui/react-charting'; + +console.log(DeclarativeChart); + +export default { + name: 'DeclarativeChart', +}; diff --git a/packages/charts/react-charting/etc/react-charting.api.md b/packages/charts/react-charting/etc/react-charting.api.md index eb0fc4896667cb..0f37b87a4e8997 100644 --- a/packages/charts/react-charting/etc/react-charting.api.md +++ b/packages/charts/react-charting/etc/react-charting.api.md @@ -200,6 +200,7 @@ export interface IAreaChartProps extends ICartesianChartProps { data: IChartProps; enableGradient?: boolean; enablePerfOptimization?: boolean; + mode?: 'tozeroy' | 'tonexty'; onRenderCalloutPerDataPoint?: IRenderFunction; onRenderCalloutPerStack?: IRenderFunction; // (undocumented) diff --git a/packages/charts/react-charting/package.json b/packages/charts/react-charting/package.json index 80f4f6edff1ebd..d91ee34bf3ac28 100644 --- a/packages/charts/react-charting/package.json +++ b/packages/charts/react-charting/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-charting", - "version": "5.23.40", + "version": "5.23.43", "description": "React web charting controls for Microsoft fluentui system.", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -40,7 +40,7 @@ }, "dependencies": { "@fluentui/react-focus": "^8.9.20", - "@fluentui/theme-samples": "^8.7.195", + "@fluentui/theme-samples": "^8.7.196", "@microsoft/load-themed-styles": "^1.10.26", "@types/d3-array": "^3.0.0", "@types/d3-axis": "^3.0.0", @@ -66,7 +66,7 @@ "tslib": "^2.1.0" }, "peerDependencies": { - "@fluentui/react": "^8.122.6", + "@fluentui/react": "^8.122.7", "@types/react": ">=16.8.0 <19.0.0", "@types/react-dom": ">=16.8.0 <19.0.0", "react": ">=16.8.0 <19.0.0", diff --git a/packages/charts/react-charting/src/Styling.ts b/packages/charts/react-charting/src/Styling.ts index 31e6ed2005a051..563a5a90452e3b 100644 --- a/packages/charts/react-charting/src/Styling.ts +++ b/packages/charts/react-charting/src/Styling.ts @@ -6,7 +6,7 @@ export { DefaultEffects, DefaultFontStyles, DefaultPalette, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated EdgeChromiumHighContrastSelector, FontClassNames, FontSizes, @@ -39,11 +39,11 @@ export { createTheme, focusClear, fontFace, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getEdgeChromiumNoHighContrastAdjustSelector, getFadedOverflowStyle, getFocusOutlineStyle, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getFocusStyle, getGlobalClassNames, getHighContrastNoAdjustStyle, diff --git a/packages/charts/react-charting/src/Utilities.ts b/packages/charts/react-charting/src/Utilities.ts index 0850eaa19b0634..82dae884afcb13 100644 --- a/packages/charts/react-charting/src/Utilities.ts +++ b/packages/charts/react-charting/src/Utilities.ts @@ -1,10 +1,8 @@ export { Async, AutoScroll, - // eslint-disable-next-line deprecation/deprecation BaseComponent, Customizations, - // eslint-disable-next-line deprecation/deprecation Customizer, CustomizerContext, DATA_IS_SCROLLABLE_ATTRIBUTE, @@ -87,7 +85,6 @@ export { getRTL, getRTLSafeKeyCode, getRect, - // eslint-disable-next-line deprecation/deprecation getResourceUrl, getScrollbarWidth, getVirtualParent, @@ -99,11 +96,9 @@ export { hoistStatics, htmlElementProperties, iframeProperties, - // eslint-disable-next-line deprecation/deprecation imageProperties, imgProperties, initializeComponentRef, - // eslint-disable-next-line deprecation/deprecation initializeFocusRects, inputProperties, isControlled, @@ -135,7 +130,6 @@ export { optionProperties, portalContainsElement, precisionRound, - // eslint-disable-next-line deprecation/deprecation raiseClick, removeIndex, replaceElement, @@ -145,15 +139,12 @@ export { safeRequestAnimationFrame, safeSetTimeout, selectProperties, - // eslint-disable-next-line deprecation/deprecation setBaseUrl, setFocusVisibility, - // eslint-disable-next-line deprecation/deprecation setLanguage, setMemoizeWeakMap, setPortalAttribute, setRTL, - // eslint-disable-next-line deprecation/deprecation setSSR, setVirtualParent, setWarningCallback, @@ -184,7 +175,6 @@ export type { ICancelable, IChangeDescription, IChangeEventCallback, - // eslint-disable-next-line deprecation/deprecation IClassNames, IClassNamesFunctionOptions, IComponentAs, @@ -207,7 +197,6 @@ export type { IPerfData, IPerfMeasurement, IPerfSummary, - // eslint-disable-next-line deprecation/deprecation IPoint, IPropsWithStyles, IRectangle, @@ -226,13 +215,10 @@ export type { IStyleFunctionOrObject, IVirtualElement, IWarnControlledUsageParams, - // eslint-disable-next-line deprecation/deprecation Omit, Point, RefObject, - // eslint-disable-next-line deprecation/deprecation Settings, - // eslint-disable-next-line deprecation/deprecation SettingsFunction, StyleFunction, } from '@fluentui/react/lib/Utilities'; 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 300ef5a45656be..d4411e51c3d674 100644 --- a/packages/charts/react-charting/src/components/AreaChart/AreaChart.base.tsx +++ b/packages/charts/react-charting/src/components/AreaChart/AreaChart.base.tsx @@ -64,7 +64,7 @@ export interface IAreaChartAreaPoint { values: IAreaChartDataSetPoint; } export interface IAreaChartDataSetPoint { - [key: string]: number | string; + [key: string]: number | string | number[]; } export interface IDPointType { values: { 0: number; 1: number; data: {} }; @@ -102,7 +102,7 @@ export class AreaChartBase extends React.Component { - const stackedValues = d3Stack().keys(keys)(dataSet); - const maxOfYVal = d3Max(stackedValues[stackedValues.length - 1], dp => dp[1])!; - const stackedData: Array = []; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - stackedValues.forEach((layer: any) => { - const currentStack: IAreaChartDataSetPoint[] = []; + private _getDataPoints = (keys: string[], dataSet: any) => { + const renderPoints: Array = []; + let maxOfYVal = 0; + + if (this.props.mode === 'tozeroy') { + keys.forEach((key, index) => { + const currentLayer: IAreaChartDataSetPoint[] = []; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + dataSet.forEach((d: any) => { + currentLayer.push({ + values: [0, d[key]], // Start from zero for "tozeroy" mode + xVal: d.xVal, + }); + if (d[key] > maxOfYVal) { + maxOfYVal = d[key]; + } + }); + renderPoints.push(currentLayer); + }); + } else { + const dataValues = d3Stack().keys(keys)(dataSet); + maxOfYVal = d3Max(dataValues[dataValues.length - 1], dp => dp[1])!; // eslint-disable-next-line @typescript-eslint/no-explicit-any - layer.forEach((d: any) => { - currentStack.push({ - values: d, - xVal: d.data.xVal, + dataValues.forEach((layer: any) => { + const currentLayer: IAreaChartDataSetPoint[] = []; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + layer.forEach((d: any) => { + currentLayer.push({ + values: d, + xVal: d.data.xVal, + }); }); + renderPoints.push(currentLayer); }); - stackedData.push(currentStack); - }); - this._isMultiStackChart = stackedData && stackedData.length > 1 ? true : false; + } + + this._isMultiStackChart = !!(this.props.legendProps?.selectedLegends + ? renderPoints?.length >= 1 + : renderPoints?.length > 1); return { - stackedData, + renderData: renderPoints, maxOfYVal, }; }; @@ -496,7 +518,7 @@ export class AreaChartBase extends React.Component, index: number) => { + this._data.forEach((singleStackedData: Array, index: number) => { + const layerOpacity = this.props.mode === 'tozeroy' ? 0.8 : this._opacity[index]; graph.push( {this.props.enableGradient && ( @@ -755,7 +778,7 @@ export class AreaChartBase extends React.Component, index: number) => { + this._data.forEach((singleStackedData: Array, index: number) => { if (points.length === index) { return; } @@ -804,7 +827,7 @@ export class AreaChartBase extends React.Component {singleStackedData.map((singlePoint: IDPointType, pointIndex: number) => { - const circleId = `${this._circleId}_${index * this._stackedData[0].length + pointIndex}`; + const circleId = `${this._circleId}_${index * this._data[0].length + pointIndex}`; const xDataPoint = singlePoint.xVal instanceof Date ? singlePoint.xVal.getTime() : singlePoint.xVal; lineColor = points[index]!.color!; const legend = points[index]!.legend; @@ -837,7 +860,7 @@ export class AreaChartBase extends React.Component { const xDataPoint = singlePoint.xVal instanceof Date ? singlePoint.xVal.getTime() : singlePoint.xVal; if (this.state.nearestCircleToHighlight === xDataPoint) { - const circleId = `${this._circleId}_${index * this._stackedData[0].length + pointIndex}`; + const circleId = `${this._circleId}_${index * this._data[0].length + pointIndex}`; lineColor = points[index]!.color!; const legend = points[index]!.legend; graph.push( diff --git a/packages/charts/react-charting/src/components/AreaChart/AreaChart.types.ts b/packages/charts/react-charting/src/components/AreaChart/AreaChart.types.ts index f0aa8a6e77eaf9..b0ff53bf52f3c5 100644 --- a/packages/charts/react-charting/src/components/AreaChart/AreaChart.types.ts +++ b/packages/charts/react-charting/src/components/AreaChart/AreaChart.types.ts @@ -70,6 +70,12 @@ export interface IAreaChartProps extends ICartesianChartProps { * The prop used to enable gradient fill color for the chart. */ enableGradient?: boolean; + + /** + * @default tonexty + * The prop used to define the Y axis mode (tonexty or tozeroy) + */ + mode?: 'tozeroy' | 'tonexty'; } /** diff --git a/packages/charts/react-charting/src/components/AreaChart/AreaChartRTL.test.tsx b/packages/charts/react-charting/src/components/AreaChart/AreaChartRTL.test.tsx index f054dd4a1ceb71..12977fac2432d6 100644 --- a/packages/charts/react-charting/src/components/AreaChart/AreaChartRTL.test.tsx +++ b/packages/charts/react-charting/src/components/AreaChart/AreaChartRTL.test.tsx @@ -512,6 +512,16 @@ describe('Area chart rendering', () => { expect(container).toMatchSnapshot(); }, ); + + testWithoutWait( + 'Should render the Area Chart with tozeroy mode', + AreaChart, + { data: chartData, mode: 'tozeroy' }, + container => { + //Asset + expect(container).toMatchSnapshot(); + }, + ); }); describe('Area chart - Subcomponent Area', () => { diff --git a/packages/charts/react-charting/src/components/AreaChart/__snapshots__/AreaChartRTL.test.tsx.snap b/packages/charts/react-charting/src/components/AreaChart/__snapshots__/AreaChartRTL.test.tsx.snap index 83e1e7b66fa1e9..d151a2c1ec4583 100644 --- a/packages/charts/react-charting/src/components/AreaChart/__snapshots__/AreaChartRTL.test.tsx.snap +++ b/packages/charts/react-charting/src/components/AreaChart/__snapshots__/AreaChartRTL.test.tsx.snap @@ -1142,6 +1142,1148 @@ exports[`Area chart rendering Should render the Area Chart with negative y value `; +exports[`Area chart rendering Should render the Area Chart with tozeroy mode 1`] = ` +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+`; + exports[`Area chart rendering Should render the Area chart with date x-axis data when tick Values given and tick format is %d 1`] = `
= DeclarativeChartProps >((props, forwardedRef) => { const { plotlySchema } = sanitizeJson(props.chartSchema); - const { data, layout } = plotlySchema; + const plotlyInput = plotlySchema as PlotlySchema; let { selectedLegends } = plotlySchema; - const xValues = data[0].x; - const isXDate = isDateArray(xValues); - const isXNumber = isNumberArray(xValues); - const isXMonth = isMonthArray(xValues); const colorMap = useColorMapping(); const theme = useTheme(); const isDarkTheme = theme?.isInverted ?? false; @@ -106,7 +105,7 @@ export const DeclarativeChart: React.FunctionComponent = const onActiveLegendsChange = (keys: string[]) => { setActiveLegends(keys); if (props.onSchemaChange) { - props.onSchemaChange({ plotlySchema: { data, layout, selectedLegends: keys } }); + props.onSchemaChange({ plotlySchema: { plotlyInput, selectedLegends: keys } }); } }; @@ -118,16 +117,69 @@ export const DeclarativeChart: React.FunctionComponent = setActiveLegends(selectedLegends ?? []); }, [props.chartSchema]); - const legendProps = { - canSelectMultipleLegends: false, + const multiSelectLegendProps = { + canSelectMultipleLegends: true, onChange: onActiveLegendsChange, - selectedLegend: activeLegends.slice(0, 1)[0], + selectedLegends: activeLegends, + }; + + const commonProps = { + legendProps: multiSelectLegendProps, + componentRef: chartRef, + calloutProps: { layerProps: { eventBubblingEnabled: true } }, + }; + + const checkAndRenderChart = ( + renderChartJsx: (chartProps: ILineChartProps | IAreaChartProps) => JSX.Element, + isAreaChart: boolean = false, + ) => { + let fallbackVSBC = false; + const xValues = (plotlyInput.data[0] as PlotData).x; + const isXDate = isDateArray(xValues); + const isXNumber = isNumberArray(xValues); + const isXMonth = isMonthArray(xValues); + if (isXDate || isXNumber) { + const chartProps: ILineChartProps | IAreaChartProps = { + ...transformPlotlyJsonToScatterChartProps( + { data: plotlyInput.data, layout: plotlyInput.layout }, + isAreaChart, + colorMap, + isDarkTheme, + ), + ...commonProps, + }; + return renderChartJsx(chartProps); + } else if (isXMonth) { + const updatedData = plotlyInput.data.map((dataPoint: PlotData) => ({ + ...dataPoint, + x: updateXValues(dataPoint.x), + })); + const chartProps: ILineChartProps | IAreaChartProps = { + ...transformPlotlyJsonToScatterChartProps( + { data: updatedData, layout: plotlyInput.layout }, + isAreaChart, + colorMap, + isDarkTheme, + ), + ...commonProps, + }; + return renderChartJsx(chartProps); + } + // Unsupported schema, render as VerticalStackedBarChart + fallbackVSBC = true; + return ( + + ); }; const exportAsImage = React.useCallback( (opts?: IImageExportOptions) => { return toImage(chartRef.current?.chartContainer, { background: theme.semanticColors.bodyBackground, + scale: 5, ...opts, }); }, @@ -142,146 +194,78 @@ export const DeclarativeChart: React.FunctionComponent = [exportAsImage], ); - const multiSelectLegendProps = { - ...legendProps, - canSelectMultipleLegends: true, - selectedLegends: activeLegends, - }; - - switch (data[0].type) { + switch (plotlyInput.data[0].type) { case 'pie': - return ( - - ); + return ; case 'bar': - const orientation = data[0].orientation; + const orientation = plotlyInput.data[0].orientation; if (orientation === 'h') { return ( ); } else { - if (['group', 'overlay'].includes(plotlySchema?.layout?.barmode)) { + const containsLines = plotlyInput.data.some( + series => series.type === 'scatter' || isLineData(series as Partial), + ); + if (['group', 'overlay'].includes(plotlySchema?.layout?.barmode) && !containsLines) { return ( ); } return ( ); } case 'scatter': - const isAreaChart = data.some((series: any) => series.fill === 'tonexty' || series.fill === 'tozeroy'); - const renderChart = (chartProps: any) => { + if (plotlyInput.data[0].mode === 'markers') { + throw new Error(`Unsupported chart - type :${plotlyInput.data[0]?.type}, mode: ${plotlyInput.data[0]?.mode}`); + } + const isAreaChart = plotlyInput.data.some( + (series: PlotData) => series.fill === 'tonexty' || series.fill === 'tozeroy', + ); + const renderChartJsx = (chartProps: ILineChartProps | IAreaChartProps) => { if (isAreaChart) { - return ( - - ); + return ; } - return ( - - ); + return ; }; - if (isXDate || isXNumber) { - const chartProps = { - ...transformPlotlyJsonToScatterChartProps({ data, layout }, isAreaChart, colorMap, isDarkTheme), - legendProps, - componentRef: chartRef, - calloutProps: { layerProps: { eventBubblingEnabled: true } }, - }; - return renderChart(chartProps); - } else if (isXMonth) { - const updatedData = data.map((dataPoint: any) => ({ - ...dataPoint, - x: updateXValues(dataPoint.x), - })); - const chartProps = { - ...transformPlotlyJsonToScatterChartProps({ data: updatedData, layout }, isAreaChart, colorMap, isDarkTheme), - legendProps, - componentRef: chartRef, - calloutProps: { layerProps: { eventBubblingEnabled: true } }, - }; - return renderChart(chartProps); - } - return ( - - ); + return checkAndRenderChart(renderChartJsx, isAreaChart); case 'heatmap': - return ( - - ); + return ; case 'sankey': return ( - + ); case 'indicator': - if (data?.[0]?.mode?.includes('gauge')) { + if (plotlyInput.data?.[0]?.mode?.includes('gauge')) { return ( - + ); } - return
Unsupported Schema
; + throw new Error(`Unsupported chart - type: ${plotlyInput.data[0]?.type}, mode: ${plotlyInput.data[0]?.mode}`); case 'histogram': return ( - + ); default: - throw new Error('Unsupported chart schema'); + const xValues = (plotlyInput.data[0] as PlotData).x; + const yValues = (plotlyInput.data[0] as PlotData).y; + if (xValues && yValues && xValues.length > 0 && yValues.length > 0) { + const renderLineChartJsx = (chartProps: ILineChartProps) => { + return ; + }; + return checkAndRenderChart(renderLineChartJsx); + } + throw new Error(`Unsupported chart type :${plotlyInput.data[0]?.type}`); } }); DeclarativeChart.displayName = 'DeclarativeChart'; diff --git a/packages/charts/react-charting/src/components/DeclarativeChart/DeclarativeChartRTL.test.tsx b/packages/charts/react-charting/src/components/DeclarativeChart/DeclarativeChartRTL.test.tsx index f796516f504e44..d9f0b23cb8efd7 100644 --- a/packages/charts/react-charting/src/components/DeclarativeChart/DeclarativeChartRTL.test.tsx +++ b/packages/charts/react-charting/src/components/DeclarativeChart/DeclarativeChartRTL.test.tsx @@ -30,7 +30,7 @@ describe('DeclarativeChart', () => { expect(container).toMatchSnapshot(); }); - test.skip('Should render gaugechart in DeclarativeChart', () => { + test('Should render gaugechart in DeclarativeChart', () => { // Arrange const plotlySchema = require('./tests/schema/fluent_gauge_test.json'); const { container } = render(); @@ -51,24 +51,38 @@ describe('DeclarativeChart', () => { expect(container).toMatchSnapshot(); }); - test.skip('Should render piechart in DeclarativeChart', () => { + test('Should render piechart in DeclarativeChart', () => { // Arrange const plotlySchema = require('./tests/schema/fluent_pie_test.json'); const { container } = render(); expect(container).toMatchSnapshot(); }); - test.skip('Should render sankeychart in DeclarativeChart', () => { + test('Should render sankeychart in DeclarativeChart', () => { // Arrange const plotlySchema = require('./tests/schema/fluent_sankey_test.json'); const { container } = render(); expect(container).toMatchSnapshot(); }); - test('Should render verticalbarchart in DeclarativeChart', () => { + test.skip('Should render verticalbarchart in DeclarativeChart', () => { // Arrange const plotlySchema = require('./tests/schema/fluent_verticalbar_test.json'); const { container } = render(); expect(container).toMatchSnapshot(); }); + + test.skip('Should render histogram chart in DeclarativeChart', () => { + // Arrange + const plotlySchema = require('./tests/schema/fluent_verticalbar_histogram_test.json'); + const { container } = render(); + expect(container).toMatchSnapshot(); + }); + + test.skip('Should render horizontalbar chart in DeclarativeChart', () => { + // Arrange + const plotlySchema = require('./tests/schema/fluent_horizontalbar_test.json'); + const { container } = render(); + expect(container).toMatchSnapshot(); + }); }); diff --git a/packages/charts/react-charting/src/components/DeclarativeChart/PlotlySchema.ts b/packages/charts/react-charting/src/components/DeclarativeChart/PlotlySchema.ts new file mode 100644 index 00000000000000..e1ac07356818d2 --- /dev/null +++ b/packages/charts/react-charting/src/components/DeclarativeChart/PlotlySchema.ts @@ -0,0 +1,1937 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +/** + * This interface is extracted from Plotly.js typescript definitions. + * All the unsupported types are removed to align with fluent charts. + * https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/plotly.js/index.d.ts + */ + +export type PieColor = string | number; +export type PieColors = Array; + +export interface PieFont { + family: string | string[]; + size: number | number[]; + color: PieColor | PieColors; +} + +export interface PieDataTitle extends Pick { + font: Partial; +} + +export type PieTextPosition = 'inside' | 'outside' | 'auto' | 'none'; + +export type PieHoverInfo = + | 'all' + | 'none' + | 'skip' + | 'label' + | 'text' + | 'value' + | 'percent' + | 'name' + | 'label+text' + | 'label+value' + | 'label+percent' + | 'label+name' + | 'text+value' + | 'text+percent' + | 'text+name' + | 'value+percent' + | 'value+name' + | 'percent+name' + | 'label+text+value' + | 'label+text+percent' + | 'label+text+name' + | 'label+value+percent' + | 'label+value+name' + | 'label+percent+name' + | 'text+value+percent' + | 'text+value+name' + | 'text+percent+name' + | 'value+percent+name' + | 'label+text+value+percent' + | 'label+text+value+name' + | 'label+text+percent+name' + | 'label+value+percent+name' + | 'text+value+percent+name'; + +export interface PieDomain { + x: number[]; + y: number[]; + row: number; + column: number; +} + +export interface PieLine { + color: PieColor | PieColors; + width: number | number[]; +} + +export interface PieMarker { + colors: PieColors; + line: Partial; +} + +export interface PieHoverLabel { + bgcolor: PieColor | PieColors; + bordercolor: PieColor | PieColors; + font: PieFont; + align: HoverLabel['align'] | Array; + namelength: number | number[]; +} + +export type PieInsideTextOrientation = 'horizontal' | 'radial' | 'tangential' | 'auto'; + +export interface PieData + extends Pick< + PlotData, + | 'name' + | 'visible' + | 'showlegend' + | 'legendgroup' + | 'opacity' + | 'ids' + | 'labels' + | 'hovertext' + | 'automargin' + | 'textinfo' + | 'direction' + | 'hole' + | 'rotation' + > { + type: 'pie'; + title: Partial; + values: Array; + dlabel: number; + label0: number; + pull: number | number[]; + text: Datum | Datum[]; + textposition: PieTextPosition | PieTextPosition[]; + texttemplate: string | string[]; + hoverinfo: PieHoverInfo; + hovertemplate: string | string[]; + meta: number | string; + customdata: Datum[]; + domain: Partial; + marker: Partial; + textfont: PieFont; + hoverlabel: Partial; + insidetextfont: PieFont; + insidetextorientation: PieInsideTextOrientation; + outsidetextfont: PieFont; + scalegroup: string; + sort: boolean; + uirevision: number | string; +} + +export type SankeyColor = string | number; +export type SankeyColors = Array; + +export interface SankeyFont { + family: string | string[]; + size: number | number[]; + color: SankeyColor | SankeyColors; +} + +export interface SankeyDataTitle { + font: Partial; + title: string; +} + +export type SankeyOrientation = 'v' | 'h'; + +export interface SankeyHoverLabel { + bgcolor: SankeyColor | SankeyColors; + bordercolor: SankeyColor | SankeyColors; + font: SankeyFont; + align: HoverLabel['align'] | Array; + namelength: number | number[]; +} + +export interface SankeyDomain { + row: number; + column: number; + x: number[]; + y: number[]; +} + +export interface SankeyNode { + color: SankeyColor[]; + customdata: Datum[]; + groups: SankeyNode[]; + hoverinfo: 'all' | 'none' | 'skip'; + hoverlabel: Partial; + hovertemplate: string | string[]; + label: Datum[]; + line: Partial<{ + color: SankeyColor; + width: number; + }>; + pad: number; + thickness: number; + x: number[]; + y: number[]; +} + +export interface SankeyColorscale { + cmax: number; + cmin: number; + colorscale: Array<[number, string]>; + label: string; + name: string; + templateitemname: string; +} + +export interface SankeyLink { + arrowlen: number; + color: SankeyColor | SankeyColor[]; + colorscale: Partial; + customdata: Datum[]; + hoverinfo: 'all' | 'none' | 'skip'; + hoverlabel: Partial; + hovertemplate: string | string[]; + hovercolor: SankeyColor | SankeyColor[]; + label: Datum[]; + line: Partial<{ + color: SankeyColor; + width: number; + }>; + source: number[]; + target: number[]; + value: number[]; +} + +export interface SankeyData { + type: 'sankey'; + name: string; + orientation: SankeyOrientation; + visible: boolean | 'legendonly'; + legend: string; + legendrank: number; + legendgrouptitle: Partial; + legendwidth: number; + ids: string[]; + hoverinfo: string; + meta: number | string; + customdata: Datum[]; + domain: Partial; + node: Partial; + link: Partial; + textfont: Partial; + selectpoints: string | number; + arrangement: 'snap' | 'perpendicular' | 'freeform' | 'fixed'; + hoverlabel: Partial; + valueformat: string; + valuesuffix: string; + uirevision: string | number; +} + +export interface Point { + x: number; + y: number; + z: number; +} + +export interface PlotScatterDataPoint { + curveNumber: number; + data: PlotData; + pointIndex: number; + pointNumber: number; + x: number; + xaxis: LayoutAxis; + y: number; + yaxis: LayoutAxis; +} + +export interface PlotDatum { + curveNumber: number; + data: PlotData; + customdata: Datum; + pointIndex: number; + pointNumber: number; + x: Datum; + xaxis: LayoutAxis; + y: Datum; + yaxis: LayoutAxis; + text: string; +} + +export interface PlotCoordinate { + x: number; + y: number; + pointNumber: number; +} + +export interface SelectionRange { + x: number[]; + y: number[]; +} + +export type PlotSelectedData = Partial; + +export interface PlotScene { + center: Point; + eye: Point; + up: Point; +} + +export interface PolarLayout { + domain: Partial; + sector: number[]; + hole: number; + bgcolor: Color; + radialaxis: Partial; + angularaxis: Partial; + gridshape: 'circular' | 'linear'; + uirevision: string | number; + uid: string; +} + +export interface PlotlySchema { + data: Data[]; + layout?: Partial; + config?: Partial; +} + +// Layout +export interface Layout { + colorway: string[]; + title: + | string + | Partial<{ + text: string; + font: Partial; + xref: 'container' | 'paper'; + yref: 'container' | 'paper'; + x: number; + y: number; + xanchor: 'auto' | 'left' | 'center' | 'right'; + yanchor: 'auto' | 'top' | 'middle' | 'bottom'; + pad: Partial; + }>; + titlefont: Partial; + autosize: boolean; + showlegend: boolean; + paper_bgcolor: Color; + plot_bgcolor: Color; + separators: string; + hidesources: boolean; + xaxis: Partial; + xaxis2: Partial; + xaxis3: Partial; + xaxis4: Partial; + xaxis5: Partial; + xaxis6: Partial; + xaxis7: Partial; + xaxis8: Partial; + xaxis9: Partial; + yaxis: Partial; + yaxis2: Partial; + yaxis3: Partial; + yaxis4: Partial; + yaxis5: Partial; + yaxis6: Partial; + yaxis7: Partial; + yaxis8: Partial; + yaxis9: Partial; + margin: Partial; + height: number; + width: number; + hovermode: 'closest' | 'x' | 'y' | 'x unified' | 'y unified' | false; + hoverdistance: number; + hoverlabel: Partial; + calendar: Calendar; + 'xaxis.range': [Datum, Datum]; + 'xaxis.range[0]': Datum; + 'xaxis.range[1]': Datum; + 'yaxis.range': [Datum, Datum]; + 'yaxis.range[0]': Datum; + 'yaxis.range[1]': Datum; + 'yaxis.type': AxisType; + 'xaxis.type': AxisType; + 'xaxis.autorange': boolean; + 'yaxis.autorange': boolean; + 'xaxis.title': string; + 'yaxis.title': string; + ternary: any; + geo: any; + mapbox: any; + subplot: string; + radialaxis: Partial; + angularaxis: {}; + dragmode: + | 'zoom' + | 'pan' + | 'select' + | 'lasso' + | 'drawclosedpath' + | 'drawopenpath' + | 'drawline' + | 'drawrect' + | 'drawcircle' + | 'orbit' + | 'turntable' + | false; + orientation: number; + annotations: Array>; + shapes: Array>; + legend: Partial; + font: Partial; + barmode: 'stack' | 'group' | 'overlay' | 'relative'; + barnorm: '' | 'fraction' | 'percent'; + bargap: number; + bargroupgap: number; + boxmode: 'group' | 'overlay'; + selectdirection: 'h' | 'v' | 'd' | 'any'; + hiddenlabels: string[]; + grid: Partial<{ + rows: number; + roworder: 'top to bottom' | 'bottom to top'; + columns: number; + subplots: string[]; + xaxes: string[]; + yaxes: string[]; + pattern: 'independent' | 'coupled'; + xgap: number; + ygap: number; + domain: Partial<{ + x: number[]; + y: number[]; + }>; + xside: 'bottom' | 'bottom plot' | 'top plot' | 'top'; + yside: 'left' | 'left plot' | 'right plot' | 'right'; + }>; + polar: Partial; + polar2: Partial; + polar3: Partial; + polar4: Partial; + polar5: Partial; + polar6: Partial; + polar7: Partial; + polar8: Partial; + polar9: Partial; + template: Template; + clickmode: 'event' | 'select' | 'event+select' | 'none'; + uirevision: number | string; + uid: string; + datarevision: number | string; + editrevision: number | string; + selectionrevision: number | string; +} + +export interface Legend extends Label { + borderwidth: number; + groupclick: 'toggleitem' | 'togglegroup'; + grouptitlefont: Partial; + itemclick: 'toggle' | 'toggleothers' | false; + itemdoubleclick: 'toggle' | 'toggleothers' | false; + itemsizing: 'trace' | 'constant'; + itemwidth: number; + orientation: 'v' | 'h'; + title: Partial; + tracegroupgap: number; + traceorder: 'grouped' | 'normal' | 'reversed' | 'reversed+grouped'; + uirevision: number | string; + uid: string; + valign: 'top' | 'middle' | 'bottom'; + x: number; + xanchor: 'auto' | 'left' | 'center' | 'right'; + xref: 'container' | 'paper'; + y: number; + yanchor: 'auto' | 'top' | 'middle' | 'bottom'; + yref: 'container' | 'paper'; +} + +export type AxisType = '-' | 'linear' | 'log' | 'date' | 'category' | 'multicategory'; + +export type DTickValue = number | string; + +export interface TickFormatStop { + /** + * Determines whether or not this stop is used. If `false`, + * this stop is ignored even within its `dtickrange`. + */ + enabled: boolean; + /** + * Range [`min`, `max`], where `min`, `max` - dtick values + * which describe some zoom level, it is possible to omit `min` or `max` + * value by passing `null` + */ + dtickrange: [DTickValue | null, DTickValue | null]; + /** + * dtickformat for described zoom level, the same as `tickformat` + */ + value: string; + /** + * When used in a template, named items are created in the output figure + * in addition to any items the figure already has in this array. + * You can modify these items in the output figure by making + * your own item with `templateitemname` matching this `name` + * alongside your modifications (including `visible: false` or `enabled: false` to hide it). + * Has no effect outside of a template. + */ + name: string; + /** + * Used to refer to a named item in this array in the template. + * Named items from the template will be created even without + * a matching item in the input figure, but you can modify one by + * making an item with `templateitemname` matching its `name`, + * alongside your modifications (including `visible: false` or `enabled: false` to hide it). + * If there is no template or no matching item, this item will be hidden + * unless you explicitly show it with `visible: true`. + */ + templateitemname: string; +} + +export interface AutoRangeOptions { + clipmax: DTickValue; + clipmin: DTickValue; + include: DTickValue; + maxallowed: DTickValue; + minallowed: DTickValue; +} + +export interface MinorAxisLayout { + dtick: DTickValue; + gridcolor: Color; + griddash: Dash; + gridwidth: number; + nticks: number; + showgrid: boolean; + tick0: DTickValue; + tickcolor: Color; + ticklen: number; + tickmode: 'auto' | 'linear' | 'array'; + ticks: 'outside' | 'inside' | ''; + tickvals: any[]; + tickwidth: number; +} + +export interface RangeBreak { + bounds: any[]; + dvalue: number; + enabled: boolean; + name: string; + pattern: 'day of week' | 'hour' | ''; + templateitemname: string; + values: any[]; +} + +export interface Axis { + /** + * A single toggle to hide the axis while preserving interaction like dragging. + * Default is true when a cheater plot is present on the axis, otherwise + * false + */ + visible: boolean; + /** + * Sets default for all colors associated with this axis + * all at once: line, font, tick, and grid colors. + * Grid color is lightened by blending this with the plot background + * Individual pieces can override this. + */ + color: Color; + title: string | Partial; + /** + * Former `titlefont` is now the sub-attribute `font` of `title`. + * To customize title font properties, please use `title.font` now. + */ + titlefont: Partial; + type: AxisType; + autorange: true | false | 'reversed' | 'min reversed' | 'max reversed' | 'min' | 'max'; + autorangeoptions: Partial; + /** + * 'If *normal*, the range is computed in relation to the extrema + * of the input data. + * If *tozero*`, the range extends to 0, + * regardless of the input data + * If *nonnegative*, the range is non-negative, + * regardless of the input data. + * Applies only to linear axes. + */ + rangemode: 'normal' | 'tozero' | 'nonnegative'; + range: any[]; + /** + * Determines whether or not this axis is zoom-able. + * If true, then zoom is disabled. + */ + fixedrange: boolean; + + /** + * Ticks + */ + tickmode: 'auto' | 'linear' | 'array'; + nticks: number; + tick0: number | string; + dtick: DTickValue; + tickvals: any[]; + ticktext: string[]; + ticks: 'outside' | 'inside' | ''; + mirror: true | 'ticks' | false | 'all' | 'allticks'; + ticklen: number; + tickwidth: number; + tickcolor: Color; + showticklabels: boolean; + showspikes: boolean; + spikecolor: Color; + spikethickness: number; + /** + * Specifies the ordering logic for the case of categorical variables. + * By default, plotly uses *trace*, which specifies the order that is present in the data supplied. + * Set `categoryorder` to *category ascending* or *category descending* if order should be determined by + * the alphanumerical order of the category names. + * Set `categoryorder` to *array* to derive the ordering from the attribute `categoryarray`. If a category + * is not found in the `categoryarray` array, the sorting behavior for that attribute will be identical to + * the *trace* mode. The unspecified categories will follow the categories in `categoryarray`. + * Set `categoryorder` to *total ascending* or *total descending* if order should be determined by the + * numerical order of the values. + * Similarly, the order can be determined by the min, max, sum, mean or median of all the values. + */ + categoryorder: + | 'trace' + | 'category ascending' + | 'category descending' + | 'array' + | 'total ascending' + | 'total descending' + | 'min ascending' + | 'min descending' + | 'max ascending' + | 'max descending' + | 'sum ascending' + | 'sum descending' + | 'mean ascending' + | 'mean descending' + | 'median ascending' + | 'median descending'; + categoryarray: any[]; + tickfont: Partial; + tickangle: 'auto' | number; + tickprefix: string; + /** + * If `all`, all tick labels are displayed with a prefix. + * If `first`, only the first tick is displayed with a prefix. + * If `last`, only the last tick is displayed with a suffix. + * If `none`, tick prefixes are hidden. + */ + showtickprefix: 'all' | 'first' | 'last' | 'none'; + /** + * Sets a tick label suffix. + */ + ticksuffix: string; + /** + * Same as `showtickprefix` but for tick suffixes. + */ + showticksuffix: 'all' | 'first' | 'last' | 'none'; + /** + * If `all`, all exponents are shown besides their significands. + * If `first`, only the exponent of the first tick is shown. + * If `last`, only the exponent of the last tick is shown. + * If `none`, no exponents appear. + */ + showexponent: 'all' | 'first' | 'last' | 'none'; + /** + * Determines a formatting rule for the tick exponents. + * For example, consider the number 1,000,000,000. + * If `none`, it appears as *1,000,000,000*. + * If `e`, *1e+9*. + * If `E`, *1E+9*. + * If `power`, *1x10^9* (with 9 in a super script). + * If `SI`, *1G*. + * If `B`, *1B*. + */ + exponentformat: 'none' | 'e' | 'E' | 'power' | 'SI' | 'B'; + /** + * Hide SI prefix for 10^n if |n| is below this number. This only has an effect when `tickformat` is "SI" or "B". + */ + minexponent: number; + /** + * 'If `true`, even 4-digit integers are separated + */ + separatethousands: boolean; + /** + * Sets the tick label formatting rule using d3 formatting mini-languages + * which are very similar to those in Python. + * For numbers, see: https://github.com/d3/d3-3.x-api-reference/blob/master/Formatting.md#d3_format + * And for dates see: https://github.com/d3/d3-3.x-api-reference/blob/master/Time-Formatting.md#format + * We add one item to d3's date formatter: `%{n}f` for fractional seconds with n digits. + * For example, `"2016-10-13 09:15:23.456"` with tickformat `"%H~%M~%S.%2f"` would display `"09~15~23.46"` + */ + tickformat: string; + /** + * Sets the hover text formatting rule using d3 formatting mini-languages + * which are very similar to those in Python. + * For numbers, see: https://github.com/d3/d3-3.x-api-reference/blob/master/Formatting.md#d3_format + * And for dates see: https://github.com/d3/d3-3.x-api-reference/blob/master/Time-Formatting.md#format + * We add one item to d3's date formatter: `%{n}f` for fractional seconds with n digits. + * For example, `"2016-10-13 09:15:23.456"` with tickformat `"%H~%M~%S.%2f"` would display "09~15~23.46" + */ + hoverformat: string; + calendar: Calendar; + /** + * Array of `Partial` objects. + */ + tickformatstops: Array>; + spikedash: string; + /** + * Determines the drawing mode for the spike line. + * If `toaxis`, the line is drawn from the data point to the axis the + * series is plotted on. + * If `across`, the line is drawn across the entire plot area, and + * supercedes *toaxis*. + * If `marker`, then a marker dot is drawn on the axis the series is + * plotted on + */ + spikemode: + | 'toaxis' + | 'across' + | 'marker' + | 'toaxis+across' + | 'toaxis+across+marker' + | 'across+marker' + | 'toaxis+marker'; + /** + * Determines whether spikelines are stuck to the cursor or to the closest datapoints. + */ + spikesnap: 'data' | 'cursor' | 'hovered data'; + + /** + * Lines and Grids + */ + + /** + * Determines whether or not a line bounding this axis is drawn. + */ + showline: boolean; + /** + * Sets the axis line color + */ + linecolor: Color; + /** + * Sets the width (in px) of the axis line. + */ + linewidth: number; + /** + * Determines whether or not grid lines are drawn. + * If `true`, the grid lines are drawn at every tick mark. + */ + showgrid: boolean; + /** + * Sets the color of the grid lines. + */ + gridcolor: Color; + /** + * Sets the width (in px) of the grid lines. + */ + gridwidth: number; + /** + * Determines whether or not a line is drawn at along the 0 value + * of this axis. + * If `true`, the zero line is drawn on top of the grid lines. + */ + zeroline: boolean; + /** + * Sets the line color of the zero line. + */ + zerolinecolor: Color; + /** + * Sets the width (in px) of the zero line. + */ + zerolinewidth: number; + /** + * Determines whether or not a dividers are drawn + * between the category levels of this axis. + * Only has an effect on *multicategory* axes. + */ + showdividers: boolean; + /** + * Sets the color of the dividers + * Only has an effect on *multicategory* axes. + */ + dividercolor: Color; + /** + * Sets the width (in px) of the dividers + * Only has an effect on *multicategory* axes. + */ + dividerwidth: number; + + autotypenumbers: 'convert types' | 'strict'; + labelalias: DTickValue; + maxallowed: DTickValue; + minallowed: DTickValue; +} + +export type Calendar = + | 'gregorian' + | 'chinese' + | 'coptic' + | 'discworld' + | 'ethiopian' + | 'hebrew' + | 'islamic' + | 'julian' + | 'mayan' + | 'nanakshahi' + | 'nepali' + | 'persian' + | 'jalali' + | 'taiwan' + | 'thai' + | 'ummalqura'; + +// regex from documentation: "/^x([2-9]|[1-9][0-9]+)?( domain)?$/" | "/^y([2-9]|[1-9][0-9]+)?( domain)?$/" +// regex allows for an unlimited amount of digits for the 'axis number', +// but the following typescript definition is limited to two digits +type xYAxisNames = `${ + | '' + | `${2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}` + | `${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}${0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}`}${'' | ' domain'}`; + +export type XAxisName = `x${xYAxisNames}`; +export type YAxisName = `y${xYAxisNames}`; + +export type AxisName = XAxisName | YAxisName; + +export interface LayoutAxis extends Axis { + fixedrange: boolean; + scaleanchor: AxisName; + scaleratio: number; + constrain: 'range' | 'domain'; + constraintoward: 'left' | 'center' | 'right' | 'top' | 'middle' | 'bottom'; + anchor: 'free' | AxisName; + side: 'top' | 'bottom' | 'left' | 'right' | 'clockwise' | 'counterclockwise'; + overlaying: 'free' | AxisName; + layer: 'above traces' | 'below traces'; + domain: number[]; + position: number; + rotation: number; + direction: 'counterclockwise' | 'clockwise'; + rangeslider: Partial; + rangeselector: Partial; + automargin: boolean; + autotick: boolean; + angle: any; + griddash: Dash; + l2p: (v: Datum) => number; + + autotickangles: number[]; + insiderange: any[]; + matches: AxisName; + minor: Partial; + rangebreaks: Array>; + ticklabelmode: 'instant' | 'period'; + ticklabeloverflow: 'allow' | 'hide past div' | 'hide past domain'; + ticklabelposition: + | 'outside' + | 'inside' + | 'outside top' + | 'inside top' + | 'outside left' + | 'inside left' + | 'outside right' + | 'inside right' + | 'outside bottom' + | 'inside bottom'; + ticklabelstep: number; + tickson: 'labels' | 'boundaries'; + uirevision: DTickValue; +} + +export interface SceneAxis extends Axis { + spikesides: boolean; + showbackground: boolean; + backgroundcolor: Color; + showaxeslabels: boolean; +} + +export interface ShapeLine { + color: string; + width: number; + dash: Dash; +} + +export interface ShapeLabel { + font: Partial; + padding: number; + text: string; + textangle: 'auto' | number; + textposition: + | 'top left' + | 'top center' + | 'top right' + | 'middle left' + | 'middle center' + | 'middle right' + | 'bottom left' + | 'bottom center' + | 'bottom right' + | 'start' + | 'middle' + | 'end'; + texttemplate: string; + xanchor: 'auto' | 'left' | 'center' | 'right'; + yanchor: 'top' | 'middle' | 'bottom'; +} + +export interface Shape { + visible: boolean | 'legendonly'; + layer: 'below' | 'above'; + type: 'rect' | 'circle' | 'line' | 'path'; + path: string; + xref: 'paper' | XAxisName; + xsizemode: 'scaled' | 'pixel'; + xanchor: number | string; + yref: 'paper' | YAxisName; + ysizemode: 'scaled' | 'pixel'; + yanchor: number | string; + x0: Datum; + y0: Datum; + x1: Datum; + y1: Datum; + fillcolor: string; + name: string; + templateitemname: string; + opacity: number; + line: Partial; + label: Partial; + showlegend: boolean; + legendgroup: string; + legendgrouptitle: { + text: string; + font?: Partial; + }; + legendrank: number; +} + +export interface Margin { + t: number; + b: number; + l: number; + r: number; + pad: number; +} + +export interface Icon { + height?: number | undefined; + width?: number | undefined; + ascent?: number | undefined; + descent?: number | undefined; + name?: string | undefined; + path?: string | undefined; + svg?: string | undefined; + transform?: string | undefined; +} + +export interface GaugeLine { + color: Color; + width: number; +} +export interface Threshold { + line: Partial; + value: number; + thickness: number; +} + +export interface GaugeBar { + color: Color; + line: Partial; + thickness: number; +} +export interface Gauge { + shape: 'angular' | 'bullet'; + bar: Partial; + bgcolor: Color; + bordercolor: Color; + borderwidth: number; + axis: Partial; + steps: Array<{ range: number[]; color: Color }>; + threshold: Partial; +} + +export interface Delta { + reference: number; + position: 'top' | 'bottom' | 'left' | 'right'; + relative: boolean; + valueformat: string; + increasing: { + symbol: string; + color: Color; + }; + decreasing: { + symbol: string; + color: Color; + }; +} + +export interface DataTitle { + text: string; + font: Partial; + standoff: number; + position: + | 'top left' + | 'top center' + | 'top right' + | 'middle center' + | 'bottom left' + | 'bottom center' + | 'bottom right'; +} + +export interface PlotNumber { + valueformat: string; + font: Partial; + prefix: string; + suffix: string; +} + +export interface Template { + data?: { [type in PlotType]?: Array> } | undefined; + layout?: Partial | undefined; +} + +// Data + +export type Datum = string | number | Date | null; +export type TypedArray = + | Int8Array + | Uint8Array + | Int16Array + | Uint16Array + | Int32Array + | Uint32Array + | Uint8ClampedArray + | Float32Array + | Float64Array; + +export interface ErrorOptions { + visible: boolean; + symmetric: boolean; + color: Color; + thickness: number; + width: number; + opacity: number; +} + +export type ErrorBar = Partial & + ( + | { + type: 'constant' | 'percent'; + value: number; + valueminus?: number | undefined; + } + | { + type: 'data'; + array: Datum[]; + arrayminus?: Datum[] | undefined; + } + ); + +export type Dash = 'solid' | 'dot' | 'dash' | 'longdash' | 'dashdot' | 'longdashdot'; +export type PlotType = + | 'bar' + | 'barpolar' + | 'box' + | 'candlestick' + | 'carpet' + | 'choropleth' + | 'choroplethmapbox' + | 'cone' + | 'contour' + | 'contourcarpet' + | 'densitymapbox' + | 'funnel' + | 'funnelarea' + | 'heatmap' + | 'heatmapgl' + | 'histogram' + | 'histogram2d' + | 'histogram2dcontour' + | 'image' + | 'indicator' + | 'isosurface' + | 'mesh3d' + | 'ohlc' + | 'parcats' + | 'parcoords' + | 'pie' + | 'pointcloud' + | 'sankey' + | 'scatter' + | 'scatter3d' + | 'scattercarpet' + | 'scattergeo' + | 'scattergl' + | 'scattermapbox' + | 'scatterpolar' + | 'scatterpolargl' + | 'scatterternary' + | 'splom' + | 'streamtube' + | 'sunburst' + | 'surface' + | 'table' + | 'treemap' + | 'violin' + | 'volume' + | 'waterfall'; + +export type Data = Partial | Partial | Partial; + +export type Color = + | string + | number + | Array + | Array>; +export type ColorScale = string | string[] | Array<[number, string]>; +export type DataTransform = Partial; +export type ScatterData = PlotData; + +// Bar Scatter +export interface PlotData { + type: PlotType; + x: Datum[] | Datum[][] | TypedArray; + y: Datum[] | Datum[][] | TypedArray; + z: Datum[] | Datum[][] | Datum[][][] | TypedArray; + i: TypedArray; + j: TypedArray; + k: TypedArray; + xy: Float32Array; + error_x: ErrorBar; + error_y: ErrorBar; + xaxis: string; + yaxis: string; + text: string | string[]; + lat: Datum[]; + lon: Datum[]; + line: Partial; + 'line.color': Color; + 'line.width': number; + 'line.dash': Dash; + 'line.shape': 'linear' | 'spline' | 'hv' | 'vh' | 'hvh' | 'vhv'; + 'line.smoothing': number; + 'line.simplify': boolean; + marker: Partial; + 'marker.symbol': MarkerSymbol | MarkerSymbol[]; + 'marker.color': Color; + 'marker.colorscale': ColorScale | ColorScale[]; + 'marker.opacity': number | number[]; + 'marker.size': number | number[] | number[][]; + 'marker.maxdisplayed': number; + 'marker.sizeref': number; + 'marker.sizemax': number; + 'marker.sizemin': number; + 'marker.sizemode': 'diameter' | 'area'; + 'marker.showscale': boolean; + 'marker.line': Partial; + 'marker.line.color': Color; + 'marker.line.colorscale': ColorScale | ColorScale[]; + 'marker.colorbar': {}; // TODO + 'marker.pad.t': number; + 'marker.pad.b': number; + 'marker.pad.l': number; + 'marker.pad.r': number; + mode: + | 'lines' + | 'markers' + | 'text' + | 'lines+markers' + | 'text+markers' + | 'text+lines' + | 'text+lines+markers' + | 'none' + | 'gauge' + | 'number' + | 'delta' + | 'number+delta' + | 'gauge+number' + | 'gauge+number+delta' + | 'gauge+delta'; + histfunc: 'count' | 'sum' | 'avg' | 'min' | 'max'; + histnorm: '' | 'percent' | 'probability' | 'density' | 'probability density'; + hoveron: 'points' | 'fills'; + hoverinfo: + | 'all' + | 'name' + | 'none' + | 'skip' + | 'text' + | 'x' + | 'x+text' + | 'x+name' + | 'x+y' + | 'x+y+text' + | 'x+y+name' + | 'x+y+z' + | 'x+y+z+text' + | 'x+y+z+name' + | 'y' + | 'y+name' + | 'y+x' + | 'y+text' + | 'y+x+text' + | 'y+x+name' + | 'y+z' + | 'y+z+text' + | 'y+z+name' + | 'y+x+z' + | 'y+x+z+text' + | 'y+x+z+name' + | 'z' + | 'z+x' + | 'z+x+text' + | 'z+x+name' + | 'z+y+x' + | 'z+y+x+text' + | 'z+y+x+name' + | 'z+x+y' + | 'z+x+y+text' + | 'z+x+y+name'; + hoverlabel: Partial; + hovertemplate: string | string[]; + hovertext: string | string[]; + hoverongaps: boolean; + xhoverformat: string; + yhoverformat: string; + zhoverformat: string; + texttemplate: string | string[]; + textinfo: + | 'label' + | 'label+text' + | 'label+value' + | 'label+percent' + | 'label+text+value' + | 'label+text+percent' + | 'label+value+percent' + | 'text' + | 'text+value' + | 'text+percent' + | 'text+value+percent' + | 'value' + | 'value+percent' + | 'percent' + | 'none'; + textposition: + | 'top left' + | 'top center' + | 'top right' + | 'middle left' + | 'middle center' + | 'middle right' + | 'bottom left' + | 'bottom center' + | 'bottom right' + | 'inside' + | 'outside' + | 'auto' + | 'none'; + textfont: Partial; + textangle: 'auto' | number; + insidetextanchor: 'end' | 'middle' | 'start'; + constraintext: 'inside' | 'outside' | 'both' | 'none'; + fill: 'none' | 'tozeroy' | 'tozerox' | 'tonexty' | 'tonextx' | 'toself' | 'tonext'; + fillcolor: string; + fillpattern: Partial; + showlegend: boolean; + legendgroup: string; + legendgrouptitle: { + text: string; + font?: Partial; + }; + legendrank: number; + parents: string[]; + name: string; + stackgroup: string; + groupnorm: '' | 'fraction' | 'percent'; + stackgaps: 'infer zero' | 'interpolate'; + connectgaps: boolean; + visible: boolean | 'legendonly'; + delta: Partial; + gauge: Partial; + number: Partial; + transforms: DataTransform[]; + orientation: 'v' | 'h'; + width: number | number[]; + boxmean: boolean | 'sd'; + boxpoints: 'all' | 'outliers' | 'suspectedoutliers' | false; + jitter: number; + pointpos: number; + opacity: number; + showscale: boolean; + colorscale: ColorScale; + zsmooth: 'fast' | 'best' | false; + zmin: number; + zmax: number; + ygap: number; + xgap: number; + transpose: boolean; + autobinx: boolean; + xbins: { + start: number | string; + end: number | string; + size: number | string; + }; + value: number; + values: Datum[]; + labels: Datum[]; + direction: 'clockwise' | 'counterclockwise'; + hole: number; + rotation: number; + theta: Datum[]; + r: Datum[]; + customdata: Datum[] | Datum[][]; + selectedpoints: Datum[]; + domain: Partial<{ + row: number; + column: number; + x: number[]; + y: number[]; + }>; + title: Partial; + branchvalues: 'total' | 'remainder'; + ids: string[]; + level: string; + cliponaxis: boolean; + automargin: boolean; + locationmode: 'ISO-3' | 'USA-states' | 'country names' | 'geojson-id'; + locations: Datum[]; + reversescale: boolean; + colorbar: Partial; + offset: number | number[]; + contours: Partial<{ + coloring: 'fill' | 'heatmap' | 'lines' | 'none'; + end: number; + labelfont: Partial; + labelformat: string; + operation: '=' | '<' | '>=' | '>' | '<=' | '[]' | '()' | '[)' | '(]' | '][' | ')(' | '](' | ')['; + showlabels: boolean; + showlines: boolean; + size: number; + start: number; + type: 'levels' | 'constraint'; + value: number | [lowerBound: number, upperBound: number]; + }>; + autocontour: boolean; + ncontours: number; + uirevision: string | number; + uid: string; +} + +/** + * These interfaces are based on attribute descriptions in + * https://github.com/plotly/plotly.js/tree/9d6144304308fc3007f0facf2535d38ea3e9b26c/src/transforms + */ +export interface TransformStyle { + target: number | string | number[] | string[]; + value: Partial; +} + +export interface TransformAggregation { + target: string; + func?: 'count' | 'sum' | 'avg' | 'median' | 'mode' | 'rms' | 'stddev' | 'min' | 'max' | 'first' | 'last' | undefined; + funcmode?: 'sample' | 'population' | undefined; + enabled?: boolean | undefined; +} + +export interface Transform { + type: 'aggregate' | 'filter' | 'groupby' | 'sort'; + enabled: boolean; + target: number | string | number[] | string[]; + operation: string; + aggregations: TransformAggregation[]; + preservegaps: boolean; + groups: string | number[] | string[]; + nameformat: string; + styles: TransformStyle[]; + value: any; + order: 'ascending' | 'descending'; +} + +export interface ColorBar { + thicknessmode: 'fraction' | 'pixels'; + thickness: number; + lenmode: 'fraction' | 'pixels'; + len: number; + x: number; + xanchor: 'left' | 'center' | 'right'; + xpad: number; + y: number; + yanchor: 'top' | 'middle' | 'bottom'; + ypad: number; + outlinecolor: Color; + outlinewidth: number; + bordercolor: Color; + borderwidth: Color; + bgcolor: Color; + tickmode: 'auto' | 'linear' | 'array'; + nticks: number; + tick0: number | string; + dtick: DTickValue; + tickvals: Datum[] | Datum[][] | Datum[][][] | TypedArray; + ticktext: Datum[] | Datum[][] | Datum[][][] | TypedArray; + ticks: 'outside' | 'inside' | ''; + ticklen: number; + tickwidth: number; + tickcolor: Color; + showticklabels: boolean; + tickfont: Font; + tickangle: 'auto' | number; + tickformat: string; + tickformatstops: Array>; + tickprefix: string; + showtickprefix: 'all' | 'first' | 'last' | 'none'; + ticksuffix: string; + showticksuffix: 'all' | 'first' | 'last' | 'none'; + separatethousands: boolean; + exponentformat: 'none' | 'e' | 'E' | 'power' | 'SI' | 'B'; + showexponent: 'all' | 'first' | 'last' | 'none'; + minexponent: number; + title: string; + titlefont: Font; + titleside: 'right' | 'top' | 'bottom'; + tickvalssrc: any; + ticktextsrc: any; +} + +export type MarkerSymbol = string | number | Array; + +/** + * Any combination of "x", "y", "z", "text", "name" joined with a "+" OR "all" or "none" or "skip". + * examples: "x", "y", "x+y", "x+y+z", "all" + * default: "all" + */ +export interface PlotMarker { + symbol: MarkerSymbol; + color?: Color | Color[] | undefined; + colors?: Color[] | undefined; + colorscale?: ColorScale | undefined; + cauto?: boolean | undefined; + cmax?: number | undefined; + cmin?: number | undefined; + autocolorscale?: boolean | undefined; + reversescale?: boolean | undefined; + opacity: number | number[]; + size: number | number[]; + maxdisplayed?: number | undefined; + sizeref?: number | undefined; + sizemax?: number | undefined; + sizemin?: number | undefined; + sizemode?: 'diameter' | 'area' | undefined; + showscale?: boolean | undefined; + line: Partial; + pad?: Partial | undefined; + width?: number | undefined; + colorbar?: Partial | undefined; + gradient?: + | { + type: 'radial' | 'horizontal' | 'vertical' | 'none'; + color: Color; + typesrc: any; + colorsrc: any; + } + | undefined; + pattern?: Partial; +} + +export type ScatterMarker = PlotMarker; + +export interface ScatterMarkerLine { + width: number | number[]; + color: Color; + cauto?: boolean | undefined; + cmax?: number | undefined; + cmin?: number | undefined; + cmid?: number | undefined; + colorscale?: ColorScale | undefined; + autocolorscale?: boolean | undefined; + reversescale?: boolean | undefined; + coloraxis?: string | undefined; +} + +export interface ScatterLine { + color: Color; + width: number; + dash: Dash; + shape: 'linear' | 'spline' | 'hv' | 'vh' | 'hvh' | 'vhv'; + smoothing: number; + simplify: boolean; +} + +export interface Font { + color: Color; + /** + * HTML font family - the typeface that will be applied by the web browser. + * The web browser will only be able to apply a font if it is available on the system + * which it operates. Provide multiple font families, separated by commas, to indicate + * the preference in which to apply fonts if they aren't available on the system. + * The plotly service (at https://plot.ly or on-premise) generates images on a server, + * where only a select number of fonts are installed and supported. + * These include *Arial*, *Balto*, *Courier New*, *Droid Sans*, *Droid Serif*, + * *Droid Sans Mono*, *Gravitas One*, *Old Standard TT*, *Open Sans*, *Overpass*, + * *PT Sans Narrow*, *Raleway*, *Times New Roman*. + * @default "Arial, sans-serif" + */ + family: string; + /** + * Sets the shape and color of the shadow behind text. "auto" places minimal shadow and applies contrast text font color. See https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow for additional options. + * @default "none" + */ + shadow: string; + /** + * number greater than or equal to 1 + * @default 13 + */ + size: number; + /** + * Sets the weight (or boldness) of the font. + * number between or equal to 1 and 1000 + * @default normal + */ + weight: number; +} + +export interface Config { + /** + * Determines whether math should be typeset or not, + * when MathJax (either v2 or v3) is present on the page. + */ + typesetMath: boolean; + + /** DO autosize once regardless of layout.autosize (use default width or height values otherwise) */ + autosizable: boolean; + + /** set the length of the undo/redo queue */ + queueLength: number; + + /** if we DO autosize, do we fill the container or the screen? */ + fillFrame: boolean; + + /** if we DO autosize, set the frame margins in percents of plot size */ + frameMargins: number; + + /** Set global transform to be applied to all traces with no specification needed */ + globalTransforms: any[]; + + /** Which localization should we use? Should be a string like 'en' or 'en-US' */ + locale: string; + + /** + * Localization definitions + * Locales can be provided either here (specific to one chart) or globally + * by registering them as modules. + * Should be an object of objects {locale: {dictionary: {...}, format: {...}}} + * { + * da: { + * dictionary: {'Reset axes': 'Nulstil aksler', ...}, + * format: {months: [...], shortMonths: [...]} + * }, + * ... + * } + * All parts are optional. When looking for translation or format fields, we + * look first for an exact match in a config locale, then in a registered + * module. If those fail, we strip off any regionalization ('en-US' -> 'en') + * and try each (config, registry) again. The final fallback for translation + * is untranslated (which is US English) and for formats is the base English + * (the only consequence being the last fallback date format %x is DD/MM/YYYY + * instead of MM/DD/YYYY). Currently `grouping` and `currency` are ignored + * for our automatic number formatting, but can be used in custom formats. + */ + locales: {}; + + /** Make the chart responsive to window size */ + responsive: boolean; +} + +// Components + +export interface RangeSlider { + visible: boolean; + thickness: number; + range: [Datum, Datum]; + borderwidth: number; + bordercolor: string; + bgcolor: string; +} + +export interface RangeSelectorButton { + step: 'second' | 'minute' | 'hour' | 'day' | 'month' | 'year' | 'all'; + stepmode: 'backward' | 'todate'; + count: number; + label: string; +} + +export interface RangeSelector extends Label { + buttons: Array>; + visible: boolean; + x: number; + xanchor: 'auto' | 'left' | 'center' | 'right'; + y: number; + yanchor: 'auto' | 'top' | 'middle' | 'bottom'; + activecolor: string; + borderwidth: number; +} + +export interface Label { + /** Sets the background color of all hover labels on graph. */ + bgcolor: string; + + /** Sets the border color of all hover labels on graph. */ + bordercolor: string; + + /** Sets the default hover label font used by all traces on the graph. */ + font: Partial; +} + +export interface LegendTitle { + font: Partial; + side: 'top' | 'left' | 'top left' | 'top center' | 'top right'; + text: string; +} + +export interface HoverLabel extends Label { + /** + * Sets the horizontal alignment of the text content within hover label box. + * @default "auto" + */ + align: 'left' | 'right' | 'auto'; + + /** + * Sets the default length (in number of characters) of the trace name + * in the hover labels for all traces. + * -1 shows the whole name regardless of length. + * @default 15 + */ + namelength: number; +} + +export interface Annotations extends Label { + /** Determines whether or not this annotation is visible. */ + visible: boolean; + + /** + * Sets the text associated with this annotation. + * Plotly uses a subset of HTML tags to do things like + * newline (
), bold (), italics (), + * hyperlinks (). Tags , , + * are also supported. + */ + text: string; + + /** Sets the angle at which the `text` is drawn with respect to the horizontal. */ + textangle: string; + + /** + * Sets an explicit width for the text box. null (default) lets the + * text set the box width. Wider text will be clipped. + * There is no automatic wrapping; use
to start a new line. + */ + width: number; + + /** + * Sets an explicit height for the text box. null (default) lets the + * text set the box height. Taller text will be clipped. + */ + height: number; + + /** Sets the opacity of the annotation (text + arrow). */ + opacity: number; + + /** + * Sets the horizontal alignment of the `text` within the box. + * Has an effect only if `text` spans more two or more lines + * (i.e. `text` contains one or more
HTML tags) or if an + * explicit width is set to override the text width. + */ + align: 'left' | 'center' | 'right'; + + /** + * Sets the vertical alignment of the `text` within the box. + * Has an effect only if an explicit height is set to override the text height. + */ + valign: 'top' | 'middle' | 'bottom'; + + /** Sets the padding (in px) between the `text` and the enclosing border. */ + borderpad: number; + + /** Sets the width (in px) of the border enclosing the annotation `text`. */ + borderwidth: number; + + /** + * Determines whether or not the annotation is drawn with an arrow. + * If *true*, `text` is placed near the arrow's tail. + * If *false*, `text` lines up with the `x` and `y` provided. + */ + showarrow: boolean; + + /** Sets the color of the annotation arrow. */ + arrowcolor: string; + + /** Sets the end annotation arrow head style. */ + arrowhead: number; + + /** Sets the start annotation arrow head style. */ + startarrowhead: number; + + /** Sets the annotation arrow head position. */ + arrowside: 'end' | 'start'; + + /** + * Sets the size of the end annotation arrow head, relative to `arrowwidth`. + * A value of 1 (default) gives a head about 3x as wide as the line. + */ + arrowsize: number; + + /** + * Sets the size of the start annotation arrow head, relative to `arrowwidth`. + * A value of 1 (default) gives a head about 3x as wide as the line. + */ + startarrowsize: number; + + /** Sets the width (in px) of annotation arrow line. */ + arrowwidth: number; + + /** + * Sets a distance, in pixels, to move the end arrowhead away from the + * position it is pointing at, for example to point at the edge of + * a marker independent of zoom. Note that this shortens the arrow + * from the `ax` / `ay` vector, in contrast to `xshift` / `yshift` + * which moves everything by this amount. + */ + standoff: number; + + /** + * Sets a distance, in pixels, to move the start arrowhead away from the + * position it is pointing at, for example to point at the edge of + * a marker independent of zoom. Note that this shortens the arrow + * from the `ax` / `ay` vector, in contrast to `xshift` / `yshift` + * which moves everything by this amount. + */ + startstandoff: number; + + /** + * Sets the x component of the arrow tail about the arrow head. + * If `axref` is `pixel`, a positive (negative) + * component corresponds to an arrow pointing + * from right to left (left to right). + * If `axref` is an axis, this is an absolute value on that axis, + * like `x`, NOT a relative value. + */ + ax: number; + + /** + * Sets the y component of the arrow tail about the arrow head. + * If `ayref` is `pixel`, a positive (negative) + * component corresponds to an arrow pointing + * from bottom to top (top to bottom). + * If `ayref` is an axis, this is an absolute value on that axis, + * like `y`, NOT a relative value. + */ + ay: number; + + /** + * Indicates in what terms the tail of the annotation (ax,ay) + * is specified. If `pixel`, `ax` is a relative offset in pixels + * from `x`. If set to an x axis id (e.g. *x* or *x2*), `ax` is + * specified in the same terms as that axis. This is useful + * for trendline annotations which should continue to indicate + * the correct trend when zoomed. + */ + axref: 'pixel' | XAxisName; + + /** + * Indicates in what terms the tail of the annotation (ax,ay) + * is specified. If `pixel`, `ay` is a relative offset in pixels + * from `y`. If set to a y axis id (e.g. *y* or *y2*), `ay` is + * specified in the same terms as that axis. This is useful + * for trendline annotations which should continue to indicate + * the correct trend when zoomed. + */ + ayref: 'pixel' | YAxisName; + + /** + * Sets the annotation's x coordinate axis. + * If set to an x axis id (e.g. *x* or *x2*), the `x` position refers to an x coordinate + * If set to *paper*, the `x` position refers to the distance from + * the left side of the plotting area in normalized coordinates + * where 0 (1) corresponds to the left (right) side. + */ + xref: 'paper' | XAxisName; + + /** + * Sets the annotation's x position. + * If the axis `type` is *log*, then you must take the log of your desired range. + * If the axis `type` is *date*, it should be date strings, like date data, + * though Date objects and unix milliseconds will be accepted and converted to strings. + * If the axis `type` is *category*, it should be numbers, using the scale where each + * category is assigned a serial number from zero in the order it appears. + */ + x: number | string; + + /** + * Sets the text box's horizontal position anchor + * This anchor binds the `x` position to the *left*, *center* or *right* of the annotation. + * For example, if `x` is set to 1, `xref` to *paper* and `xanchor` to *right* then the + * right-most portion of the annotation lines up with the right-most edge of the plotting area. + * If *auto*, the anchor is equivalent to *center* for data-referenced annotations or if there + * is an arrow, whereas for paper-referenced with no arrow, the anchor picked corresponds to the closest side. + */ + xanchor: 'auto' | 'left' | 'center' | 'right'; + + /** + * Shifts the position of the whole annotation and arrow to the + * right (positive) or left (negative) by this many pixels. + */ + xshift: number; + + /** + * Sets the annotation's y coordinate axis. + * If set to an y axis id (e.g. *y* or *y2*), the `y` position refers to an y coordinate + * If set to *paper*, the `y` position refers to the distance from + * the bottom of the plotting area in normalized coordinates + * where 0 (1) corresponds to the bottom (top). + */ + yref: 'paper' | YAxisName; + + /** + * Sets the annotation's y position. + * If the axis `type` is *log*, then you must take the log of your desired range. + * If the axis `type` is *date*, it should be date strings, like date data, + * though Date objects and unix milliseconds will be accepted and converted to strings. + * If the axis `type` is *category*, it should be numbers, using the scale where each + * category is assigned a serial number from zero in the order it appears. + */ + y: number | string; + + /** + * Sets the text box's vertical position anchor + * This anchor binds the `y` position to the *top*, *middle* or *bottom* of the annotation. + * For example, if `y` is set to 1, `yref` to *paper* and `yanchor` to *top* then the + * top-most portion of the annotation lines up with the top-most edge of the plotting area. + * If *auto*, the anchor is equivalent to *middle* for data-referenced annotations or if + * there is an arrow, whereas for paper-referenced with no arrow, the anchor picked + * corresponds to the closest side. + */ + yanchor: 'auto' | 'top' | 'middle' | 'bottom'; + + /** + * Shifts the position of the whole annotation and arrow up + * (positive) or down (negative) by this many pixels. + */ + yshift: number; + + /** + * Makes this annotation respond to clicks on the plot. + * If you click a data point that exactly matches the `x` and `y` values of this annotation, + * and it is hidden (visible: false), it will appear. In *onoff* mode, you must click the same + * point again to make it disappear, so if you click multiple points, you can show multiple + * annotations. In *onout* mode, a click anywhere else in the plot (on another data point or not) + * will hide this annotation. If you need to show/hide this annotation in response to different + * `x` or `y` values, you can set `xclick` and/or `yclick`. This is useful for example to label + * the side of a bar. To label markers though, `standoff` is preferred over `xclick` and `yclick`. + */ + clicktoshow: false | 'onoff' | 'onout'; + + /** + * Toggle this annotation when clicking a data point whose `x` value + * is `xclick` rather than the annotation's `x` value. + */ + xclick: any; + + /** + * Toggle this annotation when clicking a data point whose `y` value + * is `yclick` rather than the annotation's `y` value. + */ + yclick: any; + + /** + * Sets text to appear when hovering over this annotation. + * If omitted or blank, no hover label will appear. + */ + hovertext: string; + + hoverlabel: Partial; + + /** + * Determines whether the annotation text box captures mouse move and click events, + * or allows those events to pass through to data points in the plot that may be + * behind the annotation. By default `captureevents` is *false* unless `hovertext` + * is provided. If you use the event `plotly_clickannotation` without `hovertext` + * you must explicitly enable `captureevents`. + */ + captureevents: boolean; +} + +export interface Domain { + x: number[]; + y: number[]; + row: number; + column: number; +} + +export interface Padding { + /** + * The amount of padding (in px) along the top of the component. + */ + t: number; + /** + * The amount of padding (in px) on the right side of the component. + */ + r: number; + /** + * The amount of padding (in px) along the bottom of the component. + */ + b: number; + /** + * The amount of padding (in px) on the left side of the component. + */ + l: number; + editType: 'arraydraw'; +} + +/** + * 'Sets the pattern within the marker. + */ +export interface Pattern { + /** + * Sets the shape of the pattern fill. + * By default, no pattern is used for filling the area. + */ + shape?: '' | '/' | '\\' | 'x' | '-' | '|' | '+' | '.'; + /** + * Determines whether `marker.color` should be used + * as a default to `bgcolor` or a `fgcolor`. + */ + fillmode?: 'replace' | 'overlay'; + /** + * When there is no colorscale sets the color of background pattern fill. + * Defaults to a `marker.color` background when `fillmode` is *overlay*. + * Otherwise, defaults to a transparent background. + */ + bgcolor?: string; + /** + * When there is no colorscale sets the color of foreground pattern fill. + * Defaults to a `marker.color` background when `fillmode` is *replace*. + * Otherwise, defaults to dark grey or white + * to increase contrast with the `bgcolor`. + */ + fgcolor?: string; + /** + * Sets the opacity of the foreground pattern fill. + * Defaults to a 0.5 when `fillmode` is *overlay*. + * Otherwise, defaults to 1. + */ + fgopacity?: string; + /** + * Sets the size of unit squares of the pattern fill in pixels, + * which corresponds to the interval of repetition of the pattern. + */ + size?: number; + /** + * Sets the solidity of the pattern fill. + * Solidity is roughly the fraction of the area filled by the pattern. + * Solidity of 0 shows only the background color without pattern + * and solidty of 1 shows only the foreground color without pattern. + */ + solidity?: number; +} diff --git a/packages/charts/react-charting/src/components/DeclarativeChart/PlotlySchemaAdapter.ts b/packages/charts/react-charting/src/components/DeclarativeChart/PlotlySchemaAdapter.ts index c2a3f250a3933a..2ac63ecf848e55 100644 --- a/packages/charts/react-charting/src/components/DeclarativeChart/PlotlySchemaAdapter.ts +++ b/packages/charts/react-charting/src/components/DeclarativeChart/PlotlySchemaAdapter.ts @@ -17,6 +17,7 @@ import { IHeatMapChartDataPoint, IGroupedVerticalBarChartData, IVerticalBarChartDataPoint, + ISankeyChartData, } from '../../types/IDataPoint'; import { ISankeyChartProps } from '../SankeyChart/index'; import { IVerticalStackedBarChartProps } from '../VerticalStackedBarChart/index'; @@ -24,48 +25,113 @@ import { IHorizontalBarChartWithAxisProps } from '../HorizontalBarChartWithAxis/ import { ILineChartProps } from '../LineChart/index'; import { IAreaChartProps } from '../AreaChart/index'; import { IHeatMapChartProps } from '../HeatMapChart/index'; -import { DataVizPalette, getNextColor } from '../../utilities/colors'; +import { DataVizPalette, getColorFromToken, getNextColor } from '../../utilities/colors'; import { GaugeChartVariant, IGaugeChartProps, IGaugeChartSegment } from '../GaugeChart/index'; import { IGroupedVerticalBarChartProps } from '../GroupedVerticalBarChart/index'; import { IVerticalBarChartProps } from '../VerticalBarChart/index'; +import { Layout, PlotlySchema, PieData, PlotData, SankeyData } from './PlotlySchema'; +import type { Datum, TypedArray } from './PlotlySchema'; +import { timeParse } from 'd3-time-format'; + +interface ISecondaryYAxisValues { + secondaryYAxistitle?: string; + secondaryYScaleOptions?: { yMinValue?: number; yMaxValue?: number }; +} + +const SUPPORTED_PLOT_TYPES = ['pie', 'bar', 'scatter', 'heatmap', 'sankey', 'indicator', 'histogram']; +const isDate = (value: any): boolean => { + const parsedDate = new Date(Date.parse(value)); + if (isNaN(parsedDate.getTime())) { + return false; + } + const parsedYear = parsedDate.getFullYear(); + const yearInString = /\b\d{4}\b/.test(value); + if (!yearInString && (parsedYear === 2000 || parsedYear === 2001)) { + return false; + } + return true; +}; -const isDate = (value: any): boolean => !isNaN(Date.parse(value)); const isNumber = (value: any): boolean => !isNaN(parseFloat(value)) && isFinite(value); -export const isDateArray = (array: any[]): boolean => isArrayOrTypedArray(array) && array.every(isDate); -export const isNumberArray = (array: any[]): boolean => isArrayOrTypedArray(array) && array.every(isNumber); -export const isMonthArray = (array: any[]): boolean => { - if (array && array.length > 0) { - const presentYear = new Date().getFullYear(); - return array.every(possiblyMonthValue => { - return isDate(`${possiblyMonthValue} 01, ${presentYear}`); - }); + +const isMonth = (possiblyMonthValue: any): boolean => { + const parseFullMonth = timeParse('%B'); + const parseShortMonth = timeParse('%b'); + return parseFullMonth(possiblyMonthValue) !== null || parseShortMonth(possiblyMonthValue) !== null; +}; + +const isArrayOfType = ( + plotCoordinates: Datum[] | Datum[][] | TypedArray | undefined, + typeCheck: (datum: any, ...args: any[]) => boolean, + ...args: any[] +): boolean => { + if (!isArrayOrTypedArray(plotCoordinates)) { + return false; } - return false; + + if (plotCoordinates!.length === 0) { + return false; + } + + if (Array.isArray(plotCoordinates![0])) { + // Handle 2D array + return (plotCoordinates as Datum[][]).every(innerArray => innerArray.every(datum => typeCheck(datum, ...args))); + } else { + // Handle 1D array + return (plotCoordinates as Datum[]).every(datum => typeCheck(datum, ...args)); + } +}; + +export const isDateArray = (data: Datum[] | Datum[][] | TypedArray): boolean => { + return isArrayOfType(data, isDate); +}; + +export const isNumberArray = (data: Datum[] | Datum[][] | TypedArray): boolean => { + return isArrayOfType(data, isNumber); +}; + +export const isMonthArray = (data: Datum[] | Datum[][] | TypedArray): boolean => { + return isArrayOfType(data, isMonth); }; -function getTitles(layout: any) { +export const isLineData = (data: Partial): boolean => { + return ( + !SUPPORTED_PLOT_TYPES.includes(`${data.type}`) && + Array.isArray(data.x) && + isArrayOfType(data.y, (value: any) => typeof value === 'number') && + data.x.length > 0 && + data.x.length === data.y!.length + ); +}; + +const invalidate2Dseries = (series: PlotData, chartType: string): void => { + if (series.x?.length > 0 && Array.isArray(series.x[0])) { + throw new Error(`transform to ${chartType}:: 2D x array not supported`); + } + if (series.y?.length > 0 && Array.isArray(series.y[0])) { + throw new Error(`transform to ${chartType}:: 2D y array not supported`); + } +}; + +const getLegend = (series: PlotData, index: number): string => { + return series.name || `Series ${index + 1}`; +}; + +function getTitles(layout: Partial | undefined) { const titles = { - chartTitle: - typeof layout.title === 'string' ? layout.title : typeof layout.title?.text === 'string' ? layout.title.text : '', - xAxisTitle: - typeof layout?.xaxis?.title === 'string' - ? layout?.xaxis?.title - : typeof layout?.xaxis?.title?.text === 'string' - ? layout?.xaxis?.title?.text - : '', - yAxisTitle: - typeof layout?.yaxis?.title === 'string' - ? layout?.yaxis?.title - : typeof layout?.yaxis?.title?.text === 'string' - ? layout?.yaxis?.title?.text - : '', + chartTitle: typeof layout?.title === 'string' ? layout.title : layout?.title?.text ?? '', + xAxisTitle: typeof layout?.xaxis?.title === 'string' ? layout?.xaxis?.title : layout?.xaxis?.title?.text ?? '', + yAxisTitle: typeof layout?.yaxis?.title === 'string' ? layout?.yaxis?.title : layout?.yaxis?.title?.text ?? '', }; return titles; } -export const updateXValues = (xValues: any[]): any[] => { +export const updateXValues = (xValues: Datum[] | Datum[][] | TypedArray): any[] => { const presentYear = new Date().getFullYear(); - const dates = xValues.map(possiblyMonthValue => { + if (xValues.length > 0 && Array.isArray(xValues[0])) { + throw new Error('updateXValues:: 2D array not supported'); + } + const dates = (xValues as Datum[]).map(possiblyMonthValue => { const parsedDate = `${possiblyMonthValue} 01, ${presentYear}`; return isDate(parsedDate) ? new Date(parsedDate) : null; }); @@ -80,11 +146,12 @@ export const updateXValues = (xValues: any[]): any[] => { dates[i - 1]!.setFullYear(currentYear); } } - xValues = xValues.map((month, index) => { + xValues = (xValues as Datum[]).map((month, index) => { return `${month} 01, ${dates[index]!.getFullYear()}`; }); return xValues; }; + export const getColor = ( legendLabel: string, colorMap: React.MutableRefObject>, @@ -99,25 +166,57 @@ export const getColor = ( return colorMap.current.get(legendLabel) as string; }; +const getSecondaryYAxisValues = (series: PlotData, layout: Partial | undefined) => { + const secondaryYAxisValues: ISecondaryYAxisValues = {}; + if (layout && layout.yaxis2 && series.yaxis === 'y2') { + secondaryYAxisValues.secondaryYAxistitle = + typeof layout.yaxis2.title === 'string' + ? layout.yaxis2.title + : typeof layout.yaxis2.title?.text === 'string' + ? layout.yaxis2.title.text + : ''; + if (layout.yaxis2.range) { + secondaryYAxisValues.secondaryYScaleOptions = { + yMinValue: layout.yaxis2.range[0], + yMaxValue: layout.yaxis2.range[1], + }; + } else { + const yValues = series.y as number[]; + if (yValues) { + secondaryYAxisValues.secondaryYScaleOptions = { + yMinValue: Math.min(...yValues), + yMaxValue: Math.max(...yValues), + }; + } + } + } + secondaryYAxisValues.secondaryYAxistitle = + secondaryYAxisValues.secondaryYAxistitle !== '' ? secondaryYAxisValues.secondaryYAxistitle : undefined; + secondaryYAxisValues.secondaryYScaleOptions = + secondaryYAxisValues.secondaryYScaleOptions && Object.keys(secondaryYAxisValues.secondaryYScaleOptions).length !== 0 + ? secondaryYAxisValues.secondaryYScaleOptions + : undefined; + return secondaryYAxisValues; +}; + export const transformPlotlyJsonToDonutProps = ( - jsonObj: any, + input: PlotlySchema, colorMap: React.MutableRefObject>, isDarkTheme?: boolean, ): IDonutChartProps => { - const { data, layout } = jsonObj; - const firstData = data[0]; + const firstData = input.data[0] as PieData; const donutData = firstData.labels?.map((label: string, index: number): IChartDataPoint => { const color = getColor(label, colorMap, isDarkTheme); return { legend: label, - data: firstData.values?.[index], + data: firstData.values?.[index] as number, //ToDo how to handle string data? color, }; }); - const width: number = typeof layout?.width === 'number' ? layout?.width : 440; - const height: number = typeof layout?.height === 'number' ? layout?.height : 220; + const width: number = input.layout?.width ?? 440; + const height: number = input.layout?.height ?? 220; const hideLabels: boolean = firstData.textinfo ? !['value', 'percent', 'label+percent'].includes(firstData.textinfo) : false; @@ -135,59 +234,67 @@ export const transformPlotlyJsonToDonutProps = ( }, }; - const { chartTitle } = getTitles(layout); + const { chartTitle } = getTitles(input.layout); return { data: { chartTitle, chartData: donutData, }, - hideLegend: layout?.showlegend === false ? true : false, + hideLegend: input.layout?.showlegend === false ? true : false, width, height, innerRadius, hideLabels, - showLabelsInPercent: firstData.textinfo ? firstData.textinfo === 'percent' : true, + showLabelsInPercent: firstData.textinfo ? ['percent', 'label+percent'].includes(firstData.textinfo) : true, styles, }; }; export const transformPlotlyJsonToVSBCProps = ( - jsonObj: any, + input: PlotlySchema, colorMap: React.MutableRefObject>, isDarkTheme?: boolean, + fallbackVSBC?: boolean, ): IVerticalStackedBarChartProps => { - const { data, layout } = jsonObj; const mapXToDataPoints: { [key: string]: IVerticalStackedChartProps } = {}; let yMaxValue = 0; + let secondaryYAxisValues: ISecondaryYAxisValues = {}; + input.data.forEach((series: PlotData, index1: number) => { + invalidate2Dseries(series, 'VSBC'); + + if (!isNumberArray(series.y)) { + throw new Error('transform to VSBC:: y values should be numeric'); + } - data.forEach((series: any, index1: number) => { - series.x?.forEach((x: string | number, index2: number) => { + (series.x as Datum[])?.forEach((x: string | number, index2: number) => { if (!mapXToDataPoints[x]) { mapXToDataPoints[x] = { xAxisPoint: x, chartData: [], lineData: [] }; } - const legend: string = series.name || `Series ${index1 + 1}`; - if (series.type === 'bar' || series.type === 'scatter') { + const legend: string = getLegend(series, index1); + const yVal: number = (series.y?.[index2] as number) ?? 0; + if (series.type === 'bar') { const color = getColor(legend, colorMap, isDarkTheme); mapXToDataPoints[x].chartData.push({ legend, - data: series.y?.[index2], + data: yVal, color, }); - } else if (series.type === 'line') { + } else if (series.type === 'scatter' || isLineData(series) || !!fallbackVSBC) { const color = getColor(legend, colorMap, isDarkTheme); mapXToDataPoints[x].lineData!.push({ legend, - y: series.y?.[index2], + y: yVal, color, }); } - yMaxValue = Math.max(yMaxValue, series.y?.[index2]); + yMaxValue = Math.max(yMaxValue, yVal); }); + secondaryYAxisValues = getSecondaryYAxisValues(series, input.layout); }); - const { chartTitle, xAxisTitle, yAxisTitle } = getTitles(layout); + const { chartTitle, xAxisTitle, yAxisTitle } = getTitles(input.layout); return { data: Object.values(mapXToDataPoints), @@ -199,39 +306,47 @@ export const transformPlotlyJsonToVSBCProps = ( xAxisTitle, yAxisTitle, mode: 'plotly', + secondaryYAxistitle: secondaryYAxisValues.secondaryYAxistitle, + secondaryYScaleOptions: secondaryYAxisValues.secondaryYScaleOptions, hideTickOverlap: true, }; }; export const transformPlotlyJsonToGVBCProps = ( - jsonObj: any, + input: PlotlySchema, colorMap: React.MutableRefObject>, isDarkTheme?: boolean, ): IGroupedVerticalBarChartProps => { - const { data, layout } = jsonObj; const mapXToDataPoints: Record = {}; + let secondaryYAxisValues: ISecondaryYAxisValues = {}; + input.data.forEach((series: PlotData, index1: number) => { + invalidate2Dseries(series, 'GVBC'); - data.forEach((series: any, index1: number) => { - series.x?.forEach((x: string | number, index2: number) => { + if (!isNumberArray(series.y)) { + throw new Error('transform to GVBC:: y values should be numeric'); + } + + (series.x as Datum[])?.forEach((x: string | number, index2: number) => { if (!mapXToDataPoints[x]) { mapXToDataPoints[x] = { name: x.toString(), series: [] }; } if (series.type === 'bar') { - const legend: string = series.name || `Series ${index1 + 1}`; + const legend: string = getLegend(series, index1); const color = getColor(legend, colorMap, isDarkTheme); mapXToDataPoints[x].series.push({ key: legend, - data: series.y?.[index2], + data: (series.y?.[index2] as number) ?? 0, xAxisCalloutData: x as string, color, legend, }); } }); + secondaryYAxisValues = getSecondaryYAxisValues(series, input.layout); }); - const { chartTitle, xAxisTitle, yAxisTitle } = getTitles(layout); + const { chartTitle, xAxisTitle, yAxisTitle } = getTitles(input.layout); return { data: Object.values(mapXToDataPoints), @@ -242,25 +357,28 @@ export const transformPlotlyJsonToGVBCProps = ( xAxisTitle, yAxisTitle, mode: 'plotly', + secondaryYAxistitle: secondaryYAxisValues.secondaryYAxistitle, + secondaryYScaleOptions: secondaryYAxisValues.secondaryYScaleOptions, hideTickOverlap: true, }; }; export const transformPlotlyJsonToVBCProps = ( - jsonObj: any, + input: PlotlySchema, colorMap: React.MutableRefObject>, isDarkTheme?: boolean, ): IVerticalBarChartProps => { - const { data, layout } = jsonObj; const vbcData: IVerticalBarChartDataPoint[] = []; - data.forEach((series: any, index: number) => { + input.data.forEach((series: PlotData, index: number) => { + invalidate2Dseries(series, 'VBC'); + if (!series.x) { return; } const scale = d3ScaleLinear() - .domain(d3Extent(series.x) as [number, number]) + .domain(d3Extent(series.x as number[]) as [number, number]) .nice(); let [xMin, xMax] = scale.domain(); @@ -285,12 +403,12 @@ export const transformPlotlyJsonToVBCProps = ( bin.domain([xMin, xMax]).thresholds(thresholds); } - const buckets = bin(series.x); + const buckets = bin(series.x as number[]); // If the start or end of xbins is specified, then the number of datapoints may become less than x.length const totalDataPoints = d3Merge(buckets).length; buckets.forEach(bucket => { - const legend: string = series.name || `Series ${index + 1}`; + const legend: string = getLegend(series, index); const color: string = getColor(legend, colorMap, isDarkTheme); let y = bucket.length; @@ -322,13 +440,12 @@ export const transformPlotlyJsonToVBCProps = ( }); }); - const { chartTitle, xAxisTitle, yAxisTitle } = getTitles(layout); + const { chartTitle, xAxisTitle, yAxisTitle } = getTitles(input.layout); return { data: vbcData, // width: layout?.width, // height: layout?.height, - barWidth: 24, supportNegativeData: true, chartTitle, xAxisTitle, @@ -339,32 +456,35 @@ export const transformPlotlyJsonToVBCProps = ( }; export const transformPlotlyJsonToScatterChartProps = ( - jsonObj: any, + input: PlotlySchema, isAreaChart: boolean, colorMap: React.MutableRefObject>, isDarkTheme?: boolean, ): ILineChartProps | IAreaChartProps => { - const { data, layout } = jsonObj; - - const chartData: ILineChartPoints[] = data.map((series: any, index: number) => { - const xValues = series.x; + let secondaryYAxisValues: ISecondaryYAxisValues = {}; + let mode: string = 'tonexty'; + const chartData: ILineChartPoints[] = input.data.map((series: PlotData, index: number) => { + invalidate2Dseries(series, 'Scatter'); + const xValues = series.x as Datum[]; const isString = typeof xValues[0] === 'string'; const isXDate = isDateArray(xValues); const isXNumber = isNumberArray(xValues); - const legend: string = series.name || `Series ${index + 1}`; + const legend: string = getLegend(series, index); const lineColor = getColor(legend, colorMap, isDarkTheme); + secondaryYAxisValues = getSecondaryYAxisValues(series, input.layout); + mode = series.fill === 'tozeroy' ? 'tozeroy' : 'tonexty'; return { legend, - data: xValues.map((x: string | number, i: number) => ({ - x: isString ? (isXDate ? new Date(x) : isXNumber ? parseFloat(x as string) : x) : x, + data: xValues.map((x, i: number) => ({ + x: isString ? (isXDate ? new Date(x as string) : isXNumber ? parseFloat(x as string) : x) : x, y: series.y[i], })), color: lineColor, - }; + } as ILineChartPoints; }); - const { chartTitle, xAxisTitle, yAxisTitle } = getTitles(layout); + const { chartTitle, xAxisTitle, yAxisTitle } = getTitles(input.layout); const chartProps: IChartProps = { chartTitle, @@ -377,6 +497,9 @@ export const transformPlotlyJsonToScatterChartProps = ( supportNegativeData: true, xAxisTitle, yAxisTitle, + secondaryYAxistitle: secondaryYAxisValues.secondaryYAxistitle, + secondaryYScaleOptions: secondaryYAxisValues.secondaryYScaleOptions, + mode, hideTickOverlap: true, } as IAreaChartProps; } else { @@ -385,42 +508,46 @@ export const transformPlotlyJsonToScatterChartProps = ( supportNegativeData: true, xAxisTitle, yAxisTitle, + secondaryYAxistitle: secondaryYAxisValues.secondaryYAxistitle, + secondaryYScaleOptions: secondaryYAxisValues.secondaryYScaleOptions, hideTickOverlap: true, } as ILineChartProps; } }; export const transformPlotlyJsonToHorizontalBarWithAxisProps = ( - jsonObj: any, + input: PlotlySchema, colorMap: React.MutableRefObject>, isDarkTheme?: boolean, ): IHorizontalBarChartWithAxisProps => { - const { data, layout } = jsonObj; + const chartData: IHorizontalBarChartWithAxisDataPoint[] = input.data + .map((series: PlotData, index: number) => { + invalidate2Dseries(series, 'HBC'); - const chartData: IHorizontalBarChartWithAxisDataPoint[] = data - .map((series: any, index: number) => { - return series.y.map((yValue: string, i: number) => { + return (series.y as Datum[]).map((yValue: string, i: number) => { const color = getColor(yValue, colorMap, isDarkTheme); return { x: series.x[i], y: yValue, legend: yValue, color, - }; + } as IHorizontalBarChartWithAxisDataPoint; }); }) - .flat(); + .flat() + //reversing the order to invert the Y bars order as required by plotly. + .reverse(); - const chartHeight: number = typeof layout.height === 'number' ? layout.height : 450; - const margin: number = typeof layout.margin?.l === 'number' ? layout.margin?.l : 0; - const padding: number = typeof layout.margin?.pad === 'number' ? layout.margin?.pad : 0; + const chartHeight: number = input.layout?.height ?? 450; + const margin: number = input.layout?.margin?.l ?? 0; + const padding: number = input.layout?.margin?.pad ?? 0; const availableHeight: number = chartHeight - margin - padding; - const numberOfBars = data[0].y.length; + const numberOfBars = (input.data[0] as PlotData).y.length; const scalingFactor = 0.01; const gapFactor = 1 / (1 + scalingFactor * numberOfBars); const barHeight = availableHeight / (numberOfBars * (1 + gapFactor)); - const { chartTitle, xAxisTitle, yAxisTitle } = getTitles(layout); + const { chartTitle, xAxisTitle, yAxisTitle } = getTitles(input.layout); return { data: chartData, @@ -428,33 +555,34 @@ export const transformPlotlyJsonToHorizontalBarWithAxisProps = ( xAxisTitle, yAxisTitle, secondaryYAxistitle: - typeof layout?.yaxis2?.title === 'string' ? layout?.yaxis2?.title : layout?.yaxis2?.title?.text || '', + typeof input.layout?.yaxis2?.title === 'string' + ? input.layout?.yaxis2?.title + : input.layout?.yaxis2?.title?.text || '', barHeight, showYAxisLables: true, styles: { root: { height: chartHeight, - width: typeof layout.width === 'number' ? layout.width : 600, + width: input.layout?.width ?? 600, }, }, hideTickOverlap: true, }; }; -export const transformPlotlyJsonToHeatmapProps = (jsonObj: any): IHeatMapChartProps => { - const { data, layout } = jsonObj; - const firstData = data[0]; +export const transformPlotlyJsonToHeatmapProps = (input: PlotlySchema): IHeatMapChartProps => { + const firstData = input.data[0] as PlotData; const heatmapDataPoints: IHeatMapChartDataPoint[] = []; let zMin = Number.POSITIVE_INFINITY; let zMax = Number.NEGATIVE_INFINITY; - firstData.x?.forEach((xVal: any, xIdx: number) => { + (firstData.x as Datum[])?.forEach((xVal, xIdx: number) => { firstData.y?.forEach((yVal: any, yIdx: number) => { - const zVal = firstData.z?.[yIdx]?.[xIdx]; + const zVal = (firstData.z as number[][])?.[yIdx]?.[xIdx]; heatmapDataPoints.push({ - x: layout.xaxis?.type === 'date' ? new Date(xVal) : xVal, - y: layout.yaxis?.type === 'date' ? new Date(yVal) : yVal, + x: input.layout?.xaxis?.type === 'date' ? (xVal as Date) : xVal ?? 0, + y: input.layout?.yaxis?.type === 'date' ? (yVal as Date) : yVal, value: zVal, rectText: zVal, }); @@ -464,17 +592,27 @@ export const transformPlotlyJsonToHeatmapProps = (jsonObj: any): IHeatMapChartPr }); }); const heatmapData: IHeatMapChartData = { - legend: typeof firstData.name === 'string' ? firstData.name : '', + legend: firstData.name, data: heatmapDataPoints, value: 0, }; - // Convert normalized values to actual values - const domainValuesForColorScale: number[] = firstData.colorscale - ? firstData.colorscale.map((arr: any) => arr[0] * (zMax - zMin) + zMin) - : []; - const rangeValuesForColorScale: string[] = firstData.colorscale ? firstData.colorscale.map((arr: any) => arr[1]) : []; - const { chartTitle, xAxisTitle, yAxisTitle } = getTitles(layout); + // Initialize domain and range to default values + const defaultDomain = [zMin, zMax]; + const defaultRange = [ + getColorFromToken(DataVizPalette.color1), + getColorFromToken(DataVizPalette.color2), + getColorFromToken(DataVizPalette.color3), + ]; + const domainValuesForColorScale: number[] = Array.isArray(firstData.colorscale) + ? (firstData.colorscale as Array<[number, string]>).map(arr => arr[0] * (zMax - zMin) + zMin) + : defaultDomain; + + const rangeValuesForColorScale: string[] = Array.isArray(firstData.colorscale) + ? (firstData.colorscale as Array<[number, string]>).map(arr => arr[1]) + : defaultRange; + + const { chartTitle, xAxisTitle, yAxisTitle } = getTitles(input.layout); return { data: [heatmapData], @@ -491,25 +629,23 @@ export const transformPlotlyJsonToHeatmapProps = (jsonObj: any): IHeatMapChartPr }; export const transformPlotlyJsonToSankeyProps = ( - jsonObj: any, + input: PlotlySchema, colorMap: React.MutableRefObject>, isDarkTheme?: boolean, ): ISankeyChartProps => { - const { data, layout } = jsonObj; - const { link, node } = data[0]; - const validLinks = link.value + const { link, node } = input.data[0] as SankeyData; + const validLinks = (link?.value ?? []) .map((val: number, index: number) => ({ value: val, - source: link.source[index], - target: link.target[index], + source: link?.source![index], + target: link?.target![index], })) // eslint-disable-next-line @typescript-eslint/no-shadow - //@ts-expect-error Dynamic link object. Ignore for now. // Filter out negative nodes, unequal nodes and self-references (circular links) .filter(x => x.source >= 0 && x.target >= 0 && x.source !== x.target); const sankeyChartData = { - nodes: node.label.map((label: string, index: number) => { + nodes: node.label?.map((label: string, index: number) => { const color = getColor(label, colorMap, isDarkTheme); return { @@ -523,18 +659,18 @@ export const transformPlotlyJsonToSankeyProps = ( ...validLink, }; }), - }; + } as ISankeyChartData; - const width: number = typeof layout?.width === 'number' ? layout?.width : 440; - const height: number = typeof layout?.height === 'number' ? layout?.height : 220; + const width: number = input.layout?.width ?? 440; + const height: number = input.layout?.height ?? 220; const styles: ISankeyChartProps['styles'] = { root: { - ...(typeof layout.font?.size === 'number' ? { fontSize: layout.font?.size } : {}), + ...(input.layout?.font?.size ? { fontSize: input.layout.font?.size } : {}), }, }; const shouldResize: number = width + height; - const { chartTitle } = getTitles(layout); + const { chartTitle } = getTitles(input.layout); return { data: { @@ -550,12 +686,11 @@ export const transformPlotlyJsonToSankeyProps = ( }; export const transformPlotlyJsonToGaugeProps = ( - jsonObj: any, + input: PlotlySchema, colorMap: React.MutableRefObject>, isDarkTheme?: boolean, ): IGaugeChartProps => { - const { data, layout } = jsonObj; - const firstData = data[0]; + const firstData = input.data[0] as PlotData; const segments = firstData.gauge?.steps?.length ? firstData.gauge.steps.map((step: any, index: number): IGaugeChartSegment => { @@ -570,27 +705,27 @@ export const transformPlotlyJsonToGaugeProps = ( : [ { legend: 'Current', - size: firstData.value ?? 0 - (firstData.gauge?.range?.[0] ?? 0), + size: firstData.value ?? 0 - (firstData.gauge?.axis?.range?.[0] ?? 0), color: getColor('Current', colorMap, isDarkTheme), }, { legend: 'Target', - size: (firstData.gauge?.range?.[1] ?? 100) - (firstData.value ?? 0), + size: (firstData.gauge?.axis?.range?.[1] ?? 100) - (firstData.value ?? 0), color: DataVizPalette.disabled, }, ]; let sublabel: string | undefined; let sublabelColor: string | undefined; - if (typeof firstData.delta?.reference === 'number') { + if (firstData.delta?.reference) { const diff = firstData.value - firstData.delta.reference; if (diff >= 0) { sublabel = `\u25B2 ${diff}`; - const color = getColor(firstData.delta.increasing?.color || '', colorMap, isDarkTheme); + const color = getColorFromToken(DataVizPalette.success, isDarkTheme); sublabelColor = color; } else { sublabel = `\u25BC ${Math.abs(diff)}`; - const color = getColor(firstData.delta.decreasing?.color || '', colorMap, isDarkTheme); + const color = getColorFromToken(DataVizPalette.error, isDarkTheme); sublabelColor = color; } } @@ -601,19 +736,19 @@ export const transformPlotlyJsonToGaugeProps = ( }, }; - const { chartTitle } = getTitles(layout); + const { chartTitle } = getTitles(input.layout); return { segments, - chartValue: typeof firstData.value === 'number' ? firstData.value : 0, + chartValue: firstData.value ?? 0, chartTitle, sublabel, // range values can be null minValue: typeof firstData.gauge?.axis?.range?.[0] === 'number' ? firstData.gauge?.axis?.range?.[0] : undefined, maxValue: typeof firstData.gauge?.axis?.range?.[1] === 'number' ? firstData.gauge?.axis?.range?.[1] : undefined, - chartValueFormat: () => firstData.value, - width: typeof layout?.width === 'number' ? layout?.width : 440, - height: typeof layout?.height === 'number' ? layout?.height : 220, + chartValueFormat: () => firstData.value?.toString() ?? '', + width: input.layout?.width ?? 440, + height: input.layout?.height ?? 220, styles, variant: firstData.gauge?.steps?.length ? GaugeChartVariant.MultipleSegments : GaugeChartVariant.SingleSegment, }; diff --git a/packages/charts/react-charting/src/components/DeclarativeChart/PlotlySchemaAdapterUT.test.tsx b/packages/charts/react-charting/src/components/DeclarativeChart/PlotlySchemaAdapterUT.test.tsx new file mode 100644 index 00000000000000..b0764953469fac --- /dev/null +++ b/packages/charts/react-charting/src/components/DeclarativeChart/PlotlySchemaAdapterUT.test.tsx @@ -0,0 +1,343 @@ +import { + isDateArray, + isNumberArray, + isMonthArray, + updateXValues, + getColor, + transformPlotlyJsonToDonutProps, + transformPlotlyJsonToVSBCProps, + transformPlotlyJsonToGVBCProps, + transformPlotlyJsonToVBCProps, + transformPlotlyJsonToScatterChartProps, + transformPlotlyJsonToHorizontalBarWithAxisProps, + transformPlotlyJsonToHeatmapProps, + transformPlotlyJsonToSankeyProps, + transformPlotlyJsonToGaugeProps, + sanitizeJson, +} from './PlotlySchemaAdapter'; + +const date = new Date(); +const colorMap = new Map(); + +describe('isDate', () => { + test('Should return true when input array contains Date objects', () => { + const nextDay = new Date(date); + nextDay.setDate(date.getDate() + 1); + expect(isDateArray([date, nextDay])).toBe(true); + }); + + test('Should return false when input array contains numeric data', () => { + expect(isDateArray([20, 30, 40])).toBe(false); + }); + + test('Should return false when input array contains string data', () => { + expect(isDateArray(['twenty', 'thirty', 'forty'])).toBe(false); + }); + + test('Should return false when input array contains different data type objects', () => { + expect(isDateArray(['twenty', 20, date])).toBe(false); + }); + + test('Should return true when input array contains string date objects which contains month in short format', () => { + expect(isDateArray(['20 Jan 2025', '10 Feb 2025'])).toBe(true); + }); + + test('Should return true when input array contains string date objects', () => { + expect(isDateArray(['20 January 2025', '10 February 2025'])).toBe(true); + }); + + test('Should return true when input array contains date in different data types and formats', () => { + expect(isDateArray([date, '10 February 2025', '10 Feb 2025'])).toBe(true); + }); + + test('Should return true when input array contains date in DD/MM/YYYY format(string)', () => { + expect(isDateArray(['10/11/2025', '10/10/2025'])).toBe(true); + }); + + test('Should return false when input array contains date in DD/MM/YYYY format with invalid date objects', () => { + expect(isDateArray(['14/14/2025', '10/14/2025'])).toBe(false); + }); + + test('Should return true when input array contains date in MM/DD/YYYY format', () => { + expect(isDateArray(['12/1/2025', '12/11/2025'])).toBe(true); + }); + + test.skip('Should return true when input array contains date in simple date Object format', () => { + expect(isDateArray([11 / 2 / 2025, 10 / 2 / 2025])).toBe(true); + }); + + test.skip('Should return false when input array is empty', () => { + expect(isDateArray([])).toBe(false); + }); + + test('Should return false when input array contains only month(MMM)', () => { + expect(isDateArray(['January', 'February'])).toBe(false); + }); + + test('Should return false when input array contains only month(MM)', () => { + expect(isDateArray(['Jan', 'Feb'])).toBe(false); + }); +}); + +describe('isNumberArray', () => { + test('Should return false when input array contains Date objects', () => { + expect(isNumberArray([date, date.getDate() + 1, date.getDate() + 2])).toBe(false); + }); + + test('Should return true when input array contains numeric data', () => { + expect(isNumberArray([20, 30, 40])).toBe(true); + }); + + test('Should return true when input array contains numaric data in string formatt', () => { + expect(isNumberArray(['20', '30', '40'])).toBe(true); + }); + + test('Should return false when input array contains string data', () => { + expect(isNumberArray(['twenty', 'thirty', 'forty'])).toBe(false); + }); +}); + +describe('isMonthArray', () => { + test('Should return false when input array contains Date objects', () => { + expect(isMonthArray([date, date.getDate() + 1, date.getDate() + 2])).toBe(false); + }); + + test('Should return false when input array contains numeric data', () => { + expect(isMonthArray([20, 30, 40])).toBe(false); + }); + + test('Should return false when input array contains numaric data in string formatt', () => { + expect(isMonthArray(['20', '30', '40'])).toBe(false); + }); + + test('Should return false when input array contains numbers in string data', () => { + expect(isMonthArray(['One', 'Two', 'Three'])).toBe(false); + }); + + test('Should return true when input array contains only months in string formatt(MMM)', () => { + expect(isMonthArray(['January', 'February'])).toBe(true); + }); + + test('Should return true when input array contains only months in string formatt(MM)', () => { + expect(isMonthArray(['Jan', 'Feb'])).toBe(true); + }); + + test('Should return false when input array is empty', () => { + expect(isMonthArray([])).toBe(false); + }); + + test.skip('Should return true when input array contains only months in string formatt(MMM) in spanish', () => { + expect(isMonthArray(['Enero', 'Febrero'])).toBe(true); + }); + + test.skip('Should return true when input array contains only months in string formatt(MM) in spanish', () => { + expect(isMonthArray(['Ene', 'Feb'])).toBe(true); + }); + + test.skip('Should return true when input array contains only months in string format(MMM) in italian', () => { + expect(isMonthArray(['Gennaio', 'Febbraio'])).toBe(true); + }); +}); + +describe('updateXValues', () => { + test('Should return dates array when input array contains months data', () => { + expect(updateXValues([10, 11, 1])).toStrictEqual(['10 01, 2024', '11 01, 2024', '1 01, 2025']); + }); + + test('Should return error when input array contains invalid months', () => { + try { + expect(updateXValues([10, 11, 16])).toStrictEqual([]); + } catch (e) { + expect(e).toStrictEqual(TypeError("Cannot read properties of null (reading 'getMonth')")); + } + }); + + test('Should return dates array when input array contains months data in MMM format', () => { + expect(updateXValues(['January', 'February'])).toStrictEqual(['January 01, 2025', 'February 01, 2025']); + }); + + test('Should return dates array when input array contains months data in MM format', () => { + expect(updateXValues(['Jan', 'Feb'])).toStrictEqual(['Jan 01, 2025', 'Feb 01, 2025']); + }); + + test('Should return dates array when input array is empty', () => { + expect(updateXValues([])).toStrictEqual([]); + }); +}); + +describe('getColor', () => { + test('Should return color code when we had legend title', () => { + expect(getColor('test', { current: colorMap }, true)).toBe('#e3008c'); + }); + + test('Should return color code when we had legend title', () => { + expect(getColor('test', { current: colorMap }, false)).toBe('#e3008c'); + }); + + test('Should return color code when we had legend title is empty', () => { + expect(getColor('', { current: colorMap }, false)).toBe('#2aa0a4'); + }); +}); + +describe('transform Plotly Json To chart Props', () => { + test('transformPlotlyJsonToDonutProps - Should return donut chart props', () => { + const plotlySchema = require('./tests/schema/fluent_donut_test.json'); + expect(transformPlotlyJsonToDonutProps(plotlySchema, { current: colorMap }, true)).toMatchSnapshot(); + }); + + test('transformPlotlyJsonToDonutProps - Should throw an error when we pass invalid data', () => { + const plotlySchema = require('./tests/schema/fluent_nesteddata_test.json'); + try { + expect(transformPlotlyJsonToDonutProps(plotlySchema, { current: colorMap }, true)).toMatchSnapshot(); + } catch (e) { + expect(e).toStrictEqual(TypeError("Cannot read properties of undefined (reading '0')")); + } + }); + + test('transformPlotlyJsonToDonutProps - Should return pie chart props', () => { + const plotlySchema = require('./tests/schema/fluent_pie_test.json'); + expect(transformPlotlyJsonToDonutProps(plotlySchema, { current: colorMap }, true)).toMatchSnapshot(); + }); + + test('transformPlotlyJsonToVSBCProps - Should return VSBC props', () => { + const plotlySchema = require('./tests/schema/fluent_verticalstackedbarchart_test.json'); + expect(transformPlotlyJsonToVSBCProps(plotlySchema, { current: colorMap }, true)).toMatchSnapshot(); + }); + + test('transformPlotlyJsonToVSBCProps - Should throw an error when we pass invalid data', () => { + const plotlySchema = require('./tests/schema/fluent_nesteddata_test.json'); + try { + expect(transformPlotlyJsonToVSBCProps(plotlySchema, { current: colorMap }, true)).toMatchSnapshot(); + } catch (e) { + expect(e).toStrictEqual(TypeError("Cannot read properties of undefined (reading 'forEach')")); + } + }); + + test('transformPlotlyJsonToGVBCProps - Should return GVBC props', () => { + const plotlySchema = require('./tests/schema/fluent_groupedverticalbarchart_test.json'); + expect(transformPlotlyJsonToGVBCProps(plotlySchema, { current: colorMap }, true)).toMatchSnapshot(); + }); + + test('transformPlotlyJsonToGVBCProps - Should throw an error when we pass invalid data', () => { + const plotlySchema = require('./tests/schema/fluent_nesteddata_test.json'); + try { + expect(transformPlotlyJsonToGVBCProps(plotlySchema, { current: colorMap }, true)).toMatchSnapshot(); + } catch (e) { + expect(e).toStrictEqual(TypeError("Cannot read properties of undefined (reading 'forEach')")); + } + }); + + test('transformPlotlyJsonToVBCProps - Should return VBC props', () => { + const plotlySchema = require('./tests/schema/fluent_verticalbar_histogram_test.json'); + expect(transformPlotlyJsonToVBCProps(plotlySchema, { current: colorMap }, true)).toMatchSnapshot(); + }); + + test('transformPlotlyJsonToVBCProps - Should throw an error when we pass invalid data', () => { + const plotlySchema = require('./tests/schema/fluent_nesteddata_test.json'); + try { + expect(transformPlotlyJsonToVBCProps(plotlySchema, { current: colorMap }, true)).toMatchSnapshot(); + } catch (e) { + expect(e).toStrictEqual(TypeError("Cannot read properties of undefined (reading 'forEach')")); + } + }); + + test('transformPlotlyJsonToScatterChartProps - Should return line chart props', () => { + const plotlySchema = require('./tests/schema/fluent_line_test.json'); + expect(transformPlotlyJsonToScatterChartProps(plotlySchema, true, { current: colorMap }, true)).toMatchSnapshot(); + }); + + test('transformPlotlyJsonToScatterChartProps - Should throw an error when we pass invalid data', () => { + const plotlySchema = require('./tests/schema/fluent_nesteddata_test.json'); + try { + expect(transformPlotlyJsonToScatterChartProps(plotlySchema, true, { current: colorMap }, true)).toMatchSnapshot(); + } catch (e) { + expect(e).toStrictEqual(TypeError("Cannot read properties of undefined (reading 'map')")); + } + }); + + test('transformPlotlyJsonToScatterChartProps - Should return area chart props', () => { + const plotlySchema = require('./tests/schema/fluent_area_test.json'); + expect(transformPlotlyJsonToScatterChartProps(plotlySchema, true, { current: colorMap }, true)).toMatchSnapshot(); + }); + + test('transformPlotlyJsonToHorizontalBarWithAxisProps - Should return HBC with axis chart props', () => { + const plotlySchema = require('./tests/schema/fluent_horizontalbar_test.json'); + expect( + transformPlotlyJsonToHorizontalBarWithAxisProps(plotlySchema, { current: colorMap }, true), + ).toMatchSnapshot(); + }); + + test('transformPlotlyJsonToHorizontalBarWithAxisProps - Should throw an error when we pass invalid data', () => { + const plotlySchema = require('./tests/schema/fluent_nesteddata_test.json'); + try { + expect( + transformPlotlyJsonToHorizontalBarWithAxisProps(plotlySchema, { current: colorMap }, true), + ).toMatchSnapshot(); + } catch (e) { + expect(e).toStrictEqual(TypeError("Cannot read properties of undefined (reading 'map')")); + } + }); + + test('transformPlotlyJsonToHeatmapProps - Should return heatmap chart props', () => { + const plotlySchema = require('./tests/schema/fluent_heatmap_test.json'); + expect(transformPlotlyJsonToHeatmapProps(plotlySchema)).toMatchSnapshot(); + }); + + test('transformPlotlyJsonToHeatmapProps - Should throw an error when we pass invalid data', () => { + const plotlySchema = require('./tests/schema/fluent_nesteddata_test.json'); + try { + expect(transformPlotlyJsonToHeatmapProps(plotlySchema)).toMatchSnapshot(); + } catch (e) { + expect(e).toStrictEqual(TypeError("Cannot read properties of undefined (reading '0')")); + } + }); + + test('transformPlotlyJsonToSankeyProps - Should return sankey chart props', () => { + const plotlySchema = require('./tests/schema/fluent_sankey_test.json'); + expect(transformPlotlyJsonToSankeyProps(plotlySchema, { current: colorMap }, true)).toMatchSnapshot(); + }); + + test('transformPlotlyJsonToSankeyProps - Should throw an error when we pass invalid data', () => { + const plotlySchema = require('./tests/schema/fluent_nesteddata_test.json'); + try { + expect(transformPlotlyJsonToSankeyProps(plotlySchema, { current: colorMap }, true)).toMatchSnapshot(); + } catch (e) { + expect(e).toStrictEqual(TypeError("Cannot read properties of undefined (reading '0')")); + } + }); + + test('transformPlotlyJsonToGaugeProps - Should return gauge chart props', () => { + const plotlySchema = require('./tests/schema/fluent_gauge_test.json'); + expect(transformPlotlyJsonToGaugeProps(plotlySchema, { current: colorMap }, true)).toMatchSnapshot(); + }); + + test('transformPlotlyJsonToGaugeProps - Should throw an error when we pass invalid data', () => { + const plotlySchema = require('./tests/schema/fluent_nesteddata_test.json'); + try { + expect(transformPlotlyJsonToGaugeProps(plotlySchema, { current: colorMap }, true)).toMatchSnapshot(); + } catch (e) { + expect(e).toStrictEqual(TypeError("Cannot read properties of undefined (reading '0')")); + } + }); +}); + +describe('sanitizeJson', () => { + test('Should return json object when depth inside the range', () => { + const plotlySchema = require('./tests/schema/fluent_gauge_test.json'); + expect(sanitizeJson(plotlySchema)).toMatchSnapshot(); + }); + + test('Should return empty json object when input schema is empty', () => { + const plotlySchema = {}; + expect(sanitizeJson(plotlySchema)).toStrictEqual({}); + }); + + test('Should return error when input schema has depth more than max limit', () => { + const plotlySchema = require('./tests/schema/fluent_nesteddata_test.json'); + try { + sanitizeJson(plotlySchema); + } catch (e) { + expect(e).toStrictEqual(Error('Maximum json depth exceeded')); + } + }); +}); 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 2518fa0e844b78..5f131e387622e1 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 @@ -4043,7 +4043,7 @@ exports[`DeclarativeChart Should render gaugechart in DeclarativeChart 1`] = ` data-tabster="{\\"uncontrolled\\": {}}" > - +
+
@@ -25048,7 +25037,7 @@ exports[`DeclarativeChart Should render sankeychart in DeclarativeChart 1`] = ` { overflow: auto; } - data-focuszone-id="FocusZone33" + data-focuszone-id="FocusZone36" data-tabster="{\\"uncontrolled\\": {}}" > - Leave+No – 16 + Remain+No – 28 + 28 + + + + + + + + + + + + @@ -25143,14 +25207,14 @@ exports[`DeclarativeChart Should render sankeychart in DeclarativeChart 1`] = ` } > Remain+Yes – 21 @@ -25200,7 +25264,7 @@ exports[`DeclarativeChart Should render sankeychart in DeclarativeChart 1`] = ` font-weight="bold" text-anchor="start" x="48" - y="123.99999999999994" + y="208.15686274509804" > 22 @@ -25218,14 +25282,14 @@ exports[`DeclarativeChart Should render sankeychart in DeclarativeChart 1`] = ` } > Leave+Yes – 14 @@ -25275,7 +25339,7 @@ exports[`DeclarativeChart Should render sankeychart in DeclarativeChart 1`] = ` font-weight="bold" text-anchor="start" x="48" - y="241.99999999999994" + y="294.2352941176472" > 14 @@ -25293,14 +25357,14 @@ exports[`DeclarativeChart Should render sankeychart in DeclarativeChart 1`] = ` } > Didn’t vote in at least one referendum – 21 @@ -25350,7 +25414,7 @@ exports[`DeclarativeChart Should render sankeychart in DeclarativeChart 1`] = ` font-weight="bold" text-anchor="start" x="48" - y="320.00000000000006" + y="351.92156862745105" > 22 @@ -25381,7 +25445,7 @@ exports[`DeclarativeChart Should render sankeychart in DeclarativeChart 1`] = ` > - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -25950,14 +26122,14 @@ exports[`DeclarativeChart Should render sankeychart in DeclarativeChart 1`] = ` } > 46 – No @@ -26007,9 +26179,9 @@ exports[`DeclarativeChart Should render sankeychart in DeclarativeChart 1`] = ` font-weight="bold" text-anchor="start" x="739" - y="44" + y="47.48191060502646" > - 25 + 45 @@ -26025,14 +26197,14 @@ exports[`DeclarativeChart Should render sankeychart in DeclarativeChart 1`] = ` } > 39 – Yes @@ -26082,9 +26254,9 @@ exports[`DeclarativeChart Should render sankeychart in DeclarativeChart 1`] = ` font-weight="bold" text-anchor="start" x="739" - y="177.00000000000006" + y="215.1877929579676" > - 36 + 39 @@ -26100,14 +26272,14 @@ exports[`DeclarativeChart Should render sankeychart in DeclarativeChart 1`] = ` } > 14 – Don’t know / would not vote @@ -26157,9 +26329,9 @@ exports[`DeclarativeChart Should render sankeychart in DeclarativeChart 1`] = ` font-weight="bold" text-anchor="start" x="739" - y="365.0000000000002" + y="361.59955766384985" > - 13 + 18 diff --git a/packages/charts/react-charting/src/components/DeclarativeChart/__snapshots__/PlotlySchemaAdapterUT.test.tsx.snap b/packages/charts/react-charting/src/components/DeclarativeChart/__snapshots__/PlotlySchemaAdapterUT.test.tsx.snap new file mode 100644 index 00000000000000..fb2586596c12f4 --- /dev/null +++ b/packages/charts/react-charting/src/components/DeclarativeChart/__snapshots__/PlotlySchemaAdapterUT.test.tsx.snap @@ -0,0 +1,4943 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`sanitizeJson Should return json object when depth inside the range 1`] = ` +Object { + "data": Array [ + Object { + "delta": Object { + "increasing": Object { + "color": "RebeccaPurple", + }, + "reference": 400, + }, + "gauge": Object { + "axis": Object { + "range": Array [ + null, + 500, + ], + "tickcolor": "darkblue", + "tickwidth": 1, + }, + "bar": Object { + "color": "darkblue", + }, + "bgcolor": "white", + "bordercolor": "gray", + "borderwidth": 2, + "steps": Array [ + Object { + "color": "cyan", + "range": Array [ + 0, + 250, + ], + }, + Object { + "color": "royalblue", + "range": Array [ + 250, + 400, + ], + }, + ], + "threshold": Object { + "line": Object { + "color": "red", + "width": 4, + }, + "thickness": 0.75, + "value": 490, + }, + }, + "mode": "gauge+number+delta", + "title": Object { + "font": Object { + "size": 24, + }, + "text": "Speed", + }, + "type": "indicator", + "value": 420, + }, + ], + "frames": Array [], + "layout": Object { + "font": Object { + "color": "darkblue", + "family": "Arial", + }, + "height": 400, + "margin": Object { + "b": 25, + "l": 25, + "r": 25, + "t": 25, + }, + "paper_bgcolor": "lavender", + "width": 500, + }, + "visualizer": "plotly", +} +`; + +exports[`transform Plotly Json To chart Props transformPlotlyJsonToDonutProps - Should return donut chart props 1`] = ` +Object { + "data": Object { + "chartData": Array [ + Object { + "color": "#9373c0", + "data": 1, + "legend": "AMC", + }, + Object { + "color": "#13a10e", + "data": 1, + "legend": "Cadillac", + }, + Object { + "color": "#3a96dd", + "data": 1, + "legend": "Camaro", + }, + Object { + "color": "#ca5010", + "data": 1, + "legend": "Chrysler", + }, + Object { + "color": "#57811b", + "data": 1, + "legend": "Datsun", + }, + Object { + "color": "#b146c2", + "data": 1, + "legend": "Dodge", + }, + Object { + "color": "#ae8c00", + "data": 1, + "legend": "Duster", + }, + Object { + "color": "#93a4f4", + "data": 1, + "legend": "Ferrari", + }, + Object { + "color": "#ee5fb7", + "data": 2, + "legend": "Fiat", + }, + Object { + "color": "#4cb4b7", + "data": 1, + "legend": "Ford", + }, + Object { + "color": "#a083c9", + "data": 1, + "legend": "Honda", + }, + Object { + "color": "#27ac22", + "data": 2, + "legend": "Hornet", + }, + Object { + "color": "#4fa1e1", + "data": 1, + "legend": "Lincoln", + }, + Object { + "color": "#d77440", + "data": 1, + "legend": "Lotus", + }, + Object { + "color": "#73aa24", + "data": 1, + "legend": "Maserati", + }, + Object { + "color": "#c36bd1", + "data": 2, + "legend": "Mazda", + }, + Object { + "color": "#d0b232", + "data": 7, + "legend": "Merc", + }, + Object { + "color": "#4f6bed", + "data": 1, + "legend": "Pontiac", + }, + Object { + "color": "#ea38a6", + "data": 1, + "legend": "Porsche", + }, + Object { + "color": "#038387", + "data": 2, + "legend": "Toyota", + }, + Object { + "color": "#8764b8", + "data": 1, + "legend": "Valiant", + }, + Object { + "color": "#11910d", + "data": 1, + "legend": "Volvo", + }, + ], + "chartTitle": "Donut charts using Plotly", + }, + "height": 220, + "hideLabels": false, + "hideLegend": false, + "innerRadius": 42, + "showLabelsInPercent": true, + "styles": Object { + "root": Object { + "[class^=\\"arcLabel\\"]": Object {}, + }, + }, + "width": 440, +} +`; + +exports[`transform Plotly Json To chart Props transformPlotlyJsonToDonutProps - Should return pie chart props 1`] = ` +Object { + "data": Object { + "chartData": Array [ + Object { + "color": "#3487c7", + "data": 4500, + "legend": "Oxygen", + }, + Object { + "color": "#d06228", + "data": 2500, + "legend": "Hydrogen", + }, + Object { + "color": "#689920", + "data": 1053, + "legend": "Carbon_Dioxide", + }, + Object { + "color": "#ba58c9", + "data": 500, + "legend": "Nitrogen", + }, + ], + "chartTitle": "", + }, + "height": 220, + "hideLabels": false, + "hideLegend": false, + "innerRadius": 0, + "showLabelsInPercent": false, + "styles": Object { + "root": Object { + "[class^=\\"arcLabel\\"]": Object { + "fontSize": 20, + }, + }, + }, + "width": 440, +} +`; + +exports[`transform Plotly Json To chart Props transformPlotlyJsonToGVBCProps - Should return GVBC props 1`] = ` +Object { + "barwidth": "auto", + "chartTitle": "PHP Framework Popularity at Work - SitePoint, 2015", + "data": Array [ + Object { + "name": "Jan", + "series": Array [ + Object { + "color": "#c19c00", + "data": 2000, + "key": "Category A", + "legend": "Category A", + "xAxisCalloutData": "Jan", + }, + Object { + "color": "#c8d1fa", + "data": 3000, + "key": "Category B", + "legend": "Category B", + "xAxisCalloutData": "Jan", + }, + ], + }, + Object { + "name": "Feb", + "series": Array [ + Object { + "color": "#c19c00", + "data": 2100, + "key": "Category A", + "legend": "Category A", + "xAxisCalloutData": "Feb", + }, + Object { + "color": "#c8d1fa", + "data": 3100, + "key": "Category B", + "legend": "Category B", + "xAxisCalloutData": "Feb", + }, + ], + }, + Object { + "name": "Mar", + "series": Array [ + Object { + "color": "#c19c00", + "data": 2200, + "key": "Category A", + "legend": "Category A", + "xAxisCalloutData": "Mar", + }, + Object { + "color": "#c8d1fa", + "data": 3200, + "key": "Category B", + "legend": "Category B", + "xAxisCalloutData": "Mar", + }, + ], + }, + Object { + "name": "Apr", + "series": Array [ + Object { + "color": "#c19c00", + "data": 2300, + "key": "Category A", + "legend": "Category A", + "xAxisCalloutData": "Apr", + }, + Object { + "color": "#c8d1fa", + "data": 3300, + "key": "Category B", + "legend": "Category B", + "xAxisCalloutData": "Apr", + }, + ], + }, + Object { + "name": "May", + "series": Array [ + Object { + "color": "#c19c00", + "data": 2400, + "key": "Category A", + "legend": "Category A", + "xAxisCalloutData": "May", + }, + Object { + "color": "#c8d1fa", + "data": 3400, + "key": "Category B", + "legend": "Category B", + "xAxisCalloutData": "May", + }, + ], + }, + ], + "mode": "plotly", + "secondaryYAxistitle": undefined, + "secondaryYScaleOptions": undefined, + "xAxisTitle": "Votes", + "yAxisTitle": "Framework", +} +`; + +exports[`transform Plotly Json To chart Props transformPlotlyJsonToGaugeProps - Should return gauge chart props 1`] = ` +Object { + "chartTitle": "", + "chartValue": 420, + "chartValueFormat": [Function], + "height": 400, + "maxValue": 500, + "minValue": undefined, + "segments": Array [ + Object { + "color": "#c19c00", + "legend": "Segment 1", + "size": 250, + }, + Object { + "color": "#c8d1fa", + "legend": "Segment 2", + "size": 150, + }, + ], + "styles": Object { + "sublabel": Object { + "fill": "#54b054", + }, + }, + "sublabel": "▲ 20", + "variant": "multiple-segments", + "width": 500, +} +`; + +exports[`transform Plotly Json To chart Props transformPlotlyJsonToHeatmapProps - Should return heatmap chart props 1`] = ` +Object { + "chartTitle": "", + "data": Array [ + Object { + "data": Array [ + Object { + "rectText": 12, + "value": 12, + "x": "x_0", + "y": "y_0", + }, + Object { + "rectText": 18.072596781382654, + "value": 18.072596781382654, + "x": "x_0", + "y": "y_1", + }, + Object { + "rectText": 16.104827483834423, + "value": 16.104827483834423, + "x": "x_0", + "y": "y_2", + }, + Object { + "rectText": 12.732656491556462, + "value": 12.732656491556462, + "x": "x_0", + "y": "y_3", + }, + Object { + "rectText": 10.424697200562369, + "value": 10.424697200562369, + "x": "x_0", + "y": "y_4", + }, + Object { + "rectText": 1.3848305486418013, + "value": 1.3848305486418013, + "x": "x_0", + "y": "y_5", + }, + Object { + "rectText": -6.877933971525136, + "value": -6.877933971525136, + "x": "x_0", + "y": "y_6", + }, + Object { + "rectText": -7.513284950652834, + "value": -7.513284950652834, + "x": "x_0", + "y": "y_7", + }, + Object { + "rectText": 0.02929945240777787, + "value": 0.02929945240777787, + "x": "x_0", + "y": "y_8", + }, + Object { + "rectText": 1.3315750803470996, + "value": 1.3315750803470996, + "x": "x_0", + "y": "y_9", + }, + Object { + "rectText": -0.34155835630595655, + "value": -0.34155835630595655, + "x": "x_0", + "y": "y_10", + }, + Object { + "rectText": -1.2496939708148902, + "value": -1.2496939708148902, + "x": "x_0", + "y": "y_11", + }, + Object { + "rectText": 3.673504371828866, + "value": 3.673504371828866, + "x": "x_0", + "y": "y_12", + }, + Object { + "rectText": 9.197351864496074, + "value": 9.197351864496074, + "x": "x_0", + "y": "y_13", + }, + Object { + "rectText": 17.878378279408615, + "value": 17.878378279408615, + "x": "x_0", + "y": "y_14", + }, + Object { + "rectText": 18.3594620989525, + "value": 18.3594620989525, + "x": "x_0", + "y": "y_15", + }, + Object { + "rectText": 9.52854140993721, + "value": 9.52854140993721, + "x": "x_0", + "y": "y_16", + }, + Object { + "rectText": 8.834804620855842, + "value": 8.834804620855842, + "x": "x_0", + "y": "y_17", + }, + Object { + "rectText": 2.008683713506029, + "value": 2.008683713506029, + "x": "x_0", + "y": "y_18", + }, + Object { + "rectText": 1.4746401926975559, + "value": 1.4746401926975559, + "x": "x_0", + "y": "y_19", + }, + Object { + "rectText": 11.697147742124411, + "value": 11.697147742124411, + "x": "x_1", + "y": "y_0", + }, + Object { + "rectText": 6.872368565119988, + "value": 6.872368565119988, + "x": "x_1", + "y": "y_1", + }, + Object { + "rectText": 16.816096580158092, + "value": 16.816096580158092, + "x": "x_1", + "y": "y_2", + }, + Object { + "rectText": 24.158612074358526, + "value": 24.158612074358526, + "x": "x_1", + "y": "y_3", + }, + Object { + "rectText": 28.78022939969912, + "value": 28.78022939969912, + "x": "x_1", + "y": "y_4", + }, + Object { + "rectText": 28.88858899620542, + "value": 28.88858899620542, + "x": "x_1", + "y": "y_5", + }, + Object { + "rectText": 44.04384439381119, + "value": 44.04384439381119, + "x": "x_1", + "y": "y_6", + }, + Object { + "rectText": 44.21182779048812, + "value": 44.21182779048812, + "x": "x_1", + "y": "y_7", + }, + Object { + "rectText": 47.8943258538308, + "value": 47.8943258538308, + "x": "x_1", + "y": "y_8", + }, + Object { + "rectText": 45.90255894008207, + "value": 45.90255894008207, + "x": "x_1", + "y": "y_9", + }, + Object { + "rectText": 52.257883472637104, + "value": 52.257883472637104, + "x": "x_1", + "y": "y_10", + }, + Object { + "rectText": 52.0753263525035, + "value": 52.0753263525035, + "x": "x_1", + "y": "y_11", + }, + Object { + "rectText": 55.66537870906952, + "value": 55.66537870906952, + "x": "x_1", + "y": "y_12", + }, + Object { + "rectText": 55.98556586180058, + "value": 55.98556586180058, + "x": "x_1", + "y": "y_13", + }, + Object { + "rectText": 65.61603877495548, + "value": 65.61603877495548, + "x": "x_1", + "y": "y_14", + }, + Object { + "rectText": 66.76755465163893, + "value": 66.76755465163893, + "x": "x_1", + "y": "y_15", + }, + Object { + "rectText": 66.15934256222516, + "value": 66.15934256222516, + "x": "x_1", + "y": "y_16", + }, + Object { + "rectText": 58.63396530456222, + "value": 58.63396530456222, + "x": "x_1", + "y": "y_17", + }, + Object { + "rectText": 68.77074374390875, + "value": 68.77074374390875, + "x": "x_1", + "y": "y_18", + }, + Object { + "rectText": 76.5710413276318, + "value": 76.5710413276318, + "x": "x_1", + "y": "y_19", + }, + Object { + "rectText": 7.1748009833505355, + "value": 7.1748009833505355, + "x": "x_2", + "y": "y_0", + }, + Object { + "rectText": 2.6331323456979367, + "value": 2.6331323456979367, + "x": "x_2", + "y": "y_1", + }, + Object { + "rectText": -1.0796033248100874, + "value": -1.0796033248100874, + "x": "x_2", + "y": "y_2", + }, + Object { + "rectText": 1.8639666906231516, + "value": 1.8639666906231516, + "x": "x_2", + "y": "y_3", + }, + Object { + "rectText": 3.274446200066722, + "value": 3.274446200066722, + "x": "x_2", + "y": "y_4", + }, + Object { + "rectText": 12.971410893817621, + "value": 12.971410893817621, + "x": "x_2", + "y": "y_5", + }, + Object { + "rectText": 13.548126342387011, + "value": 13.548126342387011, + "x": "x_2", + "y": "y_6", + }, + Object { + "rectText": 14.479713711226983, + "value": 14.479713711226983, + "x": "x_2", + "y": "y_7", + }, + Object { + "rectText": 13.4384038570412, + "value": 13.4384038570412, + "x": "x_2", + "y": "y_8", + }, + Object { + "rectText": 9.162060301209916, + "value": 9.162060301209916, + "x": "x_2", + "y": "y_9", + }, + Object { + "rectText": 14.63013635132661, + "value": 14.63013635132661, + "x": "x_2", + "y": "y_10", + }, + Object { + "rectText": 16.573843720560127, + "value": 16.573843720560127, + "x": "x_2", + "y": "y_11", + }, + Object { + "rectText": 22.222025244923273, + "value": 22.222025244923273, + "x": "x_2", + "y": "y_12", + }, + Object { + "rectText": 19.688495387348357, + "value": 19.688495387348357, + "x": "x_2", + "y": "y_13", + }, + Object { + "rectText": 21.1073514253479, + "value": 21.1073514253479, + "x": "x_2", + "y": "y_14", + }, + Object { + "rectText": 23.378561600159312, + "value": 23.378561600159312, + "x": "x_2", + "y": "y_15", + }, + Object { + "rectText": 25.727095609917317, + "value": 25.727095609917317, + "x": "x_2", + "y": "y_16", + }, + Object { + "rectText": 32.725737544844485, + "value": 32.725737544844485, + "x": "x_2", + "y": "y_17", + }, + Object { + "rectText": 27.561261630596558, + "value": 27.561261630596558, + "x": "x_2", + "y": "y_18", + }, + Object { + "rectText": 22.444170064560886, + "value": 22.444170064560886, + "x": "x_2", + "y": "y_19", + }, + Object { + "rectText": 11.443688379214382, + "value": 11.443688379214382, + "x": "x_3", + "y": "y_0", + }, + Object { + "rectText": 8.910260123844887, + "value": 8.910260123844887, + "x": "x_3", + "y": "y_1", + }, + Object { + "rectText": 13.037577162924944, + "value": 13.037577162924944, + "x": "x_3", + "y": "y_2", + }, + Object { + "rectText": 9.195075731494875, + "value": 9.195075731494875, + "x": "x_3", + "y": "y_3", + }, + Object { + "rectText": 8.669870516018236, + "value": 8.669870516018236, + "x": "x_3", + "y": "y_4", + }, + Object { + "rectText": 21.143305039916708, + "value": 21.143305039916708, + "x": "x_3", + "y": "y_5", + }, + Object { + "rectText": 17.74014481550033, + "value": 17.74014481550033, + "x": "x_3", + "y": "y_6", + }, + Object { + "rectText": 17.660499931671584, + "value": 17.660499931671584, + "x": "x_3", + "y": "y_7", + }, + Object { + "rectText": 17.917433759396193, + "value": 17.917433759396193, + "x": "x_3", + "y": "y_8", + }, + Object { + "rectText": -1.2943200134022526, + "value": -1.2943200134022526, + "x": "x_3", + "y": "y_9", + }, + Object { + "rectText": -1.1475310646451669, + "value": -1.1475310646451669, + "x": "x_3", + "y": "y_10", + }, + Object { + "rectText": 0.6254954059905691, + "value": 0.6254954059905691, + "x": "x_3", + "y": "y_11", + }, + Object { + "rectText": -2.1871046243479864, + "value": -2.1871046243479864, + "x": "x_3", + "y": "y_12", + }, + Object { + "rectText": -1.1757697666321, + "value": -1.1757697666321, + "x": "x_3", + "y": "y_13", + }, + Object { + "rectText": -9.253213203481765, + "value": -9.253213203481765, + "x": "x_3", + "y": "y_14", + }, + Object { + "rectText": -9.221557127656212, + "value": -9.221557127656212, + "x": "x_3", + "y": "y_15", + }, + Object { + "rectText": -16.01042996598902, + "value": -16.01042996598902, + "x": "x_3", + "y": "y_16", + }, + Object { + "rectText": -13.465901648481573, + "value": -13.465901648481573, + "x": "x_3", + "y": "y_17", + }, + Object { + "rectText": -11.972754232678293, + "value": -11.972754232678293, + "x": "x_3", + "y": "y_18", + }, + Object { + "rectText": -11.754560357801614, + "value": -11.754560357801614, + "x": "x_3", + "y": "y_19", + }, + Object { + "rectText": 23.648522429525176, + "value": 23.648522429525176, + "x": "x_4", + "y": "y_0", + }, + Object { + "rectText": 23.29825386450679, + "value": 23.29825386450679, + "x": "x_4", + "y": "y_1", + }, + Object { + "rectText": 25.071276081749808, + "value": 25.071276081749808, + "x": "x_4", + "y": "y_2", + }, + Object { + "rectText": 19.788944565361437, + "value": 19.788944565361437, + "x": "x_4", + "y": "y_3", + }, + Object { + "rectText": 17.75655781585482, + "value": 17.75655781585482, + "x": "x_4", + "y": "y_4", + }, + Object { + "rectText": 7.466382276034302, + "value": 7.466382276034302, + "x": "x_4", + "y": "y_5", + }, + Object { + "rectText": 15.7912983146064, + "value": 15.7912983146064, + "x": "x_4", + "y": "y_6", + }, + Object { + "rectText": 14.436062506263415, + "value": 14.436062506263415, + "x": "x_4", + "y": "y_7", + }, + Object { + "rectText": 17.039432522289083, + "value": 17.039432522289083, + "x": "x_4", + "y": "y_8", + }, + Object { + "rectText": 21.982396858443334, + "value": 21.982396858443334, + "x": "x_4", + "y": "y_9", + }, + Object { + "rectText": 19.815434611539906, + "value": 19.815434611539906, + "x": "x_4", + "y": "y_10", + }, + Object { + "rectText": 25.67070005332393, + "value": 25.67070005332393, + "x": "x_4", + "y": "y_11", + }, + Object { + "rectText": 28.014054309766728, + "value": 28.014054309766728, + "x": "x_4", + "y": "y_12", + }, + Object { + "rectText": 26.78831096366896, + "value": 26.78831096366896, + "x": "x_4", + "y": "y_13", + }, + Object { + "rectText": 27.879670681460908, + "value": 27.879670681460908, + "x": "x_4", + "y": "y_14", + }, + Object { + "rectText": 28.23165649899542, + "value": 28.23165649899542, + "x": "x_4", + "y": "y_15", + }, + Object { + "rectText": 24.77811171644336, + "value": 24.77811171644336, + "x": "x_4", + "y": "y_16", + }, + Object { + "rectText": 31.313375862796256, + "value": 31.313375862796256, + "x": "x_4", + "y": "y_17", + }, + Object { + "rectText": 27.652138241890253, + "value": 27.652138241890253, + "x": "x_4", + "y": "y_18", + }, + Object { + "rectText": 31.65020848831535, + "value": 31.65020848831535, + "x": "x_4", + "y": "y_19", + }, + Object { + "rectText": 10.040502684649338, + "value": 10.040502684649338, + "x": "x_5", + "y": "y_0", + }, + Object { + "rectText": 9.18418261775059, + "value": 9.18418261775059, + "x": "x_5", + "y": "y_1", + }, + Object { + "rectText": -6.016235615271988, + "value": -6.016235615271988, + "x": "x_5", + "y": "y_2", + }, + Object { + "rectText": -6.833645216204284, + "value": -6.833645216204284, + "x": "x_5", + "y": "y_3", + }, + Object { + "rectText": -6.896721183137775, + "value": -6.896721183137775, + "x": "x_5", + "y": "y_4", + }, + Object { + "rectText": -2.108394838355938, + "value": -2.108394838355938, + "x": "x_5", + "y": "y_5", + }, + Object { + "rectText": -6.563883600581922, + "value": -6.563883600581922, + "x": "x_5", + "y": "y_6", + }, + Object { + "rectText": -8.630753569571617, + "value": -8.630753569571617, + "x": "x_5", + "y": "y_7", + }, + Object { + "rectText": -4.774743239794282, + "value": -4.774743239794282, + "x": "x_5", + "y": "y_8", + }, + Object { + "rectText": -2.0046315173801657, + "value": -2.0046315173801657, + "x": "x_5", + "y": "y_9", + }, + Object { + "rectText": -0.3597615447940745, + "value": -0.3597615447940745, + "x": "x_5", + "y": "y_10", + }, + Object { + "rectText": 2.8833642841959586, + "value": 2.8833642841959586, + "x": "x_5", + "y": "y_11", + }, + Object { + "rectText": -1.9343227464152601, + "value": -1.9343227464152601, + "x": "x_5", + "y": "y_12", + }, + Object { + "rectText": -5.206570891432279, + "value": -5.206570891432279, + "x": "x_5", + "y": "y_13", + }, + Object { + "rectText": -2.8320537701090256, + "value": -2.8320537701090256, + "x": "x_5", + "y": "y_14", + }, + Object { + "rectText": -0.3620931039471351, + "value": -0.3620931039471351, + "x": "x_5", + "y": "y_15", + }, + Object { + "rectText": -1.2825355952790376, + "value": -1.2825355952790376, + "x": "x_5", + "y": "y_16", + }, + Object { + "rectText": -1.937020141351771, + "value": -1.937020141351771, + "x": "x_5", + "y": "y_17", + }, + Object { + "rectText": -8.994598412149836, + "value": -8.994598412149836, + "x": "x_5", + "y": "y_18", + }, + Object { + "rectText": -6.747073251084499, + "value": -6.747073251084499, + "x": "x_5", + "y": "y_19", + }, + Object { + "rectText": 10.819974608119614, + "value": 10.819974608119614, + "x": "x_6", + "y": "y_0", + }, + Object { + "rectText": 18.052236884018036, + "value": 18.052236884018036, + "x": "x_6", + "y": "y_1", + }, + Object { + "rectText": 12.248777535804365, + "value": 12.248777535804365, + "x": "x_6", + "y": "y_2", + }, + Object { + "rectText": 9.969142303073252, + "value": 9.969142303073252, + "x": "x_6", + "y": "y_3", + }, + Object { + "rectText": 17.337127681913973, + "value": 17.337127681913973, + "x": "x_6", + "y": "y_4", + }, + Object { + "rectText": 16.027000754389025, + "value": 16.027000754389025, + "x": "x_6", + "y": "y_5", + }, + Object { + "rectText": 21.49865383744765, + "value": 21.49865383744765, + "x": "x_6", + "y": "y_6", + }, + Object { + "rectText": 18.920515851612024, + "value": 18.920515851612024, + "x": "x_6", + "y": "y_7", + }, + Object { + "rectText": 12.169188113505435, + "value": 12.169188113505435, + "x": "x_6", + "y": "y_8", + }, + Object { + "rectText": 23.75776947991829, + "value": 23.75776947991829, + "x": "x_6", + "y": "y_9", + }, + Object { + "rectText": 22.773438522174473, + "value": 22.773438522174473, + "x": "x_6", + "y": "y_10", + }, + Object { + "rectText": 21.05489065711163, + "value": 21.05489065711163, + "x": "x_6", + "y": "y_11", + }, + Object { + "rectText": 29.16438526268995, + "value": 29.16438526268995, + "x": "x_6", + "y": "y_12", + }, + Object { + "rectText": 29.755041090905404, + "value": 29.755041090905404, + "x": "x_6", + "y": "y_13", + }, + Object { + "rectText": 26.13796211607032, + "value": 26.13796211607032, + "x": "x_6", + "y": "y_14", + }, + Object { + "rectText": 28.91643855216486, + "value": 28.91643855216486, + "x": "x_6", + "y": "y_15", + }, + Object { + "rectText": 19.064261874916085, + "value": 19.064261874916085, + "x": "x_6", + "y": "y_16", + }, + Object { + "rectText": 14.893297536987049, + "value": 14.893297536987049, + "x": "x_6", + "y": "y_17", + }, + Object { + "rectText": 16.01202612993778, + "value": 16.01202612993778, + "x": "x_6", + "y": "y_18", + }, + Object { + "rectText": 10.677375854561543, + "value": 10.677375854561543, + "x": "x_6", + "y": "y_19", + }, + Object { + "rectText": 20.83991840239746, + "value": 20.83991840239746, + "x": "x_7", + "y": "y_0", + }, + Object { + "rectText": 32.088269277118485, + "value": 32.088269277118485, + "x": "x_7", + "y": "y_1", + }, + Object { + "rectText": 35.617617939013286, + "value": 35.617617939013286, + "x": "x_7", + "y": "y_2", + }, + Object { + "rectText": 46.34145242145437, + "value": 46.34145242145437, + "x": "x_7", + "y": "y_3", + }, + Object { + "rectText": 42.70107878756259, + "value": 42.70107878756259, + "x": "x_7", + "y": "y_4", + }, + Object { + "rectText": 40.70844626018491, + "value": 40.70844626018491, + "x": "x_7", + "y": "y_5", + }, + Object { + "rectText": 38.24729505908534, + "value": 38.24729505908534, + "x": "x_7", + "y": "y_6", + }, + Object { + "rectText": 41.961872256649784, + "value": 41.961872256649784, + "x": "x_7", + "y": "y_7", + }, + Object { + "rectText": 40.42317097918186, + "value": 40.42317097918186, + "x": "x_7", + "y": "y_8", + }, + Object { + "rectText": 42.681396519281044, + "value": 42.681396519281044, + "x": "x_7", + "y": "y_9", + }, + Object { + "rectText": 45.16830973647258, + "value": 45.16830973647258, + "x": "x_7", + "y": "y_10", + }, + Object { + "rectText": 45.54977153406254, + "value": 45.54977153406254, + "x": "x_7", + "y": "y_11", + }, + Object { + "rectText": 44.051494895676456, + "value": 44.051494895676456, + "x": "x_7", + "y": "y_12", + }, + Object { + "rectText": 35.45913888587404, + "value": 35.45913888587404, + "x": "x_7", + "y": "y_13", + }, + Object { + "rectText": 24.926244822709098, + "value": 24.926244822709098, + "x": "x_7", + "y": "y_14", + }, + Object { + "rectText": 11.188848304771073, + "value": 11.188848304771073, + "x": "x_7", + "y": "y_15", + }, + Object { + "rectText": 14.509555473536986, + "value": 14.509555473536986, + "x": "x_7", + "y": "y_16", + }, + Object { + "rectText": 23.629750932895455, + "value": 23.629750932895455, + "x": "x_7", + "y": "y_17", + }, + Object { + "rectText": 27.496822437992087, + "value": 27.496822437992087, + "x": "x_7", + "y": "y_18", + }, + Object { + "rectText": 18.290237353501528, + "value": 18.290237353501528, + "x": "x_7", + "y": "y_19", + }, + Object { + "rectText": 14.378243279399832, + "value": 14.378243279399832, + "x": "x_8", + "y": "y_0", + }, + Object { + "rectText": 15.862814449470617, + "value": 15.862814449470617, + "x": "x_8", + "y": "y_1", + }, + Object { + "rectText": 20.621055215762404, + "value": 20.621055215762404, + "x": "x_8", + "y": "y_2", + }, + Object { + "rectText": 27.310374393715577, + "value": 27.310374393715577, + "x": "x_8", + "y": "y_3", + }, + Object { + "rectText": 27.376076996458107, + "value": 27.376076996458107, + "x": "x_8", + "y": "y_4", + }, + Object { + "rectText": 25.966261645863177, + "value": 25.966261645863177, + "x": "x_8", + "y": "y_5", + }, + Object { + "rectText": 25.710457133039732, + "value": 25.710457133039732, + "x": "x_8", + "y": "y_6", + }, + Object { + "rectText": 30.992785862263872, + "value": 30.992785862263872, + "x": "x_8", + "y": "y_7", + }, + Object { + "rectText": 37.22474246115934, + "value": 37.22474246115934, + "x": "x_8", + "y": "y_8", + }, + Object { + "rectText": 44.65189694360409, + "value": 44.65189694360409, + "x": "x_8", + "y": "y_9", + }, + Object { + "rectText": 50.90620858214391, + "value": 50.90620858214391, + "x": "x_8", + "y": "y_10", + }, + Object { + "rectText": 54.790476948309696, + "value": 54.790476948309696, + "x": "x_8", + "y": "y_11", + }, + Object { + "rectText": 47.138525452751004, + "value": 47.138525452751004, + "x": "x_8", + "y": "y_12", + }, + Object { + "rectText": 48.543398737558654, + "value": 48.543398737558654, + "x": "x_8", + "y": "y_13", + }, + Object { + "rectText": 41.22820882460708, + "value": 41.22820882460708, + "x": "x_8", + "y": "y_14", + }, + Object { + "rectText": 43.30138646653476, + "value": 43.30138646653476, + "x": "x_8", + "y": "y_15", + }, + Object { + "rectText": 43.57067434580797, + "value": 43.57067434580797, + "x": "x_8", + "y": "y_16", + }, + Object { + "rectText": 41.77269087492713, + "value": 41.77269087492713, + "x": "x_8", + "y": "y_17", + }, + Object { + "rectText": 42.223038572972655, + "value": 42.223038572972655, + "x": "x_8", + "y": "y_18", + }, + Object { + "rectText": 44.04246479548906, + "value": 44.04246479548906, + "x": "x_8", + "y": "y_19", + }, + Object { + "rectText": 9.546437633051273, + "value": 9.546437633051273, + "x": "x_9", + "y": "y_0", + }, + Object { + "rectText": 20.517302217015732, + "value": 20.517302217015732, + "x": "x_9", + "y": "y_1", + }, + Object { + "rectText": 18.321563171124787, + "value": 18.321563171124787, + "x": "x_9", + "y": "y_2", + }, + Object { + "rectText": 15.451738777747869, + "value": 15.451738777747869, + "x": "x_9", + "y": "y_3", + }, + Object { + "rectText": 10.416788406228507, + "value": 10.416788406228507, + "x": "x_9", + "y": "y_4", + }, + Object { + "rectText": 0.9043901831061678, + "value": 0.9043901831061678, + "x": "x_9", + "y": "y_5", + }, + Object { + "rectText": 2.2251747151953722, + "value": 2.2251747151953722, + "x": "x_9", + "y": "y_6", + }, + Object { + "rectText": 0.3821317782171232, + "value": 0.3821317782171232, + "x": "x_9", + "y": "y_7", + }, + Object { + "rectText": 0.22091049853526112, + "value": 0.22091049853526112, + "x": "x_9", + "y": "y_8", + }, + Object { + "rectText": -3.233129329636757, + "value": -3.233129329636757, + "x": "x_9", + "y": "y_9", + }, + Object { + "rectText": -4.123416917882673, + "value": -4.123416917882673, + "x": "x_9", + "y": "y_10", + }, + Object { + "rectText": -1.1319446806674005, + "value": -1.1319446806674005, + "x": "x_9", + "y": "y_11", + }, + Object { + "rectText": -2.533067604753474, + "value": -2.533067604753474, + "x": "x_9", + "y": "y_12", + }, + Object { + "rectText": 3.274578409778302, + "value": 3.274578409778302, + "x": "x_9", + "y": "y_13", + }, + Object { + "rectText": 4.291828909220028, + "value": 4.291828909220028, + "x": "x_9", + "y": "y_14", + }, + Object { + "rectText": 5.000880279196099, + "value": 5.000880279196099, + "x": "x_9", + "y": "y_15", + }, + Object { + "rectText": 7.890650307112603, + "value": 7.890650307112603, + "x": "x_9", + "y": "y_16", + }, + Object { + "rectText": 9.082388429023517, + "value": 9.082388429023517, + "x": "x_9", + "y": "y_17", + }, + Object { + "rectText": 9.14302748045202, + "value": 9.14302748045202, + "x": "x_9", + "y": "y_18", + }, + Object { + "rectText": -0.9669084139974888, + "value": -0.9669084139974888, + "x": "x_9", + "y": "y_19", + }, + Object { + "rectText": 2.117430162487592, + "value": 2.117430162487592, + "x": "x_10", + "y": "y_0", + }, + Object { + "rectText": 1.5668378537843557, + "value": 1.5668378537843557, + "x": "x_10", + "y": "y_1", + }, + Object { + "rectText": 5.106104151848498, + "value": 5.106104151848498, + "x": "x_10", + "y": "y_2", + }, + Object { + "rectText": 6.691398648622392, + "value": 6.691398648622392, + "x": "x_10", + "y": "y_3", + }, + Object { + "rectText": 5.9545352540812, + "value": 5.9545352540812, + "x": "x_10", + "y": "y_4", + }, + Object { + "rectText": -0.6718858579700804, + "value": -0.6718858579700804, + "x": "x_10", + "y": "y_5", + }, + Object { + "rectText": -10.093623877175773, + "value": -10.093623877175773, + "x": "x_10", + "y": "y_6", + }, + Object { + "rectText": -9.481337721021028, + "value": -9.481337721021028, + "x": "x_10", + "y": "y_7", + }, + Object { + "rectText": -9.687370268531138, + "value": -9.687370268531138, + "x": "x_10", + "y": "y_8", + }, + Object { + "rectText": -11.7007015295863, + "value": -11.7007015295863, + "x": "x_10", + "y": "y_9", + }, + Object { + "rectText": -10.08874106711032, + "value": -10.08874106711032, + "x": "x_10", + "y": "y_10", + }, + Object { + "rectText": -6.836880142255078, + "value": -6.836880142255078, + "x": "x_10", + "y": "y_11", + }, + Object { + "rectText": 2.4604369987892873, + "value": 2.4604369987892873, + "x": "x_10", + "y": "y_12", + }, + Object { + "rectText": 7.640442280843416, + "value": 7.640442280843416, + "x": "x_10", + "y": "y_13", + }, + Object { + "rectText": 4.713688574820864, + "value": 4.713688574820864, + "x": "x_10", + "y": "y_14", + }, + Object { + "rectText": 1.955677009677276, + "value": 1.955677009677276, + "x": "x_10", + "y": "y_15", + }, + Object { + "rectText": 1.6731169765193206, + "value": 1.6731169765193206, + "x": "x_10", + "y": "y_16", + }, + Object { + "rectText": -6.034577415215565, + "value": -6.034577415215565, + "x": "x_10", + "y": "y_17", + }, + Object { + "rectText": -9.49672264010566, + "value": -9.49672264010566, + "x": "x_10", + "y": "y_18", + }, + Object { + "rectText": -10.02999798650989, + "value": -10.02999798650989, + "x": "x_10", + "y": "y_19", + }, + Object { + "rectText": 24.053122758748437, + "value": 24.053122758748437, + "x": "x_11", + "y": "y_0", + }, + Object { + "rectText": 19.031137709612036, + "value": 19.031137709612036, + "x": "x_11", + "y": "y_1", + }, + Object { + "rectText": 20.47764211274059, + "value": 20.47764211274059, + "x": "x_11", + "y": "y_2", + }, + Object { + "rectText": 14.55281641333698, + "value": 14.55281641333698, + "x": "x_11", + "y": "y_3", + }, + Object { + "rectText": 15.043018310072712, + "value": 15.043018310072712, + "x": "x_11", + "y": "y_4", + }, + Object { + "rectText": 2.6597070827875093, + "value": 2.6597070827875093, + "x": "x_11", + "y": "y_5", + }, + Object { + "rectText": 1.9137585062069147, + "value": 1.9137585062069147, + "x": "x_11", + "y": "y_6", + }, + Object { + "rectText": 1.6266164906990555, + "value": 1.6266164906990555, + "x": "x_11", + "y": "y_7", + }, + Object { + "rectText": 10.608534707379862, + "value": 10.608534707379862, + "x": "x_11", + "y": "y_8", + }, + Object { + "rectText": 8.768962763531919, + "value": 8.768962763531919, + "x": "x_11", + "y": "y_9", + }, + Object { + "rectText": 17.77058648507848, + "value": 17.77058648507848, + "x": "x_11", + "y": "y_10", + }, + Object { + "rectText": 15.502730715077965, + "value": 15.502730715077965, + "x": "x_11", + "y": "y_11", + }, + Object { + "rectText": 19.673236477344094, + "value": 19.673236477344094, + "x": "x_11", + "y": "y_12", + }, + Object { + "rectText": 6.615425581412669, + "value": 6.615425581412669, + "x": "x_11", + "y": "y_13", + }, + Object { + "rectText": 16.71505221410986, + "value": 16.71505221410986, + "x": "x_11", + "y": "y_14", + }, + Object { + "rectText": 17.279662785715818, + "value": 17.279662785715818, + "x": "x_11", + "y": "y_15", + }, + Object { + "rectText": 11.216733394728445, + "value": 11.216733394728445, + "x": "x_11", + "y": "y_16", + }, + Object { + "rectText": 26.401238496860607, + "value": 26.401238496860607, + "x": "x_11", + "y": "y_17", + }, + Object { + "rectText": 25.872388552562622, + "value": 25.872388552562622, + "x": "x_11", + "y": "y_18", + }, + Object { + "rectText": 26.331023176529538, + "value": 26.331023176529538, + "x": "x_11", + "y": "y_19", + }, + Object { + "rectText": 14.741753869753929, + "value": 14.741753869753929, + "x": "x_12", + "y": "y_0", + }, + Object { + "rectText": 12.133745300119848, + "value": 12.133745300119848, + "x": "x_12", + "y": "y_1", + }, + Object { + "rectText": 13.078423154116999, + "value": 13.078423154116999, + "x": "x_12", + "y": "y_2", + }, + Object { + "rectText": 31.321025344254267, + "value": 31.321025344254267, + "x": "x_12", + "y": "y_3", + }, + Object { + "rectText": 32.12573718137715, + "value": 32.12573718137715, + "x": "x_12", + "y": "y_4", + }, + Object { + "rectText": 36.093975687401766, + "value": 36.093975687401766, + "x": "x_12", + "y": "y_5", + }, + Object { + "rectText": 28.853944000537858, + "value": 28.853944000537858, + "x": "x_12", + "y": "y_6", + }, + Object { + "rectText": 20.52198483872326, + "value": 20.52198483872326, + "x": "x_12", + "y": "y_7", + }, + Object { + "rectText": 22.489367975650175, + "value": 22.489367975650175, + "x": "x_12", + "y": "y_8", + }, + Object { + "rectText": 21.48008268870696, + "value": 21.48008268870696, + "x": "x_12", + "y": "y_9", + }, + Object { + "rectText": 17.40525407651549, + "value": 17.40525407651549, + "x": "x_12", + "y": "y_10", + }, + Object { + "rectText": 16.434991284495794, + "value": 16.434991284495794, + "x": "x_12", + "y": "y_11", + }, + Object { + "rectText": 23.43582349379937, + "value": 23.43582349379937, + "x": "x_12", + "y": "y_12", + }, + Object { + "rectText": 27.520672134556655, + "value": 27.520672134556655, + "x": "x_12", + "y": "y_13", + }, + Object { + "rectText": 27.48982397761371, + "value": 27.48982397761371, + "x": "x_12", + "y": "y_14", + }, + Object { + "rectText": 26.178614647552152, + "value": 26.178614647552152, + "x": "x_12", + "y": "y_15", + }, + Object { + "rectText": 25.858459074516183, + "value": 25.858459074516183, + "x": "x_12", + "y": "y_16", + }, + Object { + "rectText": 30.051671106505943, + "value": 30.051671106505943, + "x": "x_12", + "y": "y_17", + }, + Object { + "rectText": 29.591488992612543, + "value": 29.591488992612543, + "x": "x_12", + "y": "y_18", + }, + Object { + "rectText": 23.744787277420585, + "value": 23.744787277420585, + "x": "x_12", + "y": "y_19", + }, + Object { + "rectText": 11.223068582526338, + "value": 11.223068582526338, + "x": "x_13", + "y": "y_0", + }, + Object { + "rectText": 8.724453334098921, + "value": 8.724453334098921, + "x": "x_13", + "y": "y_1", + }, + Object { + "rectText": 4.270904076038434, + "value": 4.270904076038434, + "x": "x_13", + "y": "y_2", + }, + Object { + "rectText": 9.311054030160307, + "value": 9.311054030160307, + "x": "x_13", + "y": "y_3", + }, + Object { + "rectText": 11.294834569956391, + "value": 11.294834569956391, + "x": "x_13", + "y": "y_4", + }, + Object { + "rectText": 12.79240265673884, + "value": 12.79240265673884, + "x": "x_13", + "y": "y_5", + }, + Object { + "rectText": 9.119846857537635, + "value": 9.119846857537635, + "x": "x_13", + "y": "y_6", + }, + Object { + "rectText": 9.822475957217343, + "value": 9.822475957217343, + "x": "x_13", + "y": "y_7", + }, + Object { + "rectText": 10.669348146795615, + "value": 10.669348146795615, + "x": "x_13", + "y": "y_8", + }, + Object { + "rectText": 11.750650693071353, + "value": 11.750650693071353, + "x": "x_13", + "y": "y_9", + }, + Object { + "rectText": 19.428287067763215, + "value": 19.428287067763215, + "x": "x_13", + "y": "y_10", + }, + Object { + "rectText": 20.05330736176254, + "value": 20.05330736176254, + "x": "x_13", + "y": "y_11", + }, + Object { + "rectText": 18.46461800040717, + "value": 18.46461800040717, + "x": "x_13", + "y": "y_12", + }, + Object { + "rectText": 17.13948338893387, + "value": 17.13948338893387, + "x": "x_13", + "y": "y_13", + }, + Object { + "rectText": 14.998235183145638, + "value": 14.998235183145638, + "x": "x_13", + "y": "y_14", + }, + Object { + "rectText": 21.57198989722974, + "value": 21.57198989722974, + "x": "x_13", + "y": "y_15", + }, + Object { + "rectText": 18.23274943606415, + "value": 18.23274943606415, + "x": "x_13", + "y": "y_16", + }, + Object { + "rectText": 23.834062269627154, + "value": 23.834062269627154, + "x": "x_13", + "y": "y_17", + }, + Object { + "rectText": 17.887210405056912, + "value": 17.887210405056912, + "x": "x_13", + "y": "y_18", + }, + Object { + "rectText": 21.58401811955205, + "value": 21.58401811955205, + "x": "x_13", + "y": "y_19", + }, + Object { + "rectText": 2.9058799108357736, + "value": 2.9058799108357736, + "x": "x_14", + "y": "y_0", + }, + Object { + "rectText": 8.972456038301432, + "value": 8.972456038301432, + "x": "x_14", + "y": "y_1", + }, + Object { + "rectText": 10.32885307002288, + "value": 10.32885307002288, + "x": "x_14", + "y": "y_2", + }, + Object { + "rectText": 12.004790333591908, + "value": 12.004790333591908, + "x": "x_14", + "y": "y_3", + }, + Object { + "rectText": 16.313424113247194, + "value": 16.313424113247194, + "x": "x_14", + "y": "y_4", + }, + Object { + "rectText": 16.292076219475025, + "value": 16.292076219475025, + "x": "x_14", + "y": "y_5", + }, + Object { + "rectText": 16.770107402461807, + "value": 16.770107402461807, + "x": "x_14", + "y": "y_6", + }, + Object { + "rectText": 15.658011352744083, + "value": 15.658011352744083, + "x": "x_14", + "y": "y_7", + }, + Object { + "rectText": 13.95650541886101, + "value": 13.95650541886101, + "x": "x_14", + "y": "y_8", + }, + Object { + "rectText": 10.314016323078881, + "value": 10.314016323078881, + "x": "x_14", + "y": "y_9", + }, + Object { + "rectText": 10.154808609159593, + "value": 10.154808609159593, + "x": "x_14", + "y": "y_10", + }, + Object { + "rectText": 2.3102989662620654, + "value": 2.3102989662620654, + "x": "x_14", + "y": "y_11", + }, + Object { + "rectText": 3.2513035287755745, + "value": 3.2513035287755745, + "x": "x_14", + "y": "y_12", + }, + Object { + "rectText": -0.7130168306222968, + "value": -0.7130168306222968, + "x": "x_14", + "y": "y_13", + }, + Object { + "rectText": -1.0419904618770504, + "value": -1.0419904618770504, + "x": "x_14", + "y": "y_14", + }, + Object { + "rectText": -1.3161643920050667, + "value": -1.3161643920050667, + "x": "x_14", + "y": "y_15", + }, + Object { + "rectText": -1.5424885952686824, + "value": -1.5424885952686824, + "x": "x_14", + "y": "y_16", + }, + Object { + "rectText": -3.561155588342318, + "value": -3.561155588342318, + "x": "x_14", + "y": "y_17", + }, + Object { + "rectText": -5.273287251587566, + "value": -5.273287251587566, + "x": "x_14", + "y": "y_18", + }, + Object { + "rectText": -5.054619683005746, + "value": -5.054619683005746, + "x": "x_14", + "y": "y_19", + }, + Object { + "rectText": 12.523922839169199, + "value": 12.523922839169199, + "x": "x_15", + "y": "y_0", + }, + Object { + "rectText": 9.771921362871048, + "value": 9.771921362871048, + "x": "x_15", + "y": "y_1", + }, + Object { + "rectText": 11.953280688550777, + "value": 11.953280688550777, + "x": "x_15", + "y": "y_2", + }, + Object { + "rectText": 13.059625413572078, + "value": 13.059625413572078, + "x": "x_15", + "y": "y_3", + }, + Object { + "rectText": 15.444451104553893, + "value": 15.444451104553893, + "x": "x_15", + "y": "y_4", + }, + Object { + "rectText": 13.792475502830154, + "value": 13.792475502830154, + "x": "x_15", + "y": "y_5", + }, + Object { + "rectText": 7.3577813910229235, + "value": 7.3577813910229235, + "x": "x_15", + "y": "y_6", + }, + Object { + "rectText": 12.855391500184762, + "value": 12.855391500184762, + "x": "x_15", + "y": "y_7", + }, + Object { + "rectText": 6.839552569406474, + "value": 6.839552569406474, + "x": "x_15", + "y": "y_8", + }, + Object { + "rectText": 6.044971885000999, + "value": 6.044971885000999, + "x": "x_15", + "y": "y_9", + }, + Object { + "rectText": 9.41560200751194, + "value": 9.41560200751194, + "x": "x_15", + "y": "y_10", + }, + Object { + "rectText": 6.6400837474901095, + "value": 6.6400837474901095, + "x": "x_15", + "y": "y_11", + }, + Object { + "rectText": 7.4638277204597046, + "value": 7.4638277204597046, + "x": "x_15", + "y": "y_12", + }, + Object { + "rectText": 3.4923248627721257, + "value": 3.4923248627721257, + "x": "x_15", + "y": "y_13", + }, + Object { + "rectText": -0.1509352342460648, + "value": -0.1509352342460648, + "x": "x_15", + "y": "y_14", + }, + Object { + "rectText": -9.439334496282449, + "value": -9.439334496282449, + "x": "x_15", + "y": "y_15", + }, + Object { + "rectText": -9.408565254995368, + "value": -9.408565254995368, + "x": "x_15", + "y": "y_16", + }, + Object { + "rectText": -10.717340944667358, + "value": -10.717340944667358, + "x": "x_15", + "y": "y_17", + }, + Object { + "rectText": -12.231659074097587, + "value": -12.231659074097587, + "x": "x_15", + "y": "y_18", + }, + Object { + "rectText": -12.304220941049874, + "value": -12.304220941049874, + "x": "x_15", + "y": "y_19", + }, + Object { + "rectText": 12.426446278371158, + "value": 12.426446278371158, + "x": "x_16", + "y": "y_0", + }, + Object { + "rectText": 4.761205803361531, + "value": 4.761205803361531, + "x": "x_16", + "y": "y_1", + }, + Object { + "rectText": 1.5514493835400103, + "value": 1.5514493835400103, + "x": "x_16", + "y": "y_2", + }, + Object { + "rectText": 10.25485330260371, + "value": 10.25485330260371, + "x": "x_16", + "y": "y_3", + }, + Object { + "rectText": 10.443516068409753, + "value": 10.443516068409753, + "x": "x_16", + "y": "y_4", + }, + Object { + "rectText": 9.90068532879486, + "value": 9.90068532879486, + "x": "x_16", + "y": "y_5", + }, + Object { + "rectText": 5.875139865786533, + "value": 5.875139865786533, + "x": "x_16", + "y": "y_6", + }, + Object { + "rectText": 10.723957376497331, + "value": 10.723957376497331, + "x": "x_16", + "y": "y_7", + }, + Object { + "rectText": 2.066756467090924, + "value": 2.066756467090924, + "x": "x_16", + "y": "y_8", + }, + Object { + "rectText": 0.39568846222827236, + "value": 0.39568846222827236, + "x": "x_16", + "y": "y_9", + }, + Object { + "rectText": 1.9106824056688325, + "value": 1.9106824056688325, + "x": "x_16", + "y": "y_10", + }, + Object { + "rectText": 3.4554008460006247, + "value": 3.4554008460006247, + "x": "x_16", + "y": "y_11", + }, + Object { + "rectText": 5.836414662127938, + "value": 5.836414662127938, + "x": "x_16", + "y": "y_12", + }, + Object { + "rectText": 10.663420634170265, + "value": 10.663420634170265, + "x": "x_16", + "y": "y_13", + }, + Object { + "rectText": 11.562765259884168, + "value": 11.562765259884168, + "x": "x_16", + "y": "y_14", + }, + Object { + "rectText": 18.312638310718047, + "value": 18.312638310718047, + "x": "x_16", + "y": "y_15", + }, + Object { + "rectText": 24.78142561950699, + "value": 24.78142561950699, + "x": "x_16", + "y": "y_16", + }, + Object { + "rectText": 25.98741506616426, + "value": 25.98741506616426, + "x": "x_16", + "y": "y_17", + }, + Object { + "rectText": 25.21878307435221, + "value": 25.21878307435221, + "x": "x_16", + "y": "y_18", + }, + Object { + "rectText": 22.0278850405599, + "value": 22.0278850405599, + "x": "x_16", + "y": "y_19", + }, + Object { + "rectText": 15.786820017213348, + "value": 15.786820017213348, + "x": "x_17", + "y": "y_0", + }, + Object { + "rectText": 23.82727745555418, + "value": 23.82727745555418, + "x": "x_17", + "y": "y_1", + }, + Object { + "rectText": 28.102083355215736, + "value": 28.102083355215736, + "x": "x_17", + "y": "y_2", + }, + Object { + "rectText": 29.181400631242038, + "value": 29.181400631242038, + "x": "x_17", + "y": "y_3", + }, + Object { + "rectText": 33.07558322142471, + "value": 33.07558322142471, + "x": "x_17", + "y": "y_4", + }, + Object { + "rectText": 36.74806639404701, + "value": 36.74806639404701, + "x": "x_17", + "y": "y_5", + }, + Object { + "rectText": 39.12143717188403, + "value": 39.12143717188403, + "x": "x_17", + "y": "y_6", + }, + Object { + "rectText": 41.76485494373556, + "value": 41.76485494373556, + "x": "x_17", + "y": "y_7", + }, + Object { + "rectText": 54.581934085152405, + "value": 54.581934085152405, + "x": "x_17", + "y": "y_8", + }, + Object { + "rectText": 56.79992555682459, + "value": 56.79992555682459, + "x": "x_17", + "y": "y_9", + }, + Object { + "rectText": 55.50321452563245, + "value": 55.50321452563245, + "x": "x_17", + "y": "y_10", + }, + Object { + "rectText": 54.703320294165096, + "value": 54.703320294165096, + "x": "x_17", + "y": "y_11", + }, + Object { + "rectText": 63.63736027633095, + "value": 63.63736027633095, + "x": "x_17", + "y": "y_12", + }, + Object { + "rectText": 62.79712211239938, + "value": 62.79712211239938, + "x": "x_17", + "y": "y_13", + }, + Object { + "rectText": 54.381939331520186, + "value": 54.381939331520186, + "x": "x_17", + "y": "y_14", + }, + Object { + "rectText": 54.77270799612626, + "value": 54.77270799612626, + "x": "x_17", + "y": "y_15", + }, + Object { + "rectText": 55.72892300395096, + "value": 55.72892300395096, + "x": "x_17", + "y": "y_16", + }, + Object { + "rectText": 55.13836837404197, + "value": 55.13836837404197, + "x": "x_17", + "y": "y_17", + }, + Object { + "rectText": 55.4498407189013, + "value": 55.4498407189013, + "x": "x_17", + "y": "y_18", + }, + Object { + "rectText": 68.76140423378733, + "value": 68.76140423378733, + "x": "x_17", + "y": "y_19", + }, + Object { + "rectText": 25.828355052498736, + "value": 25.828355052498736, + "x": "x_18", + "y": "y_0", + }, + Object { + "rectText": 14.369250386770794, + "value": 14.369250386770794, + "x": "x_18", + "y": "y_1", + }, + Object { + "rectText": 11.122082151320692, + "value": 11.122082151320692, + "x": "x_18", + "y": "y_2", + }, + Object { + "rectText": 17.203123079730577, + "value": 17.203123079730577, + "x": "x_18", + "y": "y_3", + }, + Object { + "rectText": 22.67825393852671, + "value": 22.67825393852671, + "x": "x_18", + "y": "y_4", + }, + Object { + "rectText": 26.577346684827898, + "value": 26.577346684827898, + "x": "x_18", + "y": "y_5", + }, + Object { + "rectText": 1.341905660672623, + "value": 1.341905660672623, + "x": "x_18", + "y": "y_6", + }, + Object { + "rectText": 2.2340479176319485, + "value": 2.2340479176319485, + "x": "x_18", + "y": "y_7", + }, + Object { + "rectText": 3.5319443821756225, + "value": 3.5319443821756225, + "x": "x_18", + "y": "y_8", + }, + Object { + "rectText": 9.686881597266042, + "value": 9.686881597266042, + "x": "x_18", + "y": "y_9", + }, + Object { + "rectText": -1.086930629298445, + "value": -1.086930629298445, + "x": "x_18", + "y": "y_10", + }, + Object { + "rectText": -3.275155410653531, + "value": -3.275155410653531, + "x": "x_18", + "y": "y_11", + }, + Object { + "rectText": -2.3182235215935463, + "value": -2.3182235215935463, + "x": "x_18", + "y": "y_12", + }, + Object { + "rectText": -7.102421907260435, + "value": -7.102421907260435, + "x": "x_18", + "y": "y_13", + }, + Object { + "rectText": -15.369316543252658, + "value": -15.369316543252658, + "x": "x_18", + "y": "y_14", + }, + Object { + "rectText": -13.618633943842825, + "value": -13.618633943842825, + "x": "x_18", + "y": "y_15", + }, + Object { + "rectText": -6.132435488791322, + "value": -6.132435488791322, + "x": "x_18", + "y": "y_16", + }, + Object { + "rectText": -12.222227236438126, + "value": -12.222227236438126, + "x": "x_18", + "y": "y_17", + }, + Object { + "rectText": -16.160855914516, + "value": -16.160855914516, + "x": "x_18", + "y": "y_18", + }, + Object { + "rectText": -11.104838839030073, + "value": -11.104838839030073, + "x": "x_18", + "y": "y_19", + }, + Object { + "rectText": 15.884458175971286, + "value": 15.884458175971286, + "x": "x_19", + "y": "y_0", + }, + Object { + "rectText": 9.730029718884163, + "value": 9.730029718884163, + "x": "x_19", + "y": "y_1", + }, + Object { + "rectText": 17.271525748515398, + "value": 17.271525748515398, + "x": "x_19", + "y": "y_2", + }, + Object { + "rectText": 15.96262678993938, + "value": 15.96262678993938, + "x": "x_19", + "y": "y_3", + }, + Object { + "rectText": 14.910979364805373, + "value": 14.910979364805373, + "x": "x_19", + "y": "y_4", + }, + Object { + "rectText": 16.005211030243927, + "value": 16.005211030243927, + "x": "x_19", + "y": "y_5", + }, + Object { + "rectText": 16.777803239858564, + "value": 16.777803239858564, + "x": "x_19", + "y": "y_6", + }, + Object { + "rectText": 16.088953253894616, + "value": 16.088953253894616, + "x": "x_19", + "y": "y_7", + }, + Object { + "rectText": 24.532968918280666, + "value": 24.532968918280666, + "x": "x_19", + "y": "y_8", + }, + Object { + "rectText": 29.573837224244713, + "value": 29.573837224244713, + "x": "x_19", + "y": "y_9", + }, + Object { + "rectText": 29.942519927990794, + "value": 29.942519927990794, + "x": "x_19", + "y": "y_10", + }, + Object { + "rectText": 34.69783250602105, + "value": 34.69783250602105, + "x": "x_19", + "y": "y_11", + }, + Object { + "rectText": 28.362102774855607, + "value": 28.362102774855607, + "x": "x_19", + "y": "y_12", + }, + Object { + "rectText": 25.96909143426486, + "value": 25.96909143426486, + "x": "x_19", + "y": "y_13", + }, + Object { + "rectText": 25.018616836414115, + "value": 25.018616836414115, + "x": "x_19", + "y": "y_14", + }, + Object { + "rectText": 34.04601203745518, + "value": 34.04601203745518, + "x": "x_19", + "y": "y_15", + }, + Object { + "rectText": 32.12418971970468, + "value": 32.12418971970468, + "x": "x_19", + "y": "y_16", + }, + Object { + "rectText": 30.768724196434682, + "value": 30.768724196434682, + "x": "x_19", + "y": "y_17", + }, + Object { + "rectText": 32.26936734704534, + "value": 32.26936734704534, + "x": "x_19", + "y": "y_18", + }, + Object { + "rectText": 32.93901719565705, + "value": 32.93901719565705, + "x": "x_19", + "y": "y_19", + }, + ], + "legend": undefined, + "value": 0, + }, + ], + "domainValuesForColorScale": Array [ + -16.160855914516, + -6.8876661903012195, + 2.3855235339135596, + 11.65871325812834, + 20.931902982343118, + 30.2050927065579, + 39.47828243077268, + 48.75147215498746, + 58.024661879202235, + 67.29785160341703, + 76.5710413276318, + ], + "hideLegend": true, + "rangeValuesForColorScale": Array [ + "rgb(158,1,66)", + "rgb(213,62,79)", + "rgb(244,109,67)", + "rgb(253,174,97)", + "rgb(254,224,139)", + "rgb(255,255,191)", + "rgb(230,245,152)", + "rgb(171,221,164)", + "rgb(102,194,165)", + "rgb(50,136,189)", + "rgb(94,79,162)", + ], + "showYAxisLables": true, + "sortOrder": "none", + "xAxisTitle": "", + "yAxisTitle": "", +} +`; + +exports[`transform Plotly Json To chart Props transformPlotlyJsonToHorizontalBarWithAxisProps - Should return HBC with axis chart props 1`] = ` +Object { + "barHeight": 12.662117371807371, + "chartTitle": "PHP Framework Popularity at Work - SitePoint, 2015", + "data": Array [ + Object { + "color": "#4f6bed", + "legend": "Aura", + "x": 10, + "y": "Aura", + }, + Object { + "color": "#d0b232", + "legend": "Drupal", + "x": 11, + "y": "Drupal", + }, + Object { + "color": "#c36bd1", + "legend": "TYPO3 Flow", + "x": 17, + "y": "TYPO3 Flow", + }, + Object { + "color": "#73aa24", + "legend": "FuelPHP", + "x": 25, + "y": "FuelPHP", + }, + Object { + "color": "#d77440", + "legend": "Kohana", + "x": 35, + "y": "Kohana", + }, + Object { + "color": "#4fa1e1", + "legend": "Typo 3", + "x": 35, + "y": "Typo 3", + }, + Object { + "color": "#27ac22", + "legend": "Simple MVC Framework", + "x": 42, + "y": "Simple MVC Framework", + }, + Object { + "color": "#a083c9", + "legend": "Silex", + "x": 65, + "y": "Silex", + }, + Object { + "color": "#4cb4b7", + "legend": "Slim", + "x": 79, + "y": "Slim", + }, + Object { + "color": "#ee5fb7", + "legend": "Phalcon", + "x": 169, + "y": "Phalcon", + }, + Object { + "color": "#93a4f4", + "legend": "We use a CMS for everything", + "x": 203, + "y": "We use a CMS for everything", + }, + Object { + "color": "#ae8c00", + "legend": "No Framework", + "x": 243, + "y": "No Framework", + }, + Object { + "color": "#b146c2", + "legend": "CakePHP", + "x": 255, + "y": "CakePHP", + }, + Object { + "color": "#57811b", + "legend": "Zend Framework 1", + "x": 274, + "y": "Zend Framework 1", + }, + Object { + "color": "#ca5010", + "legend": "Company Internal Framework", + "x": 378, + "y": "Company Internal Framework", + }, + Object { + "color": "#3a96dd", + "legend": "Zend Framework 2", + "x": 390, + "y": "Zend Framework 2", + }, + Object { + "color": "#13a10e", + "legend": "Yii 1", + "x": 407, + "y": "Yii 1", + }, + Object { + "color": "#9373c0", + "legend": "PHPixie", + "x": 418, + "y": "PHPixie", + }, + Object { + "color": "#2aa0a4", + "legend": "Yii 2", + "x": 504, + "y": "Yii 2", + }, + Object { + "color": "#e3008c", + "legend": "CodeIgniter", + "x": 597, + "y": "CodeIgniter", + }, + Object { + "color": "#637cef", + "legend": "Nette", + "x": 671, + "y": "Nette", + }, + Object { + "color": "#dac157", + "legend": "Symfony2", + "x": 1067, + "y": "Symfony2", + }, + Object { + "color": "#cf87da", + "legend": "Laravel", + "x": 1659, + "y": "Laravel", + }, + ], + "secondaryYAxistitle": "", + "showYAxisLables": true, + "styles": Object { + "root": Object { + "height": 742, + "width": 850, + }, + }, + "xAxisTitle": "Votes", + "yAxisTitle": "Framework", +} +`; + +exports[`transform Plotly Json To chart Props transformPlotlyJsonToSankeyProps - Should return sankey chart props 1`] = ` +Object { + "data": Object { + "SankeyChartData": Object { + "links": Array [ + Object { + "source": 0, + "target": 5, + "value": 20, + }, + Object { + "source": 0, + "target": 6, + "value": 3, + }, + Object { + "source": 0, + "target": 7, + "value": 5, + }, + Object { + "source": 1, + "target": 5, + "value": 14, + }, + Object { + "source": 1, + "target": 6, + "value": 1, + }, + Object { + "source": 1, + "target": 7, + "value": 1, + }, + Object { + "source": 2, + "target": 5, + "value": 3, + }, + Object { + "source": 2, + "target": 6, + "value": 17, + }, + Object { + "source": 2, + "target": 7, + "value": 2, + }, + Object { + "source": 3, + "target": 5, + "value": 3, + }, + Object { + "source": 3, + "target": 6, + "value": 9, + }, + Object { + "source": 3, + "target": 7, + "value": 2, + }, + Object { + "source": 4, + "target": 5, + "value": 5, + }, + Object { + "source": 4, + "target": 6, + "value": 9, + }, + Object { + "source": 4, + "target": 7, + "value": 8, + }, + ], + "nodes": Array [ + Object { + "color": "#ea38a6", + "name": "Remain+No – 28", + "nodeId": 0, + }, + Object { + "color": "#038387", + "name": "Leave+No – 16", + "nodeId": 1, + }, + Object { + "color": "#8764b8", + "name": "Remain+Yes – 21", + "nodeId": 2, + }, + Object { + "color": "#11910d", + "name": "Leave+Yes – 14", + "nodeId": 3, + }, + Object { + "color": "#3487c7", + "name": "Didn’t vote in at least one referendum – 21", + "nodeId": 4, + }, + Object { + "color": "#d06228", + "name": "46 – No", + "nodeId": 5, + }, + Object { + "color": "#689920", + "name": "39 – Yes", + "nodeId": 6, + }, + Object { + "color": "#ba58c9", + "name": "14 – Don’t know / would not vote", + "nodeId": 7, + }, + ], + }, + "chartTitle": "Scottish Referendum Voters who now want Independence", + }, + "enableReflow": true, + "height": 772, + "shouldResize": 1212, + "styles": Object { + "root": Object { + "fontSize": 10, + }, + }, + "width": 440, +} +`; + +exports[`transform Plotly Json To chart Props transformPlotlyJsonToScatterChartProps - Should return area chart props 1`] = ` +Object { + "data": Object { + "chartTitle": "", + "lineChartData": Array [ + Object { + "color": "#f7adda", + "data": Array [ + Object { + "x": 0, + "y": 0.17048910089864067, + }, + Object { + "x": 1, + "y": 0.05390702725063046, + }, + Object { + "x": 2, + "y": 0.7560889217240573, + }, + Object { + "x": 3, + "y": 0.7393313216390578, + }, + Object { + "x": 4, + "y": 0.7562979443674754, + }, + Object { + "x": 5, + "y": 0.983908108492343, + }, + Object { + "x": 6, + "y": 0.4552096139092071, + }, + Object { + "x": 7, + "y": 0.751939393026647, + }, + Object { + "x": 8, + "y": 0.42441695150031034, + }, + Object { + "x": 9, + "y": 0.6119820237450841, + }, + ], + "legend": "a", + }, + Object { + "color": "#9bd9db", + "data": Array [ + Object { + "x": 0, + "y": 1.0921498980687505, + }, + Object { + "x": 1, + "y": 0.628379692444796, + }, + Object { + "x": 2, + "y": 1.6804387333467445, + }, + Object { + "x": 3, + "y": 1.1741874271317159, + }, + Object { + "x": 4, + "y": 1.7098535938519392, + }, + Object { + "x": 5, + "y": 1.0165440369832146, + }, + Object { + "x": 6, + "y": 0.8201578488720772, + }, + Object { + "x": 7, + "y": 1.019179653143562, + }, + Object { + "x": 8, + "y": 0.5391840333768539, + }, + Object { + "x": 9, + "y": 0.9023036941696878, + }, + ], + "legend": "b", + }, + Object { + "color": "#b29ad4", + "data": Array [ + Object { + "x": 0, + "y": 1.5084498776097979, + }, + Object { + "x": 1, + "y": 1.0993096327196032, + }, + Object { + "x": 2, + "y": 2.5468884763826125, + }, + Object { + "x": 3, + "y": 1.3139261978658, + }, + Object { + "x": 4, + "y": 1.7288516603693358, + }, + Object { + "x": 5, + "y": 1.3500413551768342, + }, + Object { + "x": 6, + "y": 1.4111774146124456, + }, + Object { + "x": 7, + "y": 1.1245312639069405, + }, + Object { + "x": 8, + "y": 1.4068617318281056, + }, + Object { + "x": 9, + "y": 0.9236499701488171, + }, + ], + "legend": "c", + }, + Object { + "color": "#a4cc6c", + "data": Array [ + Object { + "x": 0, + "y": 1.912915766078795, + }, + Object { + "x": 1, + "y": 1.6450103381519354, + }, + Object { + "x": 2, + "y": 3.523866933241722, + }, + Object { + "x": 3, + "y": 1.656799203492564, + }, + Object { + "x": 4, + "y": 2.666064160881149, + }, + Object { + "x": 5, + "y": 2.2985767814076814, + }, + Object { + "x": 6, + "y": 1.6491300653173326, + }, + Object { + "x": 7, + "y": 1.2880873970749964, + }, + Object { + "x": 8, + "y": 2.192375146193222, + }, + Object { + "x": 9, + "y": 1.6271909616796654, + }, + ], + "legend": "d", + }, + ], + }, + "mode": "tonexty", + "secondaryYAxistitle": undefined, + "secondaryYScaleOptions": undefined, + "supportNegativeData": true, + "xAxisTitle": "", + "yAxisTitle": "", +} +`; + +exports[`transform Plotly Json To chart Props transformPlotlyJsonToScatterChartProps - Should return line chart props 1`] = ` +Object { + "data": Object { + "chartTitle": "", + "lineChartData": Array [ + Object { + "color": "#a7e3a5", + "data": Array [ + Object { + "x": 2015-01-01T00:00:00.000Z, + "y": 0.5353935439391206, + }, + Object { + "x": 2015-01-02T00:00:00.000Z, + "y": -0.3510205670171982, + }, + Object { + "x": 2015-01-03T00:00:00.000Z, + "y": -1.3420793330744663, + }, + Object { + "x": 2015-01-04T00:00:00.000Z, + "y": -1.683479706754631, + }, + Object { + "x": 2015-01-05T00:00:00.000Z, + "y": -2.0207368899942826, + }, + Object { + "x": 2015-01-06T00:00:00.000Z, + "y": 0.006604084375472663, + }, + Object { + "x": 2015-01-07T00:00:00.000Z, + "y": 0.8037048387382045, + }, + Object { + "x": 2015-01-08T00:00:00.000Z, + "y": 1.6685589999803645, + }, + Object { + "x": 2015-01-09T00:00:00.000Z, + "y": 1.2683547027403048, + }, + Object { + "x": 2015-01-10T00:00:00.000Z, + "y": -1.3330462677331034, + }, + Object { + "x": 2015-01-11T00:00:00.000Z, + "y": -1.8663123665480104, + }, + Object { + "x": 2015-01-12T00:00:00.000Z, + "y": -2.8051461261147357, + }, + Object { + "x": 2015-01-13T00:00:00.000Z, + "y": -4.563508055068453, + }, + Object { + "x": 2015-01-14T00:00:00.000Z, + "y": -3.7591847216910996, + }, + Object { + "x": 2015-01-15T00:00:00.000Z, + "y": -3.5134185618878746, + }, + Object { + "x": 2015-01-16T00:00:00.000Z, + "y": -5.3419268826351995, + }, + Object { + "x": 2015-01-17T00:00:00.000Z, + "y": -3.332156069299614, + }, + Object { + "x": 2015-01-18T00:00:00.000Z, + "y": -3.5678897362109545, + }, + Object { + "x": 2015-01-19T00:00:00.000Z, + "y": -3.8548236009547465, + }, + Object { + "x": 2015-01-20T00:00:00.000Z, + "y": -4.58628192762981, + }, + Object { + "x": 2015-01-21T00:00:00.000Z, + "y": -4.116554826788904, + }, + Object { + "x": 2015-01-22T00:00:00.000Z, + "y": -2.7610003378381496, + }, + Object { + "x": 2015-01-23T00:00:00.000Z, + "y": -2.621859111953831, + }, + Object { + "x": 2015-01-24T00:00:00.000Z, + "y": -2.6349689848833315, + }, + Object { + "x": 2015-01-25T00:00:00.000Z, + "y": -2.0581142585936076, + }, + Object { + "x": 2015-01-26T00:00:00.000Z, + "y": -0.7744078058377932, + }, + Object { + "x": 2015-01-27T00:00:00.000Z, + "y": 0.9002451055355818, + }, + Object { + "x": 2015-01-28T00:00:00.000Z, + "y": 0.8373590393039949, + }, + Object { + "x": 2015-01-29T00:00:00.000Z, + "y": 0.5532093840234236, + }, + Object { + "x": 2015-01-30T00:00:00.000Z, + "y": 1.469976651890828, + }, + Object { + "x": 2015-01-31T00:00:00.000Z, + "y": 3.1860367266233904, + }, + Object { + "x": 2015-02-01T00:00:00.000Z, + "y": 2.493612510772345, + }, + Object { + "x": 2015-02-02T00:00:00.000Z, + "y": 1.9464391258267615, + }, + Object { + "x": 2015-02-03T00:00:00.000Z, + "y": 1.8807283125005585, + }, + Object { + "x": 2015-02-04T00:00:00.000Z, + "y": 3.0189402685173534, + }, + Object { + "x": 2015-02-05T00:00:00.000Z, + "y": 4.556005864163605, + }, + Object { + "x": 2015-02-06T00:00:00.000Z, + "y": 5.516442345945973, + }, + Object { + "x": 2015-02-07T00:00:00.000Z, + "y": 4.319606652282435, + }, + Object { + "x": 2015-02-08T00:00:00.000Z, + "y": 6.845756127344204, + }, + Object { + "x": 2015-02-09T00:00:00.000Z, + "y": 7.053236096270982, + }, + Object { + "x": 2015-02-10T00:00:00.000Z, + "y": 7.681494725458877, + }, + Object { + "x": 2015-02-11T00:00:00.000Z, + "y": 7.526563745782537, + }, + Object { + "x": 2015-02-12T00:00:00.000Z, + "y": 8.858342186205558, + }, + Object { + "x": 2015-02-13T00:00:00.000Z, + "y": 9.021889375014881, + }, + Object { + "x": 2015-02-14T00:00:00.000Z, + "y": 8.209805336778926, + }, + Object { + "x": 2015-02-15T00:00:00.000Z, + "y": 9.383959972549016, + }, + Object { + "x": 2015-02-16T00:00:00.000Z, + "y": 11.195848970970625, + }, + Object { + "x": 2015-02-17T00:00:00.000Z, + "y": 12.561537445362251, + }, + Object { + "x": 2015-02-18T00:00:00.000Z, + "y": 14.373511358982237, + }, + Object { + "x": 2015-02-19T00:00:00.000Z, + "y": 15.887456275652418, + }, + Object { + "x": 2015-02-20T00:00:00.000Z, + "y": 14.491455240251522, + }, + Object { + "x": 2015-02-21T00:00:00.000Z, + "y": 15.199461217404735, + }, + Object { + "x": 2015-02-22T00:00:00.000Z, + "y": 16.378844807972094, + }, + Object { + "x": 2015-02-23T00:00:00.000Z, + "y": 14.348345501207364, + }, + Object { + "x": 2015-02-24T00:00:00.000Z, + "y": 14.961597203409823, + }, + Object { + "x": 2015-02-25T00:00:00.000Z, + "y": 15.457566696478484, + }, + Object { + "x": 2015-02-26T00:00:00.000Z, + "y": 14.942769687687289, + }, + Object { + "x": 2015-02-27T00:00:00.000Z, + "y": 15.721527909780036, + }, + Object { + "x": 2015-02-28T00:00:00.000Z, + "y": 13.091278962257627, + }, + Object { + "x": 2015-03-01T00:00:00.000Z, + "y": 14.295247001092115, + }, + Object { + "x": 2015-03-02T00:00:00.000Z, + "y": 15.296655272416865, + }, + Object { + "x": 2015-03-03T00:00:00.000Z, + "y": 14.436440585461526, + }, + Object { + "x": 2015-03-04T00:00:00.000Z, + "y": 13.912453188370755, + }, + Object { + "x": 2015-03-05T00:00:00.000Z, + "y": 12.433861225213807, + }, + Object { + "x": 2015-03-06T00:00:00.000Z, + "y": 14.061345247447989, + }, + Object { + "x": 2015-03-07T00:00:00.000Z, + "y": 13.326092951912521, + }, + Object { + "x": 2015-03-08T00:00:00.000Z, + "y": 13.566974950387175, + }, + Object { + "x": 2015-03-09T00:00:00.000Z, + "y": 12.96345607653163, + }, + Object { + "x": 2015-03-10T00:00:00.000Z, + "y": 12.205278846692087, + }, + Object { + "x": 2015-03-11T00:00:00.000Z, + "y": 11.364010452431279, + }, + Object { + "x": 2015-03-12T00:00:00.000Z, + "y": 12.120962982512733, + }, + Object { + "x": 2015-03-13T00:00:00.000Z, + "y": 13.570258079014422, + }, + Object { + "x": 2015-03-14T00:00:00.000Z, + "y": 14.613857418348378, + }, + Object { + "x": 2015-03-15T00:00:00.000Z, + "y": 15.48868026864105, + }, + Object { + "x": 2015-03-16T00:00:00.000Z, + "y": 15.421250297066777, + }, + Object { + "x": 2015-03-17T00:00:00.000Z, + "y": 16.562957844203055, + }, + Object { + "x": 2015-03-18T00:00:00.000Z, + "y": 16.365666723485436, + }, + Object { + "x": 2015-03-19T00:00:00.000Z, + "y": 15.848038393086913, + }, + Object { + "x": 2015-03-20T00:00:00.000Z, + "y": 16.170083705874156, + }, + Object { + "x": 2015-03-21T00:00:00.000Z, + "y": 16.446617416519754, + }, + Object { + "x": 2015-03-22T00:00:00.000Z, + "y": 15.024371154281331, + }, + Object { + "x": 2015-03-23T00:00:00.000Z, + "y": 14.802238239296665, + }, + Object { + "x": 2015-03-24T00:00:00.000Z, + "y": 13.156751496135007, + }, + Object { + "x": 2015-03-25T00:00:00.000Z, + "y": 14.06168725142282, + }, + Object { + "x": 2015-03-26T00:00:00.000Z, + "y": 14.94588113322983, + }, + Object { + "x": 2015-03-27T00:00:00.000Z, + "y": 14.127589669913032, + }, + Object { + "x": 2015-03-28T00:00:00.000Z, + "y": 13.885898170515487, + }, + Object { + "x": 2015-03-29T00:00:00.000Z, + "y": 13.692030694564533, + }, + Object { + "x": 2015-03-30T00:00:00.000Z, + "y": 14.943253908206318, + }, + Object { + "x": 2015-03-31T00:00:00.000Z, + "y": 14.529368596515058, + }, + Object { + "x": 2015-04-01T00:00:00.000Z, + "y": 14.661473471114782, + }, + Object { + "x": 2015-04-02T00:00:00.000Z, + "y": 13.67375983483632, + }, + Object { + "x": 2015-04-03T00:00:00.000Z, + "y": 13.382284458918326, + }, + Object { + "x": 2015-04-04T00:00:00.000Z, + "y": 12.527287002966496, + }, + Object { + "x": 2015-04-05T00:00:00.000Z, + "y": 12.767994473001014, + }, + Object { + "x": 2015-04-06T00:00:00.000Z, + "y": 12.651030056419879, + }, + Object { + "x": 2015-04-07T00:00:00.000Z, + "y": 12.141617852418765, + }, + Object { + "x": 2015-04-08T00:00:00.000Z, + "y": 13.606694447410502, + }, + Object { + "x": 2015-04-09T00:00:00.000Z, + "y": 13.923089943159189, + }, + Object { + "x": 2015-04-10T00:00:00.000Z, + "y": 14.003348672865656, + }, + ], + "legend": "Trace 0", + }, + Object { + "color": "#83bdeb", + "data": Array [ + Object { + "x": 2015-01-01T00:00:00.000Z, + "y": -2.58404773330316, + }, + Object { + "x": 2015-01-02T00:00:00.000Z, + "y": -1.9162964761259451, + }, + Object { + "x": 2015-01-03T00:00:00.000Z, + "y": -1.8899798841571565, + }, + Object { + "x": 2015-01-04T00:00:00.000Z, + "y": -1.098466181069551, + }, + Object { + "x": 2015-01-05T00:00:00.000Z, + "y": -1.2161136413159992, + }, + Object { + "x": 2015-01-06T00:00:00.000Z, + "y": -0.9298011508867184, + }, + Object { + "x": 2015-01-07T00:00:00.000Z, + "y": -2.5216450120142193, + }, + Object { + "x": 2015-01-08T00:00:00.000Z, + "y": -1.5547013224314532, + }, + Object { + "x": 2015-01-09T00:00:00.000Z, + "y": -3.1293219775443117, + }, + Object { + "x": 2015-01-10T00:00:00.000Z, + "y": -2.7232351981528025, + }, + Object { + "x": 2015-01-11T00:00:00.000Z, + "y": -1.704449229625379, + }, + Object { + "x": 2015-01-12T00:00:00.000Z, + "y": -1.2702366750752472, + }, + Object { + "x": 2015-01-13T00:00:00.000Z, + "y": -1.7688923656442583, + }, + Object { + "x": 2015-01-14T00:00:00.000Z, + "y": -1.9810878959630682, + }, + Object { + "x": 2015-01-15T00:00:00.000Z, + "y": -1.0881359248000217, + }, + Object { + "x": 2015-01-16T00:00:00.000Z, + "y": -0.5214761704035035, + }, + Object { + "x": 2015-01-17T00:00:00.000Z, + "y": -0.639866394654719, + }, + Object { + "x": 2015-01-18T00:00:00.000Z, + "y": -2.258513886233204, + }, + Object { + "x": 2015-01-19T00:00:00.000Z, + "y": -0.8711892253875131, + }, + Object { + "x": 2015-01-20T00:00:00.000Z, + "y": -0.45426547393253053, + }, + Object { + "x": 2015-01-21T00:00:00.000Z, + "y": -2.4076676391235785, + }, + Object { + "x": 2015-01-22T00:00:00.000Z, + "y": -2.2450025826137097, + }, + Object { + "x": 2015-01-23T00:00:00.000Z, + "y": -2.3488062397069234, + }, + Object { + "x": 2015-01-24T00:00:00.000Z, + "y": -3.2188990647525304, + }, + Object { + "x": 2015-01-25T00:00:00.000Z, + "y": -2.6042445674055594, + }, + Object { + "x": 2015-01-26T00:00:00.000Z, + "y": -2.9702468803291966, + }, + Object { + "x": 2015-01-27T00:00:00.000Z, + "y": -4.139691822816822, + }, + Object { + "x": 2015-01-28T00:00:00.000Z, + "y": -3.9967022316870042, + }, + Object { + "x": 2015-01-29T00:00:00.000Z, + "y": -4.796271521377118, + }, + Object { + "x": 2015-01-30T00:00:00.000Z, + "y": -5.244924380701339, + }, + Object { + "x": 2015-01-31T00:00:00.000Z, + "y": -6.965620503609484, + }, + Object { + "x": 2015-02-01T00:00:00.000Z, + "y": -6.430396926773768, + }, + Object { + "x": 2015-02-02T00:00:00.000Z, + "y": -5.234457265252843, + }, + Object { + "x": 2015-02-03T00:00:00.000Z, + "y": -6.181791776690352, + }, + Object { + "x": 2015-02-04T00:00:00.000Z, + "y": -7.3464387119459085, + }, + Object { + "x": 2015-02-05T00:00:00.000Z, + "y": -7.085650875056526, + }, + Object { + "x": 2015-02-06T00:00:00.000Z, + "y": -6.795217278293396, + }, + Object { + "x": 2015-02-07T00:00:00.000Z, + "y": -6.08725142043377, + }, + Object { + "x": 2015-02-08T00:00:00.000Z, + "y": -5.3416313194169875, + }, + Object { + "x": 2015-02-09T00:00:00.000Z, + "y": -4.900094995211111, + }, + Object { + "x": 2015-02-10T00:00:00.000Z, + "y": -4.715363010029477, + }, + Object { + "x": 2015-02-11T00:00:00.000Z, + "y": -3.6757033584677927, + }, + Object { + "x": 2015-02-12T00:00:00.000Z, + "y": -5.873900613367271, + }, + Object { + "x": 2015-02-13T00:00:00.000Z, + "y": -7.685787089886274, + }, + Object { + "x": 2015-02-14T00:00:00.000Z, + "y": -8.833149292574403, + }, + Object { + "x": 2015-02-15T00:00:00.000Z, + "y": -9.373517123532867, + }, + Object { + "x": 2015-02-16T00:00:00.000Z, + "y": -10.519456187180836, + }, + Object { + "x": 2015-02-17T00:00:00.000Z, + "y": -8.012082850355387, + }, + Object { + "x": 2015-02-18T00:00:00.000Z, + "y": -8.556759031756883, + }, + Object { + "x": 2015-02-19T00:00:00.000Z, + "y": -8.78527769843948, + }, + Object { + "x": 2015-02-20T00:00:00.000Z, + "y": -8.801850250864483, + }, + Object { + "x": 2015-02-21T00:00:00.000Z, + "y": -9.031427690493008, + }, + Object { + "x": 2015-02-22T00:00:00.000Z, + "y": -9.289972806031075, + }, + Object { + "x": 2015-02-23T00:00:00.000Z, + "y": -8.434541044235305, + }, + Object { + "x": 2015-02-24T00:00:00.000Z, + "y": -8.543619303217836, + }, + Object { + "x": 2015-02-25T00:00:00.000Z, + "y": -9.817816201809572, + }, + Object { + "x": 2015-02-26T00:00:00.000Z, + "y": -9.691704922707196, + }, + Object { + "x": 2015-02-27T00:00:00.000Z, + "y": -9.172230718814316, + }, + Object { + "x": 2015-02-28T00:00:00.000Z, + "y": -10.389025830978015, + }, + Object { + "x": 2015-03-01T00:00:00.000Z, + "y": -9.418276522564378, + }, + Object { + "x": 2015-03-02T00:00:00.000Z, + "y": -8.844666134378604, + }, + Object { + "x": 2015-03-03T00:00:00.000Z, + "y": -10.649699554950736, + }, + Object { + "x": 2015-03-04T00:00:00.000Z, + "y": -11.433978738990442, + }, + Object { + "x": 2015-03-05T00:00:00.000Z, + "y": -11.022214964648152, + }, + Object { + "x": 2015-03-06T00:00:00.000Z, + "y": -11.156982299530265, + }, + Object { + "x": 2015-03-07T00:00:00.000Z, + "y": -12.846500605483975, + }, + Object { + "x": 2015-03-08T00:00:00.000Z, + "y": -12.700459270895378, + }, + Object { + "x": 2015-03-09T00:00:00.000Z, + "y": -13.701718476553872, + }, + Object { + "x": 2015-03-10T00:00:00.000Z, + "y": -14.281259852458456, + }, + Object { + "x": 2015-03-11T00:00:00.000Z, + "y": -13.197701892598191, + }, + Object { + "x": 2015-03-12T00:00:00.000Z, + "y": -13.444607930505104, + }, + Object { + "x": 2015-03-13T00:00:00.000Z, + "y": -12.703127086621702, + }, + Object { + "x": 2015-03-14T00:00:00.000Z, + "y": -12.38184968649959, + }, + Object { + "x": 2015-03-15T00:00:00.000Z, + "y": -13.545422038889187, + }, + Object { + "x": 2015-03-16T00:00:00.000Z, + "y": -12.062411162554307, + }, + Object { + "x": 2015-03-17T00:00:00.000Z, + "y": -12.190051993521331, + }, + Object { + "x": 2015-03-18T00:00:00.000Z, + "y": -13.801739083658532, + }, + Object { + "x": 2015-03-19T00:00:00.000Z, + "y": -14.198265394729127, + }, + Object { + "x": 2015-03-20T00:00:00.000Z, + "y": -14.29078542197376, + }, + Object { + "x": 2015-03-21T00:00:00.000Z, + "y": -13.45263060195906, + }, + Object { + "x": 2015-03-22T00:00:00.000Z, + "y": -13.130412206893606, + }, + Object { + "x": 2015-03-23T00:00:00.000Z, + "y": -14.189794518505105, + }, + Object { + "x": 2015-03-24T00:00:00.000Z, + "y": -12.647928857811877, + }, + Object { + "x": 2015-03-25T00:00:00.000Z, + "y": -13.252175401809115, + }, + Object { + "x": 2015-03-26T00:00:00.000Z, + "y": -13.526006774399674, + }, + Object { + "x": 2015-03-27T00:00:00.000Z, + "y": -13.640567463371012, + }, + Object { + "x": 2015-03-28T00:00:00.000Z, + "y": -13.234252510186453, + }, + Object { + "x": 2015-03-29T00:00:00.000Z, + "y": -12.313307209824384, + }, + Object { + "x": 2015-03-30T00:00:00.000Z, + "y": -11.218557557877709, + }, + Object { + "x": 2015-03-31T00:00:00.000Z, + "y": -10.7821947135954, + }, + Object { + "x": 2015-04-01T00:00:00.000Z, + "y": -8.89016408336461, + }, + Object { + "x": 2015-04-02T00:00:00.000Z, + "y": -9.662631443485989, + }, + Object { + "x": 2015-04-03T00:00:00.000Z, + "y": -6.909371824212538, + }, + Object { + "x": 2015-04-04T00:00:00.000Z, + "y": -7.048202688582138, + }, + Object { + "x": 2015-04-05T00:00:00.000Z, + "y": -4.971706592042745, + }, + Object { + "x": 2015-04-06T00:00:00.000Z, + "y": -4.310618310025603, + }, + Object { + "x": 2015-04-07T00:00:00.000Z, + "y": -2.954237793688564, + }, + Object { + "x": 2015-04-08T00:00:00.000Z, + "y": -2.0883264569176156, + }, + Object { + "x": 2015-04-09T00:00:00.000Z, + "y": 1.1805740980198571, + }, + Object { + "x": 2015-04-10T00:00:00.000Z, + "y": 0.5040426644599496, + }, + ], + "legend": "Trace 1", + }, + Object { + "color": "#df8e64", + "data": Array [ + Object { + "x": 2015-01-01T00:00:00.000Z, + "y": 0.4661114764240781, + }, + Object { + "x": 2015-01-02T00:00:00.000Z, + "y": 1.0610769506804194, + }, + Object { + "x": 2015-01-03T00:00:00.000Z, + "y": 1.0620659379275244, + }, + Object { + "x": 2015-01-04T00:00:00.000Z, + "y": -0.5603096501263787, + }, + Object { + "x": 2015-01-05T00:00:00.000Z, + "y": -0.22966983294858567, + }, + Object { + "x": 2015-01-06T00:00:00.000Z, + "y": 1.1358334022099883, + }, + Object { + "x": 2015-01-07T00:00:00.000Z, + "y": 1.8697838063194905, + }, + Object { + "x": 2015-01-08T00:00:00.000Z, + "y": 1.8307593169232188, + }, + Object { + "x": 2015-01-09T00:00:00.000Z, + "y": 2.6294937170536055, + }, + Object { + "x": 2015-01-10T00:00:00.000Z, + "y": 1.456439760404607, + }, + Object { + "x": 2015-01-11T00:00:00.000Z, + "y": 3.571977139947352, + }, + Object { + "x": 2015-01-12T00:00:00.000Z, + "y": 3.305623978930223, + }, + Object { + "x": 2015-01-13T00:00:00.000Z, + "y": 4.369054542737759, + }, + Object { + "x": 2015-01-14T00:00:00.000Z, + "y": 4.134928856846778, + }, + Object { + "x": 2015-01-15T00:00:00.000Z, + "y": 2.525747905079978, + }, + Object { + "x": 2015-01-16T00:00:00.000Z, + "y": 4.45625041538837, + }, + Object { + "x": 2015-01-17T00:00:00.000Z, + "y": 5.331621195457201, + }, + Object { + "x": 2015-01-18T00:00:00.000Z, + "y": 5.01722152487662, + }, + Object { + "x": 2015-01-19T00:00:00.000Z, + "y": 3.2730061427478807, + }, + Object { + "x": 2015-01-20T00:00:00.000Z, + "y": 2.3895586625726164, + }, + Object { + "x": 2015-01-21T00:00:00.000Z, + "y": 1.5551868349111646, + }, + Object { + "x": 2015-01-22T00:00:00.000Z, + "y": 0.9222137047406664, + }, + Object { + "x": 2015-01-23T00:00:00.000Z, + "y": -0.2408476097748915, + }, + Object { + "x": 2015-01-24T00:00:00.000Z, + "y": -0.7735805458656726, + }, + Object { + "x": 2015-01-25T00:00:00.000Z, + "y": -0.8871954038346644, + }, + Object { + "x": 2015-01-26T00:00:00.000Z, + "y": -1.9822438634492547, + }, + Object { + "x": 2015-01-27T00:00:00.000Z, + "y": -0.8886612143982666, + }, + Object { + "x": 2015-01-28T00:00:00.000Z, + "y": -0.7149527896910689, + }, + Object { + "x": 2015-01-29T00:00:00.000Z, + "y": -1.1377284325144619, + }, + Object { + "x": 2015-01-30T00:00:00.000Z, + "y": -1.7585300048885872, + }, + Object { + "x": 2015-01-31T00:00:00.000Z, + "y": -2.8117170543153254, + }, + Object { + "x": 2015-02-01T00:00:00.000Z, + "y": -2.6809842525932175, + }, + Object { + "x": 2015-02-02T00:00:00.000Z, + "y": -1.6457602974924186, + }, + Object { + "x": 2015-02-03T00:00:00.000Z, + "y": -2.1361202183757593, + }, + Object { + "x": 2015-02-04T00:00:00.000Z, + "y": -3.506112394459107, + }, + Object { + "x": 2015-02-05T00:00:00.000Z, + "y": -3.338531391597358, + }, + Object { + "x": 2015-02-06T00:00:00.000Z, + "y": -5.511057758779813, + }, + Object { + "x": 2015-02-07T00:00:00.000Z, + "y": -3.5261371875358676, + }, + Object { + "x": 2015-02-08T00:00:00.000Z, + "y": -4.05255557741406, + }, + Object { + "x": 2015-02-09T00:00:00.000Z, + "y": -5.188415501615373, + }, + Object { + "x": 2015-02-10T00:00:00.000Z, + "y": -6.032557392677557, + }, + Object { + "x": 2015-02-11T00:00:00.000Z, + "y": -5.6858700345353785, + }, + Object { + "x": 2015-02-12T00:00:00.000Z, + "y": -6.667528307767753, + }, + Object { + "x": 2015-02-13T00:00:00.000Z, + "y": -6.733517550988596, + }, + Object { + "x": 2015-02-14T00:00:00.000Z, + "y": -7.0502984033473615, + }, + Object { + "x": 2015-02-15T00:00:00.000Z, + "y": -7.574898212324232, + }, + Object { + "x": 2015-02-16T00:00:00.000Z, + "y": -7.1843491903366, + }, + Object { + "x": 2015-02-17T00:00:00.000Z, + "y": -6.080355259797091, + }, + Object { + "x": 2015-02-18T00:00:00.000Z, + "y": -6.398354606750326, + }, + Object { + "x": 2015-02-19T00:00:00.000Z, + "y": -6.286331305269291, + }, + Object { + "x": 2015-02-20T00:00:00.000Z, + "y": -7.175762338255774, + }, + Object { + "x": 2015-02-21T00:00:00.000Z, + "y": -6.6277002690607105, + }, + Object { + "x": 2015-02-22T00:00:00.000Z, + "y": -6.031655281290095, + }, + Object { + "x": 2015-02-23T00:00:00.000Z, + "y": -5.243102836583583, + }, + Object { + "x": 2015-02-24T00:00:00.000Z, + "y": -4.612608200873672, + }, + Object { + "x": 2015-02-25T00:00:00.000Z, + "y": -5.180512683218164, + }, + Object { + "x": 2015-02-26T00:00:00.000Z, + "y": -5.0321319726702916, + }, + Object { + "x": 2015-02-27T00:00:00.000Z, + "y": -4.567844497333498, + }, + Object { + "x": 2015-02-28T00:00:00.000Z, + "y": -3.347239903958168, + }, + Object { + "x": 2015-03-01T00:00:00.000Z, + "y": -2.5263058621799597, + }, + Object { + "x": 2015-03-02T00:00:00.000Z, + "y": -3.554423668680612, + }, + Object { + "x": 2015-03-03T00:00:00.000Z, + "y": -1.7466537357472816, + }, + Object { + "x": 2015-03-04T00:00:00.000Z, + "y": 0.08618389027480222, + }, + Object { + "x": 2015-03-05T00:00:00.000Z, + "y": 1.0223852208396356, + }, + Object { + "x": 2015-03-06T00:00:00.000Z, + "y": 2.2260700096326724, + }, + Object { + "x": 2015-03-07T00:00:00.000Z, + "y": 2.976731277433707, + }, + Object { + "x": 2015-03-08T00:00:00.000Z, + "y": 2.5457541264066235, + }, + Object { + "x": 2015-03-09T00:00:00.000Z, + "y": 2.412842465270771, + }, + Object { + "x": 2015-03-10T00:00:00.000Z, + "y": 2.1270496073872933, + }, + Object { + "x": 2015-03-11T00:00:00.000Z, + "y": 4.350264423349324, + }, + Object { + "x": 2015-03-12T00:00:00.000Z, + "y": 3.6000820362032346, + }, + Object { + "x": 2015-03-13T00:00:00.000Z, + "y": 3.6547717673422704, + }, + Object { + "x": 2015-03-14T00:00:00.000Z, + "y": 4.29856786980301, + }, + Object { + "x": 2015-03-15T00:00:00.000Z, + "y": 4.61832134099102, + }, + Object { + "x": 2015-03-16T00:00:00.000Z, + "y": 5.1364308299997825, + }, + Object { + "x": 2015-03-17T00:00:00.000Z, + "y": 5.647209819441451, + }, + Object { + "x": 2015-03-18T00:00:00.000Z, + "y": 6.041357011724418, + }, + Object { + "x": 2015-03-19T00:00:00.000Z, + "y": 4.789997568683162, + }, + Object { + "x": 2015-03-20T00:00:00.000Z, + "y": 6.041650920258338, + }, + Object { + "x": 2015-03-21T00:00:00.000Z, + "y": 5.860878612223213, + }, + Object { + "x": 2015-03-22T00:00:00.000Z, + "y": 5.6050673038102214, + }, + Object { + "x": 2015-03-23T00:00:00.000Z, + "y": 3.900259274681964, + }, + Object { + "x": 2015-03-24T00:00:00.000Z, + "y": 2.1974477295325476, + }, + Object { + "x": 2015-03-25T00:00:00.000Z, + "y": 0.979239291658772, + }, + Object { + "x": 2015-03-26T00:00:00.000Z, + "y": 0.9769412141062032, + }, + Object { + "x": 2015-03-27T00:00:00.000Z, + "y": 1.1215546396840912, + }, + Object { + "x": 2015-03-28T00:00:00.000Z, + "y": 1.4131546401228463, + }, + Object { + "x": 2015-03-29T00:00:00.000Z, + "y": -0.5715019565360024, + }, + Object { + "x": 2015-03-30T00:00:00.000Z, + "y": -0.4798030419178908, + }, + Object { + "x": 2015-03-31T00:00:00.000Z, + "y": -0.19867316746947167, + }, + Object { + "x": 2015-04-01T00:00:00.000Z, + "y": -1.3237063703965808, + }, + Object { + "x": 2015-04-02T00:00:00.000Z, + "y": -1.5132847802948692, + }, + Object { + "x": 2015-04-03T00:00:00.000Z, + "y": -0.9466159703619573, + }, + Object { + "x": 2015-04-04T00:00:00.000Z, + "y": 1.3543877997088902, + }, + Object { + "x": 2015-04-05T00:00:00.000Z, + "y": 1.3745632832250965, + }, + Object { + "x": 2015-04-06T00:00:00.000Z, + "y": 1.2843024279329955, + }, + Object { + "x": 2015-04-07T00:00:00.000Z, + "y": 1.1384756757773304, + }, + Object { + "x": 2015-04-08T00:00:00.000Z, + "y": 1.841477239971831, + }, + Object { + "x": 2015-04-09T00:00:00.000Z, + "y": 1.0626945214201182, + }, + Object { + "x": 2015-04-10T00:00:00.000Z, + "y": 1.6018849370336259, + }, + ], + "legend": "Trace 2", + }, + ], + }, + "mode": "tonexty", + "secondaryYAxistitle": undefined, + "secondaryYScaleOptions": undefined, + "supportNegativeData": true, + "xAxisTitle": "", + "yAxisTitle": "", +} +`; + +exports[`transform Plotly Json To chart Props transformPlotlyJsonToVBCProps - Should return VBC props 1`] = ` +Object { + "chartTitle": "", + "data": Array [ + Object { + "color": "#f7adda", + "legend": "a", + "x": -1.75, + "xAxisCalloutData": "[-2 - -1.5)", + "y": 3, + }, + Object { + "color": "#f7adda", + "legend": "a", + "x": -1.25, + "xAxisCalloutData": "[-1.5 - -1)", + "y": 18, + }, + Object { + "color": "#f7adda", + "legend": "a", + "x": -0.75, + "xAxisCalloutData": "[-1 - -0.5)", + "y": 53, + }, + Object { + "color": "#f7adda", + "legend": "a", + "x": -0.25, + "xAxisCalloutData": "[-0.5 - 0)", + "y": 87, + }, + Object { + "color": "#f7adda", + "legend": "a", + "x": 0.25, + "xAxisCalloutData": "[0 - 0.5)", + "y": 129, + }, + Object { + "color": "#f7adda", + "legend": "a", + "x": 0.75, + "xAxisCalloutData": "[0.5 - 1)", + "y": 194, + }, + Object { + "color": "#f7adda", + "legend": "a", + "x": 1.25, + "xAxisCalloutData": "[1 - 1.5)", + "y": 188, + }, + Object { + "color": "#f7adda", + "legend": "a", + "x": 1.75, + "xAxisCalloutData": "[1.5 - 2)", + "y": 163, + }, + Object { + "color": "#f7adda", + "legend": "a", + "x": 2.25, + "xAxisCalloutData": "[2 - 2.5)", + "y": 102, + }, + Object { + "color": "#f7adda", + "legend": "a", + "x": 2.75, + "xAxisCalloutData": "[2.5 - 3)", + "y": 44, + }, + Object { + "color": "#f7adda", + "legend": "a", + "x": 3.25, + "xAxisCalloutData": "[3 - 3.5)", + "y": 11, + }, + Object { + "color": "#f7adda", + "legend": "a", + "x": 3.75, + "xAxisCalloutData": "[3.5 - 4)", + "y": 8, + }, + Object { + "color": "#9bd9db", + "legend": "b", + "x": -2.75, + "xAxisCalloutData": "[-3 - -2.5)", + "y": 6, + }, + Object { + "color": "#9bd9db", + "legend": "b", + "x": -2.25, + "xAxisCalloutData": "[-2.5 - -2)", + "y": 11, + }, + Object { + "color": "#9bd9db", + "legend": "b", + "x": -1.75, + "xAxisCalloutData": "[-2 - -1.5)", + "y": 40, + }, + Object { + "color": "#9bd9db", + "legend": "b", + "x": -1.25, + "xAxisCalloutData": "[-1.5 - -1)", + "y": 100, + }, + Object { + "color": "#9bd9db", + "legend": "b", + "x": -0.75, + "xAxisCalloutData": "[-1 - -0.5)", + "y": 158, + }, + Object { + "color": "#9bd9db", + "legend": "b", + "x": -0.25, + "xAxisCalloutData": "[-0.5 - 0)", + "y": 189, + }, + Object { + "color": "#9bd9db", + "legend": "b", + "x": 0.25, + "xAxisCalloutData": "[0 - 0.5)", + "y": 192, + }, + Object { + "color": "#9bd9db", + "legend": "b", + "x": 0.75, + "xAxisCalloutData": "[0.5 - 1)", + "y": 148, + }, + Object { + "color": "#9bd9db", + "legend": "b", + "x": 1.25, + "xAxisCalloutData": "[1 - 1.5)", + "y": 90, + }, + Object { + "color": "#9bd9db", + "legend": "b", + "x": 1.75, + "xAxisCalloutData": "[1.5 - 2)", + "y": 47, + }, + Object { + "color": "#9bd9db", + "legend": "b", + "x": 2.25, + "xAxisCalloutData": "[2 - 2.5)", + "y": 18, + }, + Object { + "color": "#9bd9db", + "legend": "b", + "x": 2.75, + "xAxisCalloutData": "[2.5 - 3)", + "y": 1, + }, + Object { + "color": "#b29ad4", + "legend": "c", + "x": -4.25, + "xAxisCalloutData": "[-4.5 - -4)", + "y": 2, + }, + Object { + "color": "#b29ad4", + "legend": "c", + "x": -3.75, + "xAxisCalloutData": "[-4 - -3.5)", + "y": 4, + }, + Object { + "color": "#b29ad4", + "legend": "c", + "x": -3.25, + "xAxisCalloutData": "[-3.5 - -3)", + "y": 8, + }, + Object { + "color": "#b29ad4", + "legend": "c", + "x": -2.75, + "xAxisCalloutData": "[-3 - -2.5)", + "y": 49, + }, + Object { + "color": "#b29ad4", + "legend": "c", + "x": -2.25, + "xAxisCalloutData": "[-2.5 - -2)", + "y": 99, + }, + Object { + "color": "#b29ad4", + "legend": "c", + "x": -1.75, + "xAxisCalloutData": "[-2 - -1.5)", + "y": 137, + }, + Object { + "color": "#b29ad4", + "legend": "c", + "x": -1.25, + "xAxisCalloutData": "[-1.5 - -1)", + "y": 220, + }, + Object { + "color": "#b29ad4", + "legend": "c", + "x": -0.75, + "xAxisCalloutData": "[-1 - -0.5)", + "y": 181, + }, + Object { + "color": "#b29ad4", + "legend": "c", + "x": -0.25, + "xAxisCalloutData": "[-0.5 - 0)", + "y": 142, + }, + Object { + "color": "#b29ad4", + "legend": "c", + "x": 0.25, + "xAxisCalloutData": "[0 - 0.5)", + "y": 94, + }, + Object { + "color": "#b29ad4", + "legend": "c", + "x": 0.75, + "xAxisCalloutData": "[0.5 - 1)", + "y": 45, + }, + Object { + "color": "#b29ad4", + "legend": "c", + "x": 1.25, + "xAxisCalloutData": "[1 - 1.5)", + "y": 11, + }, + Object { + "color": "#b29ad4", + "legend": "c", + "x": 1.75, + "xAxisCalloutData": "[1.5 - 2)", + "y": 6, + }, + Object { + "color": "#b29ad4", + "legend": "c", + "x": 2.25, + "xAxisCalloutData": "[2 - 2.5)", + "y": 2, + }, + ], + "mode": "plotly", + "supportNegativeData": true, + "xAxisTitle": "", + "yAxisTitle": "", +} +`; + +exports[`transform Plotly Json To chart Props transformPlotlyJsonToVSBCProps - Should return VSBC props 1`] = ` +Object { + "barWidth": "auto", + "chartTitle": "", + "data": Array [ + Object { + "chartData": Array [ + Object { + "color": "#c19c00", + "data": 2000, + "legend": "Category A", + }, + Object { + "color": "#c8d1fa", + "data": 3000, + "legend": "Category B", + }, + ], + "lineData": Array [], + "xAxisPoint": "Jan", + }, + Object { + "chartData": Array [ + Object { + "color": "#c19c00", + "data": 2100, + "legend": "Category A", + }, + Object { + "color": "#c8d1fa", + "data": 3100, + "legend": "Category B", + }, + ], + "lineData": Array [], + "xAxisPoint": "Feb", + }, + Object { + "chartData": Array [ + Object { + "color": "#c19c00", + "data": 2200, + "legend": "Category A", + }, + Object { + "color": "#c8d1fa", + "data": 3200, + "legend": "Category B", + }, + ], + "lineData": Array [], + "xAxisPoint": "Mar", + }, + Object { + "chartData": Array [ + Object { + "color": "#c19c00", + "data": 2300, + "legend": "Category A", + }, + Object { + "color": "#c8d1fa", + "data": 3300, + "legend": "Category B", + }, + ], + "lineData": Array [], + "xAxisPoint": "Apr", + }, + Object { + "chartData": Array [ + Object { + "color": "#c19c00", + "data": 2400, + "legend": "Category A", + }, + Object { + "color": "#c8d1fa", + "data": 3400, + "legend": "Category B", + }, + ], + "lineData": Array [], + "xAxisPoint": "May", + }, + ], + "mode": "plotly", + "secondaryYAxistitle": undefined, + "secondaryYScaleOptions": undefined, + "xAxisTitle": "", + "yAxisTitle": "", + "yMaxValue": 3400, +} +`; diff --git a/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_groupedverticalbarchart_test.json b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_groupedverticalbarchart_test.json new file mode 100644 index 00000000000000..97c18b6462b187 --- /dev/null +++ b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_groupedverticalbarchart_test.json @@ -0,0 +1,95 @@ +{ + "visualizer": "plotly", + "data": [ + { + "uid": "2f399e", + "type": "bar", + "x": ["Jan", "Feb", "Mar", "Apr", "May"], + "y": [2000, 2100, 2200, 2300, 2400], + "name": "Category A", + "zmax": 1, + "zmin": 0, + "xbins": { + "end": 2499.5, + "size": 500, + "start": -500.5 + }, + "ybins": { + "end": 23.5, + "size": 1, + "start": -1.5 + }, + "opacity": 1, + "visible": true, + "autobinx": true, + "autobiny": true, + "contours": { + "end": 0.901, + "size": 0.1, + "start": 0.1, + "coloring": "fill", + "showlines": true + }, + "showlegend": true, + "orientation": "v" + }, + { + "uid": "2f399e", + "type": "bar", + "x": ["Jan", "Feb", "Mar", "Apr", "May"], + "y": [3000, 3100, 3200, 3300, 3400], + "name": "Category B", + "zmax": 1, + "zmin": 0, + "xbins": { + "end": 2499.5, + "size": 500, + "start": -500.5 + }, + "ybins": { + "end": 23.5, + "size": 1, + "start": -1.5 + }, + "opacity": 1, + "visible": true, + "autobinx": true, + "autobiny": true, + "contours": { + "end": 0.901, + "size": 0.1, + "start": 0.1, + "coloring": "fill", + "showlines": true + }, + "showlegend": true, + "orientation": "v" + } + ], + "layout": { + "title": "PHP Framework Popularity at Work - SitePoint, 2015", + "width": 850, + "xaxis": { + "type": "linear", + "range": [-198.2562959184288, 1830.6731869091736], + "title": "Votes", + "autorange": false + }, + "yaxis": { + "type": "category", + "range": [-3.301575351429676, 23.42061223132087], + "title": "Framework", + "autorange": false + }, + "height": 742, + "margin": { + "l": 210, + "pad": 4 + }, + "barmode": "group", + "barnorm": "", + "autosize": true, + "showlegend": false + }, + "frames": [] +} diff --git a/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_nesteddata_test.json b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_nesteddata_test.json new file mode 100644 index 00000000000000..4e726910baac16 --- /dev/null +++ b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_nesteddata_test.json @@ -0,0 +1,23 @@ +[ + { + "level1": { + "level2": { + "level3": { + "level4": { + "level5": { + "level6": { + "level7": { + "level8": { + "level9": { + "level10": "Testing data" + } + } + } + } + } + } + } + } + } + } +] diff --git a/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_verticalstackedbarchart_test.json b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_verticalstackedbarchart_test.json new file mode 100644 index 00000000000000..c87c4978b72adc --- /dev/null +++ b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_verticalstackedbarchart_test.json @@ -0,0 +1,75 @@ +{ + "visualizer": "plotly", + "data": [ + { + "type": "bar", + "x": ["Jan", "Feb", "Mar", "Apr", "May"], + "y": [2000, 2100, 2200, 2300, 2400], + "name": "Category A", + "xaxis": "x1", + "yaxis": "y1", + "marker": { + "line": { + "width": 1 + }, + "color": "#0000FF" + }, + "opacity": 1, + "orientation": "v" + }, + { + "type": "bar", + "x": ["Jan", "Feb", "Mar", "Apr", "May"], + "y": [3000, 3100, 3200, 3300, 3400], + "name": "Category B", + "xaxis": "x1", + "yaxis": "y1", + "marker": { + "line": { + "width": 1 + }, + "color": "#007F00" + }, + "opacity": 1, + "orientation": "v" + } + ], + "layout": { + "bargap": 11.864179406671795, + "xaxis1": { + "side": "bottom", + "type": "linear", + "range": [50, 300], + "ticks": "inside", + "anchor": "y1", + "domain": [0, 1], + "mirror": "ticks", + "nticks": 6, + "showgrid": false, + "showline": true, + "tickfont": { + "size": 12 + }, + "zeroline": false + }, + "yaxis1": { + "side": "left", + "type": "linear", + "range": [0, 350], + "ticks": "inside", + "anchor": "x1", + "domain": [0, 1], + "mirror": "ticks", + "nticks": 8, + "showgrid": false, + "showline": true, + "tickfont": { + "size": 12 + }, + "zeroline": false + }, + "hovermode": "closest", + "showlegend": false + }, + "frames": [] +} diff --git a/packages/charts/react-charting/src/components/DonutChart/DonutChart.base.tsx b/packages/charts/react-charting/src/components/DonutChart/DonutChart.base.tsx index 79c4414e3307ab..5fc0da02192505 100644 --- a/packages/charts/react-charting/src/components/DonutChart/DonutChart.base.tsx +++ b/packages/charts/react-charting/src/components/DonutChart/DonutChart.base.tsx @@ -178,6 +178,7 @@ export class DonutChartBase extends React.Component - 25,000 + 25000 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 bae69324657ec7..7b897388bb9203 100644 --- a/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChart.base.tsx +++ b/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChart.base.tsx @@ -524,7 +524,7 @@ export class VerticalStackedBarChartBase this._barWidth = getBarWidth(this.props.barWidth, this.props.maxBarWidth); const { theme } = this.props; const { palette } = theme!; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated this._colors = this.props.colors || [palette.blueLight, palette.blue, palette.blueMid, palette.red, palette.black]; this._xAxisType = getTypeOfAxis(this.props.data[0].xAxisPoint, true) as XAxisTypes; this._lineObject = this._getFormattedLineData(this.props.data); @@ -1254,7 +1254,7 @@ export class VerticalStackedBarChartBase return !( this.props.data && this.props.data.length > 0 && - this.props.data.filter(item => item.chartData.length === 0).length === 0 + this.props.data.some(item => item.chartData.length > 0 || (item.lineData && item.lineData.length > 0)) ); } diff --git a/packages/charts/react-charting/src/utilities/SVGTooltipText.tsx b/packages/charts/react-charting/src/utilities/SVGTooltipText.tsx index eb625317a5465b..d130fee6d592e7 100644 --- a/packages/charts/react-charting/src/utilities/SVGTooltipText.tsx +++ b/packages/charts/react-charting/src/utilities/SVGTooltipText.tsx @@ -252,7 +252,7 @@ export class SVGTooltipText }; private _onTooltipKeyDown = (ev: React.KeyboardEvent): void => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if ((ev.which === KeyCodes.escape || ev.ctrlKey) && this.state.isTooltipVisible) { this._hideTooltip(); ev.stopPropagation(); diff --git a/packages/charts/react-charting/src/utilities/utilities.ts b/packages/charts/react-charting/src/utilities/utilities.ts index 38dfd656797437..39f1d592877531 100644 --- a/packages/charts/react-charting/src/utilities/utilities.ts +++ b/packages/charts/react-charting/src/utilities/utilities.ts @@ -360,14 +360,9 @@ export function createStringXAxis( .paddingOuter(typeof xAxisOuterPadding !== 'undefined' ? xAxisOuterPadding : xAxisPadding); let tickValues = (tickParams.tickValues as string[] | undefined) ?? dataset; - const tickFormat = (domainValue: string, _index: number) => { - return convertToLocaleString(domainValue, culture) as string; - }; if (hideTickOverlap) { let nonOverlappingTickValues = []; - const tickSizes = tickValues.map((value, index) => - calculateLongestLabelWidth([tickFormat(value, index)], '[class^="xAxis-"] text'), - ); + const tickSizes = tickValues.map((value, index) => calculateLongestLabelWidth([value], '[class^="xAxis-"] text')); // for LTR let start = 0; let end = containerWidth; @@ -393,16 +388,12 @@ export function createStringXAxis( tickValues = nonOverlappingTickValues; } - const xAxis = d3AxisBottom(xAxisScale) - .tickSize(xAxistickSize) - .tickPadding(tickPadding) - .tickValues(tickValues) - .tickFormat(tickFormat); + const xAxis = d3AxisBottom(xAxisScale).tickSize(xAxistickSize).tickPadding(tickPadding).tickValues(tickValues); if (xAxisParams.xAxisElement) { d3Select(xAxisParams.xAxisElement).call(xAxis).selectAll('text').attr('aria-hidden', 'true'); } - return { xScale: xAxisScale, tickValues: tickValues.map(xAxis.tickFormat()!) }; + return { xScale: xAxisScale, tickValues }; } /** diff --git a/packages/codemods/.eslintrc.json b/packages/codemods/.eslintrc.json index 3659e1a174fbb0..554b7ea5d198a2 100644 --- a/packages/codemods/.eslintrc.json +++ b/packages/codemods/.eslintrc.json @@ -9,7 +9,7 @@ "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/naming-convention": "off", "import/no-extraneous-dependencies": "off", - "deprecation/deprecation": "off" + "@typescript-eslint/no-deprecated": "off" } } ] diff --git a/packages/codemods/CHANGELOG.json b/packages/codemods/CHANGELOG.json index 2056607f1acf2e..9b2d21d8a738fb 100644 --- a/packages/codemods/CHANGELOG.json +++ b/packages/codemods/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/codemods", "entries": [ + { + "date": "Mon, 20 Jan 2025 07:21:45 GMT", + "tag": "@fluentui/codemods_v8.4.27", + "version": "8.4.27", + "comments": { + "none": [ + { + "author": "vgenaev@gmail.com", + "package": "@fluentui/codemods", + "commit": "fd420e1e0b66e04c8a423cff3eea6d21d9434d2d", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule" + } + ] + } + }, { "date": "Mon, 23 Dec 2024 07:22:57 GMT", "tag": "@fluentui/codemods_v8.4.27", diff --git a/packages/codemods/src/codeMods/utilities/helpers/propHelpers.ts b/packages/codemods/src/codeMods/utilities/helpers/propHelpers.ts index 5c2d951a2a3b0d..814aaa3a9ee055 100644 --- a/packages/codemods/src/codeMods/utilities/helpers/propHelpers.ts +++ b/packages/codemods/src/codeMods/utilities/helpers/propHelpers.ts @@ -255,7 +255,7 @@ function tryInsertExistingDecomposedProp(oldProp: string, statement: VariableSta const decompObject = statement.getFirstDescendantByKind(SyntaxKind.ObjectBindingPattern); if (decompObject) { let objectText = decompObject.getText(); - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated objectText = objectText.substr(0, 1) + ` ${oldProp},` + objectText.substr(1); decompObject.replaceWithText(objectText); return true; diff --git a/packages/cra-template/package.json b/packages/cra-template/package.json index 53539c3f54f811..93d870af2b4e44 100644 --- a/packages/cra-template/package.json +++ b/packages/cra-template/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/cra-template", - "version": "8.4.196", + "version": "8.4.197", "description": "Create React App template for Fluent UI React (@fluentui/react)", "repository": { "type": "git", diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 797cd8dce675b5..87282caa800235 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -19,7 +19,6 @@ "eslint-config-airbnb": "^18.2.1", "eslint-config-prettier": "^8.3.0", "eslint-import-resolver-typescript": "^3.6.1", - "eslint-plugin-deprecation": "^3.0.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-jest": "^28.6.0", "eslint-plugin-jsdoc": "^48.7.0", diff --git a/packages/eslint-plugin/src/configs/core.js b/packages/eslint-plugin/src/configs/core.js index 72bbfac84c0783..879695816f13ee 100644 --- a/packages/eslint-plugin/src/configs/core.js +++ b/packages/eslint-plugin/src/configs/core.js @@ -14,16 +14,7 @@ const config = { 'prettier', ], parser: '@typescript-eslint/parser', - plugins: [ - 'import', - '@fluentui', - '@rnx-kit', - '@typescript-eslint', - 'deprecation', - 'jest', - 'jsdoc', - ...__internal.plugins, - ], + plugins: ['import', '@fluentui', '@rnx-kit', '@typescript-eslint', 'jest', 'jsdoc', ...__internal.plugins], settings: { 'import/resolver': { // @see https://github.com/alexgorbatchev/eslint-import-resolver-typescript#configuration @@ -248,7 +239,7 @@ const typeAwareRules = { /** * plugin: https://github.com/gund/eslint-plugin-deprecation */ - 'deprecation/deprecation': 'error', + '@typescript-eslint/no-deprecated': 'error', }; /** @@ -318,7 +309,7 @@ const getOverrides = () => [ { files: 'src/**/*.deprecated.test.{ts,tsx}', rules: { - 'deprecation/deprecation': 'off', // the purpose of these tests + '@typescript-eslint/no-deprecated': 'off', }, }, { diff --git a/packages/fluent2-theme/CHANGELOG.json b/packages/fluent2-theme/CHANGELOG.json index 5accf0e86228d6..d1bb9fd55ca5a1 100644 --- a/packages/fluent2-theme/CHANGELOG.json +++ b/packages/fluent2-theme/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/fluent2-theme", "entries": [ + { + "date": "Fri, 17 Jan 2025 07:21:32 GMT", + "tag": "@fluentui/fluent2-theme_v8.107.124", + "version": "8.107.124", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/fluent2-theme", + "comment": "Bump @fluentui/react to v8.122.7", + "commit": "baf887d95f91874c814a7cae749c20e797f828be" + } + ] + } + }, { "date": "Mon, 13 Jan 2025 07:21:23 GMT", "tag": "@fluentui/fluent2-theme_v8.107.123", diff --git a/packages/fluent2-theme/CHANGELOG.md b/packages/fluent2-theme/CHANGELOG.md index 669e0f54e84205..0c6911011eb685 100644 --- a/packages/fluent2-theme/CHANGELOG.md +++ b/packages/fluent2-theme/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/fluent2-theme -This log was last generated on Mon, 13 Jan 2025 07:21:23 GMT and should not be manually modified. +This log was last generated on Fri, 17 Jan 2025 07:21:32 GMT and should not be manually modified. +## [8.107.124](https://github.com/microsoft/fluentui/tree/@fluentui/fluent2-theme_v8.107.124) + +Fri, 17 Jan 2025 07:21:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/fluent2-theme_v8.107.123..@fluentui/fluent2-theme_v8.107.124) + +### Patches + +- Bump @fluentui/react to v8.122.7 ([commit](https://github.com/microsoft/fluentui/commit/baf887d95f91874c814a7cae749c20e797f828be) by beachball) + ## [8.107.123](https://github.com/microsoft/fluentui/tree/@fluentui/fluent2-theme_v8.107.123) Mon, 13 Jan 2025 07:21:23 GMT diff --git a/packages/fluent2-theme/package.json b/packages/fluent2-theme/package.json index c9bd931fde9043..6922e4d226a17b 100644 --- a/packages/fluent2-theme/package.json +++ b/packages/fluent2-theme/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/fluent2-theme", - "version": "8.107.123", + "version": "8.107.124", "description": "A Fluent2 theme for Fluent UI React 8.x", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -27,7 +27,7 @@ "@fluentui/scripts-webpack": "*" }, "dependencies": { - "@fluentui/react": "^8.122.6", + "@fluentui/react": "^8.122.7", "@fluentui/set-version": "^8.2.23", "tslib": "^2.1.0" } diff --git a/packages/font-icons-mdl2/CHANGELOG.json b/packages/font-icons-mdl2/CHANGELOG.json index cda94a3050c548..d74062a138bc77 100644 --- a/packages/font-icons-mdl2/CHANGELOG.json +++ b/packages/font-icons-mdl2/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/font-icons-mdl2", "entries": [ + { + "date": "Mon, 20 Jan 2025 07:21:45 GMT", + "tag": "@fluentui/font-icons-mdl2_v8.5.57", + "version": "8.5.57", + "comments": { + "none": [ + { + "author": "vgenaev@gmail.com", + "package": "@fluentui/font-icons-mdl2", + "commit": "fd420e1e0b66e04c8a423cff3eea6d21d9434d2d", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule" + } + ] + } + }, { "date": "Mon, 23 Dec 2024 07:22:58 GMT", "tag": "@fluentui/font-icons-mdl2_v8.5.57", diff --git a/packages/font-icons-mdl2/src/IconNames.ts b/packages/font-icons-mdl2/src/IconNames.ts index 3041a5bc2ca612..371cf9f7253cc6 100644 --- a/packages/font-icons-mdl2/src/IconNames.ts +++ b/packages/font-icons-mdl2/src/IconNames.ts @@ -1805,5 +1805,5 @@ export const enum IconNames { SizeLegacy = 'SizeLegacy', } -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated export type IconNamesInput = keyof typeof IconNames; diff --git a/packages/font-icons-mdl2/src/iconNames.test.ts b/packages/font-icons-mdl2/src/iconNames.test.ts index 022c8aeddd4f51..a73a638b33f498 100644 --- a/packages/font-icons-mdl2/src/iconNames.test.ts +++ b/packages/font-icons-mdl2/src/iconNames.test.ts @@ -1,6 +1,6 @@ import { IconNames, IconNamesInput } from './IconNames'; -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated declare const allIconNamesValues: IconNames; function validateIconNamesValues(allowedIconNamesValues: IconNamesInput): void { diff --git a/packages/font-icons-mdl2/src/index.ts b/packages/font-icons-mdl2/src/index.ts index de32b506be3675..afaf1c0f9de156 100644 --- a/packages/font-icons-mdl2/src/index.ts +++ b/packages/font-icons-mdl2/src/index.ts @@ -69,9 +69,9 @@ export function initializeIcons( registerIconAliases(); } -/* eslint-disable deprecation/deprecation */ +/* eslint-disable @typescript-eslint/no-deprecated */ export type { IconNamesInput } from './IconNames'; export { IconNames } from './IconNames'; -/* eslint-enable deprecation/deprecation */ +/* eslint-enable @typescript-eslint/no-deprecated */ import './version'; diff --git a/packages/foundation-legacy/CHANGELOG.json b/packages/foundation-legacy/CHANGELOG.json index d7708bd4ff75aa..0e62c7992c91d7 100644 --- a/packages/foundation-legacy/CHANGELOG.json +++ b/packages/foundation-legacy/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/foundation-legacy", "entries": [ + { + "date": "Mon, 20 Jan 2025 07:21:46 GMT", + "tag": "@fluentui/foundation-legacy_v8.4.23", + "version": "8.4.23", + "comments": { + "none": [ + { + "author": "vgenaev@gmail.com", + "package": "@fluentui/foundation-legacy", + "commit": "fd420e1e0b66e04c8a423cff3eea6d21d9434d2d", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule" + } + ] + } + }, { "date": "Mon, 23 Dec 2024 07:22:58 GMT", "tag": "@fluentui/foundation-legacy_v8.4.23", diff --git a/packages/foundation-legacy/src/ThemeProvider.tsx b/packages/foundation-legacy/src/ThemeProvider.tsx index e28335d078e2da..12a572e8f2e3fc 100644 --- a/packages/foundation-legacy/src/ThemeProvider.tsx +++ b/packages/foundation-legacy/src/ThemeProvider.tsx @@ -25,6 +25,6 @@ export const ThemeProvider: React.FunctionComponent = (prop return getThemedContext(context, scheme, theme); }; - // eslint-disable-next-line react/jsx-no-bind, deprecation/deprecation + // eslint-disable-next-line react/jsx-no-bind, @typescript-eslint/no-deprecated return ; }; diff --git a/packages/keyboard-key/CHANGELOG.json b/packages/keyboard-key/CHANGELOG.json index d07257fdba6618..eb90eae00e4eb3 100644 --- a/packages/keyboard-key/CHANGELOG.json +++ b/packages/keyboard-key/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/keyboard-key", "entries": [ + { + "date": "Mon, 20 Jan 2025 07:21:46 GMT", + "tag": "@fluentui/keyboard-key_v0.4.23", + "version": "0.4.23", + "comments": { + "none": [ + { + "author": "vgenaev@gmail.com", + "package": "@fluentui/keyboard-key", + "commit": "fd420e1e0b66e04c8a423cff3eea6d21d9434d2d", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule" + } + ] + } + }, { "date": "Thu, 01 Aug 2024 07:24:44 GMT", "tag": "@fluentui/keyboard-key_v0.4.23", diff --git a/packages/keyboard-key/src/index.ts b/packages/keyboard-key/src/index.ts index 8120aad882e9f6..da8e3ae8b3269d 100644 --- a/packages/keyboard-key/src/index.ts +++ b/packages/keyboard-key/src/index.ts @@ -182,7 +182,7 @@ const isObject = (val: any): val is KeyboardEventLike => { */ export function getCode(eventOrKey: Partial | string): number | undefined { if (isObject(eventOrKey)) { - // eslint-disable-next-line deprecation/deprecation, @typescript-eslint/no-explicit-any + // eslint-disable-next-line @typescript-eslint/no-deprecated, @typescript-eslint/no-explicit-any return eventOrKey.keyCode || eventOrKey.which || (keyboardKey as any)[eventOrKey.key as string]; } // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -204,7 +204,7 @@ export function getKey(eventOrCode: Partial | number): string return event.key; } - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated let name = codes[(isEvent ? event.keyCode || event.which : eventOrCode) as number]; if (Array.isArray(name)) { diff --git a/packages/merge-styles/CHANGELOG.json b/packages/merge-styles/CHANGELOG.json index eed97b22305b13..d9254e59cb9873 100644 --- a/packages/merge-styles/CHANGELOG.json +++ b/packages/merge-styles/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/merge-styles", "entries": [ + { + "date": "Mon, 20 Jan 2025 07:21:46 GMT", + "tag": "@fluentui/merge-styles_v8.6.13", + "version": "8.6.13", + "comments": { + "none": [ + { + "author": "vgenaev@gmail.com", + "package": "@fluentui/merge-styles", + "commit": "fd420e1e0b66e04c8a423cff3eea6d21d9434d2d", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule" + } + ] + } + }, { "date": "Thu, 08 Aug 2024 07:24:14 GMT", "tag": "@fluentui/merge-styles_v8.6.13", diff --git a/packages/merge-styles/src/DeepPartial.ts b/packages/merge-styles/src/DeepPartial.ts index ca351bd5feb541..f2e7ad6463bc4f 100644 --- a/packages/merge-styles/src/DeepPartial.ts +++ b/packages/merge-styles/src/DeepPartial.ts @@ -3,7 +3,7 @@ * @deprecated - This type will hit infinite type instantiation recursion. Please use {@link DeepPartialV2} */ export type DeepPartial = { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated [P in keyof T]?: T[P] extends Array ? Array> : T[P] extends object ? DeepPartial : T[P]; }; diff --git a/packages/merge-styles/src/IStyleSet.ts b/packages/merge-styles/src/IStyleSet.ts index 7f6c20b407d46a..8a9274af481f5d 100644 --- a/packages/merge-styles/src/IStyleSet.ts +++ b/packages/merge-styles/src/IStyleSet.ts @@ -12,9 +12,9 @@ export type Diff = ({ [P in T]: P } & /** * @deprecated Use the version provided by TypeScript instead. */ -// eslint-disable-next-line deprecation/deprecation, @typescript-eslint/naming-convention +// eslint-disable-next-line @typescript-eslint/no-deprecated, @typescript-eslint/naming-convention type _Omit = Pick>; -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated export type { _Omit as Omit }; /** @@ -40,7 +40,7 @@ export interface IStyleSetBase { * property. */ export type IStyleSet = { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated [P in keyof _Omit]: IStyle; } & { subComponentStyles?: { [P in keyof TStyleSet['subComponentStyles']]: IStyleFunctionOrObject }; @@ -50,7 +50,7 @@ export type IStyleSet * A concatenated style set differs from `IStyleSet` in that subComponentStyles will always be a style function. */ export type IConcatenatedStyleSet = { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated [P in keyof _Omit]: IStyle; } & { subComponentStyles?: { [P in keyof TStyleSet['subComponentStyles']]: IStyleFunction }; @@ -61,7 +61,7 @@ export type IConcatenatedStyleSet = { * into a class name. Additionally, all subComponentStyles are style functions. */ export type IProcessedStyleSet = { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated [P in keyof _Omit]: string; } & { subComponentStyles: { diff --git a/packages/merge-styles/src/Stylesheet.ts b/packages/merge-styles/src/Stylesheet.ts index 4ffe12028d9a4f..0130f878d479a0 100644 --- a/packages/merge-styles/src/Stylesheet.ts +++ b/packages/merge-styles/src/Stylesheet.ts @@ -347,9 +347,9 @@ export class Stylesheet { this._rules.push(rule); } - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (this._config.onInsertRule) { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated this._config.onInsertRule(rule); } diff --git a/packages/merge-styles/src/index.ts b/packages/merge-styles/src/index.ts index 273d88371f2fd0..72d6836a34aac8 100644 --- a/packages/merge-styles/src/index.ts +++ b/packages/merge-styles/src/index.ts @@ -6,10 +6,10 @@ export type { IKeyframes } from './IKeyframes'; export type { IStyleFunction, IStyleFunctionOrObject } from './IStyleFunction'; -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated export type { DeepPartial } from './DeepPartial'; -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated export type { IConcatenatedStyleSet, IProcessedStyleSet, IStyleSet, IStyleSetBase, Omit } from './IStyleSet'; export type { diff --git a/packages/react-cards/.eslintrc.json b/packages/react-cards/.eslintrc.json index fcffc3d29ca9e6..4c0d4b83a6d43a 100644 --- a/packages/react-cards/.eslintrc.json +++ b/packages/react-cards/.eslintrc.json @@ -9,7 +9,7 @@ "files": "**/*.{ts,tsx}", "rules": { // The components in this package are all deprecated - "deprecation/deprecation": "off" + "@typescript-eslint/no-deprecated": "off" } } ] diff --git a/packages/react-cards/CHANGELOG.json b/packages/react-cards/CHANGELOG.json index 894fc0a4338fa7..55faad53754276 100644 --- a/packages/react-cards/CHANGELOG.json +++ b/packages/react-cards/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/react-cards", "entries": [ + { + "date": "Fri, 17 Jan 2025 07:21:32 GMT", + "tag": "@fluentui/react-cards_v0.205.196", + "version": "0.205.196", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-cards", + "comment": "Bump @fluentui/react to v8.122.7", + "commit": "baf887d95f91874c814a7cae749c20e797f828be" + } + ] + } + }, { "date": "Mon, 13 Jan 2025 07:21:23 GMT", "tag": "@fluentui/react-cards_v0.205.195", diff --git a/packages/react-cards/CHANGELOG.md b/packages/react-cards/CHANGELOG.md index 8842b2aa64790c..6772d275a15ad3 100644 --- a/packages/react-cards/CHANGELOG.md +++ b/packages/react-cards/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/react-cards -This log was last generated on Mon, 13 Jan 2025 07:21:23 GMT and should not be manually modified. +This log was last generated on Fri, 17 Jan 2025 07:21:32 GMT and should not be manually modified. +## [0.205.196](https://github.com/microsoft/fluentui/tree/@fluentui/react-cards_v0.205.196) + +Fri, 17 Jan 2025 07:21:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-cards_v0.205.195..@fluentui/react-cards_v0.205.196) + +### Patches + +- Bump @fluentui/react to v8.122.7 ([commit](https://github.com/microsoft/fluentui/commit/baf887d95f91874c814a7cae749c20e797f828be) by beachball) + ## [0.205.195](https://github.com/microsoft/fluentui/tree/@fluentui/react-cards_v0.205.195) Mon, 13 Jan 2025 07:21:23 GMT diff --git a/packages/react-cards/package.json b/packages/react-cards/package.json index d3b373b949b12f..1d983cc06104c4 100644 --- a/packages/react-cards/package.json +++ b/packages/react-cards/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-cards", - "version": "0.205.195", + "version": "0.205.196", "description": "Deprecated experimental Card container components for Fluent UI React.", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -33,7 +33,7 @@ "@fluentui/scripts-webpack": "*" }, "dependencies": { - "@fluentui/react": "^8.122.6", + "@fluentui/react": "^8.122.7", "@fluentui/foundation-legacy": "^8.4.23", "@fluentui/set-version": "^8.2.23", "@microsoft/load-themed-styles": "^1.10.26", diff --git a/packages/react-components/react-accordion/library/src/components/Accordion/useAccordion.ts b/packages/react-components/react-accordion/library/src/components/Accordion/useAccordion.ts index 2901ae3fa5b778..38ee613568d58f 100644 --- a/packages/react-components/react-accordion/library/src/components/Accordion/useAccordion.ts +++ b/packages/react-components/react-accordion/library/src/components/Accordion/useAccordion.ts @@ -20,7 +20,7 @@ export const useAccordion_unstable = ( multiple = false, collapsible = false, onToggle, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated navigation, } = props; const [openItems, setOpenItems] = useControllableState({ diff --git a/packages/react-components/react-accordion/library/src/components/AccordionItem/useAccordionItemContextValues.ts b/packages/react-components/react-accordion/library/src/components/AccordionItem/useAccordionItemContextValues.ts index 48aa5b3207e9f9..801e3580b89ef8 100644 --- a/packages/react-components/react-accordion/library/src/components/AccordionItem/useAccordionItemContextValues.ts +++ b/packages/react-components/react-accordion/library/src/components/AccordionItem/useAccordionItemContextValues.ts @@ -3,7 +3,7 @@ import type { AccordionItemContextValues, AccordionItemState } from './Accordion import { AccordionItemContextValue } from '../../contexts/accordionItem'; export function useAccordionItemContextValues_unstable(state: AccordionItemState): AccordionItemContextValues { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { disabled, open, value, onHeaderClick } = state; const accordionItem = React.useMemo( () => ({ disabled, open, value, onHeaderClick }), diff --git a/packages/react-components/react-aria/library/src/activedescendant/useActivedescendant.test.tsx b/packages/react-components/react-aria/library/src/activedescendant/useActivedescendant.test.tsx index 45ceea2b591653..b8f8fe07cc8312 100644 --- a/packages/react-components/react-aria/library/src/activedescendant/useActivedescendant.test.tsx +++ b/packages/react-components/react-aria/library/src/activedescendant/useActivedescendant.test.tsx @@ -272,7 +272,7 @@ describe('useActivedescendant', () => { const { getByRole } = render(); // there should not be a last active descendant yet - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated expect(imperativeRef.current?.focusLastActive()).toBeFalsy(); imperativeRef.current?.focus('option-3'); @@ -281,7 +281,7 @@ describe('useActivedescendant', () => { imperativeRef.current?.blur(); expect(imperativeRef.current?.active()).toBeUndefined(); - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated expect(imperativeRef.current?.focusLastActive()).toBeTruthy(); expect(imperativeRef.current?.active()).toBe('option-3'); diff --git a/packages/react-components/react-aria/library/src/button/index.ts b/packages/react-components/react-aria/library/src/button/index.ts index a4eca5f0101884..39a345a2417328 100644 --- a/packages/react-components/react-aria/library/src/button/index.ts +++ b/packages/react-components/react-aria/library/src/button/index.ts @@ -1,5 +1,5 @@ export { useARIAButtonProps } from './useARIAButtonProps'; -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated export { useARIAButtonShorthand } from './useARIAButtonShorthand'; export type { ARIAButtonAlteredProps, diff --git a/packages/react-components/react-aria/library/src/button/useARIAButtonShorthand.test.tsx b/packages/react-components/react-aria/library/src/button/useARIAButtonShorthand.test.tsx index a2d40caa9ccce4..64438aec8bedc7 100644 --- a/packages/react-components/react-aria/library/src/button/useARIAButtonShorthand.test.tsx +++ b/packages/react-components/react-aria/library/src/button/useARIAButtonShorthand.test.tsx @@ -5,22 +5,22 @@ describe('useARIAButtonShorthands', () => { it('should return shorthands', () => { const { result: { current: buttonShorthand }, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated } = renderHook(() => useARIAButtonShorthand({ as: 'button' }, { required: true })); expect(buttonShorthand.as).toBe('button'); const { result: { current: buttonShorthand2 }, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated } = renderHook(() => useARIAButtonShorthand({ as: undefined }, { required: true })); expect(buttonShorthand2.as).toBe(undefined); const { result: { current: anchorShorthand }, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated } = renderHook(() => useARIAButtonShorthand({ as: 'a' }, { required: true })); expect(anchorShorthand.as).toBe('a'); const { result: { current: divShorthand }, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated } = renderHook(() => useARIAButtonShorthand({ as: 'div' }, { required: true })); expect(divShorthand.as).toBe('div'); }); diff --git a/packages/react-components/react-aria/library/src/button/useARIAButtonShorthand.ts b/packages/react-components/react-aria/library/src/button/useARIAButtonShorthand.ts index b5b18bae1c3146..9d8b64067a863e 100644 --- a/packages/react-components/react-aria/library/src/button/useARIAButtonShorthand.ts +++ b/packages/react-components/react-aria/library/src/button/useARIAButtonShorthand.ts @@ -14,9 +14,9 @@ import type { ARIAButtonProps, ARIAButtonSlotProps, ARIAButtonType } from './typ * for multiple scenarios of shorthand properties. Ensuring 1st rule of ARIA for cases * where no attribute addition is required. */ -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated export const useARIAButtonShorthand: ResolveShorthandFunction = (value, options) => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const shorthand = resolveShorthand(value, options); const shorthandARIAButton = useARIAButtonProps(shorthand?.as ?? 'button', shorthand); return shorthand && shorthandARIAButton; diff --git a/packages/react-components/react-aria/library/src/index.ts b/packages/react-components/react-aria/library/src/index.ts index 45a9dc54c4afdd..ad3356f83b1de0 100644 --- a/packages/react-components/react-aria/library/src/index.ts +++ b/packages/react-components/react-aria/library/src/index.ts @@ -1,5 +1,5 @@ export { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated useARIAButtonShorthand, useARIAButtonProps, } from './button/index'; diff --git a/packages/react-components/react-avatar/library/src/Avatar.ts b/packages/react-components/react-avatar/library/src/Avatar.ts index 8ca97c6548782f..642b24efddd5c4 100644 --- a/packages/react-components/react-avatar/library/src/Avatar.ts +++ b/packages/react-components/react-avatar/library/src/Avatar.ts @@ -3,7 +3,7 @@ export type { AvatarProps, AvatarShape, AvatarSize, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated AvatarSizes, AvatarSlots, AvatarState, diff --git a/packages/react-components/react-avatar/library/src/components/Avatar/index.ts b/packages/react-components/react-avatar/library/src/components/Avatar/index.ts index e797bdbe9904cd..410a795a32eb43 100644 --- a/packages/react-components/react-avatar/library/src/components/Avatar/index.ts +++ b/packages/react-components/react-avatar/library/src/components/Avatar/index.ts @@ -3,7 +3,7 @@ export type { AvatarProps, AvatarShape, AvatarSize, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated AvatarSizes, AvatarSlots, AvatarState, diff --git a/packages/react-components/react-avatar/library/src/index.ts b/packages/react-components/react-avatar/library/src/index.ts index af3c17671056a6..6575eeafb28f75 100644 --- a/packages/react-components/react-avatar/library/src/index.ts +++ b/packages/react-components/react-avatar/library/src/index.ts @@ -11,7 +11,7 @@ export type { AvatarSlots, AvatarState, AvatarShape, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated AvatarSizes, AvatarSize, } from './Avatar'; diff --git a/packages/react-components/react-carousel/stories/src/Carousel/index.stories.tsx b/packages/react-components/react-carousel/stories/src/Carousel/index.stories.tsx index 29d2ccf2468add..9d3be3b898bc6f 100644 --- a/packages/react-components/react-carousel/stories/src/Carousel/index.stories.tsx +++ b/packages/react-components/react-carousel/stories/src/Carousel/index.stories.tsx @@ -24,7 +24,7 @@ export { FirstRunExperience } from './CarouselFirstRunExperience.stories'; export { Eventing } from './CarouselEventing.stories'; export default { - title: 'Components/Carousel', + title: 'Components/Carousel/Carousel', component: Carousel, subcomponents: { CarouselAutoplayButton, diff --git a/packages/react-components/react-color-picker-preview/library/etc/react-color-picker-preview.api.md b/packages/react-components/react-color-picker-preview/library/etc/react-color-picker-preview.api.md index 0ff850de65940e..8190eeb7f921ca 100644 --- a/packages/react-components/react-color-picker-preview/library/etc/react-color-picker-preview.api.md +++ b/packages/react-components/react-color-picker-preview/library/etc/react-color-picker-preview.api.md @@ -20,7 +20,9 @@ export const AlphaSlider: ForwardRefComponent; export const alphaSliderClassNames: SlotClassNames; // @public -export type AlphaSliderProps = ColorSliderProps; +export type AlphaSliderProps = ColorSliderProps & { + transparency?: boolean; +}; // @public (undocumented) export type AlphaSliderSlots = ColorSliderSlots; diff --git a/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/AlphaSlider.types.ts b/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/AlphaSlider.types.ts index 7a471fa974f46c..2f4c1195416b14 100644 --- a/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/AlphaSlider.types.ts +++ b/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/AlphaSlider.types.ts @@ -6,7 +6,17 @@ export type AlphaSliderSlots = ColorSliderSlots; /** * AlphaSlider Props */ -export type AlphaSliderProps = ColorSliderProps; +export type AlphaSliderProps = ColorSliderProps & { + /** + * The `transparency` property determines how the alpha channel is interpreted. + * - When `false`, the alpha channel represents the opacity of the color. + * - When `true`, the alpha channel represents the transparency of the color. + * For example, a 30% transparent color has 70% opacity. + * + * @defaultvalue false + */ + transparency?: boolean; +}; /** * State used in rendering AlphaSlider diff --git a/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/alphaSliderUtils.test.ts b/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/alphaSliderUtils.test.ts new file mode 100644 index 00000000000000..2756ee7164985a --- /dev/null +++ b/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/alphaSliderUtils.test.ts @@ -0,0 +1,54 @@ +import { adjustToTransparency, calculateTransparencyValue, getSliderDirection } from './alphaSliderUtils'; + +describe('AlphaSlider Utils', () => { + describe('adjustToTransparency', () => { + it('should return 100 - value when transparency is true', () => { + expect(adjustToTransparency(30, true)).toBe(70); + }); + + it('should return value when transparency is false', () => { + expect(adjustToTransparency(30, false)).toBe(30); + }); + }); + + describe('calculateTransparencyValue', () => { + it('should return adjusted value when value is provided and transparency is true', () => { + expect(calculateTransparencyValue(true, 0.3)).toBe(70); + }); + + it('should return adjusted value when value is provided and transparency is false', () => { + expect(calculateTransparencyValue(false, 0.3)).toBe(30); + }); + + it('should return undefined when value is not provided', () => { + expect(calculateTransparencyValue(true)).toBeUndefined(); + expect(calculateTransparencyValue(false)).toBeUndefined(); + }); + }); + + describe('getSliderDirection', () => { + it('should return "180deg" when vertical is true and transparency is true', () => { + expect(getSliderDirection('ltr', true, true)).toBe('180deg'); + }); + + it('should return "0deg" when vertical is true and transparency is false', () => { + expect(getSliderDirection('ltr', true, false)).toBe('0deg'); + }); + + it('should return "90deg" when dir is "ltr" and transparency is false', () => { + expect(getSliderDirection('ltr', false, false)).toBe('90deg'); + }); + + it('should return "-90deg" when dir is "ltr" and transparency is true', () => { + expect(getSliderDirection('ltr', false, true)).toBe('-90deg'); + }); + + it('should return "-90deg" when dir is "rtl" and transparency is false', () => { + expect(getSliderDirection('rtl', false, false)).toBe('-90deg'); + }); + + it('should return "-90deg" when dir is "rtl" and transparency is true', () => { + expect(getSliderDirection('rtl', false, true)).toBe('-90deg'); + }); + }); +}); diff --git a/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/alphaSliderUtils.ts b/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/alphaSliderUtils.ts new file mode 100644 index 00000000000000..739fe0c7fcde8f --- /dev/null +++ b/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/alphaSliderUtils.ts @@ -0,0 +1,36 @@ +/** + * Adjusts the given value based on the transparency flag. + * + * @param value - The numeric value to adjust. + * @param transparency - A boolean flag indicating whether to adjust for transparency. + * @returns The adjusted value. + */ +export function adjustToTransparency(value: number, transparency: boolean) { + return transparency ? 100 - value : value; +} + +/** + * Calculates the transparency value based on the given parameters. + * + * @param transparency - A boolean flag indicating whether to adjust for transparency. + * @param value - An optional numeric value to adjust. + * @returns The calculated transparency value or undefined if the value is not provided. + */ +export function calculateTransparencyValue(transparency: boolean, value?: number) { + return value !== undefined ? adjustToTransparency(value * 100, transparency) : undefined; +} + +/** + * Determines the direction of the slider based on the given parameters. + * + * @param dir - The text direction, either 'ltr' (left-to-right) or 'rtl' (right-to-left). + * @param vertical - A boolean indicating if the slider is vertical. + * @param transparency - A boolean indicating if the slider is for transparency. + * @returns The direction of the slider as a string representing degrees (e.g., '90deg'). + */ +export function getSliderDirection(dir: 'ltr' | 'rtl', vertical: boolean, transparency: boolean) { + if (vertical) { + return transparency ? '180deg' : '0deg'; + } + return dir === 'ltr' && !transparency ? '90deg' : '-90deg'; +} diff --git a/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/useAlphaSliderState.ts b/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/useAlphaSliderState.ts index 153975294f8e5a..c1654f5eef77c2 100644 --- a/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/useAlphaSliderState.ts +++ b/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/useAlphaSliderState.ts @@ -8,6 +8,7 @@ import { useColorPickerContextValue_unstable } from '../../contexts/colorPicker' import { MIN, MAX } from '../../utils/constants'; import { getPercent } from '../../utils/getPercent'; import type { HsvColor } from '../../types/color'; +import { adjustToTransparency, calculateTransparencyValue, getSliderDirection } from './alphaSliderUtils'; export const useAlphaSliderState_unstable = (state: AlphaSliderState, props: AlphaSliderProps) => { 'use no memo'; @@ -15,30 +16,33 @@ export const useAlphaSliderState_unstable = (state: AlphaSliderState, props: Alp const { dir } = useFluent(); const onChangeFromContext = useColorPickerContextValue_unstable(ctx => ctx.requestChange); const colorFromContext = useColorPickerContextValue_unstable(ctx => ctx.color); - const { color, onChange = onChangeFromContext } = props; + const { color, onChange = onChangeFromContext, transparency = false, vertical = false } = props; const hsvColor = color || colorFromContext; const hslColor = tinycolor(hsvColor).toHsl(); const [currentValue, setCurrentValue] = useControllableState({ - defaultState: props.defaultColor?.a ? props.defaultColor.a * 100 : undefined, - state: hsvColor?.a ? hsvColor.a * 100 : undefined, - initialState: 100, + defaultState: calculateTransparencyValue(transparency, props.defaultColor?.a), + state: calculateTransparencyValue(transparency, hsvColor?.a), + initialState: adjustToTransparency(100, transparency), }); + const clampedValue = clamp(currentValue, MIN, MAX); const valuePercent = getPercent(clampedValue, MIN, MAX); const inputOnChange = state.input.onChange; const _onChange: React.ChangeEventHandler = useEventCallback(event => { - const newValue = Number(event.target.value); + const newValue = adjustToTransparency(Number(event.target.value), transparency); const newColor: HsvColor = { ...hsvColor, a: newValue / 100 }; setCurrentValue(newValue); inputOnChange?.(event); onChange?.(event, { type: 'change', event, color: newColor }); }); + const sliderDirection = getSliderDirection(dir, vertical, transparency); + const rootVariables = { - [alphaSliderCSSVars.sliderDirectionVar]: state.vertical ? '0deg' : dir === 'ltr' ? '90deg' : '-90deg', + [alphaSliderCSSVars.sliderDirectionVar]: sliderDirection, [alphaSliderCSSVars.sliderProgressVar]: `${valuePercent}%`, [alphaSliderCSSVars.thumbColorVar]: `transparent`, [alphaSliderCSSVars.railColorVar]: `hsl(${hslColor.h} ${hslColor.s * 100}%, ${hslColor.l * 100}%)`, diff --git a/packages/react-components/react-color-picker-preview/library/src/components/ColorArea/useColorArea.ts b/packages/react-components/react-color-picker-preview/library/src/components/ColorArea/useColorArea.ts index e11b88384ff351..d3b814a6aac836 100644 --- a/packages/react-components/react-color-picker-preview/library/src/components/ColorArea/useColorArea.ts +++ b/packages/react-components/react-color-picker-preview/library/src/components/ColorArea/useColorArea.ts @@ -175,7 +175,7 @@ export const useColorArea_unstable = (props: ColorAreaProps, ref: React.Ref) => { const styles = useStyles(); const [color, setColor] = React.useState(COLOR); + const [transparancyColor, setTransparancyColor] = React.useState(COLOR); const [value, setValue] = React.useState(COLOR.a * 100); const onSliderChange: AlphaSliderProps['onChange'] = (_, data) => { const alpha = data.color.a ?? 1; setColor({ ...data.color, a: alpha }); setValue(alpha * 100); }; + const onTransparancySliderChange: AlphaSliderProps['onChange'] = (_, data) => + setTransparancyColor({ ...data.color, a: data.color.a ?? 1 }); const resetSlider = () => setColor(COLOR); + const resetTransparencySlider = () => setTransparancyColor(COLOR); return (
@@ -48,6 +51,26 @@ export const AlphaSliderExample = (props: Partial) => { />
+

Transparency

+ + +
+
); }; diff --git a/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorAndSwatchPicker.stories.tsx b/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorAndSwatchPicker.stories.tsx index 4c702b95060c0f..8d883d2f3661e7 100644 --- a/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorAndSwatchPicker.stories.tsx +++ b/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorAndSwatchPicker.stories.tsx @@ -48,8 +48,9 @@ const useStyles = makeStyles({ const ITEMS_LIMIT = 8; const DEFAULT_SELECTED_VALUE = '2be700'; -const DEFAULT_SELECTED_COLOR = '#2be700'; -const DEFAULT_COLOR_HSV = tinycolor(DEFAULT_SELECTED_COLOR).toHsv(); + +const DEFAULT_COLOR_HSV = { h: 109, s: 1, v: 0.9, a: 1 }; +const DEFAULT_SELECTED_COLOR = tinycolor(DEFAULT_COLOR_HSV).toHex(); export const ColorAndSwatchPickerExample = () => { const styles = useStyles(); @@ -97,11 +98,11 @@ export const ColorAndSwatchPickerExample = () => { return (
- +
- - + +
@@ -110,6 +111,7 @@ export const ColorAndSwatchPickerExample = () => { aria-label="SwatchPicker with empty swatches" selectedValue={selectedValue} onSelectionChange={handleSelect} + shape="rounded" > {items.map(item => ( diff --git a/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorAreaDefault.stories.tsx b/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorAreaDefault.stories.tsx index 53b06d3ee52946..121943a471ee61 100644 --- a/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorAreaDefault.stories.tsx +++ b/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorAreaDefault.stories.tsx @@ -21,7 +21,7 @@ const useStyles = makeStyles({ }, }); -const DEFAULT_COLOR_HSV = tinycolor('#804066').toHsv(); +const DEFAULT_COLOR_HSV = { h: 324, s: 0.5, v: 0.5, a: 1 }; export const ColorAreaExample = () => { const styles = useStyles(); @@ -38,14 +38,18 @@ export const ColorAreaExample = () => { }; const resetSlider = () => setColor(DEFAULT_COLOR_HSV); const ariaAttributes = { - 'aria-label': 'ColorPicker', 'aria-roledescription': '2D slider', 'aria-valuetext': `Saturation ${color.s * 100}, Brightness: ${color.v * 100}, ${namedColor}`, }; return (
- +
diff --git a/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorPickerDefault.stories.tsx b/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorPickerDefault.stories.tsx index 394822d70e8309..f329dbf2bd9a68 100644 --- a/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorPickerDefault.stories.tsx +++ b/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorPickerDefault.stories.tsx @@ -56,7 +56,7 @@ const useStyles = makeStyles({ const HEX_COLOR_REGEX = /^#?([0-9A-Fa-f]{0,6})$/; const NUMBER_REGEX = /^\d+$/; -const DEFAULT_COLOR_HSV = tinycolor('#2be700').toHsv(); +const DEFAULT_COLOR_HSV = { h: 109, s: 1, v: 0.9, a: 1 }; type RgbKey = 'r' | 'g' | 'b'; @@ -120,7 +120,6 @@ export const Default = () => { ); const colorAriaAttributes = { - 'aria-label': 'ColorPicker', 'aria-roledescription': '2D slider', 'aria-valuetext': `Saturation ${color.s * 100}, Brightness: ${color.v * 100}, ${namedColor}`, }; @@ -128,7 +127,10 @@ export const Default = () => { return (
- + diff --git a/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorPickerPopup.stories.tsx b/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorPickerPopup.stories.tsx index 3b1b43a2bd4108..54c783638ba87e 100644 --- a/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorPickerPopup.stories.tsx +++ b/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorPickerPopup.stories.tsx @@ -36,7 +36,7 @@ const useStyles = makeStyles({ }, }); -const DEFAULT_COLOR_HSV = tinycolor('#2be700').toHsv(); +const DEFAULT_COLOR_HSV = { h: 109, s: 1, v: 0.9, a: 1 }; export const ColorPickerPopup = () => { const styles = useStyles(); @@ -58,11 +58,11 @@ export const ColorPickerPopup = () => { - +
- - + +
diff --git a/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorPickerShape.stories.tsx b/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorPickerShape.stories.tsx index 89349528ca0f00..048d8862fa5297 100644 --- a/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorPickerShape.stories.tsx +++ b/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorPickerShape.stories.tsx @@ -27,7 +27,7 @@ const useStyles = makeStyles({ }, }); -const DEFAULT_COLOR_HSV = tinycolor('#2be700').toHsv(); +const DEFAULT_COLOR_HSV = { h: 109, s: 1, v: 0.91, a: 1 }; export const ColorPickerShape = () => { const styles = useStyles(); @@ -39,15 +39,15 @@ export const ColorPickerShape = () => {

Rounded (default)

- - - + + +

Square (default)

+ -
diff --git a/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorSliderDefault.stories.tsx b/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorSliderDefault.stories.tsx index 1062a371d2bb9e..2c1cbdec1772dc 100644 --- a/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorSliderDefault.stories.tsx +++ b/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorSliderDefault.stories.tsx @@ -20,8 +20,7 @@ const useStyles = makeStyles({ }, }, }); - -const DEFAULT_COLOR_HSV = tinycolor('#2be700').toHsv(); +const DEFAULT_COLOR_HSV = { h: 109, s: 1, v: 0.9, a: 1 }; export const ColorSliderExample = (props: Partial) => { const styles = useStyles(); diff --git a/packages/react-components/react-combobox/library/src/components/Combobox/renderCombobox.tsx b/packages/react-components/react-combobox/library/src/components/Combobox/renderCombobox.tsx index b0a5796ec06ca7..5702e653d61545 100644 --- a/packages/react-components/react-combobox/library/src/components/Combobox/renderCombobox.tsx +++ b/packages/react-components/react-combobox/library/src/components/Combobox/renderCombobox.tsx @@ -18,7 +18,7 @@ export const renderCombobox_unstable = (state: ComboboxState, contextValues: Com - {/*eslint-disable-next-line deprecation/deprecation*/} + {/*eslint-disable-next-line @typescript-eslint/no-deprecated*/} {state.clearIcon && } @@ -31,7 +31,7 @@ export const renderCombobox_unstable = (state: ComboboxState, contextValues: Com ))} - {/*eslint-disable-next-line deprecation/deprecation*/} + {/*eslint-disable-next-line @typescript-eslint/no-deprecated*/} diff --git a/packages/react-components/react-combobox/library/src/components/Dropdown/renderDropdown.tsx b/packages/react-components/react-combobox/library/src/components/Dropdown/renderDropdown.tsx index 130540c32d52fe..69238109c1ef71 100644 --- a/packages/react-components/react-combobox/library/src/components/Dropdown/renderDropdown.tsx +++ b/packages/react-components/react-combobox/library/src/components/Dropdown/renderDropdown.tsx @@ -19,7 +19,7 @@ export const renderDropdown_unstable = (state: DropdownState, contextValues: Dro - {/*eslint-disable-next-line deprecation/deprecation*/} + {/*eslint-disable-next-line @typescript-eslint/no-deprecated*/} {state.button.children} @@ -34,7 +34,7 @@ export const renderDropdown_unstable = (state: DropdownState, contextValues: Dro ))} - {/*eslint-disable-next-line deprecation/deprecation*/} + {/*eslint-disable-next-line @typescript-eslint/no-deprecated*/} diff --git a/packages/react-components/react-combobox/library/src/contexts/ComboboxContext.ts b/packages/react-components/react-combobox/library/src/contexts/ComboboxContext.ts index 1d96af9f998140..128877010abdf7 100644 --- a/packages/react-components/react-combobox/library/src/contexts/ComboboxContext.ts +++ b/packages/react-components/react-combobox/library/src/contexts/ComboboxContext.ts @@ -50,5 +50,5 @@ export const ComboboxContext = createContext({ * @see ListboxProvider * @see useListboxContext_unstable */ -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated export const ComboboxProvider = ComboboxContext.Provider; diff --git a/packages/react-components/react-combobox/library/src/index.ts b/packages/react-components/react-combobox/library/src/index.ts index 1ca229c8b342dd..66637ff8ccf367 100644 --- a/packages/react-components/react-combobox/library/src/index.ts +++ b/packages/react-components/react-combobox/library/src/index.ts @@ -1,4 +1,4 @@ -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated export { ComboboxProvider } from './contexts/ComboboxContext'; export type { ComboboxContextValue } from './contexts/ComboboxContext'; export { ListboxProvider, useListboxContext_unstable } from './contexts/ListboxContext'; diff --git a/packages/react-components/react-components/etc/react-components.api.md b/packages/react-components/react-components/etc/react-components.api.md index 75bc436038bc95..9fa63ed455f95c 100644 --- a/packages/react-components/react-components/etc/react-components.api.md +++ b/packages/react-components/react-components/etc/react-components.api.md @@ -1135,6 +1135,7 @@ import { tagPickerButtonClassNames } from '@fluentui/react-tag-picker'; import { TagPickerButtonProps } from '@fluentui/react-tag-picker'; import { TagPickerButtonSlots } from '@fluentui/react-tag-picker'; import { TagPickerButtonState } from '@fluentui/react-tag-picker'; +import { TagPickerContextValue } from '@fluentui/react-tag-picker'; import { TagPickerContextValues } from '@fluentui/react-tag-picker'; import { TagPickerControl } from '@fluentui/react-tag-picker'; import { tagPickerControlClassNames } from '@fluentui/react-tag-picker'; @@ -1368,6 +1369,7 @@ import { TreeOpenChangeData } from '@fluentui/react-tree'; import { TreeOpenChangeEvent } from '@fluentui/react-tree'; import { TreeProps } from '@fluentui/react-tree'; import { TreeProvider } from '@fluentui/react-tree'; +import { TreeRootReset } from '@fluentui/react-tree'; import { TreeSelectionValue } from '@fluentui/react-tree'; import { TreeSlots } from '@fluentui/react-tree'; import { TreeState } from '@fluentui/react-tree'; @@ -1733,6 +1735,7 @@ import { useTagGroupStyles_unstable } from '@fluentui/react-tags'; import { useTagPicker_unstable } from '@fluentui/react-tag-picker'; import { useTagPickerButton_unstable } from '@fluentui/react-tag-picker'; import { useTagPickerButtonStyles_unstable } from '@fluentui/react-tag-picker'; +import { useTagPickerContext_unstable } from '@fluentui/react-tag-picker'; import { useTagPickerControl_unstable } from '@fluentui/react-tag-picker'; import { useTagPickerControlStyles_unstable } from '@fluentui/react-tag-picker'; import { useTagPickerFilter } from '@fluentui/react-tag-picker'; @@ -4086,6 +4089,8 @@ export { TagPickerButtonSlots } export { TagPickerButtonState } +export { TagPickerContextValue } + export { TagPickerContextValues } export { TagPickerControl } @@ -4552,6 +4557,8 @@ export { TreeProps } export { TreeProvider } +export { TreeRootReset } + export { TreeSelectionValue } export { TreeSlots } @@ -5282,6 +5289,8 @@ export { useTagPickerButton_unstable } export { useTagPickerButtonStyles_unstable } +export { useTagPickerContext_unstable } + export { useTagPickerControl_unstable } export { useTagPickerControlStyles_unstable } diff --git a/packages/react-components/react-components/src/index.ts b/packages/react-components/react-components/src/index.ts index dc4d8fbed60524..32dd9b20295d32 100644 --- a/packages/react-components/react-components/src/index.ts +++ b/packages/react-components/react-components/src/index.ts @@ -103,19 +103,19 @@ export { export type { AnnounceContextValue } from '@fluentui/react-shared-contexts'; export { // getNativeElementProps is deprecated but removing it would be a breaking change - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getNativeElementProps, getIntrinsicElementProps, getPartitionedNativeProps, // getSlots is deprecated but removing it would be a breaking change - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSlots, slot, assertSlots, IdPrefixProvider, resetIdsForTests, // resolveShorthand is deprecated but removing it would be a breaking change - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated resolveShorthand, SSRProvider, useAnimationFrame, @@ -134,10 +134,10 @@ export type { ComponentState, ForwardRefComponent, // ResolveShorthandFunction is deprecated but removing it would be a breaking change - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated ResolveShorthandFunction, // ResolveShorthandOptions is deprecated but removing it would be a breaking change - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated ResolveShorthandOptions, Slot, SlotOptions, @@ -241,7 +241,7 @@ export type { AvatarNamedColor, AvatarProps, // AvatarSizes is deprecated but removing it would be a breaking change - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated AvatarSizes, AvatarSize, AvatarSlots, @@ -374,7 +374,7 @@ export { optionGroupClassNames, useOptionGroupStyles_unstable, useOptionGroup_unstable, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated ComboboxProvider, useComboboxContextValues, ListboxProvider, @@ -562,7 +562,7 @@ export type { MenuOpenChangeData, MenuOpenEvent, // MenuOpenEvents is deprecated but removing it would be a breaking change - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated MenuOpenEvents, MenuPopoverProps, MenuPopoverSlots, @@ -578,7 +578,7 @@ export type { MenuTriggerState, SelectableHandler, // UninitializedMenuListState is deprecated but removing it would be a breaking change - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated UninitializedMenuListState, } from '@fluentui/react-menu'; export { @@ -630,7 +630,7 @@ export { renderRadio_unstable, renderRadioGroup_unstable, useRadio_unstable, - useRadioGroupContext_unstable, // eslint-disable-line deprecation/deprecation + useRadioGroupContext_unstable, // eslint-disable-line @typescript-eslint/no-deprecated useRadioGroupContextValue_unstable, useRadioGroupContextValues, useRadioGroup_unstable, @@ -1306,6 +1306,7 @@ export { useTreeItem_unstable, useTreeStyles_unstable, useTree_unstable, + TreeRootReset, } from '@fluentui/react-tree'; export type { @@ -1781,6 +1782,7 @@ export { useTagPickerOptionGroupStyles, useTagPickerOptionGroup, useTagPickerFilter, + useTagPickerContext_unstable, } from '@fluentui/react-tag-picker'; export type { TagPickerContextValues, @@ -1811,6 +1813,7 @@ export type { TagPickerOptionGroupProps, TagPickerOptionGroupSlots, TagPickerOptionGroupState, + TagPickerContextValue, } from '@fluentui/react-tag-picker'; export { diff --git a/packages/react-components/react-components/src/unstable/index.ts b/packages/react-components/react-components/src/unstable/index.ts index 97cbbb4f339bda..b821e46f85ef9c 100644 --- a/packages/react-components/react-components/src/unstable/index.ts +++ b/packages/react-components/react-components/src/unstable/index.ts @@ -7,7 +7,7 @@ // - use/consume `*-preview` packages directly for preview/unstable Fluent UI core controls early access // ===================================================================================================== -/* eslint-disable deprecation/deprecation */ +/* eslint-disable @typescript-eslint/no-deprecated */ export { Alert, alertClassNames, @@ -37,7 +37,7 @@ export type { InfoLabelSlots, InfoLabelState, } from '@fluentui/react-infobutton'; -/* eslint-enable deprecation/deprecation */ +/* eslint-enable @typescript-eslint/no-deprecated */ export { Virtualizer, diff --git a/packages/react-components/react-dialog/stories/src/Dialog/DialogAlert.stories.tsx b/packages/react-components/react-dialog/stories/src/Dialog/DialogAlert.stories.tsx index acd15f5ad3e12e..d7dcfef470850c 100644 --- a/packages/react-components/react-dialog/stories/src/Dialog/DialogAlert.stories.tsx +++ b/packages/react-components/react-dialog/stories/src/Dialog/DialogAlert.stories.tsx @@ -25,10 +25,10 @@ export const Alert = () => { pressed to dismiss this Alert + - diff --git a/packages/react-components/react-dialog/stories/src/Dialog/DialogChangeFocus.stories.tsx b/packages/react-components/react-dialog/stories/src/Dialog/DialogChangeFocus.stories.tsx index d872b259e1df0c..f5d6e8b2fb4e0d 100644 --- a/packages/react-components/react-dialog/stories/src/Dialog/DialogChangeFocus.stories.tsx +++ b/packages/react-components/react-dialog/stories/src/Dialog/DialogChangeFocus.stories.tsx @@ -31,12 +31,12 @@ export const ChangeFocus = () => { + - diff --git a/packages/react-components/react-dialog/stories/src/Dialog/DialogControllingOpenAndClose.stories.tsx b/packages/react-components/react-dialog/stories/src/Dialog/DialogControllingOpenAndClose.stories.tsx index d2fcf0ede0a42f..f76d7da8f00903 100644 --- a/packages/react-components/react-dialog/stories/src/Dialog/DialogControllingOpenAndClose.stories.tsx +++ b/packages/react-components/react-dialog/stories/src/Dialog/DialogControllingOpenAndClose.stories.tsx @@ -27,10 +27,10 @@ export const ControllingOpenAndClose = () => { cumque eaque? + - diff --git a/packages/react-components/react-dialog/stories/src/Dialog/DialogCustomTrigger.stories.tsx b/packages/react-components/react-dialog/stories/src/Dialog/DialogCustomTrigger.stories.tsx index 526402fab05bfe..7dd51ba339194e 100644 --- a/packages/react-components/react-dialog/stories/src/Dialog/DialogCustomTrigger.stories.tsx +++ b/packages/react-components/react-dialog/stories/src/Dialog/DialogCustomTrigger.stories.tsx @@ -35,10 +35,10 @@ export const CustomTrigger = () => { cumque eaque? + - diff --git a/packages/react-components/react-dialog/stories/src/Dialog/DialogDefault.stories.tsx b/packages/react-components/react-dialog/stories/src/Dialog/DialogDefault.stories.tsx index e36839a8ddfdfb..00c1940b9e354a 100644 --- a/packages/react-components/react-dialog/stories/src/Dialog/DialogDefault.stories.tsx +++ b/packages/react-components/react-dialog/stories/src/Dialog/DialogDefault.stories.tsx @@ -25,10 +25,10 @@ export const Default = () => { cumque eaque? + - diff --git a/packages/react-components/react-dialog/stories/src/Dialog/DialogFluidDialogActions.stories.tsx b/packages/react-components/react-dialog/stories/src/Dialog/DialogFluidDialogActions.stories.tsx index de95f61c2a9210..4bd53c955f0eac 100644 --- a/packages/react-components/react-dialog/stories/src/Dialog/DialogFluidDialogActions.stories.tsx +++ b/packages/react-components/react-dialog/stories/src/Dialog/DialogFluidDialogActions.stories.tsx @@ -26,12 +26,12 @@ export const FluidActions = () => { cumque eaque? + - diff --git a/packages/react-components/react-dialog/stories/src/Dialog/DialogScrollingLongContent.stories.tsx b/packages/react-components/react-dialog/stories/src/Dialog/DialogScrollingLongContent.stories.tsx index 4cd63e09f95db4..a35205026b8051 100644 --- a/packages/react-components/react-dialog/stories/src/Dialog/DialogScrollingLongContent.stories.tsx +++ b/packages/react-components/react-dialog/stories/src/Dialog/DialogScrollingLongContent.stories.tsx @@ -126,10 +126,10 @@ export const ScrollingLongContent = () => {

+ - diff --git a/packages/react-components/react-dialog/stories/src/Dialog/DialogTriggerOutsideDialog.stories.tsx b/packages/react-components/react-dialog/stories/src/Dialog/DialogTriggerOutsideDialog.stories.tsx index f4589ee411be72..584610b8bc7205 100644 --- a/packages/react-components/react-dialog/stories/src/Dialog/DialogTriggerOutsideDialog.stories.tsx +++ b/packages/react-components/react-dialog/stories/src/Dialog/DialogTriggerOutsideDialog.stories.tsx @@ -47,11 +47,11 @@ export const TriggerOutsideDialog = () => { + {/* DialogTrigger inside of a Dialog still works properly */} - diff --git a/packages/react-components/react-dialog/stories/src/Dialog/DialogWithForm.stories.tsx b/packages/react-components/react-dialog/stories/src/Dialog/DialogWithForm.stories.tsx index b1d739aec6860e..082d22dcad06ca 100644 --- a/packages/react-components/react-dialog/stories/src/Dialog/DialogWithForm.stories.tsx +++ b/packages/react-components/react-dialog/stories/src/Dialog/DialogWithForm.stories.tsx @@ -48,12 +48,12 @@ export const WithForm = () => { - - - + + + diff --git a/packages/react-components/react-icons-compat/library/src/icon.ts b/packages/react-components/react-icons-compat/library/src/icon.ts index 9c64d247c04927..47e689293d0e31 100644 --- a/packages/react-components/react-icons-compat/library/src/icon.ts +++ b/packages/react-components/react-icons-compat/library/src/icon.ts @@ -171,7 +171,7 @@ export function getIcon(name?: string): IconRecord | undefined { } } } else { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (!options.disableWarnings && options.warnOnMissingIcons) { // eslint-disable-next-line no-console console.warn( diff --git a/packages/react-components/react-input/library/src/components/Input/Input.test.tsx b/packages/react-components/react-input/library/src/components/Input/Input.test.tsx index 2d12b3fbca0d4c..55f93f73560398 100644 --- a/packages/react-components/react-input/library/src/components/Input/Input.test.tsx +++ b/packages/react-components/react-input/library/src/components/Input/Input.test.tsx @@ -128,4 +128,15 @@ describe('Input', () => { expect(input.value).toBe('foo'); expect(spy).not.toHaveBeenCalled(); }); + + it('forwards native input props to the input element', () => { + renderedComponent = render(); + + expect(getInput()).toMatchObject({ + minLength: 1, + maxLength: 2, + }); + + expect(getInput().getAttribute('autocorrect')).toEqual('on'); + }); }); diff --git a/packages/react-components/react-jsx-runtime/src/createElement.test.tsx b/packages/react-components/react-jsx-runtime/src/createElement.test.tsx index 59cd16ff8b906e..3b670e327d6f50 100644 --- a/packages/react-components/react-jsx-runtime/src/createElement.test.tsx +++ b/packages/react-components/react-jsx-runtime/src/createElement.test.tsx @@ -77,12 +77,12 @@ describe('createElement with getSlotsNext', () => { const state: TestComponentState = { components: { slot: 'div' }, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated slot: resolveShorthand(props.slot, { defaultProps: { children: 'Default Children', id: 'slot' }, }), }; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { slots, slotProps } = getSlotsNext(state); return ; @@ -120,12 +120,12 @@ describe('createElement with getSlotsNext', () => { const state: TestComponentState = { components: { inner: 'div', outer: 'div' }, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated inner: resolveShorthand(props.inner, { defaultProps: { id: 'inner' } }), - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated outer: resolveShorthand(props.outer, { defaultProps: { id: 'outer' } }), }; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { slots, slotProps } = getSlotsNext(state); return ( diff --git a/packages/react-components/react-jsx-runtime/src/interop.test.tsx b/packages/react-components/react-jsx-runtime/src/interop.test.tsx index d6c46a016b4ef4..24d2f754c91f99 100644 --- a/packages/react-components/react-jsx-runtime/src/interop.test.tsx +++ b/packages/react-components/react-jsx-runtime/src/interop.test.tsx @@ -19,7 +19,7 @@ describe('resolveShorthand with assertSlots', () => { const TestComponent = (props: TestComponentProps) => { const state: TestComponentState = { components: { someSlot: 'div' }, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated someSlot: resolveShorthand(props.someSlot, { required: true, defaultProps: { children: 'Default Children', id: 'slot' }, @@ -64,9 +64,9 @@ describe('resolveShorthand with assertSlots', () => { const TestComponent = (props: TestComponentProps) => { const state: TestComponentState = { components: { outer: 'div', inner: 'div' }, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated inner: resolveShorthand(props.inner, { defaultProps: { id: 'inner' }, required: true }), - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated outer: resolveShorthand(props.outer, { defaultProps: { id: 'outer' }, required: true }), }; assertSlots(state); @@ -125,7 +125,7 @@ describe('resolveShorthand with assertSlots', () => { const TestComponent = (props: TestComponentProps) => { const state: TestComponentState = { components: { slot: 'div' }, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated slot: resolveShorthand(props.slot, { required: true }), }; assertSlots(state); diff --git a/packages/react-components/react-jsx-runtime/src/jsx-runtime.test.tsx b/packages/react-components/react-jsx-runtime/src/jsx-runtime.test.tsx index 66d5a5343aa3ca..ed8b53687fcabe 100644 --- a/packages/react-components/react-jsx-runtime/src/jsx-runtime.test.tsx +++ b/packages/react-components/react-jsx-runtime/src/jsx-runtime.test.tsx @@ -71,12 +71,12 @@ describe('createElement with getSlotsNext', () => { const state: TestComponentState = { components: { slot: 'div' }, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated slot: resolveShorthand(props.slot, { defaultProps: { children: 'Default Children', id: 'slot' }, }), }; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { slots, slotProps } = getSlotsNext(state); return ; @@ -114,12 +114,12 @@ describe('createElement with getSlotsNext', () => { const state: TestComponentState = { components: { inner: 'div', outer: 'div' }, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated inner: resolveShorthand(props.inner, { defaultProps: { id: 'inner' } }), - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated outer: resolveShorthand(props.outer, { defaultProps: { id: 'outer' } }), }; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { slots, slotProps } = getSlotsNext(state); return ( diff --git a/packages/react-components/react-link/library/src/components/Link/Link.test.tsx b/packages/react-components/react-link/library/src/components/Link/Link.test.tsx index 57ab9a049db1df..44bd49f27fea89 100644 --- a/packages/react-components/react-link/library/src/components/Link/Link.test.tsx +++ b/packages/react-components/react-link/library/src/components/Link/Link.test.tsx @@ -1,9 +1,11 @@ import * as React from 'react'; import { render } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { linkBehaviorDefinition, validateBehavior, ComponentTestFacade } from '@fluentui/a11y-testing'; import { isConformant } from '../../testing/isConformant'; import { Link } from './Link'; import { LinkProps } from './Link.types'; +import { Enter } from '@fluentui/keyboard-keys'; describe('Link', () => { isConformant({ @@ -140,5 +142,62 @@ describe('Link', () => { expect(result.queryAllByRole('link')).toHaveLength(0); expect(result.queryAllByRole('presentation')).toHaveLength(1); }); + + describe('when rendered as span', () => { + it('should call onClick by pressing Enter', () => { + const onClick = jest.fn(); + + render( + + This is a buttonlink + , + ); + + userEvent.tab(); + userEvent.keyboard('{Enter}'); + + expect(onClick).toHaveBeenCalledTimes(1); + }); + + it('should trigger onClick once via onKeyDown', () => { + const onClick = jest.fn(); + + render( + { + if (ev.key === Enter) { + ev.currentTarget.click(); + } + }} + > + This is a buttonlink + , + ); + + userEvent.tab(); + userEvent.keyboard('{Enter}'); + + expect(onClick).toHaveBeenCalledTimes(1); + }); + + it('should not trigger onClick', () => { + const onClick = jest.fn(); + const onKeyDown = jest.fn(); + + render( + + This is a buttonlink + , + ); + + userEvent.tab(); + userEvent.keyboard('{Enter}'); + + expect(onClick).toHaveBeenCalledTimes(0); + expect(onKeyDown).toHaveBeenCalledTimes(1); + }); + }); }); }); diff --git a/packages/react-components/react-link/library/src/components/Link/useLinkState.ts b/packages/react-components/react-link/library/src/components/Link/useLinkState.ts index c8655ea6b95b85..b7ef6679ab9c32 100644 --- a/packages/react-components/react-link/library/src/components/Link/useLinkState.ts +++ b/packages/react-components/react-link/library/src/components/Link/useLinkState.ts @@ -36,11 +36,18 @@ export const useLinkState_unstable = (state: LinkState): LinkState => { // Disallow keydown event when component is disabled and eat events when disabledFocusable is set to true. state.root.onKeyDown = (ev: React.KeyboardEvent) => { - if ((disabled || disabledFocusable) && (ev.key === Enter || ev.key === Space)) { + const keyPressed = ev.key === Enter || ev.key === Space; + + if ((disabled || disabledFocusable) && keyPressed) { ev.preventDefault(); ev.stopPropagation(); } else { onKeyDown?.(ev); + // if there is already onKeyDown provided - respect it + if (state.root.as === 'span' && !!state.root.onClick && !onKeyDown && keyPressed) { + ev.preventDefault(); + ev.currentTarget.click(); + } } }; diff --git a/packages/react-components/react-link/stories/src/Link/LinkAsSpan.stories.tsx b/packages/react-components/react-link/stories/src/Link/LinkAsSpan.stories.tsx index a2a421e9f796e8..2c178fe605f436 100644 --- a/packages/react-components/react-link/stories/src/Link/LinkAsSpan.stories.tsx +++ b/packages/react-components/react-link/stories/src/Link/LinkAsSpan.stories.tsx @@ -8,7 +8,7 @@ const useDivWithWidthClassName = makeResetStyles({ export const AsSpan = () => (
The following link renders as a span.{' '} - + alert('Link rendered as span')}> Links that render as a span wrap correctly between lines when their content is very long . This is because they behave as regular inline elements. diff --git a/packages/react-components/react-menu/library/src/Menu.ts b/packages/react-components/react-menu/library/src/Menu.ts index a1d64d15e3ae75..4a6cc2cb8481fd 100644 --- a/packages/react-components/react-menu/library/src/Menu.ts +++ b/packages/react-components/react-menu/library/src/Menu.ts @@ -2,7 +2,7 @@ export type { MenuContextValues, MenuOpenChangeData, MenuOpenEvent, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated MenuOpenEvents, MenuProps, MenuSlots, diff --git a/packages/react-components/react-menu/library/src/MenuList.ts b/packages/react-components/react-menu/library/src/MenuList.ts index 5869d3b2473fcc..bdf7061fb1a954 100644 --- a/packages/react-components/react-menu/library/src/MenuList.ts +++ b/packages/react-components/react-menu/library/src/MenuList.ts @@ -5,7 +5,7 @@ export type { MenuListProps, MenuListSlots, MenuListState, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated UninitializedMenuListState, } from './components/MenuList/index'; export { diff --git a/packages/react-components/react-menu/library/src/components/Menu/index.ts b/packages/react-components/react-menu/library/src/components/Menu/index.ts index 0830f525ad16ad..f8f52e39aa00d2 100644 --- a/packages/react-components/react-menu/library/src/components/Menu/index.ts +++ b/packages/react-components/react-menu/library/src/components/Menu/index.ts @@ -3,7 +3,7 @@ export type { MenuContextValues, MenuOpenChangeData, MenuOpenEvent, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated MenuOpenEvents, MenuProps, MenuSlots, diff --git a/packages/react-components/react-menu/library/src/components/MenuList/index.ts b/packages/react-components/react-menu/library/src/components/MenuList/index.ts index 66b24f6405c9a2..eb018a4ed49ead 100644 --- a/packages/react-components/react-menu/library/src/components/MenuList/index.ts +++ b/packages/react-components/react-menu/library/src/components/MenuList/index.ts @@ -6,7 +6,7 @@ export type { MenuListProps, MenuListSlots, MenuListState, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated UninitializedMenuListState, } from './MenuList.types'; export { renderMenuList_unstable } from './renderMenuList'; diff --git a/packages/react-components/react-menu/library/src/components/index.ts b/packages/react-components/react-menu/library/src/components/index.ts index 778a42b08abe47..eb7e7cd5f0785b 100644 --- a/packages/react-components/react-menu/library/src/components/index.ts +++ b/packages/react-components/react-menu/library/src/components/index.ts @@ -13,7 +13,7 @@ export type { MenuListProps, MenuListSlots, MenuListState, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated UninitializedMenuListState, } from './MenuList/index'; export { diff --git a/packages/react-components/react-menu/library/src/index.ts b/packages/react-components/react-menu/library/src/index.ts index 85019a022946d0..1d2d53e93f1fa0 100644 --- a/packages/react-components/react-menu/library/src/index.ts +++ b/packages/react-components/react-menu/library/src/index.ts @@ -12,7 +12,7 @@ export type { MenuOpenChangeData, MenuOpenEvent, // MenuOpenEvents is deprecated but removing it would be a breaking change - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated MenuOpenEvents, MenuProps, MenuSlots, @@ -83,7 +83,7 @@ export type { MenuListSlots, MenuListState, // UninitializedMenuListState is deprecated but removing it would be a breaking change - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated UninitializedMenuListState, } from './MenuList'; export { diff --git a/packages/react-components/react-message-bar/library/src/components/MessageBar/MessageBar.test.tsx b/packages/react-components/react-message-bar/library/src/components/MessageBar/MessageBar.test.tsx index 056dce8a52bfdf..bd108f6054cab9 100644 --- a/packages/react-components/react-message-bar/library/src/components/MessageBar/MessageBar.test.tsx +++ b/packages/react-components/react-message-bar/library/src/components/MessageBar/MessageBar.test.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { render } from '@testing-library/react'; import { isConformant } from '../../testing/isConformant'; import { MessageBar } from './MessageBar'; -import { AnnounceProvider_unstable } from '@fluentui/react-shared-contexts'; +import { AnnounceProvider } from '@fluentui/react-shared-contexts'; import { MessageBarBody } from '../MessageBarBody/MessageBarBody'; import { MessageBarTitle } from '../MessageBarTitle/MessageBarTitle'; import { MessageBarActions } from '../MessageBarActions/MessageBarActions'; @@ -67,13 +67,13 @@ describe('MessageBar', () => { ])('should announce %s with %s intent', (politeness, intent) => { const announce = jest.fn(); render( - + TitleBody - , + , ); expect(announce).toHaveBeenCalledTimes(1); @@ -86,7 +86,7 @@ describe('MessageBar', () => { it('should announce actions', () => { const announce = jest.fn(); render( - + TitleBody @@ -96,7 +96,7 @@ describe('MessageBar', () => { - , + , ); expect(announce).toHaveBeenCalledTimes(1); diff --git a/packages/react-components/react-message-bar/library/src/components/MessageBar/useMessageBar.ts b/packages/react-components/react-message-bar/library/src/components/MessageBar/useMessageBar.ts index 1c6145749da4fa..7ab387059a5841 100644 --- a/packages/react-components/react-message-bar/library/src/components/MessageBar/useMessageBar.ts +++ b/packages/react-components/react-message-bar/library/src/components/MessageBar/useMessageBar.ts @@ -21,7 +21,7 @@ export const useMessageBar_unstable = (props: MessageBarProps, ref: React.Ref(null); const bodyRef = React.useRef(null); diff --git a/packages/react-components/react-migration-v8-v9/library/package.json b/packages/react-components/react-migration-v8-v9/library/package.json index c7cc7dd2fc481f..d5f844d5560978 100644 --- a/packages/react-components/react-migration-v8-v9/library/package.json +++ b/packages/react-components/react-migration-v8-v9/library/package.json @@ -19,8 +19,8 @@ }, "dependencies": { "@ctrl/tinycolor": "^3.3.4", - "@fluentui/fluent2-theme": "^8.107.123", - "@fluentui/react": "^8.122.6", + "@fluentui/fluent2-theme": "^8.107.124", + "@fluentui/react": "^8.122.7", "@fluentui/react-components": "^9.57.0", "@fluentui/react-icons": "^2.0.245", "@fluentui/react-hooks": "^8.8.16", diff --git a/packages/react-components/react-motion-components-preview/library/src/atoms/fade-atom.ts b/packages/react-components/react-motion-components-preview/library/src/atoms/fade-atom.ts new file mode 100644 index 00000000000000..91b369be83ff71 --- /dev/null +++ b/packages/react-components/react-motion-components-preview/library/src/atoms/fade-atom.ts @@ -0,0 +1,33 @@ +import { AtomMotion, PresenceDirection, motionTokens } from '@fluentui/react-motion'; + +interface FadeAtomParams { + direction: PresenceDirection; + duration: number; + easing?: string; + fromValue?: number; +} + +/** + * Generates a motion atom object for a fade in or fade out. + * @param direction - The functional direction of the motion: 'enter' or 'exit'. + * @param duration - The duration of the motion in milliseconds. + * @param easing - The easing curve for the motion. Defaults to `motionTokens.curveLinear`. + * @param fromValue - The starting opacity value. Defaults to 0. + * @returns A motion atom object with opacity keyframes and the supplied duration and easing. + */ +export const fadeAtom = ({ + direction, + duration, + easing = motionTokens.curveLinear, + fromValue = 0, +}: FadeAtomParams): AtomMotion => { + const keyframes = [{ opacity: fromValue }, { opacity: 1 }]; + if (direction === 'exit') { + keyframes.reverse(); + } + return { + keyframes, + duration, + easing, + }; +}; diff --git a/packages/react-components/react-motion-components-preview/library/src/components/Collapse/Collapse.ts b/packages/react-components/react-motion-components-preview/library/src/components/Collapse/Collapse.ts index 6aa4b7bb66d5dc..22c8862cc3b82f 100644 --- a/packages/react-components/react-motion-components-preview/library/src/components/Collapse/Collapse.ts +++ b/packages/react-components/react-motion-components-preview/library/src/components/Collapse/Collapse.ts @@ -1,14 +1,8 @@ import { motionTokens, createPresenceComponent, AtomMotion } from '@fluentui/react-motion'; import type { PresenceMotionFnCreator } from '../../types'; import type { CollapseDelayedVariantParams, CollapseRuntimeParams, CollapseVariantParams } from './collapse-types'; -import { - sizeEnterAtom, - whitespaceEnterAtom, - opacityEnterAtom, - opacityExitAtom, - sizeExitAtom, - whitespaceExitAtom, -} from './collapse-atoms'; +import { sizeEnterAtom, sizeExitAtom, whitespaceAtom } from './collapse-atoms'; +import { fadeAtom } from '../../atoms/fade-atom'; /** Define a presence motion for collapse/expand that can stagger the size and opacity motions by a given delay. */ export const createCollapseDelayedPresence: PresenceMotionFnCreator< @@ -32,27 +26,16 @@ export const createCollapseDelayedPresence: PresenceMotionFnCreator< // ----- ENTER ----- // The enter transition is an array of up to 3 motion atoms: size, whitespace and opacity. const enterAtoms: AtomMotion[] = [ - sizeEnterAtom({ - orientation, - duration: enterSizeDuration, - easing: enterEasing, - element, - }), - whitespaceEnterAtom({ - orientation, - duration: enterSizeDuration, - easing: enterEasing, - }), + sizeEnterAtom({ orientation, duration: enterSizeDuration, easing: enterEasing, element }), + whitespaceAtom({ direction: 'enter', orientation, duration: enterSizeDuration, easing: enterEasing }), ]; // Fade in only if animateOpacity is true. Otherwise, leave opacity unaffected. if (animateOpacity) { - enterAtoms.push( - opacityEnterAtom({ - duration: enterOpacityDuration, - easing: enterEasing, - delay: enterDelay, - }), - ); + enterAtoms.push({ + ...fadeAtom({ direction: 'enter', duration: enterOpacityDuration, easing: enterEasing }), + delay: enterDelay, + fill: 'both', + }); } // ----- EXIT ----- @@ -60,24 +43,12 @@ export const createCollapseDelayedPresence: PresenceMotionFnCreator< const exitAtoms: AtomMotion[] = []; // Fade out only if animateOpacity is true. Otherwise, leave opacity unaffected. if (animateOpacity) { - exitAtoms.push( - opacityExitAtom({ - duration: exitOpacityDuration, - easing: exitEasing, - }), - ); + exitAtoms.push(fadeAtom({ direction: 'exit', duration: exitOpacityDuration, easing: exitEasing })); } exitAtoms.push( - sizeExitAtom({ - orientation, - duration: exitSizeDuration, - easing: exitEasing, - element, - delay: exitDelay, - }), - ); - exitAtoms.push( - whitespaceExitAtom({ + sizeExitAtom({ orientation, duration: exitSizeDuration, easing: exitEasing, element, delay: exitDelay }), + whitespaceAtom({ + direction: 'exit', orientation, duration: exitSizeDuration, easing: exitEasing, diff --git a/packages/react-components/react-motion-components-preview/library/src/components/Collapse/collapse-atoms.ts b/packages/react-components/react-motion-components-preview/library/src/components/Collapse/collapse-atoms.ts index 0ce27aa7d91c87..391b8eb2a24023 100644 --- a/packages/react-components/react-motion-components-preview/library/src/components/Collapse/collapse-atoms.ts +++ b/packages/react-components/react-motion-components-preview/library/src/components/Collapse/collapse-atoms.ts @@ -1,5 +1,5 @@ -import { AtomMotion } from '@fluentui/react-motion/src/types'; -import type { CollapseOrientation } from './collapse-types'; +import { AtomMotion, PresenceDirection } from '@fluentui/react-motion'; +import { CollapseOrientation } from './collapse-types'; // ----- SIZE ----- @@ -11,19 +11,21 @@ const sizeValuesForOrientation = (orientation: CollapseOrientation, element: Ele return { sizeName, overflowName, toSize }; }; +interface SizeEnterAtomParams { + orientation: CollapseOrientation; + duration: number; + easing: string; + element: HTMLElement; + fromSize?: string; +} + export const sizeEnterAtom = ({ orientation, duration, easing, element, fromSize = '0', -}: { - orientation: CollapseOrientation; - duration: number; - easing: string; - element: HTMLElement; - fromSize?: string; -}): AtomMotion => { +}: SizeEnterAtomParams): AtomMotion => { const { sizeName, overflowName, toSize } = sizeValuesForOrientation(orientation, element); return { @@ -37,6 +39,10 @@ export const sizeEnterAtom = ({ }; }; +interface SizeExitAtomParams extends SizeEnterAtomParams { + delay?: number; +} + export const sizeExitAtom = ({ orientation, duration, @@ -44,14 +50,7 @@ export const sizeExitAtom = ({ element, delay = 0, fromSize = '0', -}: { - orientation: CollapseOrientation; - duration: number; - easing: string; - element: HTMLElement; - delay?: number; - fromSize?: string; -}): AtomMotion => { +}: SizeExitAtomParams): AtomMotion => { const { sizeName, overflowName, toSize } = sizeValuesForOrientation(orientation, element); return { @@ -88,82 +87,39 @@ const whitespaceValuesForOrientation = (orientation: CollapseOrientation) => { }; }; -// Because a height of zero does not eliminate padding or margin, -// we will create keyframes to animate them to zero. -export const whitespaceEnterAtom = ({ - orientation, - duration, - easing, -}: { +interface WhitespaceAtomParams { + direction: PresenceDirection; orientation: CollapseOrientation; duration: number; easing: string; -}): AtomMotion => { - const { paddingStart, paddingEnd, marginStart, marginEnd } = whitespaceValuesForOrientation(orientation); - return { - // Animate from whitespace of zero to the current whitespace, by omitting the ending keyframe. - keyframes: [{ [paddingStart]: '0', [paddingEnd]: '0', [marginStart]: '0', [marginEnd]: '0', offset: 0 }], - duration, - easing, - }; -}; + delay?: number; +} -export const whitespaceExitAtom = ({ +/** + * A collapse animates an element's height to zero, + but the zero height does not eliminate padding or margin in the box model. + So here we generate keyframes to animate those whitespace properties to zero. + */ +export const whitespaceAtom = ({ + direction, orientation, duration, easing, delay = 0, -}: { - orientation: CollapseOrientation; - duration: number; - easing: string; - delay?: number; -}): AtomMotion => { +}: WhitespaceAtomParams): AtomMotion => { const { paddingStart, paddingEnd, marginStart, marginEnd } = whitespaceValuesForOrientation(orientation); - return { - // Animate from the current whitespace to whitespace of zero, by using offset 1 and omitting the starting keyframe. - keyframes: [{ [paddingStart]: '0', [paddingEnd]: '0', [marginStart]: '0', [marginEnd]: '0', offset: 1 }], + // The keyframe with zero whitespace is at the start for enter and at the end for exit. + const offset = direction === 'enter' ? 0 : 1; + const keyframes = [{ [paddingStart]: '0', [paddingEnd]: '0', [marginStart]: '0', [marginEnd]: '0', offset }]; + + const atom: AtomMotion = { + keyframes, duration, easing, - fill: 'forwards', delay, }; + if (direction === 'exit') { + atom.fill = 'forwards'; + } + return atom; }; - -// ----- OPACITY ----- - -export const opacityEnterAtom = ({ - duration, - easing, - delay = 0, - fromOpacity = 0, - toOpacity = 1, -}: { - duration: number; - easing: string; - delay?: number; - fromOpacity?: number; - toOpacity?: number; -}): AtomMotion => ({ - keyframes: [{ opacity: fromOpacity }, { opacity: toOpacity }], - duration, - easing, - delay, - fill: 'both', -}); - -export const opacityExitAtom = ({ - duration, - easing, - fromOpacity = 0, - toOpacity = 1, -}: { - duration: number; - easing: string; - fromOpacity?: number; - toOpacity?: number; -}): AtomMotion => ({ - keyframes: [{ opacity: toOpacity }, { opacity: fromOpacity }], - duration, - easing, -}); diff --git a/packages/react-components/react-motion-components-preview/library/src/components/Fade/Fade.ts b/packages/react-components/react-motion-components-preview/library/src/components/Fade/Fade.ts index 03ca3ea60567a1..d373d235504b69 100644 --- a/packages/react-components/react-motion-components-preview/library/src/components/Fade/Fade.ts +++ b/packages/react-components/react-motion-components-preview/library/src/components/Fade/Fade.ts @@ -1,5 +1,6 @@ import { motionTokens, createPresenceComponent } from '@fluentui/react-motion'; import type { PresenceMotionCreator } from '../../types'; +import { fadeAtom } from '../../atoms/fade-atom'; type FadeVariantParams = { /** Time (ms) for the enter transition (fade-in). Defaults to the `durationNormal` value (200 ms). */ @@ -22,8 +23,8 @@ export const createFadePresence: PresenceMotionCreator = ({ exitDuration = enterDuration, exitEasing = enterEasing, } = {}) => ({ - enter: { duration: enterDuration, easing: enterEasing, keyframes: [{ opacity: 0 }, { opacity: 1 }] }, - exit: { duration: exitDuration, easing: exitEasing, keyframes: [{ opacity: 1 }, { opacity: 0 }] }, + enter: fadeAtom({ direction: 'enter', duration: enterDuration, easing: enterEasing }), + exit: fadeAtom({ direction: 'exit', duration: exitDuration, easing: exitEasing }), }); /** A React component that applies fade in/out transitions to its children. */ diff --git a/packages/react-components/react-motion/library/etc/react-motion.api.md b/packages/react-components/react-motion/library/etc/react-motion.api.md index e8fd8b1a9e8bed..7f97978066768b 100644 --- a/packages/react-components/react-motion/library/etc/react-motion.api.md +++ b/packages/react-components/react-motion/library/etc/react-motion.api.md @@ -9,9 +9,9 @@ import { SlotComponentType } from '@fluentui/react-utilities'; import { SlotRenderFunction } from '@fluentui/react-utilities'; // @public (undocumented) -export type AtomMotion = { - keyframes: Keyframe[]; -} & KeyframeEffectOptions; +export type AtomMotion = AtomCore & { + reducedMotion?: Partial; +}; // @public (undocumented) export type AtomMotionFn = {}> = (params: { diff --git a/packages/react-components/react-motion/library/src/hooks/useAnimateAtoms.test.tsx b/packages/react-components/react-motion/library/src/hooks/useAnimateAtoms.test.tsx new file mode 100644 index 00000000000000..3501931bcf306c --- /dev/null +++ b/packages/react-components/react-motion/library/src/hooks/useAnimateAtoms.test.tsx @@ -0,0 +1,88 @@ +import { renderHook } from '@testing-library/react-hooks'; + +import type { AtomMotion } from '../types'; +import { DEFAULT_ANIMATION_OPTIONS, useAnimateAtoms } from './useAnimateAtoms'; + +function createElementMock() { + const animate = jest.fn().mockReturnValue({ + persist: jest.fn(), + }); + + return [{ animate } as unknown as HTMLElement, animate] as const; +} + +const DEFAULT_KEYFRAMES = [{ transform: 'rotate(0)' }, { transform: 'rotate(180deg)' }]; +const REDUCED_MOTION_KEYFRAMES = [{ opacity: 0 }, { opacity: 1 }]; + +describe('useAnimateAtoms', () => { + beforeEach(() => { + // We set production environment to avoid testing the mock implementation + process.env.NODE_ENV = 'production'; + }); + + it('should return a function', () => { + const { result } = renderHook(() => useAnimateAtoms()); + + expect(result.current).toBeInstanceOf(Function); + }); + + describe('reduce motion', () => { + it('calls ".animate()" with regular motion', () => { + const { result } = renderHook(() => useAnimateAtoms()); + + const [element, animateMock] = createElementMock(); + const motion: AtomMotion = { keyframes: DEFAULT_KEYFRAMES }; + + result.current(element, motion, { isReducedMotion: false }); + + expect(animateMock).toHaveBeenCalledTimes(1); + expect(animateMock).toHaveBeenCalledWith(DEFAULT_KEYFRAMES, { ...DEFAULT_ANIMATION_OPTIONS }); + }); + + it('calls ".animate()" with shortened duration (1ms) when reduced motion is enabled', () => { + const { result } = renderHook(() => useAnimateAtoms()); + + const [element, animateMock] = createElementMock(); + const motion: AtomMotion = { keyframes: DEFAULT_KEYFRAMES }; + + result.current(element, motion, { isReducedMotion: true }); + + expect(animateMock).toHaveBeenCalledTimes(1); + expect(animateMock).toHaveBeenCalledWith(DEFAULT_KEYFRAMES, { ...DEFAULT_ANIMATION_OPTIONS, duration: 1 }); + }); + + it('calls ".animate()" with specified reduced motion keyframes when reduced motion is enabled', () => { + const { result } = renderHook(() => useAnimateAtoms()); + + const [element, animateMock] = createElementMock(); + const motion: AtomMotion = { + keyframes: DEFAULT_KEYFRAMES, + reducedMotion: { keyframes: REDUCED_MOTION_KEYFRAMES }, + }; + + result.current(element, motion, { isReducedMotion: true }); + + expect(animateMock).toHaveBeenCalledTimes(1); + expect(animateMock).toHaveBeenCalledWith(REDUCED_MOTION_KEYFRAMES, { ...DEFAULT_ANIMATION_OPTIONS }); + }); + + it('calls ".animate()" with specified reduced motion params when reduced motion is enabled', () => { + const { result } = renderHook(() => useAnimateAtoms()); + + const [element, animateMock] = createElementMock(); + const motion: AtomMotion = { + keyframes: DEFAULT_KEYFRAMES, + reducedMotion: { duration: 100, easing: 'linear' }, + }; + + result.current(element, motion, { isReducedMotion: true }); + + expect(animateMock).toHaveBeenCalledTimes(1); + expect(animateMock).toHaveBeenCalledWith(DEFAULT_KEYFRAMES, { + ...DEFAULT_ANIMATION_OPTIONS, + easing: 'linear', + duration: 100, + }); + }); + }); +}); diff --git a/packages/react-components/react-motion/library/src/hooks/useAnimateAtoms.ts b/packages/react-components/react-motion/library/src/hooks/useAnimateAtoms.ts index 9bc31e0d2e9cee..59bfe38e32203a 100644 --- a/packages/react-components/react-motion/library/src/hooks/useAnimateAtoms.ts +++ b/packages/react-components/react-motion/library/src/hooks/useAnimateAtoms.ts @@ -1,6 +1,16 @@ import * as React from 'react'; import type { AnimationHandle, AtomMotion } from '../types'; +export const DEFAULT_ANIMATION_OPTIONS: KeyframeEffectOptions = { + fill: 'forwards', +}; + +// A motion atom's default reduced motion is a simple 1 ms duration. +// But an atom can define a custom reduced motion, overriding keyframes and/or params like duration, easing, iterations, etc. +const DEFAULT_REDUCED_MOTION_ATOM: NonNullable = { + duration: 1, +}; + function useAnimateAtomsInSupportedEnvironment() { // eslint-disable-next-line @nx/workspace-no-restricted-globals const SUPPORTS_PERSIST = typeof window !== 'undefined' && typeof window.Animation?.prototype.persist === 'function'; @@ -17,18 +27,26 @@ function useAnimateAtomsInSupportedEnvironment() { const { isReducedMotion } = options; const animations = atoms.map(motion => { - const { keyframes, ...params } = motion; - const animation = element.animate(keyframes, { - fill: 'forwards', - + // Grab the custom reduced motion definition if it exists, or fall back to the default reduced motion. + const { keyframes: motionKeyframes, reducedMotion = DEFAULT_REDUCED_MOTION_ATOM, ...params } = motion; + // Grab the reduced motion keyframes if they exist, or fall back to the regular keyframes. + const { keyframes: reducedMotionKeyframes = motionKeyframes, ...reducedMotionParams } = reducedMotion; + + const animationKeyframes: Keyframe[] = isReducedMotion ? reducedMotionKeyframes : motionKeyframes; + const animationParams: KeyframeEffectOptions = { + ...DEFAULT_ANIMATION_OPTIONS, ...params, - ...(isReducedMotion && { duration: 1 }), - }); + + // Use reduced motion overrides (e.g. duration, easing) when reduced motion is enabled + ...(isReducedMotion && reducedMotionParams), + }; + + const animation = element.animate(animationKeyframes, animationParams); if (SUPPORTS_PERSIST) { animation.persist(); } else { - const resultKeyframe = keyframes[keyframes.length - 1]; + const resultKeyframe = animationKeyframes[animationKeyframes.length - 1]; Object.assign(element.style ?? {}, resultKeyframe); } diff --git a/packages/react-components/react-motion/library/src/slots/presenceMotionSlot.tsx b/packages/react-components/react-motion/library/src/slots/presenceMotionSlot.tsx index 5c85af9d4b9b79..54f108e3b66c74 100644 --- a/packages/react-components/react-motion/library/src/slots/presenceMotionSlot.tsx +++ b/packages/react-components/react-motion/library/src/slots/presenceMotionSlot.tsx @@ -42,7 +42,7 @@ export function presenceMotionSlot { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { as, children, ...rest } = motion ?? {}; if (process.env.NODE_ENV !== 'production') { diff --git a/packages/react-components/react-motion/library/src/types.ts b/packages/react-components/react-motion/library/src/types.ts index b989d7e890b18c..6fdfd8e7130246 100644 --- a/packages/react-components/react-motion/library/src/types.ts +++ b/packages/react-components/react-motion/library/src/types.ts @@ -1,4 +1,15 @@ -export type AtomMotion = { keyframes: Keyframe[] } & KeyframeEffectOptions; +type AtomCore = { keyframes: Keyframe[] } & KeyframeEffectOptions; + +export type AtomMotion = AtomCore & { + /** + * Allows to specify a reduced motion version of the animation. If provided, the settings will be used when the + * user has enabled the reduced motion setting in the operating system (i.e `prefers-reduced-motion` media query is + * active). If not provided, the duration of the animation will be overridden to be 1ms. + * + * Note, if `keyframes` are provided, they will be used instead of the regular `keyframes`. + */ + reducedMotion?: Partial; +}; export type PresenceDirection = 'enter' | 'exit'; diff --git a/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentDefault.stories.tsx b/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentDefault.stories.tsx index 07a0143b051de2..d40b1fb87d986a 100644 --- a/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentDefault.stories.tsx +++ b/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentDefault.stories.tsx @@ -41,6 +41,10 @@ const FadeEnter = createMotionComponent({ keyframes: [{ opacity: 0 }, { opacity: 1 }], duration: motionTokens.durationSlow, iterations: Infinity, + + reducedMotion: { + iterations: 1, + }, }); export const CreateMotionComponentDefault = (props: MotionComponentProps) => { diff --git a/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentFactory.stories.tsx b/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentFactory.stories.tsx index 928ffc9bb2b67b..57b41d3f226aee 100644 --- a/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentFactory.stories.tsx +++ b/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentFactory.stories.tsx @@ -45,6 +45,10 @@ const DropIn = createMotionComponent({ ], duration: 4000, iterations: Infinity, + + reducedMotion: { + iterations: 1, + }, }); export const CreateMotionComponentFactory = () => { diff --git a/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentFunctionParams.stories.tsx b/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentFunctionParams.stories.tsx index bd0374ed4ce868..81ed56abc9ee3a 100644 --- a/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentFunctionParams.stories.tsx +++ b/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentFunctionParams.stories.tsx @@ -81,6 +81,10 @@ const Scale = createMotionComponent<{ startFrom?: number }>(({ startFrom = 0.5 } ], duration: motionTokens.durationUltraSlow, iterations: Infinity, + + reducedMotion: { + iterations: 1, + }, }; }); diff --git a/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentFunctions.stories.tsx b/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentFunctions.stories.tsx index a62027d0707b60..422b33618f6580 100644 --- a/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentFunctions.stories.tsx +++ b/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentFunctions.stories.tsx @@ -68,6 +68,10 @@ const Grow = createMotionComponent(({ element }) => ({ { opacity: 0, maxHeight: `${element.scrollHeight / 2}px` }, ], iterations: Infinity, + + reducedMotion: { + iterations: 1, + }, })); export const CreateMotionComponentFunctions = () => { diff --git a/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentImperativeRefPlayState.stories.tsx b/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentImperativeRefPlayState.stories.tsx index b06668fd66ac7c..d0e19a07e790c0 100644 --- a/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentImperativeRefPlayState.stories.tsx +++ b/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentImperativeRefPlayState.stories.tsx @@ -66,6 +66,10 @@ const FadeEnter = createMotionComponent({ keyframes: [{ opacity: 0 }, { opacity: 1 }], duration: motionTokens.durationSlow, iterations: Infinity, + + reducedMotion: { + iterations: 1, + }, }); export const CreateMotionComponentImperativeRefPlayState = () => { diff --git a/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentTokensUsage.stories.tsx b/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentTokensUsage.stories.tsx index 5ac6bed6773d91..07c8af66fe1462 100644 --- a/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentTokensUsage.stories.tsx +++ b/packages/react-components/react-motion/stories/src/CreateMotionComponent/CreateMotionComponentTokensUsage.stories.tsx @@ -45,6 +45,10 @@ const BackgroundChange = createMotionComponent({ ], duration: 3000, iterations: Infinity, + + reducedMotion: { + iterations: 1, + }, }); export const CreateMotionComponentTokensUsage = () => { diff --git a/packages/react-components/react-motion/stories/src/CreatePresenceComponent/CreatePresenceComponentReducedMotion.stories.md b/packages/react-components/react-motion/stories/src/CreatePresenceComponent/CreatePresenceComponentReducedMotion.stories.md new file mode 100644 index 00000000000000..34997dc8b2df94 --- /dev/null +++ b/packages/react-components/react-motion/stories/src/CreatePresenceComponent/CreatePresenceComponentReducedMotion.stories.md @@ -0,0 +1,24 @@ +By default, when [reduced motion](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion) is enabled the duration of the animation is set to `1ms`. `reducedMotion` allows to customize a reduced motion version of the animation: + +```ts +const Motion = createPresenceComponent({ + enter: { + keyframes: [ + { opacity: 0, transform: 'scale(0)' }, + { opacity: 1, transform: 'scale(1)' }, + ], + duration: 300, + + /* 💡reduced motion will not have scale animation */ + reducedMotion: { + keyframes: [{ opacity: 0 }, { opacity: 1 }], + duration: 1000, + }, + }, + exit: { + /* ... */ + }, +}); +``` + +> 💡Note, if `keyframes` are provided, they will be used instead of the regular keyframes. diff --git a/packages/react-components/react-motion/stories/src/CreatePresenceComponent/CreatePresenceComponentReducedMotion.stories.tsx b/packages/react-components/react-motion/stories/src/CreatePresenceComponent/CreatePresenceComponentReducedMotion.stories.tsx new file mode 100644 index 00000000000000..b480d9587821ba --- /dev/null +++ b/packages/react-components/react-motion/stories/src/CreatePresenceComponent/CreatePresenceComponentReducedMotion.stories.tsx @@ -0,0 +1,150 @@ +import { + createPresenceComponent, + Field, + makeStyles, + mergeClasses, + type MotionImperativeRef, + motionTokens, + Slider, + Switch, + tokens, +} from '@fluentui/react-components'; +import * as React from 'react'; + +import description from './CreatePresenceComponentReducedMotion.stories.md'; + +const useClasses = makeStyles({ + container: { + display: 'grid', + gridTemplate: `"card card" "controls ." / 1fr 1fr`, + gap: '20px 10px', + }, + card: { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'end', + gridArea: 'card', + + border: `${tokens.strokeWidthThicker} solid ${tokens.colorNeutralForeground3}`, + borderRadius: tokens.borderRadiusMedium, + boxShadow: tokens.shadow16, + padding: '10px', + }, + controls: { + display: 'flex', + flexDirection: 'column', + gridArea: 'controls', + + border: `${tokens.strokeWidthThicker} solid ${tokens.colorNeutralForeground3}`, + borderRadius: tokens.borderRadiusMedium, + boxShadow: tokens.shadow16, + padding: '10px', + }, + field: { + flex: 1, + }, + sliderField: { + gridTemplateColumns: 'min-content 1fr', + }, + sliderLabel: { + textWrap: 'nowrap', + }, + + item: { + backgroundColor: tokens.colorBrandBackground, + border: `${tokens.strokeWidthThicker} solid ${tokens.colorTransparentStroke}`, + + width: '100px', + height: '100px', + }, +}); + +const FadeAndScale = createPresenceComponent({ + enter: { + keyframes: [ + { opacity: 0, transform: 'rotate(0)' }, + { transform: 'rotate(90deg) scale(1.5)' }, + { opacity: 1, transform: 'rotate(0)' }, + ], + duration: motionTokens.durationGentle, + + reducedMotion: { + keyframes: [{ opacity: 0 }, { opacity: 1 }], + duration: motionTokens.durationUltraSlow, + }, + }, + exit: { + keyframes: [ + { opacity: 1, transform: 'rotate(0)' }, + { transform: 'rotate(-90deg) scale(1.5)' }, + { opacity: 0, transform: 'rotate(0)' }, + ], + duration: motionTokens.durationGentle, + + reducedMotion: { + keyframes: [{ opacity: 1 }, { opacity: 0 }], + duration: motionTokens.durationUltraSlow, + }, + }, +}); + +export const CreatePresenceComponentReducedMotion = () => { + const classes = useClasses(); + const motionRef = React.useRef(); + + const [playbackRate, setPlaybackRate] = React.useState(30); + const [visible, setVisible] = React.useState(true); + + // Heads up! + // This is optional and is intended solely to slow down the animations, making motions more visible in the examples. + React.useEffect(() => { + motionRef.current?.setPlaybackRate(playbackRate / 100); + }, [playbackRate, visible]); + + return ( +
+
+ +
+ +
+ +
+ + setVisible(v => !v)} /> + + + playbackRate: {playbackRate}% + + ), + className: classes.sliderLabel, + }} + orientation="horizontal" + > + setPlaybackRate(data.value)} + min={0} + max={100} + step={5} + /> + +
+
+ ); +}; + +CreatePresenceComponentReducedMotion.parameters = { + docs: { + description: { + story: description, + }, + }, +}; diff --git a/packages/react-components/react-motion/stories/src/CreatePresenceComponent/index.stories.ts b/packages/react-components/react-motion/stories/src/CreatePresenceComponent/index.stories.ts index 190d3b12fc3aec..71a7375a799b01 100644 --- a/packages/react-components/react-motion/stories/src/CreatePresenceComponent/index.stories.ts +++ b/packages/react-components/react-motion/stories/src/CreatePresenceComponent/index.stories.ts @@ -8,6 +8,7 @@ export { CreatePresenceComponentDefault as Default } from './CreatePresenceCompo export { CreatePresenceComponentFactory as createPresenceComponent } from './CreatePresenceComponentFactory.stories'; export { CreatePresenceComponentAppear as appear } from './CreatePresenceComponentAppear.stories'; +export { CreatePresenceComponentReducedMotion as reducedMotion } from './CreatePresenceComponentReducedMotion.stories'; export { CreatePresenceComponentUnmountOnExit as unmountOnExit } from './CreatePresenceComponentUnmountOnExit.stories'; export { CreatePresenceComponentLifecycleCallbacks as LifecycleCallbacks } from './CreatePresenceComponentLifecycleCallbacks.stories'; diff --git a/packages/react-components/react-popover/library/src/components/Popover/usePopover.ts b/packages/react-components/react-popover/library/src/components/Popover/usePopover.ts index 67e026e21b30c2..2ab6254edfee08 100644 --- a/packages/react-components/react-popover/library/src/components/Popover/usePopover.ts +++ b/packages/react-components/react-popover/library/src/components/Popover/usePopover.ts @@ -129,7 +129,7 @@ export const usePopover_unstable = (props: PopoverProps): PopoverState => { return { ...initialState, ...positioningRefs, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated inertTrapFocus: props.inertTrapFocus ?? (props.legacyTrapFocus === undefined ? false : !props.legacyTrapFocus), popoverTrigger, popoverSurface, diff --git a/packages/react-components/react-positioning/src/usePositioning.ts b/packages/react-components/react-positioning/src/usePositioning.ts index 8dd68e3434ecfa..28280848b1a078 100644 --- a/packages/react-components/react-positioning/src/usePositioning.ts +++ b/packages/react-components/react-positioning/src/usePositioning.ts @@ -173,7 +173,7 @@ function usePositioningOptions(options: PositioningOptions) { pinned, position, unstable_disableTether: disableTether, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated positionFixed, strategy, overflowBoundaryPadding, diff --git a/packages/react-components/react-provider/library/etc/react-provider.api.md b/packages/react-components/react-provider/library/etc/react-provider.api.md index e7e94b84cad4f2..de54394ef0a815 100644 --- a/packages/react-components/react-provider/library/etc/react-provider.api.md +++ b/packages/react-components/react-provider/library/etc/react-provider.api.md @@ -4,17 +4,17 @@ ```ts -import { ComponentProps } from '@fluentui/react-utilities'; +import type { ComponentProps } from '@fluentui/react-utilities'; import type { ComponentState } from '@fluentui/react-utilities'; import type { CustomStyleHooksContextValue_unstable } from '@fluentui/react-shared-contexts'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; import type { IconDirectionContextValue } from '@fluentui/react-icons/lib/providers'; -import { OverridesContextValue_unstable } from '@fluentui/react-shared-contexts'; +import type { OverridesContextValue_unstable } from '@fluentui/react-shared-contexts'; import type { PartialTheme } from '@fluentui/react-theme'; import type { ProviderContextValue_unstable } from '@fluentui/react-shared-contexts'; import * as React_2 from 'react'; import type { Slot } from '@fluentui/react-utilities'; import { SlotClassNames } from '@fluentui/react-utilities'; -import { Theme } from '@fluentui/tokens'; import type { ThemeClassNameContextValue_unstable } from '@fluentui/react-shared-contexts'; import type { ThemeContextValue_unstable } from '@fluentui/react-shared-contexts'; import type { TooltipVisibilityContextValue_unstable } from '@fluentui/react-shared-contexts'; @@ -23,160 +23,7 @@ import type { TooltipVisibilityContextValue_unstable } from '@fluentui/react-sha export function createCSSRuleFromTheme(selector: string, theme: PartialTheme | undefined): string; // @public (undocumented) -export const FluentProvider: React_2.ForwardRefExoticComponent, "dir"> & { - applyStylesToPortals?: boolean | undefined; - customStyleHooks_unstable?: Partial<{ - useAccordionHeaderStyles_unstable: (state: unknown) => void; - useAccordionItemStyles_unstable: (state: unknown) => void; - useAccordionPanelStyles_unstable: (state: unknown) => void; - useAccordionStyles_unstable: (state: unknown) => void; - useAvatarStyles_unstable: (state: unknown) => void; - useAvatarGroupStyles_unstable: (state: unknown) => void; - useAvatarGroupItemStyles_unstable: (state: unknown) => void; - useAvatarGroupPopoverStyles_unstable: (state: unknown) => void; - useBadgeStyles_unstable: (state: unknown) => void; - useCounterBadgeStyles_unstable: (state: unknown) => void; - useCardHeaderStyles_unstable: (state: unknown) => void; - useCardStyles_unstable: (state: unknown) => void; - useCardFooterStyles_unstable: (state: unknown) => void; - useCardPreviewStyles_unstable: (state: unknown) => void; - usePresenceBadgeStyles_unstable: (state: unknown) => void; - useButtonStyles_unstable: (state: unknown) => void; - useCompoundButtonStyles_unstable: (state: unknown) => void; - useMenuButtonStyles_unstable: (state: unknown) => void; - useSplitButtonStyles_unstable: (state: unknown) => void; - useToggleButtonStyles_unstable: (state: unknown) => void; - useCheckboxStyles_unstable: (state: unknown) => void; - useComboboxStyles_unstable: (state: unknown) => void; - useDropdownStyles_unstable: (state: unknown) => void; - useListboxStyles_unstable: (state: unknown) => void; - useListStyles_unstable: (state: unknown) => void; - useListItemStyles_unstable: (state: unknown) => void; - useListItemButtonStyles_unstable: (state: unknown) => void; - useOptionStyles_unstable: (state: unknown) => void; - useOptionGroupStyles_unstable: (state: unknown) => void; - useDividerStyles_unstable: (state: unknown) => void; - useInputStyles_unstable: (state: unknown) => void; - useImageStyles_unstable: (state: unknown) => void; - useLabelStyles_unstable: (state: unknown) => void; - useLinkStyles_unstable: (state: unknown) => void; - useMenuDividerStyles_unstable: (state: unknown) => void; - useMenuGroupHeaderStyles_unstable: (state: unknown) => void; - useMenuGroupStyles_unstable: (state: unknown) => void; - useMenuItemCheckboxStyles_unstable: (state: unknown) => void; - useMenuItemSwitchStyles_unstable: (state: unknown) => void; - useMenuItemRadioStyles_unstable: (state: unknown) => void; - useMenuItemStyles_unstable: (state: unknown) => void; - useMenuItemLinkStyles_unstable: (state: unknown) => void; - useMenuListStyles_unstable: (state: unknown) => void; - useMenuPopoverStyles_unstable: (state: unknown) => void; - useMenuSplitGroupStyles_unstable: (state: unknown) => void; - usePersonaStyles_unstable: (state: unknown) => void; - usePopoverSurfaceStyles_unstable: (state: unknown) => void; - useRadioGroupStyles_unstable: (state: unknown) => void; - useRadioStyles_unstable: (state: unknown) => void; - useSelectStyles_unstable: (state: unknown) => void; - useSliderStyles_unstable: (state: unknown) => void; - useSpinButtonStyles_unstable: (state: unknown) => void; - useSpinnerStyles_unstable: (state: unknown) => void; - useSwitchStyles_unstable: (state: unknown) => void; - useTabStyles_unstable: (state: unknown) => void; - useTabListStyles_unstable: (state: unknown) => void; - useTextStyles_unstable: (state: unknown) => void; - useTextareaStyles_unstable: (state: unknown) => void; - useTooltipStyles_unstable: (state: unknown) => void; - useDialogTitleStyles_unstable: (state: unknown) => void; - useDialogBodyStyles_unstable: (state: unknown) => void; - useDialogActionsStyles_unstable: (state: unknown) => void; - useDialogSurfaceStyles_unstable: (state: unknown) => void; - useDialogContentStyles_unstable: (state: unknown) => void; - useProgressBarStyles_unstable: (state: unknown) => void; - useToolbarButtonStyles_unstable: (state: unknown) => void; - useToolbarRadioButtonStyles_unstable: (state: unknown) => void; - useToolbarGroupStyles_unstable: (state: unknown) => void; - useToolbarToggleButtonStyles_unstable: (state: unknown) => void; - useToolbarDividerStyles_unstable: (state: unknown) => void; - useToolbarStyles_unstable: (state: unknown) => void; - useTableCellStyles_unstable: (state: unknown) => void; - useTableRowStyles_unstable: (state: unknown) => void; - useTableBodyStyles_unstable: (state: unknown) => void; - useTableStyles_unstable: (state: unknown) => void; - useTableHeaderStyles_unstable: (state: unknown) => void; - useTableHeaderCellStyles_unstable: (state: unknown) => void; - useTableResizeHandleStyles_unstable: (state: unknown) => void; - useTableSelectionCellStyles_unstable: (state: unknown) => void; - useTableCellActionsStyles_unstable: (state: unknown) => void; - useTableCellLayoutStyles_unstable: (state: unknown) => void; - useDataGridCellStyles_unstable: (state: unknown) => void; - useDataGridRowStyles_unstable: (state: unknown) => void; - useDataGridBodyStyles_unstable: (state: unknown) => void; - useDataGridStyles_unstable: (state: unknown) => void; - useDataGridHeaderStyles_unstable: (state: unknown) => void; - useDataGridHeaderCellStyles_unstable: (state: unknown) => void; - useDataGridSelectionCellStyles_unstable: (state: unknown) => void; - useDrawerStyles_unstable: (state: unknown) => void; - useDrawerInlineStyles_unstable: (state: unknown) => void; - useDrawerOverlayStyles_unstable: (state: unknown) => void; - useInlineDrawerStyles_unstable: (state: unknown) => void; - useOverlayDrawerStyles_unstable: (state: unknown) => void; - useDrawerHeaderStyles_unstable: (state: unknown) => void; - useDrawerHeaderNavigationStyles_unstable: (state: unknown) => void; - useDrawerHeaderTitleStyles_unstable: (state: unknown) => void; - useDrawerBodyStyles_unstable: (state: unknown) => void; - useDrawerFooterStyles_unstable: (state: unknown) => void; - useInteractionTagStyles_unstable: (state: unknown) => void; - useInteractionTagPrimaryStyles_unstable: (state: unknown) => void; - useInteractionTagSecondaryStyles_unstable: (state: unknown) => void; - useTagStyles_unstable: (state: unknown) => void; - useTagGroupStyles_unstable: (state: unknown) => void; - useBreadcrumbStyles_unstable: (state: unknown) => void; - useBreadcrumbButtonStyles_unstable: (state: unknown) => void; - useBreadcrumbItemStyles_unstable: (state: unknown) => void; - useBreadcrumbDividerStyles_unstable: (state: unknown) => void; - useMessageBarStyles_unstable: (state: unknown) => void; - useMessageBarBodyStyles_unstable: (state: unknown) => void; - useMessageBarTitleStyles_unstable: (state: unknown) => void; - useMessageBarActionsStyles_unstable: (state: unknown) => void; - useMessageBarGroupStyles_unstable: (state: unknown) => void; - useToasterStyles_unstable: (state: unknown) => void; - useTeachingPopoverStyles_unstable: (state: unknown) => void; - useTeachingPopoverActionsStyles_unstable: (state: unknown) => void; - useTeachingPopoverBodyStyles_unstable: (state: unknown) => void; - useTeachingPopoverButtonStyles_unstable: (state: unknown) => void; - useTeachingPopoverCarouselStyles_unstable: (state: unknown) => void; - useTeachingPopoverHeaderStyles_unstable: (state: unknown) => void; - useTeachingPopoverPageCountStyles_unstable: (state: unknown) => void; - useTeachingPopoverSurfaceStyles_unstable: (state: unknown) => void; - useTeachingPopoverTitleStyles_unstable: (state: unknown) => void; - useTimePickerCompatStyles_unstable: (state: unknown) => void; - useTagPickerInputStyles_unstable: (state: unknown) => void; - useTagPickerButtonStyles_unstable: (state: unknown) => void; - useTagPickerControlStyles_unstable: (state: unknown) => void; - useTagPickerGroupStyles_unstable: (state: unknown) => void; - useTagPickerListStyles_unstable: (state: unknown) => void; - useTagPickerOptionStyles_unstable: (state: unknown) => void; - useTagPickerOptionGroupStyles_unstable: (state: unknown) => void; - useColorSwatchStyles_unstable: (state: unknown) => void; - useImageSwatchStyles_unstable: (state: unknown) => void; - useEmptySwatchStyles_unstable: (state: unknown) => void; - useSwatchPickerRowStyles_unstable: (state: unknown) => void; - useSwatchPickerStyles_unstable: (state: unknown) => void; - useCarouselViewportStyles_unstable: (state: unknown) => void; - useCarouselSliderStyles_unstable: (state: unknown) => void; - useCarouselStyles_unstable: (state: unknown) => void; - useCarouselAutoplayButtonStyles_unstable: (state: unknown) => void; - useCarouselButtonStyles_unstable: (state: unknown) => void; - useCarouselCardStyles_unstable: (state: unknown) => void; - useCarouselNavStyles_unstable: (state: unknown) => void; - useCarouselNavButtonStyles_unstable: (state: unknown) => void; - useCarouselNavContainerStyles_unstable: (state: unknown) => void; - useCarouselNavImageButtonStyles_unstable: (state: unknown) => void; - }> | undefined; - dir?: "ltr" | "rtl" | undefined; - targetDocument?: Document | undefined; - theme?: Partial | undefined; - overrides_unstable?: OverridesContextValue_unstable | undefined; -} & React_2.RefAttributes>; +export const FluentProvider: ForwardRefComponent; // @public (undocumented) export const fluentProviderClassNames: SlotClassNames; diff --git a/packages/react-components/react-provider/library/src/components/FluentProvider/FluentProvider.tsx b/packages/react-components/react-provider/library/src/components/FluentProvider/FluentProvider.tsx index 6fbcb494a3c1a6..e732fb42d1ec59 100644 --- a/packages/react-components/react-provider/library/src/components/FluentProvider/FluentProvider.tsx +++ b/packages/react-components/react-provider/library/src/components/FluentProvider/FluentProvider.tsx @@ -1,11 +1,14 @@ import * as React from 'react'; + +import type { ForwardRefComponent } from '@fluentui/react-utilities'; + import { renderFluentProvider_unstable } from './renderFluentProvider'; import { useFluentProvider_unstable } from './useFluentProvider'; import { useFluentProviderStyles_unstable } from './useFluentProviderStyles.styles'; import { useFluentProviderContextValues_unstable } from './useFluentProviderContextValues'; import type { FluentProviderProps } from './FluentProvider.types'; -export const FluentProvider = React.forwardRef((props, ref) => { +export const FluentProvider: ForwardRefComponent = React.forwardRef((props, ref) => { const state = useFluentProvider_unstable(props, ref); useFluentProviderStyles_unstable(state); diff --git a/packages/react-components/react-provider/library/src/components/FluentProvider/useFluentProviderThemeStyleTag.test.tsx b/packages/react-components/react-provider/library/src/components/FluentProvider/useFluentProviderThemeStyleTag.test.tsx index 4f59835acae0a4..9ddac75eeec9df 100644 --- a/packages/react-components/react-provider/library/src/components/FluentProvider/useFluentProviderThemeStyleTag.test.tsx +++ b/packages/react-components/react-provider/library/src/components/FluentProvider/useFluentProviderThemeStyleTag.test.tsx @@ -111,7 +111,7 @@ describe('useFluentProviderThemeStyleTag', () => { expect(targetDocument.body.querySelector('style')).toBeNull(); expect(targetDocument.head.querySelectorAll('style').length).toBe(1); - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated expect(targetDocument.createElement).toHaveBeenCalledTimes(0); }); }); diff --git a/packages/react-components/react-radio/library/src/contexts/index.ts b/packages/react-components/react-radio/library/src/contexts/index.ts index 54f7374332d554..8616aab3210787 100644 --- a/packages/react-components/react-radio/library/src/contexts/index.ts +++ b/packages/react-components/react-radio/library/src/contexts/index.ts @@ -2,7 +2,7 @@ export { RadioGroupContext, RadioGroupProvider, useRadioGroupContextValue_unstable, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated useRadioGroupContext_unstable, } from './RadioGroupContext'; export { useRadioGroupContextValues } from './useRadioGroupContextValues'; diff --git a/packages/react-components/react-radio/library/src/index.ts b/packages/react-components/react-radio/library/src/index.ts index ffddc5faeeb928..68d15286c7fd13 100644 --- a/packages/react-components/react-radio/library/src/index.ts +++ b/packages/react-components/react-radio/library/src/index.ts @@ -18,6 +18,6 @@ export type { RadioProps, RadioSlots, RadioState, RadioOnChangeData } from './Ra export { RadioGroupProvider, useRadioGroupContextValues, - useRadioGroupContext_unstable, // eslint-disable-line deprecation/deprecation + useRadioGroupContext_unstable, // eslint-disable-line @typescript-eslint/no-deprecated useRadioGroupContextValue_unstable, } from './contexts/index'; diff --git a/packages/react-components/react-spinbutton/library/src/components/SpinButton/SpinButton.test.tsx b/packages/react-components/react-spinbutton/library/src/components/SpinButton/SpinButton.test.tsx index 0f166d403f3bc6..bb2b4e0ae9a0f3 100644 --- a/packages/react-components/react-spinbutton/library/src/components/SpinButton/SpinButton.test.tsx +++ b/packages/react-components/react-spinbutton/library/src/components/SpinButton/SpinButton.test.tsx @@ -554,7 +554,7 @@ describe('SpinButton', () => { userEvent.click(decrementButton); expect(onChange).toHaveBeenCalledTimes(2); - expect(onChange.mock.calls[1][1]).toEqual({ value: -1, displayValue: undefined }); + expect(onChange.mock.calls[1][1]).toEqual({ value: 0, displayValue: undefined }); }); it('calls on change when defaultValue is `null` with min when uncontrolled', () => { diff --git a/packages/react-components/react-spinbutton/library/src/components/SpinButton/useSpinButton.tsx b/packages/react-components/react-spinbutton/library/src/components/SpinButton/useSpinButton.tsx index 329c72a131958f..d88da840cfe847 100644 --- a/packages/react-components/react-spinbutton/library/src/components/SpinButton/useSpinButton.tsx +++ b/packages/react-components/react-spinbutton/library/src/components/SpinButton/useSpinButton.tsx @@ -154,11 +154,13 @@ export const useSpinButton_unstable = (props: SpinButtonProps, ref: React.Ref) => { + commit(e, currentValue, textValue); internalState.current.spinState = 'up'; stepValue(e, 'up'); }; const handleDecrementMouseDown = (e: React.MouseEvent) => { + commit(e, currentValue, textValue); internalState.current.spinState = 'down'; stepValue(e, 'down'); }; @@ -231,10 +233,12 @@ export const useSpinButton_unstable = (props: SpinButtonProps, ref: React.Ref { addons.add(THEME_ID, { title: 'Fluent Theme Picker', - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated type: types.TOOL, match: ({ viewMode }) => !!(viewMode && viewMode.match(/^(story|docs)$/)), render: ThemePicker, }); addons.add(DIR_ID, { title: 'Direction Switch', - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated type: types.TOOL, match: ({ viewMode }) => !!(viewMode && viewMode.match(/^(story|docs)$/)), render: DirectionSwitch, }); addons.add(STRICT_MODE_ID, { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated type: types.TOOL, title: 'React Strict Mode', match: ({ viewMode }) => !!(viewMode && viewMode.match(/^(story|docs)$/)), diff --git a/packages/react-components/react-switch/library/src/Switch.ts b/packages/react-components/react-switch/library/src/Switch.ts index 4ca85158f1edd1..bbdd746cfad93b 100644 --- a/packages/react-components/react-switch/library/src/Switch.ts +++ b/packages/react-components/react-switch/library/src/Switch.ts @@ -2,7 +2,7 @@ export type { SwitchOnChangeData, SwitchProps, SwitchSlots, SwitchState } from ' export { Switch, renderSwitch_unstable, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated switchClassName, switchClassNames, useSwitchStyles_unstable, diff --git a/packages/react-components/react-switch/library/src/components/Switch/index.ts b/packages/react-components/react-switch/library/src/components/Switch/index.ts index d94c2b603d131e..4853a54d26424c 100644 --- a/packages/react-components/react-switch/library/src/components/Switch/index.ts +++ b/packages/react-components/react-switch/library/src/components/Switch/index.ts @@ -3,7 +3,7 @@ export type { SwitchOnChangeData, SwitchProps, SwitchSlots, SwitchState } from ' export { renderSwitch_unstable } from './renderSwitch'; export { useSwitch_unstable } from './useSwitch'; export { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated switchClassName, switchClassNames, useSwitchStyles_unstable, diff --git a/packages/react-components/react-switch/library/src/index.ts b/packages/react-components/react-switch/library/src/index.ts index 6ca6e3524f037b..b2ae66ee66258d 100644 --- a/packages/react-components/react-switch/library/src/index.ts +++ b/packages/react-components/react-switch/library/src/index.ts @@ -1,7 +1,7 @@ export { Switch, renderSwitch_unstable, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated switchClassName, switchClassNames, useSwitchStyles_unstable, diff --git a/packages/react-components/react-table/library/src/components/DataGridHeaderCell/useDataGridHeaderCell.ts b/packages/react-components/react-table/library/src/components/DataGridHeaderCell/useDataGridHeaderCell.ts index ab2fc0cebe2416..285f4cf3532033 100644 --- a/packages/react-components/react-table/library/src/components/DataGridHeaderCell/useDataGridHeaderCell.ts +++ b/packages/react-components/react-table/library/src/components/DataGridHeaderCell/useDataGridHeaderCell.ts @@ -42,7 +42,7 @@ export const useDataGridHeaderCell_unstable = ( return ctx.columnSizing_unstable.getTableHeaderCellProps; }); - // eslint-disable-next-line deprecation/deprecation -- prefer HTMLTableCellElement + // eslint-disable-next-line @typescript-eslint/no-deprecated -- prefer HTMLTableCellElement const onClick = useEventCallback((e: React.MouseEvent) => { if (sortable) { toggleColumnSort(e, columnId); diff --git a/packages/react-components/react-table/library/src/components/TableSelectionCell/useTableSelectionCell.tsx b/packages/react-components/react-table/library/src/components/TableSelectionCell/useTableSelectionCell.tsx index d76634b1cb03d7..3770b04f5b33f3 100644 --- a/packages/react-components/react-table/library/src/components/TableSelectionCell/useTableSelectionCell.tsx +++ b/packages/react-components/react-table/library/src/components/TableSelectionCell/useTableSelectionCell.tsx @@ -26,7 +26,7 @@ export const useTableSelectionCell_unstable = ( type = 'checkbox', checked = false, subtle = false, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated hidden = false, invisible = false, } = props; diff --git a/packages/react-components/react-tabs/library/src/components/Tab/useTabStyles.styles.ts b/packages/react-components/react-tabs/library/src/components/Tab/useTabStyles.styles.ts index c6d3116d6c22cf..7c04731829d2c7 100644 --- a/packages/react-components/react-tabs/library/src/components/Tab/useTabStyles.styles.ts +++ b/packages/react-components/react-tabs/library/src/components/Tab/useTabStyles.styles.ts @@ -717,7 +717,7 @@ export const useTabContentStyles_unstable = (state: TabState): TabState => { ); // FIXME: this is a deprecated API // should be removed in the next major version - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated state.contentReservedSpaceClassName = state.contentReservedSpace.className; } diff --git a/packages/react-components/react-tabster/src/index.ts b/packages/react-components/react-tabster/src/index.ts index 879248bc4af1e6..2b5585db39a3de 100644 --- a/packages/react-components/react-tabster/src/index.ts +++ b/packages/react-components/react-tabster/src/index.ts @@ -64,10 +64,10 @@ export { /** @deprecated (Do not use! Exposed by mistake and will be removed in the next major version.) */ TabsterTypes6_0_1_DoNotUse as TabsterTypes, /** @deprecated Use element.dispatchEvent(new GroupperMoveFocusEvent({ action: GroupperMoveFocusActions.Escape })) */ - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated dispatchGroupperMoveFocusEvent, /** @deprecated Use element.dispatchEvent(new MoverMoveFocusEvent({ key: MoverKeys.ArrowDown })) */ - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated dispatchMoverMoveFocusEvent, }; diff --git a/packages/react-components/react-tag-picker/library/etc/react-tag-picker.api.md b/packages/react-components/react-tag-picker/library/etc/react-tag-picker.api.md index ad2eb52a97aab4..f24b3971d088c4 100644 --- a/packages/react-components/react-tag-picker/library/etc/react-tag-picker.api.md +++ b/packages/react-components/react-tag-picker/library/etc/react-tag-picker.api.md @@ -13,6 +13,7 @@ import { ComboboxSlots } from '@fluentui/react-combobox'; import type { ComboboxState } from '@fluentui/react-combobox'; import { ComponentProps } from '@fluentui/react-utilities'; import { ComponentState } from '@fluentui/react-utilities'; +import { ContextSelector } from '@fluentui/react-context-selector'; import { DropdownProps } from '@fluentui/react-combobox'; import type { EventData } from '@fluentui/react-utilities'; import type { EventHandler } from '@fluentui/react-utilities'; @@ -80,6 +81,26 @@ export type TagPickerButtonState = ComponentState & Pick { + // (undocumented) + noPopover?: boolean; + // (undocumented) + popoverId: string; + // (undocumented) + popoverRef: React_2.RefObject; + // (undocumented) + secondaryActionRef: React_2.RefObject; + // (undocumented) + size: TagPickerSize; + // (undocumented) + tagPickerGroupRef: React_2.RefObject; + // (undocumented) + targetRef: React_2.RefObject; + // (undocumented) + triggerRef: React_2.RefObject; +} + // @public (undocumented) export type TagPickerContextValues = { picker: TagPickerContextValue; @@ -246,6 +267,9 @@ export const useTagPickerButton_unstable: (props: TagPickerButtonProps, ref: Rea // @public export const useTagPickerButtonStyles_unstable: (state: TagPickerButtonState) => TagPickerButtonState; +// @public (undocumented) +export const useTagPickerContext_unstable: (selector: ContextSelector) => T; + // @public export const useTagPickerControl_unstable: (props: TagPickerControlProps, ref: React_2.Ref) => TagPickerControlState; diff --git a/packages/react-components/react-tag-picker/library/src/components/TagPickerControl/useTagPickerControlStyles.styles.ts b/packages/react-components/react-tag-picker/library/src/components/TagPickerControl/useTagPickerControlStyles.styles.ts index 980821d8ced7a5..dcd96c40b5556d 100644 --- a/packages/react-components/react-tag-picker/library/src/components/TagPickerControl/useTagPickerControlStyles.styles.ts +++ b/packages/react-components/react-tag-picker/library/src/components/TagPickerControl/useTagPickerControlStyles.styles.ts @@ -154,13 +154,10 @@ const useStyles = makeStyles({ const useAsideStyles = makeStyles({ root: { - display: 'grid', - alignItems: 'center', + display: 'flex', position: 'absolute', top: '0', right: tokens.spacingHorizontalM, - gridTemplateColumns: 'repeat(2, auto)', - gridTemplateRows: 'minmax(32px, auto) 1fr', height: '100%', cursor: 'text', }, @@ -187,7 +184,10 @@ const useIconStyles = makeStyles({ boxSizing: 'border-box', color: tokens.colorNeutralStrokeAccessible, cursor: 'pointer', - display: 'block', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + alignSelf: 'flex-start', fontSize: tokens.fontSizeBase500, // the SVG must have display: block for accurate positioning // otherwise an extra inline space is inserted after the svg element @@ -199,14 +199,17 @@ const useIconStyles = makeStyles({ medium: { fontSize: iconSizes.small, marginLeft: tokens.spacingHorizontalXXS, + minHeight: '32px', }, large: { fontSize: iconSizes.medium, marginLeft: tokens.spacingHorizontalXXS, + minHeight: '40px', }, 'extra-large': { fontSize: iconSizes.large, marginLeft: tokens.spacingHorizontalSNudge, + minHeight: '44px', }, disabled: { color: tokens.colorNeutralForegroundDisabled, @@ -214,6 +217,10 @@ const useIconStyles = makeStyles({ }, }); +const useSecondaryActionStyles = makeStyles({ + root: { display: 'flex' }, +}); + /** * Apply styling to the PickerControl slots based on the state */ @@ -223,6 +230,7 @@ export const useTagPickerControlStyles_unstable = (state: TagPickerControlState) const styles = useStyles(); const iconStyles = useIconStyles(); const asideStyles = useAsideStyles(); + const secondaryActionStyles = useSecondaryActionStyles(); state.root.className = mergeClasses( tagPickerControlClassNames.root, styles.root, @@ -257,6 +265,7 @@ export const useTagPickerControlStyles_unstable = (state: TagPickerControlState) if (state.secondaryAction) { state.secondaryAction.className = mergeClasses( tagPickerControlClassNames.secondaryAction, + secondaryActionStyles.root, state.secondaryAction.className, ); } diff --git a/packages/react-components/react-tag-picker/library/src/components/TagPickerOption/__snapshots__/TagPickerOption.test.tsx.snap b/packages/react-components/react-tag-picker/library/src/components/TagPickerOption/__snapshots__/TagPickerOption.test.tsx.snap index 907a79f7e94918..2b7ec9972e024e 100644 --- a/packages/react-components/react-tag-picker/library/src/components/TagPickerOption/__snapshots__/TagPickerOption.test.tsx.snap +++ b/packages/react-components/react-tag-picker/library/src/components/TagPickerOption/__snapshots__/TagPickerOption.test.tsx.snap @@ -4,7 +4,7 @@ exports[`TagPickerOption renders a default state 1`] = `
diff --git a/packages/react-components/react-tag-picker/library/src/components/TagPickerOption/useTagPickerOptionStyles.styles.ts b/packages/react-components/react-tag-picker/library/src/components/TagPickerOption/useTagPickerOptionStyles.styles.ts index d9ae8758f70399..c8b27a0f42eb16 100644 --- a/packages/react-components/react-tag-picker/library/src/components/TagPickerOption/useTagPickerOptionStyles.styles.ts +++ b/packages/react-components/react-tag-picker/library/src/components/TagPickerOption/useTagPickerOptionStyles.styles.ts @@ -2,6 +2,7 @@ import { makeStyles, mergeClasses } from '@griffel/react'; import type { SlotClassNames } from '@fluentui/react-utilities'; import type { TagPickerOptionSlots, TagPickerOptionState } from './TagPickerOption.types'; import { useOptionStyles_unstable } from '@fluentui/react-combobox'; +import { typographyStyles } from '@fluentui/react-theme'; export const tagPickerOptionClassNames: SlotClassNames = { root: 'fui-TagPickerOption', @@ -22,6 +23,7 @@ const useStyles = makeStyles({ secondaryContent: { gridColumnStart: 2, gridRowStart: 2, + ...typographyStyles.caption1, }, media: { @@ -35,6 +37,9 @@ const useStyles = makeStyles({ export const useTagPickerOptionStyles_unstable = (state: TagPickerOptionState): TagPickerOptionState => { 'use no memo'; + const styles = useStyles(); + + state.root.className = mergeClasses(tagPickerOptionClassNames.root, styles.root, state.root.className); useOptionStyles_unstable({ ...state, active: false, @@ -43,9 +48,6 @@ export const useTagPickerOptionStyles_unstable = (state: TagPickerOptionState): checkIcon: undefined, selected: false, }); - const styles = useStyles(); - - state.root.className = mergeClasses(tagPickerOptionClassNames.root, styles.root, state.root.className); if (state.media) { state.media.className = mergeClasses(tagPickerOptionClassNames.media, styles.media, state.media.className); } diff --git a/packages/react-components/react-tag-picker/library/src/index.ts b/packages/react-components/react-tag-picker/library/src/index.ts index 77af524786d038..68e8e6f000f3a5 100644 --- a/packages/react-components/react-tag-picker/library/src/index.ts +++ b/packages/react-components/react-tag-picker/library/src/index.ts @@ -71,3 +71,6 @@ export type { } from './TagPickerOptionGroup'; export { useTagPickerFilter } from './utils/useTagPickerFilter'; + +export { useTagPickerContext_unstable } from './contexts/TagPickerContext'; +export type { TagPickerContextValue } from './contexts/TagPickerContext'; diff --git a/packages/react-components/react-tag-picker/stories/src/TagPicker/TagPickerSingleLine.stories.tsx b/packages/react-components/react-tag-picker/stories/src/TagPicker/TagPickerSingleLine.stories.tsx new file mode 100644 index 00000000000000..78d105c0a449e6 --- /dev/null +++ b/packages/react-components/react-tag-picker/stories/src/TagPicker/TagPickerSingleLine.stories.tsx @@ -0,0 +1,199 @@ +import * as React from 'react'; +import { + TagPicker, + TagPickerList, + TagPickerInput, + TagPickerControl, + TagPickerProps, + TagPickerOption, + TagPickerGroup, + makeStyles, + tagPickerGroupClassNames, + useOverflowCount, + TagPickerInputProps, + useTagPickerContext_unstable, + TagProps, + Tag, + Avatar, + Overflow, + OverflowItem, +} from '@fluentui/react-components'; +import { ChevronDownRegular, ChevronUpRegular } from '@fluentui/react-icons'; + +const useStyles = makeStyles({ + focusedExpandIcon: { alignSelf: 'flex-end' }, + countButton: { minWidth: 0 }, + control: { + flexWrap: 'nowrap', + display: 'flex', + flexGrow: 1, + minWidth: 0, + overflow: 'hidden', + [`& > .${tagPickerGroupClassNames.root}`]: { + flexWrap: 'nowrap', + }, + ':focus-within': { + flexWrap: 'wrap', + [`& > .${tagPickerGroupClassNames.root}`]: { + flexWrap: 'wrap', + }, + }, + }, +}); + +const options = [ + 'John Doe', + 'Jane Doe', + 'Max Mustermann', + 'Erika Mustermann', + 'Pierre Dupont', + 'Amelie Dupont', + 'Mario Rossi', + 'Maria Rossi', +]; + +type ExpandIconProps = { open: boolean; focus: boolean }; + +const ExpandIcon = (props: ExpandIconProps) => { + const overflowCount = useOverflowCount(); + + if (props.open) { + return ; + } + if (overflowCount === 0 || props.focus) { + return ; + } + return null; +}; + +const OverFlowCountTag = (props: TagProps) => { + const overflowCount = useOverflowCount(); + const styles = useStyles(); + if (overflowCount === 0) { + return null; + } + return ( + + +{overflowCount} + + ); +}; + +type CustomTagPickerInputProps = TagPickerInputProps & { focus: boolean }; + +const CustomTagPickerInput = React.forwardRef( + ({ focus, onMouseDown, placeholder, ...rest }, ref) => { + const overflowCount = useOverflowCount(); + const selectedOptionsAmount = useTagPickerContext_unstable(ctx => ctx.selectedOptions.length); + return ( + 0 && focus) ? placeholder : undefined} + /> + ); + }, +); + +export const SingleLine = () => { + const styles = useStyles(); + const [open, setOpen] = React.useState(false); + const [selectedOptions, setSelectedOptions] = React.useState([]); + const inputRef = React.useRef(null); + const onOptionSelect: TagPickerProps['onOptionSelect'] = (e, data) => { + setSelectedOptions(data.selectedOptions); + }; + const tagPickerOptions = options.filter(option => !selectedOptions.includes(option)); + + const [hasFocus, setFocus] = React.useState(false); + + const handleOpenChange: TagPickerProps['onOpenChange'] = (_, data) => setOpen(data.open); + + const handleFocus = () => { + setFocus(true); + }; + + const handleBlur = (event: React.FocusEvent) => { + if (event.currentTarget.contains(event.relatedTarget as Node)) { + return; + } + setFocus(false); + }; + + const handleOverflowCountTagMouseDown = (event: React.MouseEvent) => { + event.preventDefault(); + inputRef.current?.focus(); + }; + + return ( + + {/* 24 = min input size */} + {/* 30 = padding right */} + {/* 2 = gap between input and tags */} + {/* 4 = gap between tags */} + + , + }} + onFocus={handleFocus} + onBlur={handleBlur} + className={styles.control} + > + + {selectedOptions.map(option => ( + + } + value={option} + > + {option} + + + ))} + {!open && !hasFocus ? : null} + + + + + + {tagPickerOptions.length > 0 + ? tagPickerOptions.map(option => ( + } + value={option} + key={option} + > + {option} + + )) + : 'No options available'} + + + ); +}; diff --git a/packages/react-components/react-tag-picker/stories/src/TagPicker/index.stories.tsx b/packages/react-components/react-tag-picker/stories/src/TagPicker/index.stories.tsx index 97b263c6324bee..32a0f841262503 100644 --- a/packages/react-components/react-tag-picker/stories/src/TagPicker/index.stories.tsx +++ b/packages/react-components/react-tag-picker/stories/src/TagPicker/index.stories.tsx @@ -24,6 +24,7 @@ export { Grouped } from './TagPickerGrouped.stories'; export { TruncatedText } from './TagPickerTruncatedText.stories'; export { SingleSelect } from './TagPickerSingleSelect.stories'; export { NoPopover } from './TagPickerNoPopover.stories'; +export { SingleLine } from './TagPickerSingleLine.stories'; export default { title: 'Components/TagPicker', diff --git a/packages/react-components/react-toolbar/stories/src/Toolbar/ToolbarSmall.stories.tsx b/packages/react-components/react-toolbar/stories/src/Toolbar/ToolbarSmall.stories.tsx index ee487910535182..f3ba53c429c6fc 100644 --- a/packages/react-components/react-toolbar/stories/src/Toolbar/ToolbarSmall.stories.tsx +++ b/packages/react-components/react-toolbar/stories/src/Toolbar/ToolbarSmall.stories.tsx @@ -24,7 +24,7 @@ Small.parameters = { description: { story: [ 'The size determines the spacing around the toolbar controls.', - 'A small sized toolbar has no vertical padding and uses 20px for horizontal padding.', + 'A small sized toolbar has no vertical padding and uses 4px for horizontal padding.', ].join('\n'), }, }, diff --git a/packages/react-components/react-tooltip/library/src/components/Tooltip/useTooltip.tsx b/packages/react-components/react-tooltip/library/src/components/Tooltip/useTooltip.tsx index 8d5382f23353f9..443acabe6049c8 100644 --- a/packages/react-components/react-tooltip/library/src/components/Tooltip/useTooltip.tsx +++ b/packages/react-components/react-tooltip/library/src/components/Tooltip/useTooltip.tsx @@ -177,7 +177,7 @@ export const useTooltip_unstable = (props: TooltipProps): TooltipState => { [setDelayTimeout, setVisible, state.showDelay, context], ); - const isNavigatingWithKeyboard = useIsNavigatingWithKeyboard()(); + const isNavigatingWithKeyboard = useIsNavigatingWithKeyboard(); // Callback ref that attaches a keyborg:focusin event listener. const [keyborgListenerCallbackRef] = React.useState(() => { @@ -186,7 +186,7 @@ export const useTooltip_unstable = (props: TooltipProps): TooltipState => { // For example, we don't want to show the tooltip when a dialog is closed // and Tabster programmatically restores focus to the trigger button. // See https://github.com/microsoft/fluentui/issues/27576 - if (ev.detail?.isFocusedProgrammatically && !isNavigatingWithKeyboard) { + if (ev.detail?.isFocusedProgrammatically && !isNavigatingWithKeyboard()) { ignoreNextFocusEventRef.current = true; } }) as EventListener; diff --git a/packages/react-components/react-tree/library/etc/react-tree.api.md b/packages/react-components/react-tree/library/etc/react-tree.api.md index 1fbeac4b6638b2..210a53b0625064 100644 --- a/packages/react-components/react-tree/library/etc/react-tree.api.md +++ b/packages/react-components/react-tree/library/etc/react-tree.api.md @@ -62,6 +62,7 @@ export type FlatTreeItemProps = TreeItemProps & { // @public (undocumented) export type FlatTreeProps = ComponentProps & { + navigationMode?: 'tree' | 'treegrid'; appearance?: 'subtle' | 'subtle-alpha' | 'transparent'; size?: 'small' | 'medium'; openItems?: Iterable; @@ -160,6 +161,7 @@ export type TreeContextValue = { checkedItems: ImmutableMap; requestTreeResponse(request: TreeItemRequest): void; forceUpdateRovingTabIndex?(): void; + navigationMode?: 'tree' | 'treegrid'; }; // @public (undocumented) @@ -331,6 +333,9 @@ export type TreeNavigationData_unstable = { // @public (undocumented) export type TreeNavigationEvent_unstable = TreeNavigationData_unstable['event']; +// @public (undocumented) +export type TreeNavigationMode = 'tree' | 'treegrid'; + // @public (undocumented) export type TreeOpenChangeData = { open: boolean; @@ -366,6 +371,7 @@ export type TreeOpenChangeEvent = TreeOpenChangeData['event']; // @public (undocumented) export type TreeProps = ComponentProps & { + navigationMode?: TreeNavigationMode; appearance?: 'subtle' | 'subtle-alpha' | 'transparent'; size?: 'small' | 'medium'; openItems?: Iterable; @@ -383,6 +389,9 @@ export const TreeProvider: { displayName: string; }; +// @public (undocumented) +export const TreeRootReset: (props: TreeRootResetProps) => JSX.Element; + // @public (undocumented) export type TreeSelectionValue = MultiSelectValue | SingleSelectValue; diff --git a/packages/react-components/react-tree/library/src/Tree.ts b/packages/react-components/react-tree/library/src/Tree.ts index f6591a88e83ac3..a4bd46d2b4b4a8 100644 --- a/packages/react-components/react-tree/library/src/Tree.ts +++ b/packages/react-components/react-tree/library/src/Tree.ts @@ -10,6 +10,7 @@ export type { TreeSelectionValue, TreeSlots, TreeState, + TreeNavigationMode, } from './components/Tree/index'; export { Tree, diff --git a/packages/react-components/react-tree/library/src/components/FlatTree/FlatTree.cy.tsx b/packages/react-components/react-tree/library/src/components/FlatTree/FlatTree.cy.tsx index 820f0ff2e38779..50d5822afc05f8 100644 --- a/packages/react-components/react-tree/library/src/components/FlatTree/FlatTree.cy.tsx +++ b/packages/react-components/react-tree/library/src/components/FlatTree/FlatTree.cy.tsx @@ -207,6 +207,25 @@ describe('FlatTree', () => { cy.document().realPress('Tab'); cy.get('#action').should('be.focused'); }); + describe('navigationMode="treegrid"', () => { + it('should focus on actions/treeitem when pressing right/left arrow', () => { + mount( + + + action}>level 1, item 1 + + + level 2, item 1 + + + + , + ); + cy.get('[data-testid="item1"]').focus().realPress('{rightarrow}'); + cy.get('#action').should('be.focused').realPress('{leftarrow}'); + cy.get('[data-testid="item1"]').should('be.focused'); + }); + }); it('should not expand/collapse item on actions Enter/Space key', () => { mount( @@ -250,25 +269,50 @@ describe('FlatTree', () => { cy.get('[data-testid="item2"]').should('be.focused'); cy.focused().realPress('Tab').should('not.exist'); }); - it('should move with Left/Right keys', () => { - mount(); - cy.get('[data-testid="item1"]').focus().realPress('{downarrow}'); - cy.get('[data-testid="item2"]').should('be.focused').realPress('{rightarrow}'); - cy.get('[data-testid="item2__item1"]').should('be.focused').realPress('{rightarrow}'); - cy.get('[data-testid="item2__item1__item1"]').should('be.focused').realPress('{leftarrow}'); - cy.get('[data-testid="item2__item1"]').should('be.focused').realPress('{leftarrow}').realPress('{leftarrow}'); - cy.get('[data-testid="item2"]').should('be.focused'); - }); - it('should not move with Alt + Left/Right keys', () => { - mount(); - cy.get('[data-testid="item1"]').focus().realPress('{downarrow}'); - cy.get('[data-testid="item2"]').should('be.focused').realPress(['Alt', '{rightarrow}']); - cy.get('[data-testid="item2"]').should('be.focused').realPress('{rightarrow}'); - cy.get('[data-testid="item2__item1"]').should('be.focused').realPress('{rightarrow}'); - cy.get('[data-testid="item2__item1__item1"]').should('be.focused').realPress(['Alt', '{leftarrow}']); - cy.get('[data-testid="item2__item1__item1"]').should('be.focused').realPress('{leftarrow}'); - cy.get('[data-testid="item2__item1"]').should('be.focused').realPress('{leftarrow}').realPress('{leftarrow}'); - cy.get('[data-testid="item2"]').should('be.focused'); + describe('navigationMode="treegrid"', () => { + it('should move with Up/Down keys', () => { + mount( + + + level 1, item 1 + + + action}>level 2, item 1 + + + level 2, item 2 + + + + , + ); + cy.get('[data-testid="item1__item1"]').focus().realPress('{rightarrow}'); + cy.get('#action').should('be.focused').realPress('{uparrow}'); + cy.get('[data-testid="item1"]').should('be.focused'); + cy.get('[data-testid="item1__item1"]').focus().realPress('{rightarrow}'); + cy.get('#action').should('be.focused').realPress('{downarrow}'); + cy.get('[data-testid="item1__item2"]').should('be.focused'); + }); + it('should move with Left keys', () => { + mount(); + cy.get('[data-testid="item1"]').focus().realPress('{downarrow}'); + cy.get('[data-testid="item2"]').should('be.focused').realPress('{downarrow}'); + cy.get('[data-testid="item2__item1"]').should('be.focused').realPress('{downarrow}'); + cy.get('[data-testid="item2__item1__item1"]').should('be.focused').realPress('{leftarrow}'); + cy.get('[data-testid="item2__item1"]').should('be.focused').realPress('{leftarrow}').realPress('{leftarrow}'); + cy.get('[data-testid="item2"]').should('be.focused'); + }); + + it('should not move with Alt + Left keys', () => { + mount(); + cy.get('[data-testid="item1"]').focus().realPress('{downarrow}'); + cy.get('[data-testid="item2"]').should('be.focused').realPress('{downarrow}'); + cy.get('[data-testid="item2__item1"]').should('be.focused').realPress('{downarrow}'); + cy.get('[data-testid="item2__item1__item1"]').should('be.focused').realPress(['Alt', '{leftarrow}']); + cy.get('[data-testid="item2__item1__item1"]').should('be.focused').realPress('{leftarrow}'); + cy.get('[data-testid="item2__item1"]').should('be.focused').realPress('{leftarrow}').realPress('{leftarrow}'); + cy.get('[data-testid="item2"]').should('be.focused'); + }); }); it('should move to last item with End key', () => { mount(); diff --git a/packages/react-components/react-tree/library/src/components/FlatTree/FlatTree.types.ts b/packages/react-components/react-tree/library/src/components/FlatTree/FlatTree.types.ts index 56e8b8a0312181..51ca908f5c16a4 100644 --- a/packages/react-components/react-tree/library/src/components/FlatTree/FlatTree.types.ts +++ b/packages/react-components/react-tree/library/src/components/FlatTree/FlatTree.types.ts @@ -19,6 +19,13 @@ export type FlatTreeContextValues = { }; export type FlatTreeProps = ComponentProps & { + /** + * Indicates how navigation between a treeitem and its actions work + * - 'tree' (default): The default navigation, pressing right arrow key navigates inward the first inner children of a branch treeitem + * - 'treegrid': Pressing right arrow key navigate towards the actions of a treeitem + * @default 'tree' + */ + navigationMode?: 'tree' | 'treegrid'; /** * A tree item can have various appearances: * - 'subtle' (default): The default tree item styles. diff --git a/packages/react-components/react-tree/library/src/components/FlatTree/useFlatTree.ts b/packages/react-components/react-tree/library/src/components/FlatTree/useFlatTree.ts index 12d019abab8748..5e7610a3193a3c 100644 --- a/packages/react-components/react-tree/library/src/components/FlatTree/useFlatTree.ts +++ b/packages/react-components/react-tree/library/src/components/FlatTree/useFlatTree.ts @@ -22,7 +22,7 @@ export const useFlatTree_unstable: (props: FlatTreeProps, ref: React.Ref): FlatTreeState { - const navigation = useFlatTreeNavigation(); + const navigation = useFlatTreeNavigation(props.navigationMode); return Object.assign( useRootTree( diff --git a/packages/react-components/react-tree/library/src/components/FlatTree/useFlatTreeContextValues.ts b/packages/react-components/react-tree/library/src/components/FlatTree/useFlatTreeContextValues.ts index a06d65e2ec568d..9c30a476081ed7 100644 --- a/packages/react-components/react-tree/library/src/components/FlatTree/useFlatTreeContextValues.ts +++ b/packages/react-components/react-tree/library/src/components/FlatTree/useFlatTreeContextValues.ts @@ -9,6 +9,7 @@ export const useFlatTreeContextValues_unstable = (state: FlatTreeState): FlatTre treeType, checkedItems, selectionMode, + navigationMode, appearance, size, requestTreeResponse, @@ -25,6 +26,7 @@ export const useFlatTreeContextValues_unstable = (state: FlatTreeState): FlatTre appearance, checkedItems, selectionMode, + navigationMode, contextType, level, requestTreeResponse, diff --git a/packages/react-components/react-tree/library/src/components/Tree/Tree.cy.tsx b/packages/react-components/react-tree/library/src/components/Tree/Tree.cy.tsx index 0413eafba5eb90..87ae49eedd53dd 100644 --- a/packages/react-components/react-tree/library/src/components/Tree/Tree.cy.tsx +++ b/packages/react-components/react-tree/library/src/components/Tree/Tree.cy.tsx @@ -188,6 +188,25 @@ describe('Tree', () => { cy.document().realPress('Tab'); cy.get('#action').should('be.focused'); }); + describe('navigationMode="treegrid"', () => { + it('should focus on actions/treeitem when pressing right/left arrow', () => { + mount( + + + action}>level 1, item 1 + + + level 2, item 1 + + + + , + ); + cy.get('[data-testid="item1"]').focus().realPress('{rightarrow}'); + cy.get('#action').should('be.focused').realPress('{leftarrow}'); + cy.get('[data-testid="item1"]').should('be.focused'); + }); + }); it('should not expand/collapse item on actions Enter/Space key', () => { mount( @@ -231,25 +250,49 @@ describe('Tree', () => { cy.get('[data-testid="item2"]').should('be.focused'); cy.focused().realPress('Tab').should('not.exist'); }); - it('should move with Left/Right keys', () => { - mount(); - cy.get('[data-testid="item1"]').focus().realPress('{downarrow}'); - cy.get('[data-testid="item2"]').should('be.focused').realPress('{rightarrow}'); - cy.get('[data-testid="item2__item1"]').should('be.focused').realPress('{rightarrow}'); - cy.get('[data-testid="item2__item1__item1"]').should('be.focused').realPress('{leftarrow}'); - cy.get('[data-testid="item2__item1"]').should('be.focused').realPress('{leftarrow}').realPress('{leftarrow}'); - cy.get('[data-testid="item2"]').should('be.focused'); - }); - it('should not move with Alt + Left/Right keys', () => { - mount(); - cy.get('[data-testid="item1"]').focus().realPress('{downarrow}'); - cy.get('[data-testid="item2"]').should('be.focused').realPress(['Alt', '{rightarrow}']); - cy.get('[data-testid="item2"]').should('be.focused').realPress('{rightarrow}'); - cy.get('[data-testid="item2__item1"]').should('be.focused').realPress('{rightarrow}'); - cy.get('[data-testid="item2__item1__item1"]').should('be.focused').realPress(['Alt', '{leftarrow}']); - cy.get('[data-testid="item2__item1__item1"]').should('be.focused').realPress('{leftarrow}'); - cy.get('[data-testid="item2__item1"]').should('be.focused').realPress('{leftarrow}').realPress('{leftarrow}'); - cy.get('[data-testid="item2"]').should('be.focused'); + describe('navigationMode="treegrid"', () => { + it('should move with Up/Down keys', () => { + mount( + + + level 1, item 1 + + + action}>level 2, item 1 + + + level 2, item 2 + + + + , + ); + cy.get('[data-testid="item1__item1"]').focus().realPress('{rightarrow}'); + cy.get('#action').should('be.focused').realPress('{uparrow}'); + cy.get('[data-testid="item1"]').should('be.focused'); + cy.get('[data-testid="item1__item1"]').focus().realPress('{rightarrow}'); + cy.get('#action').should('be.focused').realPress('{downarrow}'); + cy.get('[data-testid="item1__item2"]').should('be.focused'); + }); + it('should move with Left keys', () => { + mount(); + cy.get('[data-testid="item1"]').focus().realPress('{downarrow}'); + cy.get('[data-testid="item2"]').should('be.focused').realPress('{downarrow}'); + cy.get('[data-testid="item2__item1"]').should('be.focused').realPress('{downarrow}'); + cy.get('[data-testid="item2__item1__item1"]').should('be.focused').realPress('{leftarrow}'); + cy.get('[data-testid="item2__item1"]').should('be.focused').realPress('{leftarrow}').realPress('{leftarrow}'); + cy.get('[data-testid="item2"]').should('be.focused'); + }); + it('should not move with Alt + Left keys', () => { + mount(); + cy.get('[data-testid="item1"]').focus().realPress('{downarrow}'); + cy.get('[data-testid="item2"]').should('be.focused').realPress('{downarrow}'); + cy.get('[data-testid="item2__item1"]').should('be.focused').realPress('{downarrow}'); + cy.get('[data-testid="item2__item1__item1"]').should('be.focused').realPress(['Alt', '{leftarrow}']); + cy.get('[data-testid="item2__item1__item1"]').should('be.focused').realPress('{leftarrow}'); + cy.get('[data-testid="item2__item1"]').should('be.focused').realPress('{leftarrow}').realPress('{leftarrow}'); + cy.get('[data-testid="item2"]').should('be.focused'); + }); }); it('should move to last item with End key', () => { mount(); diff --git a/packages/react-components/react-tree/library/src/components/Tree/Tree.types.ts b/packages/react-components/react-tree/library/src/components/Tree/Tree.types.ts index 959ba074dcad9b..92f6f8824ee01a 100644 --- a/packages/react-components/react-tree/library/src/components/Tree/Tree.types.ts +++ b/packages/react-components/react-tree/library/src/components/Tree/Tree.types.ts @@ -91,7 +91,16 @@ export type TreeContextValues = { tree: TreeContextValue | SubtreeContextValue; }; +export type TreeNavigationMode = 'tree' | 'treegrid'; + export type TreeProps = ComponentProps & { + /** + * Indicates how navigation between a treeitem and its actions work + * - 'tree' (default): The default navigation, pressing right arrow key navigates inward the first inner children of a branch treeitem + * - 'treegrid': Pressing right arrow key navigate towards the actions of a treeitem + * @default 'tree' + */ + navigationMode?: TreeNavigationMode; /** * A tree item can have various appearances: * - 'subtle' (default): The default tree item styles. diff --git a/packages/react-components/react-tree/library/src/components/Tree/index.ts b/packages/react-components/react-tree/library/src/components/Tree/index.ts index c49dc6c59cd400..6d35eba2306cad 100644 --- a/packages/react-components/react-tree/library/src/components/Tree/index.ts +++ b/packages/react-components/react-tree/library/src/components/Tree/index.ts @@ -11,6 +11,7 @@ export type { TreeSelectionValue, TreeSlots, TreeState, + TreeNavigationMode, } from './Tree.types'; export { useTree_unstable } from './useTree'; export { useTreeContextValues_unstable } from './useTreeContextValues'; diff --git a/packages/react-components/react-tree/library/src/components/Tree/useTree.ts b/packages/react-components/react-tree/library/src/components/Tree/useTree.ts index 233b7fdf32628b..625dd6d5fe299a 100644 --- a/packages/react-components/react-tree/library/src/components/Tree/useTree.ts +++ b/packages/react-components/react-tree/library/src/components/Tree/useTree.ts @@ -26,7 +26,7 @@ function useNestedRootTree(props: TreeProps, ref: React.Ref): TreeS const [openItems, setOpenItems] = useControllableOpenItems(props); const checkedItems = useNestedCheckedItems(props); - const navigation = useTreeNavigation(); + const navigation = useTreeNavigation(props.navigationMode); return Object.assign( useRootTree( diff --git a/packages/react-components/react-tree/library/src/components/Tree/useTreeContextValues.ts b/packages/react-components/react-tree/library/src/components/Tree/useTreeContextValues.ts index fdfa26728522c6..4431b8be3909f8 100644 --- a/packages/react-components/react-tree/library/src/components/Tree/useTreeContextValues.ts +++ b/packages/react-components/react-tree/library/src/components/Tree/useTreeContextValues.ts @@ -13,6 +13,7 @@ export function useTreeContextValues_unstable(state: TreeState): TreeContextValu treeType, checkedItems, selectionMode, + navigationMode, appearance, size, requestTreeResponse, @@ -29,6 +30,7 @@ export function useTreeContextValues_unstable(state: TreeState): TreeContextValu appearance, checkedItems, selectionMode, + navigationMode, contextType, level, requestTreeResponse, diff --git a/packages/react-components/react-tree/library/src/components/TreeItem/useTreeItem.tsx b/packages/react-components/react-tree/library/src/components/TreeItem/useTreeItem.tsx index 0b01ccce4a61c0..bc6c4400e0c306 100644 --- a/packages/react-components/react-tree/library/src/components/TreeItem/useTreeItem.tsx +++ b/packages/react-components/react-tree/library/src/components/TreeItem/useTreeItem.tsx @@ -7,6 +7,7 @@ import { slot, elementContains, useMergedRefs, + isHTMLElement, } from '@fluentui/react-utilities'; import type { TreeItemProps, TreeItemState, TreeItemValue } from './TreeItem.types'; import { Space } from '@fluentui/keyboard-keys'; @@ -38,6 +39,7 @@ export function useTreeItem_unstable(props: TreeItemProps, ref: React.Ref ctx.requestTreeResponse); + const navigationMode = useTreeContext_unstable(ctx => ctx.navigationMode ?? 'tree'); const forceUpdateRovingTabIndex = useTreeContext_unstable(ctx => ctx.forceUpdateRovingTabIndex); const { level: contextLevel } = useSubtreeContext_unstable(); const parentValue = useTreeItemContext_unstable(ctx => props.parentValue ?? ctx.value); @@ -147,25 +149,36 @@ export function useTreeItem_unstable(props: TreeItemProps, ref: React.Ref) => { onKeyDown?.(event); - // Ignore keyboard events that do not originate from the current tree item. - if (event.isDefaultPrevented() || event.currentTarget !== event.target) { + if (event.isDefaultPrevented() || !treeItemRef.current) { return; } + const isEventFromTreeItem = event.currentTarget === event.target; + const isEventFromActions = actionsRef.current && actionsRef.current.contains(event.target as Node); + switch (event.key) { - case Space: + case Space: { + if (!isEventFromTreeItem) { + return; + } if (selectionMode !== 'none') { selectionRef.current?.click(); // Prevents the page from scrolling down when the spacebar is pressed event.preventDefault(); } return; + } case treeDataTypes.Enter: { + if (!isEventFromTreeItem) { + return; + } return event.currentTarget.click(); } case treeDataTypes.End: case treeDataTypes.Home: - case treeDataTypes.ArrowUp: - case treeDataTypes.ArrowDown: + case treeDataTypes.ArrowUp: { + if (!isEventFromTreeItem && !isEventFromActions) { + return; + } return requestTreeResponse({ requestType: 'navigate', event, @@ -175,40 +188,63 @@ export function useTreeItem_unstable(props: TreeItemProps, ref: React.Ref ctx.layoutRef); const selectionMode = useTreeContext_unstable(ctx => ctx.selectionMode); + const navigationMode = useTreeContext_unstable(ctx => ctx.navigationMode ?? 'tree'); const [isActionsVisibleFromProps, onActionVisibilityChange]: [ TreeItemLayoutActionSlotProps['visible'], @@ -134,7 +135,7 @@ export const useTreeItemLayout_unstable = ( if (expandIcon) { expandIcon.ref = expandIconRefs; } - const arrowNavigationProps = useArrowNavigationGroup({ circular: true, axis: 'horizontal' }); + const arrowNavigationProps = useArrowNavigationGroup({ circular: navigationMode === 'tree', axis: 'horizontal' }); const actions = isActionsVisible ? slot.optional(props.actions, { defaultProps: { ...arrowNavigationProps, role: 'toolbar' }, @@ -143,6 +144,7 @@ export const useTreeItemLayout_unstable = ( : undefined; delete actions?.visible; delete actions?.onVisibilityChange; + const actionsRefs = useMergedRefs(actions?.ref, actionsRef, actionsRefInternal); const handleActionsBlur = useEventCallback((event: React.FocusEvent) => { if (isResolvedShorthand(props.actions)) { diff --git a/packages/react-components/react-tree/library/src/components/TreeProvider.cy.tsx b/packages/react-components/react-tree/library/src/components/TreeProvider.cy.tsx new file mode 100644 index 00000000000000..0b466e8aabbe76 --- /dev/null +++ b/packages/react-components/react-tree/library/src/components/TreeProvider.cy.tsx @@ -0,0 +1,153 @@ +import * as React from 'react'; +import { mount as mountBase } from '@cypress/react'; +import { Tree } from '../Tree'; +import { TreeItem, TreeItemProps } from '../TreeItem'; +import { TreeItemLayout } from '../TreeItemLayout'; +import { TreeRootReset } from './TreeProvider'; +import { Popover, PopoverTrigger, PopoverSurface } from '@fluentui/react-popover'; +import { Button } from '@fluentui/react-button'; +import { FluentProvider } from '@fluentui/react-provider'; +import { teamsLightTheme } from '@fluentui/react-theme'; +import { useRestoreFocusTarget } from '@fluentui/react-tabster'; + +const mount = (element: JSX.Element) => { + mountBase({element}); +}; + +describe('TreeRootReset', () => { + it('ensure that a subtree will be treated as a root tree', () => { + const handleOpenChange1 = cy.spy().as('handleOpenChange1'); + const handleOpenChange2 = cy.spy().as('handleOpenChange2'); + + mount( + + + + + + + branch + + + leaf + + + + + + + } + /> + + , + ); + cy.get('[data-testid="item2"]').should('not.exist'); + cy.get('[data-testid="tree-item"]').focus(); + cy.get('[data-testid="item1"]').realClick(); + cy.get('@handleOpenChange1').should('not.have.been.called'); + cy.get('@handleOpenChange2').should('have.been.called'); + cy.get('[data-testid="item2"]').should('exist'); + }); + it('ensures basic navigation between multiple trees', () => { + mount(); + cy.get('[data-testid="item1"]').should('exist').focus(); + cy.get('[data-testid="item2"]').should('not.exist'); + cy.get('[data-testid="action-button"]').should('exist').realClick(); + cy.get('[data-testid="item2"]').should('exist').focus().realPress('{esc}'); + cy.get('[data-testid="action-button"]').should('be.focused').realPress(['Shift', 'Tab']); + cy.get('[data-testid="item1"]').should('exist').should('be.focused'); + }); +}); + +type CustomTreeItemProps = TreeItemProps; + +const CustomTreeItem = ({ children, ...props }: CustomTreeItemProps) => { + const focusTargetAttribute = useRestoreFocusTarget(); + const [layoutChildren, subtree] = React.Children.toArray(children); + + return ( + + + + +
)} diff --git a/packages/react-examples/src/react-experiments/Chiclet/Chiclet.Footer.Example.tsx b/packages/react-examples/src/react-experiments/Chiclet/Chiclet.Footer.Example.tsx index 7e2091f14b53b8..879b2c9677a2a2 100644 --- a/packages/react-examples/src/react-experiments/Chiclet/Chiclet.Footer.Example.tsx +++ b/packages/react-examples/src/react-experiments/Chiclet/Chiclet.Footer.Example.tsx @@ -63,7 +63,7 @@ export const ChicletFooterExample: React.FunctionComponent<{}> = () => { ); }; -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated export interface IFooterComponent extends React.Props { buttonProps: IButtonProps[]; activities: string; diff --git a/packages/react-examples/src/react-experiments/Chiclet/Chiclet.Xsmall.Footer.Example.tsx b/packages/react-examples/src/react-experiments/Chiclet/Chiclet.Xsmall.Footer.Example.tsx index 75e67ce3d8789d..23b55119737203 100644 --- a/packages/react-examples/src/react-experiments/Chiclet/Chiclet.Xsmall.Footer.Example.tsx +++ b/packages/react-examples/src/react-experiments/Chiclet/Chiclet.Xsmall.Footer.Example.tsx @@ -65,7 +65,7 @@ class FooterComponent extends React.Component { } } -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated interface IFooterComponent extends React.Props { buttonProps: IButtonProps[]; attachProps: IIconProps; diff --git a/packages/react-examples/src/react-experiments/CollapsibleSection/CollapsibleSection.Styled.Example.tsx b/packages/react-examples/src/react-experiments/CollapsibleSection/CollapsibleSection.Styled.Example.tsx index 3dceaeca9974ff..eb0edca0abe397 100644 --- a/packages/react-examples/src/react-experiments/CollapsibleSection/CollapsibleSection.Styled.Example.tsx +++ b/packages/react-examples/src/react-experiments/CollapsibleSection/CollapsibleSection.Styled.Example.tsx @@ -12,7 +12,7 @@ import { } from '@fluentui/react-experiments/lib/CollapsibleSection'; // Workaround to prevent errors on usage of Customizer in this file, without disabling all deprecation checks -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated const Customizer = DeprecatedCustomizer; const getPropStyles: ICollapsibleSectionComponent['styles'] = (props, theme): ICollapsibleSectionStylesReturnType => ({ diff --git a/packages/react-examples/src/react-experiments/FloatingPeopleSuggestions/FloatingPeopleSuggestions.HeaderFooter.Example.tsx b/packages/react-examples/src/react-experiments/FloatingPeopleSuggestions/FloatingPeopleSuggestions.HeaderFooter.Example.tsx index 6706413884d65d..c0d5348f6b14e8 100644 --- a/packages/react-examples/src/react-experiments/FloatingPeopleSuggestions/FloatingPeopleSuggestions.HeaderFooter.Example.tsx +++ b/packages/react-examples/src/react-experiments/FloatingPeopleSuggestions/FloatingPeopleSuggestions.HeaderFooter.Example.tsx @@ -186,7 +186,7 @@ export const FloatingPeopleSuggestionsHeaderFooterExample = (): JSX.Element => { }; const _onInputKeyDown = (ev: React.KeyboardEvent) => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const keyCode = ev.which; switch (keyCode) { case KeyCodes.enter: diff --git a/packages/react-examples/src/react-experiments/Slider/Slider.Example.tsx b/packages/react-examples/src/react-experiments/Slider/Slider.Example.tsx index c21925e3cd828f..34a0dbd5649078 100644 --- a/packages/react-examples/src/react-experiments/Slider/Slider.Example.tsx +++ b/packages/react-examples/src/react-experiments/Slider/Slider.Example.tsx @@ -3,7 +3,7 @@ import { Slider as DeprecatedSlider } from '@fluentui/react-experiments'; import { IStackTokens, Stack } from '@fluentui/react'; // Workaround to prevent errors on usage of Slider, without disabling all deprecation checks -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated const Slider = DeprecatedSlider; export interface ISliderBasicExampleState { diff --git a/packages/react-examples/src/react-experiments/Slider/Slider.Vertical.Example.tsx b/packages/react-examples/src/react-experiments/Slider/Slider.Vertical.Example.tsx index 0bad5853589d4d..55b8ad528e4536 100644 --- a/packages/react-examples/src/react-experiments/Slider/Slider.Vertical.Example.tsx +++ b/packages/react-examples/src/react-experiments/Slider/Slider.Vertical.Example.tsx @@ -3,7 +3,7 @@ import { Slider as DeprecatedSlider } from '@fluentui/react-experiments'; import { IStackTokens, Stack } from '@fluentui/react/lib/Stack'; // Workaround to prevent errors on usage of Slider, without disabling all deprecation checks -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated const Slider = DeprecatedSlider; export interface ISliderVerticalExampleState { diff --git a/packages/react-examples/src/react-experiments/Theming/Theming.Schemes.Custom.Example.tsx b/packages/react-examples/src/react-experiments/Theming/Theming.Schemes.Custom.Example.tsx index 841b24ed2754e1..20fc4b40d5b335 100644 --- a/packages/react-examples/src/react-experiments/Theming/Theming.Schemes.Custom.Example.tsx +++ b/packages/react-examples/src/react-experiments/Theming/Theming.Schemes.Custom.Example.tsx @@ -26,7 +26,7 @@ import { CollapsibleSectionRecursiveExample } from '@fluentui/react-examples/lib import { ThemeProvider as DeprecatedThemeProvider } from '@fluentui/foundation-legacy'; // Workaround to prevent errors on usage of ThemeProvider, without disabling all deprecation checks -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated const ThemeProvider = DeprecatedThemeProvider; const regionStyles: IStackComponent['styles'] = (props, theme): IStackStylesReturnType => ({ @@ -186,7 +186,7 @@ export class ThemingSchemesCustomExample extends React.Component<{}, IThemingExa }; public render(): JSX.Element { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated return {this._renderSchemedComponents()}; } @@ -270,7 +270,7 @@ export class ThemingSchemesCustomExample extends React.Component<{}, IThemingExa }; } -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated const onCommandClick = (ev: any, item?: ICommandBarItemProps) => console.log(item && (item.text || item.name)); const items: ICommandBarItemProps[] = [ { diff --git a/packages/react-examples/src/react-experiments/Theming/Theming.Schemes.Variant.Example.tsx b/packages/react-examples/src/react-experiments/Theming/Theming.Schemes.Variant.Example.tsx index bb9dff394be382..10b3cd60487376 100644 --- a/packages/react-examples/src/react-experiments/Theming/Theming.Schemes.Variant.Example.tsx +++ b/packages/react-examples/src/react-experiments/Theming/Theming.Schemes.Variant.Example.tsx @@ -25,7 +25,7 @@ import { CollapsibleSectionRecursiveExample } from '@fluentui/react-examples/lib import { ThemeProvider as DeprecatedThemeProvider } from '@fluentui/foundation-legacy'; // Workaround to prevent errors on usage of ThemeProvider, without disabling all deprecation checks -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated const ThemeProvider = DeprecatedThemeProvider; const regionStyles: IStackComponent['styles'] = (props, theme): IStackStylesReturnType => ({ @@ -65,7 +65,7 @@ export class ThemingSchemesVariantExample extends React.Component<{}, IThemingEx }; public render(): JSX.Element { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated return {this._renderSchemedComponents()}; } @@ -149,7 +149,7 @@ export class ThemingSchemesVariantExample extends React.Component<{}, IThemingEx }; } -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated const onCommandClick = (ev: any, item?: ICommandBarItemProps) => console.log(item && (item.text || item.name)); const items: ICommandBarItemProps[] = [ { diff --git a/packages/react-examples/src/react-experiments/UnifiedPeoplePicker/UnifiedPeoplePicker.WithEdit.Example.tsx b/packages/react-examples/src/react-experiments/UnifiedPeoplePicker/UnifiedPeoplePicker.WithEdit.Example.tsx index c7222cbccc2ab8..a3a425fbe40692 100644 --- a/packages/react-examples/src/react-experiments/UnifiedPeoplePicker/UnifiedPeoplePicker.WithEdit.Example.tsx +++ b/packages/react-examples/src/react-experiments/UnifiedPeoplePicker/UnifiedPeoplePicker.WithEdit.Example.tsx @@ -141,7 +141,7 @@ export const UnifiedPeoplePickerWithEditExample = (): JSX.Element => { const allPeople = people; const suggestions = allPeople.filter((item: IPersonaProps) => _startsWith(item.text || '', value)); const suggestionList = suggestions.map(item => { - return { item: item, isSelected: false, key: item.key } as IFloatingSuggestionItem; + return { item, isSelected: false, key: item.key } as IFloatingSuggestionItem; }); return suggestionList; }; @@ -327,7 +327,7 @@ export const UnifiedPeoplePickerWithEditExample = (): JSX.Element => { const allPeople = people; const suggestions = allPeople.filter((item: IPersonaProps) => _startsWith(item.text || '', filterText)); const suggestionList = suggestions.map(item => { - return { item: item, isSelected: false, key: item.key } as IFloatingSuggestionItem; + return { item, isSelected: false, key: item.key } as IFloatingSuggestionItem; }); // We want to show top 5 results setPeopleSuggestions(suggestionList.splice(0, 5)); @@ -339,7 +339,7 @@ export const UnifiedPeoplePickerWithEditExample = (): JSX.Element => { const _onKeyDown = React.useCallback( (ev: React.KeyboardEvent) => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.ctrlKey && ev.which === KeyCodes.k) { ev.preventDefault(); // If the input has text, resolve that diff --git a/packages/react-examples/src/react-focus/FocusZone/FocusZone.List.Example.tsx b/packages/react-examples/src/react-focus/FocusZone/FocusZone.List.Example.tsx index 9db97e849c0e36..c427bac6bb8fcb 100644 --- a/packages/react-examples/src/react-focus/FocusZone/FocusZone.List.Example.tsx +++ b/packages/react-examples/src/react-focus/FocusZone/FocusZone.List.Example.tsx @@ -75,6 +75,6 @@ export const FocusZoneListExample: React.FunctionComponent = () => { }; function _shouldEnterInnerZone(ev: React.KeyboardEvent): boolean { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated return ev.which === getRTLSafeKeyCode(KeyCodes.right); } diff --git a/packages/react-examples/src/react/Layer/Layer.Customized.Example.tsx b/packages/react-examples/src/react/Layer/Layer.Customized.Example.tsx index bb5bbf2982854b..2d45414d553559 100644 --- a/packages/react-examples/src/react/Layer/Layer.Customized.Example.tsx +++ b/packages/react-examples/src/react/Layer/Layer.Customized.Example.tsx @@ -25,7 +25,7 @@ export const LayerCustomizedExample: React.FunctionComponent = () => {

- {/* eslint-disable-next-line deprecation/deprecation */} + {/* eslint-disable-next-line @typescript-eslint/no-deprecated */} {isPanelOpen && ( { // Demonstrates how to do different things depending on how which element dismissed the panel console.log('Close button clicked or light dismissed.'); - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const srcElement = ev.nativeEvent.srcElement as Element | null; if (srcElement && srcElement.className.indexOf('ms-Button-icon') !== -1) { console.log('Close button clicked.'); diff --git a/packages/react-examples/src/react/PeoplePicker/examples/PeoplePickerExampleData.ts b/packages/react-examples/src/react/PeoplePicker/examples/PeoplePickerExampleData.ts index 26dd8d3a774818..2aaf840c3b4151 100644 --- a/packages/react-examples/src/react/PeoplePicker/examples/PeoplePickerExampleData.ts +++ b/packages/react-examples/src/react/PeoplePicker/examples/PeoplePickerExampleData.ts @@ -1,7 +1,7 @@ import { IPersonaProps, PersonaPresence } from '@fluentui/react/lib/Persona'; import { TestImages } from '@fluentui/example-data'; -/* eslint-disable deprecation/deprecation */ +/* eslint-disable @typescript-eslint/no-deprecated */ /** @deprecated Use the version from `@fluentui/example-data` instead. */ export const people: (IPersonaProps & { key: string | number })[] = [ diff --git a/packages/react-examples/src/react/Pivot/Pivot.OverflowMenu.Example.tsx b/packages/react-examples/src/react/Pivot/Pivot.OverflowMenu.Example.tsx index a770f91e5c8001..006b89f2bd3e7e 100644 --- a/packages/react-examples/src/react/Pivot/Pivot.OverflowMenu.Example.tsx +++ b/packages/react-examples/src/react/Pivot/Pivot.OverflowMenu.Example.tsx @@ -14,7 +14,7 @@ export const PivotOverflowMenuExample: React.FunctionComponent = () => {
- {/* eslint-disable-next-line deprecation/deprecation */} + {/* eslint-disable-next-line @typescript-eslint/no-deprecated */} +## [8.14.193](https://github.com/microsoft/fluentui/tree/@fluentui/react-experiments_v8.14.193) + +Fri, 17 Jan 2025 07:21:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-experiments_v8.14.192..@fluentui/react-experiments_v8.14.193) + +### Patches + +- Bump @fluentui/react to v8.122.7 ([commit](https://github.com/microsoft/fluentui/commit/baf887d95f91874c814a7cae749c20e797f828be) by beachball) + ## [8.14.192](https://github.com/microsoft/fluentui/tree/@fluentui/react-experiments_v8.14.192) Mon, 13 Jan 2025 07:21:23 GMT diff --git a/packages/react-experiments/package.json b/packages/react-experiments/package.json index f01f7b540cd0c9..c08698e4eb6eb4 100644 --- a/packages/react-experiments/package.json +++ b/packages/react-experiments/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-experiments", - "version": "8.14.192", + "version": "8.14.193", "description": "Experimental React components for building experiences for Microsoft 365.", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -38,7 +38,7 @@ "@fluentui/scripts-webpack": "*" }, "dependencies": { - "@fluentui/react": "^8.122.6", + "@fluentui/react": "^8.122.7", "@fluentui/theme": "^2.6.64", "@microsoft/load-themed-styles": "^1.10.26", "@fluentui/example-data": "^8.4.25", diff --git a/packages/react-experiments/src/Foundation.ts b/packages/react-experiments/src/Foundation.ts index dfe2afe37e74a7..9bf082389c5d77 100644 --- a/packages/react-experiments/src/Foundation.ts +++ b/packages/react-experiments/src/Foundation.ts @@ -1,5 +1,5 @@ export { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated ThemeProvider, createComponent, createFactory, @@ -22,7 +22,7 @@ export type { IHTMLElementSlot, IHTMLSlot, IProcessedSlotProps, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated IPropsWithChildren, ISlot, ISlotCreator, diff --git a/packages/react-experiments/src/Styling.ts b/packages/react-experiments/src/Styling.ts index 31e6ed2005a051..563a5a90452e3b 100644 --- a/packages/react-experiments/src/Styling.ts +++ b/packages/react-experiments/src/Styling.ts @@ -6,7 +6,7 @@ export { DefaultEffects, DefaultFontStyles, DefaultPalette, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated EdgeChromiumHighContrastSelector, FontClassNames, FontSizes, @@ -39,11 +39,11 @@ export { createTheme, focusClear, fontFace, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getEdgeChromiumNoHighContrastAdjustSelector, getFadedOverflowStyle, getFocusOutlineStyle, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getFocusStyle, getGlobalClassNames, getHighContrastNoAdjustStyle, diff --git a/packages/react-experiments/src/Utilities.ts b/packages/react-experiments/src/Utilities.ts index 0850eaa19b0634..82dae884afcb13 100644 --- a/packages/react-experiments/src/Utilities.ts +++ b/packages/react-experiments/src/Utilities.ts @@ -1,10 +1,8 @@ export { Async, AutoScroll, - // eslint-disable-next-line deprecation/deprecation BaseComponent, Customizations, - // eslint-disable-next-line deprecation/deprecation Customizer, CustomizerContext, DATA_IS_SCROLLABLE_ATTRIBUTE, @@ -87,7 +85,6 @@ export { getRTL, getRTLSafeKeyCode, getRect, - // eslint-disable-next-line deprecation/deprecation getResourceUrl, getScrollbarWidth, getVirtualParent, @@ -99,11 +96,9 @@ export { hoistStatics, htmlElementProperties, iframeProperties, - // eslint-disable-next-line deprecation/deprecation imageProperties, imgProperties, initializeComponentRef, - // eslint-disable-next-line deprecation/deprecation initializeFocusRects, inputProperties, isControlled, @@ -135,7 +130,6 @@ export { optionProperties, portalContainsElement, precisionRound, - // eslint-disable-next-line deprecation/deprecation raiseClick, removeIndex, replaceElement, @@ -145,15 +139,12 @@ export { safeRequestAnimationFrame, safeSetTimeout, selectProperties, - // eslint-disable-next-line deprecation/deprecation setBaseUrl, setFocusVisibility, - // eslint-disable-next-line deprecation/deprecation setLanguage, setMemoizeWeakMap, setPortalAttribute, setRTL, - // eslint-disable-next-line deprecation/deprecation setSSR, setVirtualParent, setWarningCallback, @@ -184,7 +175,6 @@ export type { ICancelable, IChangeDescription, IChangeEventCallback, - // eslint-disable-next-line deprecation/deprecation IClassNames, IClassNamesFunctionOptions, IComponentAs, @@ -207,7 +197,6 @@ export type { IPerfData, IPerfMeasurement, IPerfSummary, - // eslint-disable-next-line deprecation/deprecation IPoint, IPropsWithStyles, IRectangle, @@ -226,13 +215,10 @@ export type { IStyleFunctionOrObject, IVirtualElement, IWarnControlledUsageParams, - // eslint-disable-next-line deprecation/deprecation Omit, Point, RefObject, - // eslint-disable-next-line deprecation/deprecation Settings, - // eslint-disable-next-line deprecation/deprecation SettingsFunction, StyleFunction, } from '@fluentui/react/lib/Utilities'; diff --git a/packages/react-experiments/src/components/BAFAccordion/Accordion.tsx b/packages/react-experiments/src/components/BAFAccordion/Accordion.tsx index 5b06a20205cf0b..e5255d8906397f 100644 --- a/packages/react-experiments/src/components/BAFAccordion/Accordion.tsx +++ b/packages/react-experiments/src/components/BAFAccordion/Accordion.tsx @@ -33,7 +33,7 @@ export class Accordion extends React.Component } public render(): JSX.Element { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { onRenderMenu, className, buttonAs, onClick, ...other } = this.props; let { menuIconProps } = this.props; diff --git a/packages/react-experiments/src/components/CollapsibleSection/CollapsibleSection.state.tsx b/packages/react-experiments/src/components/CollapsibleSection/CollapsibleSection.state.tsx index f15391003754a6..2bf28ff5450275 100644 --- a/packages/react-experiments/src/components/CollapsibleSection/CollapsibleSection.state.tsx +++ b/packages/react-experiments/src/components/CollapsibleSection/CollapsibleSection.state.tsx @@ -37,12 +37,12 @@ export const useCollapsibleSectionState: ICollapsibleSectionComponent['state'] = const collapseKey = getRTL() ? KeyCodes.right : KeyCodes.left; const expandKey = getRTL() ? KeyCodes.left : KeyCodes.right; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.which === collapseKey && !collapsed) { setCollapsed(true); ev.preventDefault(); ev.stopPropagation(); - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated } else if (ev.which === expandKey && collapsed) { setCollapsed(false); ev.preventDefault(); @@ -58,7 +58,7 @@ export const useCollapsibleSectionState: ICollapsibleSectionComponent['state'] = // If left/right keypress originates from text input or text area inside collapsible section, // ignore the event. if ( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated ev.which === rootKey && ev.target !== titleElementRef.current && titleElementRef.current && diff --git a/packages/react-experiments/src/components/FloatingSuggestions/FloatingSuggestions.tsx b/packages/react-experiments/src/components/FloatingSuggestions/FloatingSuggestions.tsx index 2f9ff8c273ef55..da5d15c9d3a223 100644 --- a/packages/react-experiments/src/components/FloatingSuggestions/FloatingSuggestions.tsx +++ b/packages/react-experiments/src/components/FloatingSuggestions/FloatingSuggestions.tsx @@ -250,7 +250,7 @@ export class FloatingSuggestions ) { return; } - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const keyCode = ev.which; switch (keyCode) { case KeyCodes.escape: diff --git a/packages/react-experiments/src/components/FolderCover/FolderCover.types.ts b/packages/react-experiments/src/components/FolderCover/FolderCover.types.ts index a93109a9ccf976..15272a3f247347 100644 --- a/packages/react-experiments/src/components/FolderCover/FolderCover.types.ts +++ b/packages/react-experiments/src/components/FolderCover/FolderCover.types.ts @@ -38,6 +38,6 @@ export interface IFolderCoverProps extends IBaseProps, React.HTMLAttributes['children'] | ((childrenProps: IFolderCoverChildrenProps) => JSX.Element | null); } diff --git a/packages/react-experiments/src/components/SelectedItemsList/Items/CopyableItem.tsx b/packages/react-experiments/src/components/SelectedItemsList/Items/CopyableItem.tsx index 8b5f20ec850154..119fedcd7636e9 100644 --- a/packages/react-experiments/src/components/SelectedItemsList/Items/CopyableItem.tsx +++ b/packages/react-experiments/src/components/SelectedItemsList/Items/CopyableItem.tsx @@ -26,7 +26,7 @@ export const CopyableItem = ( // Try to copy the text directly to the clipboard copyInput.value = copyText; copyInput.select(); - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (!document.execCommand('copy')) { // The command failed. Fallback to the method below. throw new Error(); diff --git a/packages/react-experiments/src/components/SelectedItemsList/Items/subcomponents/DefaultEditingItem.tsx b/packages/react-experiments/src/components/SelectedItemsList/Items/subcomponents/DefaultEditingItem.tsx index d63f095f6f7084..664dee16f9b0e2 100644 --- a/packages/react-experiments/src/components/SelectedItemsList/Items/subcomponents/DefaultEditingItem.tsx +++ b/packages/react-experiments/src/components/SelectedItemsList/Items/subcomponents/DefaultEditingItem.tsx @@ -195,7 +195,7 @@ export const DefaultEditingItemInner = ( const _onInputKeyDown = React.useCallback( (ev: React.KeyboardEvent): void => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const keyCode = ev.which; switch (keyCode) { case KeyCodes.backspace: diff --git a/packages/react-experiments/src/components/Sidebar/Sidebar.tsx b/packages/react-experiments/src/components/Sidebar/Sidebar.tsx index 8fc07723bb21bf..b3511d725b7385 100644 --- a/packages/react-experiments/src/components/Sidebar/Sidebar.tsx +++ b/packages/react-experiments/src/components/Sidebar/Sidebar.tsx @@ -154,7 +154,7 @@ export class Sidebar extends React.Component imple } const ButtonAs = this._getButtonAs(item); - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const name = item.text || item.name; return ( @@ -204,7 +204,7 @@ export class Sidebar extends React.Component imple } const ButtonAs = this._getButtonAs(item); - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const name = item.text || item.name; return ( @@ -268,13 +268,13 @@ export class Sidebar extends React.Component imple return child; }); - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const name = item.text || item.name; if (name) { children.unshift({ key: name + '-header', - name: name, + name, iconProps: { iconName: '' }, className: 'ba-SidebarContextualMenuButton-header ', disabled: true, diff --git a/packages/react-experiments/src/components/Slider/Slider.base.tsx b/packages/react-experiments/src/components/Slider/Slider.base.tsx index 6da62030cbce49..2b1dc2092ff782 100644 --- a/packages/react-experiments/src/components/Slider/Slider.base.tsx +++ b/packages/react-experiments/src/components/Slider/Slider.base.tsx @@ -15,7 +15,7 @@ import { DirectionalHint } from '@fluentui/react/lib/Callout'; import { Async, EventGroup, FocusRects } from '@fluentui/utilities'; import type { ISliderProps, ISlider, ISliderStyleProps, ISliderStyles, ISliderMarks } from './Slider.types'; -/* eslint-disable deprecation/deprecation */ +/* eslint-disable @typescript-eslint/no-deprecated */ /** @deprecated */ export interface ISliderState { @@ -71,7 +71,7 @@ export class SliderBase extends React.Component impl props.value !== undefined ? props.value : props.defaultValue !== undefined ? props.defaultValue : props.min; this.state = { - value: value, + value, renderedValue: undefined, }; } diff --git a/packages/react-experiments/src/components/Slider/Slider.styles.tsx b/packages/react-experiments/src/components/Slider/Slider.styles.tsx index ce9ba0f30375a6..aaa839bebfa53e 100644 --- a/packages/react-experiments/src/components/Slider/Slider.styles.tsx +++ b/packages/react-experiments/src/components/Slider/Slider.styles.tsx @@ -3,7 +3,7 @@ import { getRTL } from '@fluentui/utilities'; import type { ISliderStyleProps, ISliderStyles } from './Slider.types'; import type { IRawStyle } from '../../Styling'; -/* eslint-disable deprecation/deprecation */ +/* eslint-disable @typescript-eslint/no-deprecated */ const tickLabelSpacing = 13; diff --git a/packages/react-experiments/src/components/Slider/Slider.test.tsx b/packages/react-experiments/src/components/Slider/Slider.test.tsx index 8a19df4636b969..3b545995fcc0f1 100644 --- a/packages/react-experiments/src/components/Slider/Slider.test.tsx +++ b/packages/react-experiments/src/components/Slider/Slider.test.tsx @@ -9,7 +9,7 @@ import { ONKEYDOWN_TIMEOUT_DURATION } from './Slider.base'; import { KeyCodes } from '../../Utilities'; import type { ISlider } from './Slider.types'; -/* eslint-disable deprecation/deprecation */ +/* eslint-disable @typescript-eslint/no-deprecated */ describe('Slider', () => { it('renders correctly', () => { diff --git a/packages/react-experiments/src/components/Slider/Slider.tsx b/packages/react-experiments/src/components/Slider/Slider.tsx index a4294f8fc02bfc..9742c6b25fa0c5 100644 --- a/packages/react-experiments/src/components/Slider/Slider.tsx +++ b/packages/react-experiments/src/components/Slider/Slider.tsx @@ -4,7 +4,7 @@ import { SliderBase } from './Slider.base'; import { getStyles } from './Slider.styles'; import type { ISliderProps, ISliderStyleProps, ISliderStyles } from './Slider.types'; -/* eslint-disable deprecation/deprecation */ +/* eslint-disable @typescript-eslint/no-deprecated */ /** * @deprecated This component was experimental and is not longer being developed on, nor will it be supported in the diff --git a/packages/react-experiments/src/components/Slider/Slider.types.ts b/packages/react-experiments/src/components/Slider/Slider.types.ts index 01d2cdbd705902..483058e5becf3d 100644 --- a/packages/react-experiments/src/components/Slider/Slider.types.ts +++ b/packages/react-experiments/src/components/Slider/Slider.types.ts @@ -3,7 +3,7 @@ import { SliderBase } from './Slider.base'; import type { IStyle, ITheme } from '../../Styling'; import type { IStyleFunctionOrObject, IRefObject } from '../../Utilities'; -/* eslint-disable deprecation/deprecation */ +/* eslint-disable @typescript-eslint/no-deprecated */ /** * @deprecated diff --git a/packages/react-experiments/src/components/TilesList/TilesList.types.ts b/packages/react-experiments/src/components/TilesList/TilesList.types.ts index 3d34844e09c8ff..0e51d4bcd60745 100644 --- a/packages/react-experiments/src/components/TilesList/TilesList.types.ts +++ b/packages/react-experiments/src/components/TilesList/TilesList.types.ts @@ -135,7 +135,7 @@ export interface ITilesGridSegment { export interface ITilesListProps extends IBaseProps, - React.Props>, // eslint-disable-line deprecation/deprecation + React.Props>, // eslint-disable-line @typescript-eslint/no-deprecated React.HTMLAttributes { /** * An array of items to assign to the list. diff --git a/packages/react-experiments/src/components/UnifiedPicker/UnifiedPicker.tsx b/packages/react-experiments/src/components/UnifiedPicker/UnifiedPicker.tsx index 383ffa43be53cd..7dbb2c6469bfd6 100644 --- a/packages/react-experiments/src/components/UnifiedPicker/UnifiedPicker.tsx +++ b/packages/react-experiments/src/components/UnifiedPicker/UnifiedPicker.tsx @@ -72,7 +72,7 @@ export const UnifiedPicker = (props: IUnifiedPickerProps): JSX. const [draggedIndex, setDraggedIndex] = React.useState(-1); const dragDropHelper = new DragDropHelper({ - selection: selection, + selection, }); const { @@ -332,19 +332,19 @@ export const UnifiedPicker = (props: IUnifiedPickerProps): JSX. // Allow the caller to handle the key down onKeyDown?.(ev); - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.ctrlKey && ev.which === KeyCodes.a) { selectAll(); } // This is a temporary work around, it has localization issues // we plan on rewriting how this works in the future - /* eslint-disable deprecation/deprecation */ + /* eslint-disable @typescript-eslint/no-deprecated */ const isDel = ev.which === KeyCodes.del; const isCut = (ev.shiftKey && isDel) || (ev.ctrlKey && ev.which === KeyCodes.x); const isBackspace = ev.which === KeyCodes.backspace; const isCopy = ev.ctrlKey && ev.which === KeyCodes.c; - /* eslint-enable deprecation/deprecation */ + /* eslint-enable @typescript-eslint/no-deprecated */ const needToCopy = isCut || isCopy; const needToDelete = (isBackspace && selectedItems.length > 0) || ((isCut || isDel) && focusedItemIndices.length > 0); @@ -421,7 +421,7 @@ export const UnifiedPicker = (props: IUnifiedPickerProps): JSX. const _onInputKeyDown = React.useCallback( (ev: React.KeyboardEvent) => { if (isSuggestionsShown) { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const keyCode = ev.which; switch (keyCode) { case KeyCodes.escape: @@ -559,11 +559,11 @@ export const UnifiedPicker = (props: IUnifiedPickerProps): JSX. const _renderSelectedItemsList = (): JSX.Element => { return onRenderSelectedItems({ ...selectedItemsListProps, - selectedItems: selectedItems, - focusedItemIndices: focusedItemIndices, + selectedItems, + focusedItemIndices, onItemsRemoved: _onRemoveSelectedItems, replaceItem: _replaceItem, - dragDropHelper: dragDropHelper, + dragDropHelper, dragDropEvents: dragDropEvents || defaultDragDropEvents, }); }; @@ -613,7 +613,7 @@ export const UnifiedPicker = (props: IUnifiedPickerProps): JSX. selectedSuggestionIndex: focusItemIndex, selectedFooterIndex: footerItemIndex, selectedHeaderIndex: headerItemIndex, - pickerSuggestionsProps: pickerSuggestionsProps, + pickerSuggestionsProps, onFloatingSuggestionsDismiss: _onFloatingSuggestionsDismiss, onSuggestionSelected: _onSuggestionSelected, onKeyDown: _onInputKeyDown, diff --git a/packages/react-focus/CHANGELOG.json b/packages/react-focus/CHANGELOG.json index 151892d1415cdb..fad38847b86b52 100644 --- a/packages/react-focus/CHANGELOG.json +++ b/packages/react-focus/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/react-focus", "entries": [ + { + "date": "Mon, 20 Jan 2025 07:21:44 GMT", + "tag": "@fluentui/react-focus_v8.9.20", + "version": "8.9.20", + "comments": { + "none": [ + { + "author": "vgenaev@gmail.com", + "package": "@fluentui/react-focus", + "commit": "fd420e1e0b66e04c8a423cff3eea6d21d9434d2d", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule" + } + ] + } + }, { "date": "Mon, 23 Dec 2024 07:22:58 GMT", "tag": "@fluentui/react-focus_v8.9.20", diff --git a/packages/react-focus/src/components/FocusZone/FocusZone.tsx b/packages/react-focus/src/components/FocusZone/FocusZone.tsx index de7e797019cab6..7d83edd178e8d9 100644 --- a/packages/react-focus/src/components/FocusZone/FocusZone.tsx +++ b/packages/react-focus/src/components/FocusZone/FocusZone.tsx @@ -62,7 +62,7 @@ function raiseClickFromKeyboardEvent(target: Element, ev?: React.KeyboardEvent implements IFocu * for ref counting to work correctly! */ private static _onKeyDownCapture(ev: KeyboardEvent): void { - // eslint-disable-next-line deprecation/deprecation, @fluentui/deprecated-keyboard-event-props + // eslint-disable-next-line @typescript-eslint/no-deprecated, @fluentui/deprecated-keyboard-event-props if (ev.which === KeyCodes.tab) { _outerZones.forEach((zone: FocusZone) => zone._updateTabIndexes()); } @@ -238,9 +238,9 @@ export class FocusZone extends React.Component implements IFocu if (this.props.defaultTabbableElement && typeof this.props.defaultTabbableElement === 'string') { this._activeElement = this._getDocument().querySelector(this.props.defaultTabbableElement) as HTMLElement; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated } else if (this.props.defaultActiveElement) { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated this._activeElement = this._getDocument().querySelector(this.props.defaultActiveElement) as HTMLElement; } @@ -306,7 +306,7 @@ export class FocusZone extends React.Component implements IFocu } public render(): React.ReactNode { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { as: tag, elementType, rootProps, ariaDescribedBy, ariaLabelledBy, className } = this.props; const divProps = getNativeProps(this.props, htmlElementProperties); @@ -338,7 +338,7 @@ export class FocusZone extends React.Component implements IFocu // be replaced so that className is passed to getRootClass and is included there so // the class names will always be in the same order. className={css(getRootClass(), className)} - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated ref={this._mergedRef(this.props.elementRef, this._root)} data-focuszone-id={this._id} // eslint-disable-next-line react/jsx-no-bind @@ -427,7 +427,7 @@ export class FocusZone extends React.Component implements IFocu * @returns True if focus could be set to an active element, false if no operation was taken. */ public focusElement(element: HTMLElement, forceAlignment?: boolean): boolean { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { onBeforeFocus, shouldReceiveFocus } = this.props; if ((shouldReceiveFocus && !shouldReceiveFocus(element)) || (onBeforeFocus && !onBeforeFocus(element))) { @@ -487,10 +487,10 @@ export class FocusZone extends React.Component implements IFocu const { onActiveElementChanged, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated doNotAllowFocusEventToPropagate, stopFocusPropagation, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated onFocusNotification, onFocus, shouldFocusInnerElementWhenReceivedFocus, @@ -671,7 +671,7 @@ export class FocusZone extends React.Component implements IFocu return; } - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { direction, disabled, isInnerZoneKeystroke, pagingSupportDisabled, shouldEnterInnerZone } = this.props; if (disabled) { @@ -722,7 +722,7 @@ export class FocusZone extends React.Component implements IFocu } else if (ev.altKey) { return; } else { - // eslint-disable-next-line @fluentui/deprecated-keyboard-event-props, deprecation/deprecation + // eslint-disable-next-line @fluentui/deprecated-keyboard-event-props, @typescript-eslint/no-deprecated switch (ev.which) { case KeyCodes.space: if (this._shouldRaiseClicksOnSpace && this._tryInvokeClickForFocusable(ev.target as HTMLElement, ev)) { @@ -778,7 +778,7 @@ export class FocusZone extends React.Component implements IFocu case KeyCodes.tab: if ( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated this.props.allowTabKey || this.props.handleTabKey === FocusZoneTabbableElements.all || (this.props.handleTabKey === FocusZoneTabbableElements.inputOnly && @@ -924,7 +924,7 @@ export class FocusZone extends React.Component implements IFocu private _moveFocus( isForward: boolean, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getDistanceFromCenter: (activeRect: ClientRect, targetRect: ClientRect) => number, ev?: Event, useDefaultWrap: boolean = true, @@ -955,7 +955,7 @@ export class FocusZone extends React.Component implements IFocu if (isBidirectional) { if (element) { const targetRect = element.getBoundingClientRect(); - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const elementDistance = getDistanceFromCenter(activeRect as ClientRect, targetRect); if (elementDistance === -1 && candidateDistance === -1) { @@ -1005,11 +1005,11 @@ export class FocusZone extends React.Component implements IFocu private _moveFocusDown(): boolean { let targetTop = -1; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const leftAlignment = this._focusAlignment.left || this._focusAlignment.x || 0; if ( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated this._moveFocus(true, (activeRect: ClientRect, targetRect: ClientRect) => { let distance = -1; // ClientRect values can be floats that differ by very small fractions of a decimal. @@ -1048,11 +1048,11 @@ export class FocusZone extends React.Component implements IFocu private _moveFocusUp(): boolean { let targetTop = -1; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const leftAlignment = this._focusAlignment.left || this._focusAlignment.x || 0; if ( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated this._moveFocus(false, (activeRect: ClientRect, targetRect: ClientRect) => { let distance = -1; // ClientRect values can be floats that differ by very small fractions of a decimal. @@ -1094,7 +1094,7 @@ export class FocusZone extends React.Component implements IFocu if ( this._moveFocus( getRTL(theme), - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated (activeRect: ClientRect, targetRect: ClientRect) => { let distance = -1; let topBottomComparison; @@ -1137,7 +1137,7 @@ export class FocusZone extends React.Component implements IFocu if ( this._moveFocus( !getRTL(theme), - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated (activeRect: ClientRect, targetRect: ClientRect) => { let distance = -1; let topBottomComparison; @@ -1177,12 +1177,12 @@ export class FocusZone extends React.Component implements IFocu private _getHorizontalDistanceFromCenter = ( isForward: boolean, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated activeRect: ClientRect, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated targetRect: ClientRect, ): number => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const leftAlignment = this._focusAlignment.left || this._focusAlignment.x || 0; // ClientRect values can be floats that differ by very small fractions of a decimal. // If the difference between top and bottom are within a pixel then we should treat diff --git a/packages/react-hooks/src/useConstCallback.test.tsx b/packages/react-hooks/src/useConstCallback.test.tsx index 0e7df950273550..aea43bcac40b3e 100644 --- a/packages/react-hooks/src/useConstCallback.test.tsx +++ b/packages/react-hooks/src/useConstCallback.test.tsx @@ -1,4 +1,4 @@ -/* eslint-disable deprecation/deprecation */ +/* eslint-disable @typescript-eslint/no-deprecated */ import * as React from 'react'; import { mount } from 'enzyme'; import { useConstCallback } from './useConstCallback'; diff --git a/packages/react-hooks/src/useMountSync.test.tsx b/packages/react-hooks/src/useMountSync.test.tsx index 8cd46d1b4cff90..08722c994e177a 100644 --- a/packages/react-hooks/src/useMountSync.test.tsx +++ b/packages/react-hooks/src/useMountSync.test.tsx @@ -7,7 +7,7 @@ describe('useMountSync', () => { const onMount = jest.fn(); const TestComponent: React.FunctionComponent = () => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated useMountSync(() => { onMount(); }); diff --git a/packages/react-monaco-editor/CHANGELOG.json b/packages/react-monaco-editor/CHANGELOG.json index a9165e4ed2632c..272c9adba363fd 100644 --- a/packages/react-monaco-editor/CHANGELOG.json +++ b/packages/react-monaco-editor/CHANGELOG.json @@ -1,6 +1,65 @@ { "name": "@fluentui/react-monaco-editor", "entries": [ + { + "date": "Tue, 21 Jan 2025 07:13:51 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.281", + "version": "1.7.281", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.43", + "commit": "08575f8e7d2362e9b986bccee516546f88fe562a" + } + ] + } + }, + { + "date": "Mon, 20 Jan 2025 07:21:45 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.280", + "version": "1.7.280", + "comments": { + "none": [ + { + "author": "vgenaev@gmail.com", + "package": "@fluentui/react-monaco-editor", + "commit": "fd420e1e0b66e04c8a423cff3eea6d21d9434d2d", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule" + } + ], + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.42", + "commit": "556fc8e7b9a921cedbb07c2f0670dfabcf8ec0ed" + } + ] + } + }, + { + "date": "Fri, 17 Jan 2025 07:21:32 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.279", + "version": "1.7.279", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react to v8.122.7", + "commit": "baf887d95f91874c814a7cae749c20e797f828be" + }, + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.41", + "commit": "baf887d95f91874c814a7cae749c20e797f828be" + } + ] + } + }, { "date": "Mon, 13 Jan 2025 07:21:23 GMT", "tag": "@fluentui/react-monaco-editor_v1.7.278", diff --git a/packages/react-monaco-editor/CHANGELOG.md b/packages/react-monaco-editor/CHANGELOG.md index 347343e2e9ed51..3ea218b12d6b2a 100644 --- a/packages/react-monaco-editor/CHANGELOG.md +++ b/packages/react-monaco-editor/CHANGELOG.md @@ -1,9 +1,37 @@ # Change Log - @fluentui/react-monaco-editor -This log was last generated on Mon, 13 Jan 2025 07:21:23 GMT and should not be manually modified. +This log was last generated on Tue, 21 Jan 2025 07:13:51 GMT and should not be manually modified. +## [1.7.281](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.281) + +Tue, 21 Jan 2025 07:13:51 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.280..@fluentui/react-monaco-editor_v1.7.281) + +### Patches + +- Bump @fluentui/react-charting to v5.23.43 ([PR #33695](https://github.com/microsoft/fluentui/pull/33695) by beachball) + +## [1.7.280](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.280) + +Mon, 20 Jan 2025 07:21:45 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.279..@fluentui/react-monaco-editor_v1.7.280) + +### Patches + +- Bump @fluentui/react-charting to v5.23.42 ([PR #33581](https://github.com/microsoft/fluentui/pull/33581) by beachball) + +## [1.7.279](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.279) + +Fri, 17 Jan 2025 07:21:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.278..@fluentui/react-monaco-editor_v1.7.279) + +### Patches + +- Bump @fluentui/react to v8.122.7 ([commit](https://github.com/microsoft/fluentui/commit/baf887d95f91874c814a7cae749c20e797f828be) by beachball) +- Bump @fluentui/react-charting to v5.23.41 ([commit](https://github.com/microsoft/fluentui/commit/baf887d95f91874c814a7cae749c20e797f828be) by beachball) + ## [1.7.278](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.278) Mon, 13 Jan 2025 07:21:23 GMT diff --git a/packages/react-monaco-editor/package.json b/packages/react-monaco-editor/package.json index 661f83943e8eef..f20c04f3ff0a78 100644 --- a/packages/react-monaco-editor/package.json +++ b/packages/react-monaco-editor/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-monaco-editor", - "version": "1.7.278", + "version": "1.7.281", "description": "Live React example editing using monaco", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -29,12 +29,12 @@ "@fluentui/scripts-webpack": "*" }, "dependencies": { - "@fluentui/react": "^8.122.6", + "@fluentui/react": "^8.122.7", "@microsoft/load-themed-styles": "^1.10.26", "@fluentui/example-data": "^8.4.25", "@fluentui/monaco-editor": "^1.3.24", "@fluentui/react-hooks": "^8.8.16", - "@fluentui/react-charting": "^5.23.40", + "@fluentui/react-charting": "^5.23.43", "raw-loader": "4.0.2", "react-syntax-highlighter": "^10.1.3", "tslib": "^2.1.0" diff --git a/packages/react-monaco-editor/src/utilities/getQueryParam.ts b/packages/react-monaco-editor/src/utilities/getQueryParam.ts index 028858691935f5..0837e5ef2833ed 100644 --- a/packages/react-monaco-editor/src/utilities/getQueryParam.ts +++ b/packages/react-monaco-editor/src/utilities/getQueryParam.ts @@ -10,7 +10,7 @@ export function getQueryParam(name: string, url?: string): string | null { url = url || (win ? win.location.href : ''); // Manually get the query string in case it's after the hash (possible with hash routing) const queryIndex = url.indexOf('?'); - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const query = queryIndex !== -1 ? url.substr(queryIndex) : ''; const regex = new RegExp(`[?&]${name}(=([^&#]*)|&|#|$)`); diff --git a/packages/react/CHANGELOG.json b/packages/react/CHANGELOG.json index 88716d9606fe0a..59b59940d8660f 100644 --- a/packages/react/CHANGELOG.json +++ b/packages/react/CHANGELOG.json @@ -1,6 +1,48 @@ { "name": "@fluentui/react", "entries": [ + { + "date": "Mon, 20 Jan 2025 07:21:47 GMT", + "tag": "@fluentui/react_v8.122.7", + "version": "8.122.7", + "comments": { + "none": [ + { + "author": "vgenaev@gmail.com", + "package": "@fluentui/react", + "commit": "fd420e1e0b66e04c8a423cff3eea6d21d9434d2d", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule" + } + ] + } + }, + { + "date": "Fri, 17 Jan 2025 07:21:31 GMT", + "tag": "@fluentui/react_v8.122.7", + "version": "8.122.7", + "comments": { + "patch": [ + { + "author": "kmatejka@microsoft.com", + "package": "@fluentui/react", + "commit": "e9706f78650b2a72e09dca1c5f69f23f4967f33b", + "comment": "fix: Passing rest of ITagItemSuggestionProps to the underlying component." + }, + { + "author": "706967+KevinTCoughlin@users.noreply.github.com", + "package": "@fluentui/react", + "commit": "6e8378b3d1ef9b27ed944b5eae855c59ce348836", + "comment": "Delete border property from ms-PositioningContainer-layerHost containing typo" + }, + { + "author": "kmatejka@microsoft.com", + "package": "@fluentui/react", + "commit": "614e8b594da0eec4104f9fcaa034a4352fee5c74", + "comment": "add missing data-id attribute to close button in TagItem" + } + ] + } + }, { "date": "Mon, 13 Jan 2025 07:21:22 GMT", "tag": "@fluentui/react_v8.122.6", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 7d8b9d600a8490..8e1e2d1642a521 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,9 +1,20 @@ # Change Log - @fluentui/react -This log was last generated on Mon, 13 Jan 2025 07:21:22 GMT and should not be manually modified. +This log was last generated on Fri, 17 Jan 2025 07:21:31 GMT and should not be manually modified. +## [8.122.7](https://github.com/microsoft/fluentui/tree/@fluentui/react_v8.122.7) + +Fri, 17 Jan 2025 07:21:31 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react_v8.122.6..@fluentui/react_v8.122.7) + +### Patches + +- fix: Passing rest of ITagItemSuggestionProps to the underlying component. ([PR #32839](https://github.com/microsoft/fluentui/pull/32839) by kmatejka@microsoft.com) +- Delete border property from ms-PositioningContainer-layerHost containing typo ([PR #32885](https://github.com/microsoft/fluentui/pull/32885) by 706967+KevinTCoughlin@users.noreply.github.com) +- add missing data-id attribute to close button in TagItem ([PR #31956](https://github.com/microsoft/fluentui/pull/31956) by kmatejka@microsoft.com) + ## [8.122.6](https://github.com/microsoft/fluentui/tree/@fluentui/react_v8.122.6) Mon, 13 Jan 2025 07:21:22 GMT diff --git a/packages/react/etc/react.api.md b/packages/react/etc/react.api.md index 9fe14cb8bfbb28..6ad1107c0ee84c 100644 --- a/packages/react/etc/react.api.md +++ b/packages/react/etc/react.api.md @@ -9205,11 +9205,17 @@ export interface ITag { export interface ITagItemProps extends IPickerItemProps { className?: string; enableTagFocusInDisabledPicker?: boolean; + removeButtonProps?: ITagItemRemoveButtonProps; styles?: IStyleFunctionOrObject; theme?: ITheme; title?: string; } +// @public +export interface ITagItemRemoveButtonProps extends IButtonProps { + 'data-id'?: string; +} + // @public export type ITagItemStyleProps = Required> & Pick & {}; diff --git a/packages/react/package.json b/packages/react/package.json index 8a452f08378d43..fe335a033141be 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react", - "version": "8.122.6", + "version": "8.122.7", "description": "Reusable React components for building web experiences.", "main": "lib-commonjs/index.js", "module": "lib/index.js", diff --git a/packages/react/src/Icons.ts b/packages/react/src/Icons.ts index 599092ba2b673d..03d3957842437a 100644 --- a/packages/react/src/Icons.ts +++ b/packages/react/src/Icons.ts @@ -1,6 +1,3 @@ export { initializeIcons } from '@fluentui/font-icons-mdl2'; -export type { - // eslint-disable-next-line deprecation/deprecation - IconNames, -} from '@fluentui/font-icons-mdl2'; +export type { IconNames } from '@fluentui/font-icons-mdl2'; diff --git a/packages/react/src/Styling.ts b/packages/react/src/Styling.ts index 4dd00c1d37dee2..70fd768411455e 100644 --- a/packages/react/src/Styling.ts +++ b/packages/react/src/Styling.ts @@ -7,7 +7,6 @@ export { DefaultEffects, DefaultFontStyles, DefaultPalette, - // eslint-disable-next-line deprecation/deprecation EdgeChromiumHighContrastSelector, FontClassNames, FontSizes, @@ -39,11 +38,9 @@ export { createFontStyles, focusClear, fontFace, - // eslint-disable-next-line deprecation/deprecation getEdgeChromiumNoHighContrastAdjustSelector, getFadedOverflowStyle, getFocusOutlineStyle, - // eslint-disable-next-line deprecation/deprecation getFocusStyle, getGlobalClassNames, getHighContrastNoAdjustStyle, diff --git a/packages/react/src/Utilities.ts b/packages/react/src/Utilities.ts index b01024409bbe23..d7dd63e523e347 100644 --- a/packages/react/src/Utilities.ts +++ b/packages/react/src/Utilities.ts @@ -2,10 +2,8 @@ import './version'; export { Async, AutoScroll, - // eslint-disable-next-line deprecation/deprecation BaseComponent, Customizations, - // eslint-disable-next-line deprecation/deprecation Customizer, CustomizerContext, DATA_IS_SCROLLABLE_ATTRIBUTE, @@ -92,7 +90,6 @@ export { getRTL, getRTLSafeKeyCode, getRect, - // eslint-disable-next-line deprecation/deprecation getResourceUrl, getScrollbarWidth, getVirtualParent, @@ -104,11 +101,9 @@ export { hoistStatics, htmlElementProperties, iframeProperties, - // eslint-disable-next-line deprecation/deprecation imageProperties, imgProperties, initializeComponentRef, - // eslint-disable-next-line deprecation/deprecation initializeFocusRects, inputProperties, isControlled, @@ -142,7 +137,6 @@ export { optionProperties, portalContainsElement, precisionRound, - // eslint-disable-next-line deprecation/deprecation raiseClick, removeDirectionalKeyCode, removeIndex, @@ -153,15 +147,12 @@ export { safeRequestAnimationFrame, safeSetTimeout, selectProperties, - // eslint-disable-next-line deprecation/deprecation setBaseUrl, setFocusVisibility, - // eslint-disable-next-line deprecation/deprecation setLanguage, setMemoizeWeakMap, setPortalAttribute, setRTL, - // eslint-disable-next-line deprecation/deprecation setSSR, setVirtualParent, setWarningCallback, @@ -203,7 +194,6 @@ export type { ICancelable, IChangeDescription, IChangeEventCallback, - // eslint-disable-next-line deprecation/deprecation IClassNames, IClassNamesFunctionOptions, IComponentAs, @@ -227,7 +217,6 @@ export type { IPerfData, IPerfMeasurement, IPerfSummary, - // eslint-disable-next-line deprecation/deprecation IPoint, IPropsWithStyles, IReactProps, @@ -247,13 +236,10 @@ export type { IStyleFunctionOrObject, IVirtualElement, IWarnControlledUsageParams, - // eslint-disable-next-line deprecation/deprecation Omit, Point, RefObject, - // eslint-disable-next-line deprecation/deprecation Settings, - // eslint-disable-next-line deprecation/deprecation SettingsFunction, ShadowConfigHook, StyleFunction, diff --git a/packages/react/src/components/ActivityItem/ActivityItem.tsx b/packages/react/src/components/ActivityItem/ActivityItem.tsx index be14dc32000938..09bffc407073da 100644 --- a/packages/react/src/components/ActivityItem/ActivityItem.tsx +++ b/packages/react/src/components/ActivityItem/ActivityItem.tsx @@ -57,7 +57,7 @@ export class ActivityItem extends React.Component { private _onRenderActivityDescription = (props: IActivityItemProps): JSX.Element | null => { const classNames = this._getClassNames(props); - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const activityDescription = props.activityDescription || props.activityDescriptionText; if (activityDescription) { @@ -70,7 +70,7 @@ export class ActivityItem extends React.Component { private _onRenderComments = (props: IActivityItemProps): JSX.Element | null => { const classNames = this._getClassNames(props); - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const comments = props.comments || props.commentText; if (!props.isCompact && comments) { @@ -117,7 +117,7 @@ export class ActivityItem extends React.Component { {...person} key={person.key || index} className={classNames.activityPersona} - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated size={showSize16Personas ? PersonaSize.size16 : PersonaSize.size32} style={style} />, diff --git a/packages/react/src/components/Autofill/Autofill.tsx b/packages/react/src/components/Autofill/Autofill.tsx index 5b5ebb4a3635fd..903d5625301414 100644 --- a/packages/react/src/components/Autofill/Autofill.tsx +++ b/packages/react/src/components/Autofill/Autofill.tsx @@ -40,9 +40,9 @@ export class Autofill extends React.Component im private _async: Async; public static getDerivedStateFromProps(props: IAutofillProps, state: IAutofillState): IAutofillState | null { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (props.updateValueInWillReceiveProps) { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const updatedInputValue = props.updateValueInWillReceiveProps(); // Don't update if we have a null value or the value isn't changing // the value should still update if an empty string is passed in @@ -247,7 +247,7 @@ export class Autofill extends React.Component im // Right now typing does not have isComposing, once that has been fixed any should be removed. if (!(ev.nativeEvent as any).isComposing) { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated switch (ev.which) { case KeyCodes.backspace: this._autoFillEnabled = false; @@ -263,7 +263,7 @@ export class Autofill extends React.Component im break; default: if (!this._autoFillEnabled) { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (this.props.enableAutofillOnKeyPress!.indexOf(ev.which) !== -1) { this._autoFillEnabled = true; } @@ -339,7 +339,7 @@ export class Autofill extends React.Component im return; } - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { onInputChange, onInputValueChange } = this.props; if (onInputChange) { newValue = onInputChange?.(newValue, composing) || ''; diff --git a/packages/react/src/components/Button/BaseButton.tsx b/packages/react/src/components/Button/BaseButton.tsx index 94d0917462d5d7..478609d9822197 100644 --- a/packages/react/src/components/Button/BaseButton.tsx +++ b/packages/react/src/components/Button/BaseButton.tsx @@ -127,7 +127,7 @@ export class BaseButton extends React.Component { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { secondaryText = this.props.description } = props; // ms-Button-description is only shown when the button type is compound. @@ -741,7 +741,7 @@ export class BaseButton extends React.Component) => { // explicity cancelling event so click won't fire after this - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (this.props.disabled && (ev.which === KeyCodes.enter || ev.which === KeyCodes.space)) { ev.preventDefault(); ev.stopPropagation(); @@ -765,9 +765,9 @@ export class BaseButton extends React.Component, ) => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (!this.props.disabled && this.props.onKeyPress !== undefined) { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated this.props.onKeyPress(ev); // not cancelling event because it's not disabled } }; @@ -801,7 +801,7 @@ export class BaseButton extends React.Component) => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.which === KeyCodes.enter || ev.which === KeyCodes.space) { if (this._buttonElement.current) { this._buttonElement.current.click(); @@ -822,9 +822,9 @@ export class BaseButton extends React.Component, ): boolean { if (this.props.menuTriggerKeyCode) { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated return ev.which === this.props.menuTriggerKeyCode; } else if (this.props.menuProps) { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated return ev.which === KeyCodes.down && (ev.altKey || ev.metaKey); } diff --git a/packages/react/src/components/Button/Button.tsx b/packages/react/src/components/Button/Button.tsx index 0d5d40b7e22f46..1116ee9954380a 100644 --- a/packages/react/src/components/Button/Button.tsx +++ b/packages/react/src/components/Button/Button.tsx @@ -27,7 +27,7 @@ export class Button extends React.Component { public render(): JSX.Element { const props = this.props; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated switch (props.buttonType) { case ButtonType.command: return ; diff --git a/packages/react/src/components/Button/Button.types.ts b/packages/react/src/components/Button/Button.types.ts index 99831ea88ca2ac..98c852b824789d 100644 --- a/packages/react/src/components/Button/Button.types.ts +++ b/packages/react/src/components/Button/Button.types.ts @@ -42,12 +42,12 @@ export interface IButton { /** * {@docCategory Button} */ -/* eslint-disable deprecation/deprecation */ +/* eslint-disable @typescript-eslint/no-deprecated */ export interface IButtonProps extends React.AllHTMLAttributes< HTMLAnchorElement | HTMLButtonElement | HTMLDivElement | BaseButton | Button | HTMLSpanElement > { - /* eslint-enable deprecation/deprecation */ + /* eslint-enable @typescript-eslint/no-deprecated */ /** * Optional callback to access the `IButton` interface. Use this instead of `ref` for accessing * the public methods and properties of the component. diff --git a/packages/react/src/components/Calendar/Calendar.base.tsx b/packages/react/src/components/Calendar/Calendar.base.tsx index 7063088c48fe72..8fbb84984bd1be 100644 --- a/packages/react/src/components/Calendar/Calendar.base.tsx +++ b/packages/react/src/components/Calendar/Calendar.base.tsx @@ -228,7 +228,7 @@ export const CalendarBase: React.FunctionComponent = React.forwa const onButtonKeyDown = (callback: () => void): ((ev: React.KeyboardEvent) => void) => { return (ev: React.KeyboardEvent) => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated switch (ev.which) { case KeyCodes.enter: case KeyCodes.space: @@ -239,7 +239,7 @@ export const CalendarBase: React.FunctionComponent = React.forwa }; const onDatePickerPopupKeyDown = (ev: React.KeyboardEvent): void => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated switch (ev.which) { case KeyCodes.enter: ev.preventDefault(); diff --git a/packages/react/src/components/Calendar/CalendarDay/CalendarDay.base.tsx b/packages/react/src/components/Calendar/CalendarDay/CalendarDay.base.tsx index 6d3d8d20887dc5..617a9c1e5d0f02 100644 --- a/packages/react/src/components/Calendar/CalendarDay/CalendarDay.base.tsx +++ b/packages/react/src/components/Calendar/CalendarDay/CalendarDay.base.tsx @@ -184,7 +184,7 @@ CalendarDayNavigationButtons.displayName = 'CalendarDayNavigationButtons'; const onButtonKeyDown = (callback?: () => void): ((ev: React.KeyboardEvent) => void) => (ev: React.KeyboardEvent) => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated switch (ev.which) { case KeyCodes.enter: callback?.(); diff --git a/packages/react/src/components/Calendar/CalendarMonth/CalendarMonth.base.tsx b/packages/react/src/components/Calendar/CalendarMonth/CalendarMonth.base.tsx index beec6b01e027cc..c4ba11411400fb 100644 --- a/packages/react/src/components/Calendar/CalendarMonth/CalendarMonth.base.tsx +++ b/packages/react/src/components/Calendar/CalendarMonth/CalendarMonth.base.tsx @@ -347,7 +347,7 @@ function isCurrentMonth(month: number, year: number, today: Date): boolean { function onButtonKeyDown(callback: () => void): (ev: React.KeyboardEvent) => void { return (ev: React.KeyboardEvent) => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated switch (ev.which) { case KeyCodes.enter: callback(); diff --git a/packages/react/src/components/Calendar/CalendarYear/CalendarYear.base.tsx b/packages/react/src/components/Calendar/CalendarYear/CalendarYear.base.tsx index f571407ed56c62..fc919642228fb7 100644 --- a/packages/react/src/components/Calendar/CalendarYear/CalendarYear.base.tsx +++ b/packages/react/src/components/Calendar/CalendarYear/CalendarYear.base.tsx @@ -78,7 +78,7 @@ const CalendarYearGridCell: React.FunctionComponent }; const onKeyDown = (ev: React.KeyboardEvent) => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.which === KeyCodes.enter) { onSelectYear?.(year); } @@ -246,7 +246,7 @@ const CalendarYearNavArrow: React.FunctionComponent }; const onKeyDown = (ev: React.KeyboardEvent) => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.which === KeyCodes.enter) { onNavigate(); } @@ -308,7 +308,7 @@ const CalendarYearTitle: React.FunctionComponent = pro }; const onHeaderKeyDown = (ev: React.KeyboardEvent) => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.which === KeyCodes.enter || ev.which === KeyCodes.space) { onHeaderSelect(); } diff --git a/packages/react/src/components/CalendarDayGrid/CalendarGridDayCell.tsx b/packages/react/src/components/CalendarDayGrid/CalendarGridDayCell.tsx index 34ba32188bf104..2cc7ec9f334f50 100644 --- a/packages/react/src/components/CalendarDayGrid/CalendarGridDayCell.tsx +++ b/packages/react/src/components/CalendarDayGrid/CalendarGridDayCell.tsx @@ -44,18 +44,18 @@ export const CalendarGridDayCell: React.FunctionComponent): void => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.which === KeyCodes.enter) { onSelectDate?.(day.originalDate); } else { diff --git a/packages/react/src/components/Callout/CalloutContent.base.tsx b/packages/react/src/components/Callout/CalloutContent.base.tsx index 9355bc972c5159..89550932965a2f 100644 --- a/packages/react/src/components/Callout/CalloutContent.base.tsx +++ b/packages/react/src/components/Callout/CalloutContent.base.tsx @@ -492,7 +492,7 @@ export const CalloutContentBase: React.FunctionComponent = React. backgroundColor, calloutMaxHeight, onScroll, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated shouldRestoreFocus = true, target, hidden, diff --git a/packages/react/src/components/Check/Check.styles.ts b/packages/react/src/components/Check/Check.styles.ts index c721df0c45a9f5..96f5e3ffea913d 100644 --- a/packages/react/src/components/Check/Check.styles.ts +++ b/packages/react/src/components/Check/Check.styles.ts @@ -12,7 +12,7 @@ export const CheckGlobalClassNames = { }; export const getStyles = (props: ICheckStyleProps): ICheckStyles => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { height = props.checkBoxHeight || '18px', checked, className, theme } = props; const { palette, semanticColors, fonts } = theme; diff --git a/packages/react/src/components/Coachmark/Coachmark.base.tsx b/packages/react/src/components/Coachmark/Coachmark.base.tsx index b9baad61890973..a6b2a25b62c6e1 100644 --- a/packages/react/src/components/Coachmark/Coachmark.base.tsx +++ b/packages/react/src/components/Coachmark/Coachmark.base.tsx @@ -215,9 +215,9 @@ function useListeners( (e: KeyboardEvent) => { // Open coachmark if user presses ALT + C (arbitrary keypress for now) if ( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated (e.altKey && e.which === KeyCodes.c) || - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated (e.which === KeyCodes.enter && translateAnimationContainer.current?.contains?.(e.target as Node)) ) { openCoachmark(); @@ -582,7 +582,7 @@ function getBounds( } function isInsideElement( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated targetElementRect: ClientRect, mouseX: number, mouseY: number, diff --git a/packages/react/src/components/Coachmark/PositioningContainer/PositioningContainer.styles.ts b/packages/react/src/components/Coachmark/PositioningContainer/PositioningContainer.styles.ts index 9a937fa4728542..0b6c0b04ae5038 100644 --- a/packages/react/src/components/Coachmark/PositioningContainer/PositioningContainer.styles.ts +++ b/packages/react/src/components/Coachmark/PositioningContainer/PositioningContainer.styles.ts @@ -27,7 +27,6 @@ export const getClassNames = memoizeFunction((): IPositioningContainerNames => { { position: 'absolute', boxSizing: 'border-box', - border: '1px solid ${}', selectors: { [HighContrastSelector]: { border: '1px solid WindowText', diff --git a/packages/react/src/components/Coachmark/__snapshots__/Coachmark.test.tsx.snap b/packages/react/src/components/Coachmark/__snapshots__/Coachmark.test.tsx.snap index 35d2abd3f2213f..88104bf8a4a12f 100644 --- a/packages/react/src/components/Coachmark/__snapshots__/Coachmark.test.tsx.snap +++ b/packages/react/src/components/Coachmark/__snapshots__/Coachmark.test.tsx.snap @@ -39,7 +39,6 @@ exports[`Coachmark renders Coachmark (color properties) 1`] = ` class= ms-PositioningContainer-layerHost { - border: 1px solid \${}; box-sizing: border-box; outline: transparent; position: absolute; @@ -275,7 +274,6 @@ exports[`Coachmark renders Coachmark (correctly) 1`] = ` class= ms-PositioningContainer-layerHost { - border: 1px solid \${}; box-sizing: border-box; outline: transparent; position: absolute; @@ -513,7 +511,6 @@ exports[`Coachmark renders Coachmark (isCollapsed) 1`] = ` class= ms-PositioningContainer-layerHost { - border: 1px solid \${}; box-sizing: border-box; outline: transparent; position: absolute; diff --git a/packages/react/src/components/ColorPicker/ColorPicker.base.tsx b/packages/react/src/components/ColorPicker/ColorPicker.base.tsx index 689124806e30dc..fbcff3c608998d 100644 --- a/packages/react/src/components/ColorPicker/ColorPicker.base.tsx +++ b/packages/react/src/components/ColorPicker/ColorPicker.base.tsx @@ -120,7 +120,7 @@ export class ColorPickerBase extends React.Component; this._textLabels = { - /* eslint-disable deprecation/deprecation */ + /* eslint-disable @typescript-eslint/no-deprecated */ r: props.redLabel || strings.red || defaultStrings.red, g: props.greenLabel || strings.green || defaultStrings.green, b: props.blueLabel || strings.blue || defaultStrings.blue, a: props.alphaLabel || strings.alpha || defaultStrings.alpha, hex: props.hexLabel || strings.hex || defaultStrings.hex, t: strings.transparency || defaultStrings.transparency, - /* eslint-enable deprecation/deprecation */ + /* eslint-enable @typescript-eslint/no-deprecated */ }; this._strings = { @@ -180,7 +180,7 @@ export class ColorPickerBase extends React.Component { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { theme, className, type = 'hue', isAlpha: useAlphaBackground = type !== 'hue' } = props; const { palette, effects } = theme; diff --git a/packages/react/src/components/ComboBox/ComboBox.tsx b/packages/react/src/components/ComboBox/ComboBox.tsx index e342c4b6798a35..9b6823d72a6d7d 100644 --- a/packages/react/src/components/ComboBox/ComboBox.tsx +++ b/packages/react/src/components/ComboBox/ComboBox.tsx @@ -1233,7 +1233,7 @@ class ComboBoxInternal extends React.Component): void => { const doc = getDocumentEx(this.context); // Do nothing if the blur is coming from something @@ -2108,7 +2108,7 @@ class ComboBoxInternal extends React.Component= 112 /* F1 */ && ev.which <= 123 /* F12 */) { return; } // If we get here and we got either and ALT key // or meta key, let the event propagate - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.keyCode === KeyCodes.alt || ev.key === 'Meta' /* && isOpen */) { return; } - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (allowParentArrowNavigation && (ev.keyCode === KeyCodes.left || ev.keyCode === KeyCodes.right)) { return; } @@ -2306,7 +2306,7 @@ class ComboBoxInternal extends React.Component 123) /* F12 */ ) { ev.stopPropagation(); @@ -2618,6 +2618,6 @@ function getPreviewText(item: IComboBoxOption): string { * Returns true if the key for the event is alt (Mac option) or meta (Mac command). */ function isAltOrMeta(ev: React.KeyboardEvent): boolean { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated return ev.which === KeyCodes.alt || ev.key === 'Meta'; } diff --git a/packages/react/src/components/CommandBar/CommandBar.base.tsx b/packages/react/src/components/CommandBar/CommandBar.base.tsx index eaee893cf0d677..42b273d37e153b 100644 --- a/packages/react/src/components/CommandBar/CommandBar.base.tsx +++ b/packages/react/src/components/CommandBar/CommandBar.base.tsx @@ -166,7 +166,7 @@ export class CommandBarBase extends React.Component implem return item.onRender(item, () => undefined); } - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const itemText = item.text || item.name; const commandButtonProps: ICommandBarItemProps = { allowDisabledFocus: true, @@ -213,7 +213,7 @@ export class CommandBarBase extends React.Component implem private _onButtonClick(item: ICommandBarItemProps): (ev: React.MouseEvent) => void { return ev => { // inactive is deprecated. remove check in 7.0 - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (item.inactive) { return; } diff --git a/packages/react/src/components/ContextualMenu/ContextualMenu.base.tsx b/packages/react/src/components/ContextualMenu/ContextualMenu.base.tsx index c457e42be1a7fd..d29bbe64054d87 100644 --- a/packages/react/src/components/ContextualMenu/ContextualMenu.base.tsx +++ b/packages/react/src/components/ContextualMenu/ContextualMenu.base.tsx @@ -98,7 +98,7 @@ export function getSubmenuItems( ): IContextualMenuItem[] | undefined { const target = options?.target; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const items = item.subMenuProps ? item.subMenuProps.items : item.items; if (items) { @@ -356,7 +356,7 @@ function useKeyHandlers( const shouldCloseSubMenu = (ev: React.KeyboardEvent): boolean => { const submenuCloseKey = getRTL(theme) ? KeyCodes.right : KeyCodes.left; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.which !== submenuCloseKey || !isSubMenu) { return false; } @@ -369,10 +369,10 @@ function useKeyHandlers( const shouldHandleKeyDown = (ev: React.KeyboardEvent) => { return ( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated ev.which === KeyCodes.escape || shouldCloseSubMenu(ev) || - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated (ev.which === KeyCodes.up && (ev.altKey || ev.metaKey)) ); }; @@ -383,7 +383,7 @@ function useKeyHandlers( lastKeyDownWasAltOrMeta.current = isAltOrMeta(ev); // On Mac, pressing escape dismisses all levels of native context menus - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const dismissAllMenus = ev.which === KeyCodes.escape && (isMac() || isIOS()); return keyHandler(ev, shouldHandleKeyDown, dismissAllMenus); @@ -421,9 +421,9 @@ function useKeyHandlers( // If we have a modifier key being pressed, we do not want to move focus. // Otherwise, handle up and down keys. const hasModifier = !!(ev.altKey || ev.metaKey); - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const isUp = ev.which === KeyCodes.up; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const isDown = ev.which === KeyCodes.down; if (!hasModifier && (isUp || isDown)) { const elementToFocus = isUp @@ -443,7 +443,7 @@ function useKeyHandlers( if ( !item.disabled && - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated (ev.which === openKey || ev.which === KeyCodes.enter || (ev.which === KeyCodes.down && (ev.altKey || ev.metaKey))) ) { openSubMenu(item, ev.currentTarget as HTMLElement); @@ -780,7 +780,7 @@ export const ContextualMenuBase: React.FunctionComponent = const onDefaultRenderMenuList = ( menuListProps: IContextualMenuListProps, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated menuClassNames: IProcessedStyleSet | IContextualMenuClassNames, defaultRender?: IRenderFunction, ): JSX.Element => { @@ -825,13 +825,13 @@ export const ContextualMenuBase: React.FunctionComponent = totalItemCount: number, hasCheckmarks: boolean, hasIcons: boolean, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated menuClassNames: IProcessedStyleSet | IContextualMenuClassNames, ): JSX.Element => { const renderedItems: React.ReactNode[] = []; const iconProps = item.iconProps || { iconName: 'None' }; const { - getItemClassNames, // eslint-disable-line deprecation/deprecation + getItemClassNames, // eslint-disable-line @typescript-eslint/no-deprecated itemProps, } = item; const styles = itemProps ? itemProps.styles : undefined; @@ -841,7 +841,7 @@ export const ContextualMenuBase: React.FunctionComponent = const dividerClassName = item.itemType === ContextualMenuItemType.Divider ? item.className : undefined; const subMenuIconClassName = item.submenuIconProps ? item.submenuIconProps.className : ''; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated let itemClassNames: IMenuItemClassNames; // IContextualMenuItem#getItemClassNames for backwards compatibility @@ -883,7 +883,7 @@ export const ContextualMenuBase: React.FunctionComponent = ); } - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (item.text === '-' || item.name === '-') { item.itemType = ContextualMenuItemType.Divider; } @@ -925,7 +925,7 @@ export const ContextualMenuBase: React.FunctionComponent = const defaultMenuItemRenderer = ( item: IContextualMenuItemRenderProps, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated menuClassNames: IProcessedStyleSet | IContextualMenuClassNames, ): React.ReactNode => { const { index, focusableElementIndex, totalItemCount, hasCheckmarks, hasIcons } = item; @@ -942,9 +942,9 @@ export const ContextualMenuBase: React.FunctionComponent = const renderSectionItem = ( sectionItem: IContextualMenuItem, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated itemClassNames: IMenuItemClassNames, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated menuClassNames: IProcessedStyleSet | IContextualMenuClassNames, index: number, hasCheckmarks: boolean, @@ -1033,7 +1033,7 @@ export const ContextualMenuBase: React.FunctionComponent = const renderListItem = ( content: React.ReactNode, key: string | number, - classNames: IMenuItemClassNames, // eslint-disable-line deprecation/deprecation + classNames: IMenuItemClassNames, // eslint-disable-line @typescript-eslint/no-deprecated title?: string, ) => { return ( @@ -1045,7 +1045,7 @@ export const ContextualMenuBase: React.FunctionComponent = const renderSeparator = ( index: number, - classNames: IMenuItemClassNames, // eslint-disable-line deprecation/deprecation + classNames: IMenuItemClassNames, // eslint-disable-line @typescript-eslint/no-deprecated top?: boolean, fromSection?: boolean, ): React.ReactNode => { @@ -1064,7 +1064,7 @@ export const ContextualMenuBase: React.FunctionComponent = const renderNormalItem = ( item: IContextualMenuItem, - classNames: IMenuItemClassNames, // eslint-disable-line deprecation/deprecation + classNames: IMenuItemClassNames, // eslint-disable-line @typescript-eslint/no-deprecated index: number, focusableElementIndex: number, totalItemCount: number, @@ -1142,9 +1142,9 @@ export const ContextualMenuBase: React.FunctionComponent = const renderHeaderMenuItem = ( item: IContextualMenuItem, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated itemClassNames: IMenuItemClassNames, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated menuClassNames: IProcessedStyleSet | IContextualMenuClassNames, index: number, hasCheckmarks: boolean, @@ -1164,7 +1164,7 @@ export const ContextualMenuBase: React.FunctionComponent = const divHtmlProperties = itemProps && getNativeProps>(itemProps, divProperties); return ( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated
= defaultRender?: IRenderFunction, ) => onDefaultRenderMenuList(menuListProps, classNames, defaultRender), focusZoneProps, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getMenuClassNames, } = props; @@ -1374,7 +1374,7 @@ ContextualMenuBase.displayName = 'ContextualMenuBase'; * Returns true if the key for the event is alt (Mac option) or meta (Mac command). */ function isAltOrMeta(ev: React.KeyboardEvent): boolean { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated return ev.which === KeyCodes.alt || ev.key === 'Meta'; } diff --git a/packages/react/src/components/ContextualMenu/ContextualMenu.classNames.ts b/packages/react/src/components/ContextualMenu/ContextualMenu.classNames.ts index 5f7fc8247bebe6..8e06f9b6710854 100644 --- a/packages/react/src/components/ContextualMenu/ContextualMenu.classNames.ts +++ b/packages/react/src/components/ContextualMenu/ContextualMenu.classNames.ts @@ -50,10 +50,10 @@ const CONTEXTUAL_SPLIT_MENU_MINWIDTH = '28px'; const MediumScreenSelector = getScreenSelector(0, ScreenWidthMaxMedium); export const getSplitButtonVerticalDividerClassNames = memoizeFunction( - /* eslint-disable deprecation/deprecation */ + /* eslint-disable @typescript-eslint/no-deprecated */ (theme: ITheme): IVerticalDividerClassNames => { return mergeStyleSets(getDividerClassNames(theme), { - /* eslint-enable deprecation/deprecation */ + /* eslint-enable @typescript-eslint/no-deprecated */ wrapper: { position: 'absolute', right: 28, // width of the splitMenu based on the padding plus icon fontSize @@ -267,7 +267,7 @@ export const getItemStyles = (props: IContextualMenuItemStyleProps): IContextual className, } = props; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated return getItemClassNames( theme, disabled, diff --git a/packages/react/src/components/ContextualMenu/ContextualMenu.types.ts b/packages/react/src/components/ContextualMenu/ContextualMenu.types.ts index d4daf4a6ff9ea3..90d202fb5d2ac1 100644 --- a/packages/react/src/components/ContextualMenu/ContextualMenu.types.ts +++ b/packages/react/src/components/ContextualMenu/ContextualMenu.types.ts @@ -50,7 +50,7 @@ export interface IContextualMenu {} export interface IContextualMenuProps extends IBaseProps, React.RefAttributes, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated IWithResponsiveModeState { /** * Optional callback to access the IContextualMenu interface. Use this instead of ref for accessing @@ -232,7 +232,7 @@ export interface IContextualMenuProps * Method to provide the classnames to style the contextual menu. * @deprecated Use `styles` instead to leverage mergeStyles API. */ - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getMenuClassNames?: (theme: ITheme, className?: string) => IContextualMenuClassNames; /** Custom render function for a submenu. */ @@ -466,7 +466,7 @@ export interface IContextualMenuItem { iconClassName?: string, subMenuClassName?: string, primaryDisabled?: boolean, - ) => // eslint-disable-next-line deprecation/deprecation + ) => // eslint-disable-next-line @typescript-eslint/no-deprecated IMenuItemClassNames; /** @@ -479,7 +479,7 @@ export interface IContextualMenuItem { * Default value is the `getSplitButtonVerticalDividerClassNames` func defined in `ContextualMenu.classnames.ts`. * @defaultvalue getSplitButtonVerticalDividerClassNames */ - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSplitButtonVerticalDividerClassNames?: (theme: ITheme) => IVerticalDividerClassNames; /** diff --git a/packages/react/src/components/ContextualMenu/ContextualMenuItem.base.tsx b/packages/react/src/components/ContextualMenu/ContextualMenuItem.base.tsx index bc1d1e70003d46..12512ae28e9f99 100644 --- a/packages/react/src/components/ContextualMenu/ContextualMenuItem.base.tsx +++ b/packages/react/src/components/ContextualMenu/ContextualMenuItem.base.tsx @@ -42,11 +42,11 @@ const renderCheckMarkIcon = ({ onCheckmarkClick, item, classNames }: IContextual }; const renderItemName = ({ item, classNames }: IContextualMenuItemProps) => { - /* eslint-disable deprecation/deprecation */ + /* eslint-disable @typescript-eslint/no-deprecated */ if (item.text || item.name) { return {item.text || item.name}; } - /* eslint-enable deprecation/deprecation */ + /* eslint-enable @typescript-eslint/no-deprecated */ return null; }; diff --git a/packages/react/src/components/ContextualMenu/ContextualMenuItem.test.tsx b/packages/react/src/components/ContextualMenu/ContextualMenuItem.test.tsx index 96e327c93c5314..ae509c0a94decc 100644 --- a/packages/react/src/components/ContextualMenu/ContextualMenuItem.test.tsx +++ b/packages/react/src/components/ContextualMenu/ContextualMenuItem.test.tsx @@ -12,7 +12,7 @@ describe('ContextMenuItemChildren', () => { describe('when a checkmark icon', () => { let onCheckmarkClick: jest.Mock; let menuItem: IContextualMenuItem; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated let menuClassNames: IMenuItemClassNames; let wrapper: ShallowWrapper; @@ -52,7 +52,7 @@ describe('ContextMenuItemChildren', () => { describe('when hide checkmark icon for toggle command', () => { let onCheckmarkClick: jest.Mock; let menuItem: IContextualMenuItem; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated let menuClassNames: IMenuItemClassNames; let wrapper: ShallowWrapper; @@ -96,7 +96,7 @@ describe('ContextMenuItemChildren', () => { describe('when it has icons', () => { describe('when it has iconProps', () => { let menuItem: IContextualMenuItem; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated let menuClassNames: IMenuItemClassNames; let wrapper: ShallowWrapper; @@ -116,7 +116,7 @@ describe('ContextMenuItemChildren', () => { describe('when it doesnt have iconProps', () => { let menuItem: IContextualMenuItem; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated let menuClassNames: IMenuItemClassNames; let wrapper: ShallowWrapper; @@ -137,7 +137,7 @@ describe('ContextMenuItemChildren', () => { describe('when it has a sub menu', () => { let menuItem: IContextualMenuItem; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated let menuClassNames: IMenuItemClassNames; let wrapper: ShallowWrapper; @@ -157,7 +157,7 @@ describe('ContextMenuItemChildren', () => { }); }); -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated function getMenuItemClassNames(): IMenuItemClassNames { return { item: 'item', diff --git a/packages/react/src/components/ContextualMenu/ContextualMenuItem.types.ts b/packages/react/src/components/ContextualMenu/ContextualMenuItem.types.ts index 7a282139185ef2..87717484ba4bdb 100644 --- a/packages/react/src/components/ContextualMenu/ContextualMenuItem.types.ts +++ b/packages/react/src/components/ContextualMenu/ContextualMenuItem.types.ts @@ -59,7 +59,7 @@ export interface IContextualMenuItemProps extends React.HTMLAttributes { describe('creates a normal button', () => { let menuItem: IContextualMenuItem; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated let menuClassNames: IMenuItemClassNames; beforeEach(() => { @@ -77,7 +77,7 @@ describe('ContextualMenuButton', () => { }); }); -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated function getMenuItemClassNames(): IMenuItemClassNames { return { item: 'item', diff --git a/packages/react/src/components/ContextualMenu/ContextualMenuItemWrapper/ContextualMenuAnchor.tsx b/packages/react/src/components/ContextualMenu/ContextualMenuItemWrapper/ContextualMenuAnchor.tsx index 1332938bf43c39..0229de4526a7ba 100644 --- a/packages/react/src/components/ContextualMenu/ContextualMenuItemWrapper/ContextualMenuAnchor.tsx +++ b/packages/react/src/components/ContextualMenu/ContextualMenuItemWrapper/ContextualMenuAnchor.tsx @@ -102,7 +102,7 @@ export class ContextualMenuAnchor extends ContextualMenuItemWrapper { aria-posinset={focusableElementIndex + 1} aria-setsize={totalItemCount} aria-disabled={isItemDisabled(item)} - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated style={item.style} onClick={this._onItemClick} onMouseEnter={this._onItemMouseEnter} diff --git a/packages/react/src/components/ContextualMenu/ContextualMenuItemWrapper/ContextualMenuButton.test.tsx b/packages/react/src/components/ContextualMenu/ContextualMenuItemWrapper/ContextualMenuButton.test.tsx index 0d7dd4aa6a0ec9..d7af3d0b3944ea 100644 --- a/packages/react/src/components/ContextualMenu/ContextualMenuItemWrapper/ContextualMenuButton.test.tsx +++ b/packages/react/src/components/ContextualMenu/ContextualMenuItemWrapper/ContextualMenuButton.test.tsx @@ -8,7 +8,7 @@ import type { IMenuItemClassNames } from '../ContextualMenu.classNames'; describe('ContextualMenuButton', () => { describe('creates a normal button', () => { let menuItem: IContextualMenuItem; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated let menuClassNames: IMenuItemClassNames; beforeEach(() => { @@ -108,7 +108,7 @@ describe('ContextualMenuButton', () => { }); }); -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated function getMenuItemClassNames(): IMenuItemClassNames { return { item: 'item', diff --git a/packages/react/src/components/ContextualMenu/ContextualMenuItemWrapper/ContextualMenuButton.tsx b/packages/react/src/components/ContextualMenu/ContextualMenuItemWrapper/ContextualMenuButton.tsx index 2e0110c0294b9c..deb0f288f57adb 100644 --- a/packages/react/src/components/ContextualMenu/ContextualMenuItemWrapper/ContextualMenuButton.tsx +++ b/packages/react/src/components/ContextualMenu/ContextualMenuItemWrapper/ContextualMenuButton.tsx @@ -103,7 +103,7 @@ export class ContextualMenuButton extends ContextualMenuItemWrapper { (itemRole === 'menuitemcheckbox' || itemRole === 'menuitemradio') && canCheck ? !!isChecked : undefined, 'aria-selected': itemRole === 'menuitem' && canCheck ? !!isChecked : undefined, role: itemRole, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated style: item.style, }; diff --git a/packages/react/src/components/ContextualMenu/ContextualMenuItemWrapper/ContextualMenuItemWrapper.types.ts b/packages/react/src/components/ContextualMenu/ContextualMenuItemWrapper/ContextualMenuItemWrapper.types.ts index ded2c689bd511f..4f396f47e4c98c 100644 --- a/packages/react/src/components/ContextualMenu/ContextualMenuItemWrapper/ContextualMenuItemWrapper.types.ts +++ b/packages/react/src/components/ContextualMenu/ContextualMenuItemWrapper/ContextualMenuItemWrapper.types.ts @@ -19,7 +19,7 @@ export interface IContextualMenuItemWrapperProps extends React.ClassAttributes { describe('creates a normal split button', () => { let menuItem: IContextualMenuItem; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated let menuClassNames: IMenuItemClassNames; beforeEach(() => { @@ -53,7 +53,7 @@ describe('ContextualMenuSplitButton', () => { }); }); -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated function getMenuItemClassNames(): IMenuItemClassNames { return { item: 'item', diff --git a/packages/react/src/components/ContextualMenu/ContextualMenuItemWrapper/ContextualMenuSplitButton.tsx b/packages/react/src/components/ContextualMenu/ContextualMenuItemWrapper/ContextualMenuSplitButton.tsx index cc31624a6acadb..451765bcf0b6cf 100644 --- a/packages/react/src/components/ContextualMenu/ContextualMenuItemWrapper/ContextualMenuSplitButton.tsx +++ b/packages/react/src/components/ContextualMenu/ContextualMenuItemWrapper/ContextualMenuSplitButton.tsx @@ -136,7 +136,7 @@ export class ContextualMenuSplitButton extends ContextualMenuItemWrapper { protected _onItemKeyDown = (ev: React.KeyboardEvent): void => { const { item, onItemKeyDown } = this.props; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.which === KeyCodes.enter) { this._executeItemClick(ev); ev.preventDefault(); @@ -161,7 +161,7 @@ export class ContextualMenuSplitButton extends ContextualMenuItemWrapper { private _renderSplitPrimaryButton( item: IContextualMenuItem, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated classNames: IMenuItemClassNames, index: number, hasCheckmarks: boolean, @@ -172,11 +172,11 @@ export class ContextualMenuSplitButton extends ContextualMenuItemWrapper { const itemProps: IContextualMenuItem = { key: item.key, disabled: isItemDisabled(item) || item.primaryDisabled, - /* eslint-disable deprecation/deprecation */ + /* eslint-disable @typescript-eslint/no-deprecated */ name: item.name, text: item.text || item.name, secondaryText: item.secondaryText, - /* eslint-enable deprecation/deprecation */ + /* eslint-enable @typescript-eslint/no-deprecated */ className: classNames.splitPrimary, canCheck: item.canCheck, isChecked: item.isChecked, @@ -214,7 +214,7 @@ export class ContextualMenuSplitButton extends ContextualMenuItemWrapper { private _renderSplitIconButton( item: IContextualMenuItem, - classNames: IMenuItemClassNames, // eslint-disable-line deprecation/deprecation + classNames: IMenuItemClassNames, // eslint-disable-line @typescript-eslint/no-deprecated index: number, keytipAttributes: any, ) { diff --git a/packages/react/src/components/ContextualMenu/index.ts b/packages/react/src/components/ContextualMenu/index.ts index 8af110d1a174a0..3271595d5d54f5 100644 --- a/packages/react/src/components/ContextualMenu/index.ts +++ b/packages/react/src/components/ContextualMenu/index.ts @@ -6,9 +6,8 @@ export * from './ContextualMenuItem.base'; export * from './ContextualMenuItem.types'; export { getMenuItemStyles } from './ContextualMenu.cnstyles'; export { - // eslint-disable-next-line deprecation/deprecation getItemClassNames as getContextualMenuItemClassNames, getItemStyles as getContextualMenuItemStyles, } from './ContextualMenu.classNames'; -// eslint-disable-next-line deprecation/deprecation + export type { IContextualMenuClassNames, IMenuItemClassNames } from './ContextualMenu.classNames'; diff --git a/packages/react/src/components/DatePicker/DatePicker.base.tsx b/packages/react/src/components/DatePicker/DatePicker.base.tsx index 57412493d53eb0..17e37f7ffee89b 100644 --- a/packages/react/src/components/DatePicker/DatePicker.base.tsx +++ b/packages/react/src/components/DatePicker/DatePicker.base.tsx @@ -344,7 +344,7 @@ export const DatePickerBase: React.FunctionComponent = React.f }; const onTextFieldKeyDown = (ev: React.KeyboardEvent): void => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated switch (ev.which) { case KeyCodes.enter: ev.preventDefault(); diff --git a/packages/react/src/components/DetailsList/DetailsColumn.base.tsx b/packages/react/src/components/DetailsList/DetailsColumn.base.tsx index 2fdd35162ea6f1..813de6d01e08b5 100644 --- a/packages/react/src/components/DetailsList/DetailsColumn.base.tsx +++ b/packages/react/src/components/DetailsList/DetailsColumn.base.tsx @@ -371,11 +371,11 @@ export class DetailsColumnBase extends React.Component { }; private _updateHeaderDragInfo = (itemIndex: number, event?: MouseEvent) => { - /* eslint-disable deprecation/deprecation */ + /* eslint-disable @typescript-eslint/no-deprecated */ if (this.props.setDraggedItemIndex) { this.props.setDraggedItemIndex(itemIndex); } - /* eslint-enable deprecation/deprecation */ + /* eslint-enable @typescript-eslint/no-deprecated */ if (this.props.updateDragInfo) { this.props.updateDragInfo({ itemIndex }, event); } diff --git a/packages/react/src/components/DetailsList/DetailsHeader.base.tsx b/packages/react/src/components/DetailsList/DetailsHeader.base.tsx index d53de17bcfe6ab..7d96fc6898d74f 100644 --- a/packages/react/src/components/DetailsList/DetailsHeader.base.tsx +++ b/packages/react/src/components/DetailsList/DetailsHeader.base.tsx @@ -413,10 +413,10 @@ export class DetailsHeaderBase targetIndex, }; columnReorderProps.onColumnDrop(dragDropDetails); - /* eslint-disable deprecation/deprecation */ + /* eslint-disable @typescript-eslint/no-deprecated */ } else if (columnReorderProps.handleColumnReorder) { columnReorderProps.handleColumnReorder(this._draggedColumnIndex, targetIndex); - /* eslint-enable deprecation/deprecation */ + /* eslint-enable @typescript-eslint/no-deprecated */ } } } @@ -773,7 +773,7 @@ export class DetailsHeaderBase const columnIndex = Number(columnIndexAttr); if (!columnResizeDetails) { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.which === KeyCodes.enter) { this.setState({ columnResizeDetails: { @@ -788,7 +788,7 @@ export class DetailsHeaderBase } else { let increment: number | undefined; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.which === KeyCodes.enter) { this.setState({ columnResizeDetails: undefined, @@ -796,10 +796,10 @@ export class DetailsHeaderBase ev.preventDefault(); ev.stopPropagation(); - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated } else if (ev.which === KeyCodes.left) { increment = getRTL(this.props.theme) ? 1 : -1; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated } else if (ev.which === KeyCodes.right) { increment = getRTL(this.props.theme) ? -1 : 1; } diff --git a/packages/react/src/components/DetailsList/DetailsList.base.tsx b/packages/react/src/components/DetailsList/DetailsList.base.tsx index 3102537a9234b6..ddf29a64d3d212 100644 --- a/packages/react/src/components/DetailsList/DetailsList.base.tsx +++ b/packages/react/src/components/DetailsList/DetailsList.base.tsx @@ -141,11 +141,11 @@ const DetailsListInner: React.ComponentType = ( selectionMode = selection.mode, selectionPreservedOnEmptyClick, selectionZoneProps, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated ariaLabel, ariaLabelForGrid, rowElementEventMap, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated shouldApplyApplicationRole = false, getKey, listProps, @@ -593,7 +593,7 @@ const DetailsListInner: React.ComponentType = ( const isRightArrow = React.useCallback( (event: React.KeyboardEvent) => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated return event.which === getRTLSafeKeyCode(KeyCodes.right, theme); }, [theme], @@ -657,7 +657,7 @@ const DetailsListInner: React.ComponentType = ( const onHeaderKeyDown = React.useCallback( (ev: React.KeyboardEvent): void => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.which === KeyCodes.down) { if (focusZoneRef.current && focusZoneRef.current.focus()) { // select the first item in list after down arrow key event @@ -676,7 +676,7 @@ const DetailsListInner: React.ComponentType = ( const onContentKeyDown = React.useCallback( (ev: React.KeyboardEvent): void => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.which === KeyCodes.up && !ev.altKey) { if (headerRef.current && headerRef.current.focus()) { ev.preventDefault(); @@ -918,10 +918,10 @@ export class DetailsListBase extends React.Component= overflowWidth || !(column.isCollapsible || column.isCollapsable)) { const originalWidth = column.calculatedWidth!; if (minimumWidth < availableWidth) { diff --git a/packages/react/src/components/DetailsList/DetailsRowCheck.tsx b/packages/react/src/components/DetailsList/DetailsRowCheck.tsx index 67c404e0f9c6f4..1fc85ff4bc6cd4 100644 --- a/packages/react/src/components/DetailsList/DetailsRowCheck.tsx +++ b/packages/react/src/components/DetailsList/DetailsRowCheck.tsx @@ -60,7 +60,7 @@ const DetailsRowCheckBase: React.FunctionComponent = prop
= prop {onRenderCheckbox(detailsCheckboxProps)}
) : ( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated
); }; diff --git a/packages/react/src/components/Dialog/Dialog.base.tsx b/packages/react/src/components/Dialog/Dialog.base.tsx index 16856684294365..34f7185188ad3b 100644 --- a/packages/react/src/components/Dialog/Dialog.base.tsx +++ b/packages/react/src/components/Dialog/Dialog.base.tsx @@ -27,7 +27,7 @@ const DefaultDialogContentProps: IDialogContentProps = { topButtonsProps: [], }; -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated @withResponsiveMode export class DialogBase extends React.Component { public static defaultProps: IDialogProps = { @@ -67,7 +67,7 @@ export class DialogBase extends React.Component { public render(): JSX.Element { const props = this.props; const { - /* eslint-disable deprecation/deprecation */ + /* eslint-disable @typescript-eslint/no-deprecated */ className, containerClassName, contentClassName, @@ -90,7 +90,7 @@ export class DialogBase extends React.Component { title, topButtonsProps, type, - /* eslint-enable deprecation/deprecation */ + /* eslint-enable @typescript-eslint/no-deprecated */ minWidth, maxWidth, modalProps, @@ -142,7 +142,7 @@ export class DialogBase extends React.Component { ...props.dialogContentProps, draggableHeaderClassName: dialogDraggableClassName, titleProps: { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated id: props.dialogContentProps?.titleId || this._defaultTitleTextId, ...props.dialogContentProps?.titleProps, }, @@ -179,7 +179,7 @@ export class DialogBase extends React.Component { } private _getSubTextId = (): string | undefined => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { ariaDescribedById, modalProps, dialogContentProps, subText } = this.props; let id = (modalProps && modalProps.subtitleAriaId) || ariaDescribedById; @@ -191,7 +191,7 @@ export class DialogBase extends React.Component { }; private _getTitleTextId = (): string | undefined => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { ariaLabelledById, modalProps, dialogContentProps, title } = this.props; let id = (modalProps && modalProps.titleAriaId) || ariaLabelledById; diff --git a/packages/react/src/components/Dialog/Dialog.styles.ts b/packages/react/src/components/Dialog/Dialog.styles.ts index 0870266ded3697..8e46df0c425ff7 100644 --- a/packages/react/src/components/Dialog/Dialog.styles.ts +++ b/packages/react/src/components/Dialog/Dialog.styles.ts @@ -8,7 +8,7 @@ const GlobalClassNames = { export const getStyles = (props: IDialogStyleProps): IDialogStyles => { const { className, - containerClassName, // eslint-disable-line deprecation/deprecation + containerClassName, // eslint-disable-line @typescript-eslint/no-deprecated dialogDefaultMinWidth = '288px', dialogDefaultMaxWidth = '340px', hidden, diff --git a/packages/react/src/components/Dialog/Dialog.types.ts b/packages/react/src/components/Dialog/Dialog.types.ts index f3544a5c0d5995..7936c9f13a7e49 100644 --- a/packages/react/src/components/Dialog/Dialog.types.ts +++ b/packages/react/src/components/Dialog/Dialog.types.ts @@ -20,7 +20,7 @@ export interface IDialog {} */ export interface IDialogProps extends React.ClassAttributes, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated IWithResponsiveModeState, IAccessiblePopupProps { children?: React.ReactNode; diff --git a/packages/react/src/components/Dialog/DialogContent.base.tsx b/packages/react/src/components/Dialog/DialogContent.base.tsx index 4f3eabbe3f9066..9db6078f82c21d 100644 --- a/packages/react/src/components/Dialog/DialogContent.base.tsx +++ b/packages/react/src/components/Dialog/DialogContent.base.tsx @@ -13,7 +13,7 @@ const DialogFooterType = (() as React.ReactElement { public static defaultProps: IDialogContentProps = { @@ -41,7 +41,7 @@ export class DialogContentBase extends React.Component subTextId, subText, titleProps = {}, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated titleId, title, type, diff --git a/packages/react/src/components/Divider/VerticalDivider.base.tsx b/packages/react/src/components/Divider/VerticalDivider.base.tsx index 16d14aa3d9d19c..cac56ddde068e0 100644 --- a/packages/react/src/components/Divider/VerticalDivider.base.tsx +++ b/packages/react/src/components/Divider/VerticalDivider.base.tsx @@ -12,7 +12,7 @@ export const VerticalDividerBase: React.FunctionComponent HTMLDivElement, IVerticalDividerProps >((props, ref) => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { styles, theme, getClassNames: deprecatedGetClassNames, className } = props; const classNames = getClassNames(styles, { theme, getClassNames: deprecatedGetClassNames, className }); return ( diff --git a/packages/react/src/components/Divider/VerticalDivider.classNames.ts b/packages/react/src/components/Divider/VerticalDivider.classNames.ts index 03e0b7eb32193d..961511a8a75674 100644 --- a/packages/react/src/components/Divider/VerticalDivider.classNames.ts +++ b/packages/react/src/components/Divider/VerticalDivider.classNames.ts @@ -7,7 +7,7 @@ import type { IVerticalDividerClassNames } from './VerticalDivider.types'; * @deprecated use getStyles exported from VerticalDivider.styles.ts */ export const getDividerClassNames = memoizeFunction( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated (theme: ITheme): IVerticalDividerClassNames => { return mergeStyleSets({ wrapper: { diff --git a/packages/react/src/components/Divider/VerticalDivider.styles.ts b/packages/react/src/components/Divider/VerticalDivider.styles.ts index 166a0fa3a97cd8..8f86e4d5456181 100644 --- a/packages/react/src/components/Divider/VerticalDivider.styles.ts +++ b/packages/react/src/components/Divider/VerticalDivider.styles.ts @@ -4,7 +4,7 @@ import type { IStyleFunction } from '../../Utilities'; export const getStyles: IStyleFunction = ( props: IVerticalDividerPropsStyles, ): IVerticalDividerStyles => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { theme, getClassNames, className } = props; if (!theme) { diff --git a/packages/react/src/components/Divider/VerticalDivider.types.ts b/packages/react/src/components/Divider/VerticalDivider.types.ts index 44ea500f5c450b..388f106d72d554 100644 --- a/packages/react/src/components/Divider/VerticalDivider.types.ts +++ b/packages/react/src/components/Divider/VerticalDivider.types.ts @@ -11,7 +11,7 @@ export interface IVerticalDividerProps extends React.HTMLAttributes * Optional function to generate the class names for the divider for custom styling * @deprecated Use `styles` instead. */ - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getClassNames?: (theme: ITheme) => IVerticalDividerClassNames; /** * The theme that should be used to render the vertical divider. diff --git a/packages/react/src/components/DocumentCard/DocumentCard.base.tsx b/packages/react/src/components/DocumentCard/DocumentCard.base.tsx index 78bbf79439ba1e..3f6ce4bb9f67e1 100644 --- a/packages/react/src/components/DocumentCard/DocumentCard.base.tsx +++ b/packages/react/src/components/DocumentCard/DocumentCard.base.tsx @@ -48,7 +48,7 @@ export class DocumentCardBase extends React.Component i } public render(): JSX.Element { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { onClick, onClickHref, children, type, accentColor, styles, theme, className } = this.props; const nativeProps = getNativeProps>(this.props, divProperties, [ 'className', @@ -104,7 +104,7 @@ export class DocumentCardBase extends React.Component i }; private _onKeyDown = (ev: React.KeyboardEvent): void => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.which === KeyCodes.enter || ev.which === KeyCodes.space) { this._onAction(ev); } diff --git a/packages/react/src/components/DocumentCard/DocumentCardLogo.styles.ts b/packages/react/src/components/DocumentCard/DocumentCardLogo.styles.ts index 68e00221a5f5e4..b6beaba76e5984 100644 --- a/packages/react/src/components/DocumentCard/DocumentCardLogo.styles.ts +++ b/packages/react/src/components/DocumentCard/DocumentCardLogo.styles.ts @@ -15,7 +15,7 @@ export const getStyles = (props: IDocumentCardLogoStyleProps): IDocumentCardLogo root: [ classNames.root, { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated fontSize: fonts.xxLargePlus.fontSize, color: palette.themePrimary, display: 'block', diff --git a/packages/react/src/components/DocumentCard/DocumentCardPreview.base.tsx b/packages/react/src/components/DocumentCard/DocumentCardPreview.base.tsx index 8fbaa6c86ae175..a3ca9f83a62f6c 100644 --- a/packages/react/src/components/DocumentCard/DocumentCardPreview.base.tsx +++ b/packages/react/src/components/DocumentCard/DocumentCardPreview.base.tsx @@ -46,13 +46,13 @@ export class DocumentCardPreviewBase extends React.Component diff --git a/packages/react/src/components/Dropdown/Dropdown.base.tsx b/packages/react/src/components/Dropdown/Dropdown.base.tsx index 70498f5ac23212..574a5bd22d686b 100644 --- a/packages/react/src/components/Dropdown/Dropdown.base.tsx +++ b/packages/react/src/components/Dropdown/Dropdown.base.tsx @@ -57,7 +57,7 @@ const COMPONENT_NAME = 'Dropdown'; const getClassNames = classNamesFunction(); /** Internal only props interface to support mixing in responsive mode */ -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated interface IDropdownInternalProps extends Omit, IWithResponsiveModeState { hoisted: { rootRef: React.RefObject; @@ -146,7 +146,7 @@ function useSelectedItemsState({ if (searchKey != null) { return option.key === searchKey; } else { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated return !!option.selected || !!option.isSelected; } }); @@ -324,7 +324,7 @@ class DropdownInternal extends React.Component { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { onChange, onChanged } = this.props; if (onChange || onChanged) { // for single-select, option passed in will always be selected. @@ -506,7 +506,7 @@ class DropdownInternal extends React.Component { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated return this.props.placeholder || this.props.placeHolder; }; @@ -1048,7 +1048,7 @@ class DropdownInternal extends React.Component): boolean { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated return ev.which === KeyCodes.alt || ev.key === 'Meta'; } @@ -1187,7 +1187,7 @@ class DropdownInternal extends React.Component boolean | undefined = () => { let { disabled } = this.props; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { isDisabled } = this.props; // Remove this deprecation workaround at 1.0.0 diff --git a/packages/react/src/components/ExtendedPicker/BaseExtendedPicker.tsx b/packages/react/src/components/ExtendedPicker/BaseExtendedPicker.tsx index 557be878741ecc..5807f75fcbb5f9 100644 --- a/packages/react/src/components/ExtendedPicker/BaseExtendedPicker.tsx +++ b/packages/react/src/components/ExtendedPicker/BaseExtendedPicker.tsx @@ -193,7 +193,7 @@ export class BaseExtendedPicker): void => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.which !== KeyCodes.backspace) { return; } diff --git a/packages/react/src/components/Fabric/Fabric.base.tsx b/packages/react/src/components/Fabric/Fabric.base.tsx index 9d42d03677541e..5ede2ddd12d90b 100644 --- a/packages/react/src/components/Fabric/Fabric.base.tsx +++ b/packages/react/src/components/Fabric/Fabric.base.tsx @@ -72,7 +72,7 @@ function useRenderedContent( if (needsTheme) { // Disabling ThemeProvider here because theme doesn't need to be re-provided by ThemeProvider if dir has changed. renderedContent = ( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated {renderedContent} ); } diff --git a/packages/react/src/components/Fabric/Fabric.test.tsx b/packages/react/src/components/Fabric/Fabric.test.tsx index 8b428b5c6eecb8..8f2c71837058e2 100644 --- a/packages/react/src/components/Fabric/Fabric.test.tsx +++ b/packages/react/src/components/Fabric/Fabric.test.tsx @@ -1,4 +1,4 @@ -/* eslint-disable deprecation/deprecation */ +/* eslint-disable @typescript-eslint/no-deprecated */ import * as React from 'react'; import { create } from '@fluentui/test-utilities'; //import { Customizer } from '@fluentui/utilities'; diff --git a/packages/react/src/components/Facepile/Facepile.base.tsx b/packages/react/src/components/Facepile/Facepile.base.tsx index bb412e7c22bba2..a082851ab6fe6a 100644 --- a/packages/react/src/components/Facepile/Facepile.base.tsx +++ b/packages/react/src/components/Facepile/Facepile.base.tsx @@ -40,7 +40,7 @@ export class FacepileBase extends React.Component { public render(): JSX.Element { let { overflowButtonProps } = this.props; const { - chevronButtonProps, // eslint-disable-line deprecation/deprecation + chevronButtonProps, // eslint-disable-line @typescript-eslint/no-deprecated maxDisplayablePersonas, personas, overflowPersonas, diff --git a/packages/react/src/components/FloatingPicker/BaseFloatingPicker.tsx b/packages/react/src/components/FloatingPicker/BaseFloatingPicker.tsx index 1e15c290f237d9..616d9947c86adc 100644 --- a/packages/react/src/components/FloatingPicker/BaseFloatingPicker.tsx +++ b/packages/react/src/components/FloatingPicker/BaseFloatingPicker.tsx @@ -125,6 +125,7 @@ export class BaseFloatingPicker JSX.Element
diff --git a/packages/react/src/components/FloatingPicker/Suggestions/SuggestionsStore.ts b/packages/react/src/components/FloatingPicker/Suggestions/SuggestionsStore.ts index 893ced2fa91f77..972f279e6da5dd 100644 --- a/packages/react/src/components/FloatingPicker/Suggestions/SuggestionsStore.ts +++ b/packages/react/src/components/FloatingPicker/Suggestions/SuggestionsStore.ts @@ -54,7 +54,7 @@ export class SuggestionsStore { ? this.getAriaLabel(suggestion) : (suggestion as any as ITag).name || (suggestion).text || - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated (suggestion).primaryText, }; } diff --git a/packages/react/src/components/FocusTrapZone/FocusTrapZone.tsx b/packages/react/src/components/FocusTrapZone/FocusTrapZone.tsx index 8fa3eabcd97117..e99993f9249e4c 100644 --- a/packages/react/src/components/FocusTrapZone/FocusTrapZone.tsx +++ b/packages/react/src/components/FocusTrapZone/FocusTrapZone.tsx @@ -87,10 +87,10 @@ export const FocusTrapZone: React.FunctionComponent & { disableFirstFocus, forceFocusInsideTrap, focusPreviouslyFocusedInnerElement, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated firstFocusableSelector, firstFocusableTarget, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated disableRestoreFocus = props.ignoreExternalFocusing, isClickableOutsideFocusTrap, enableAriaHiddenSiblings, diff --git a/packages/react/src/components/GroupedList/GroupHeader.base.tsx b/packages/react/src/components/GroupedList/GroupHeader.base.tsx index c519260c424ae2..9dbec7301ebc7b 100644 --- a/packages/react/src/components/GroupedList/GroupHeader.base.tsx +++ b/packages/react/src/components/GroupedList/GroupHeader.base.tsx @@ -66,12 +66,13 @@ export class GroupHeaderBase extends React.Component= 7.0 */ - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated styles?: IStyleFunctionOrObject; /** Count of spacer(s) */ diff --git a/packages/react/src/components/GroupedList/GroupedList.base.tsx b/packages/react/src/components/GroupedList/GroupedList.base.tsx index 557c8bb695377a..ccc831276d1085 100644 --- a/packages/react/src/components/GroupedList/GroupedList.base.tsx +++ b/packages/react/src/components/GroupedList/GroupedList.base.tsx @@ -356,7 +356,7 @@ export class GroupedListBase extends React.Component): boolean => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated return ev.which === getRTLSafeKeyCode(KeyCodes.right); }; diff --git a/packages/react/src/components/GroupedList/GroupedListV2.base.tsx b/packages/react/src/components/GroupedList/GroupedListV2.base.tsx index c146f58278cd67..6ee3a2e130ca76 100644 --- a/packages/react/src/components/GroupedList/GroupedListV2.base.tsx +++ b/packages/react/src/components/GroupedList/GroupedListV2.base.tsx @@ -199,7 +199,7 @@ const setGroupsCollapsedState = (groups: IGroup[] | undefined, isCollapsed: bool }; const isInnerZoneKeystroke = (ev: React.KeyboardEvent): boolean => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated return ev.which === getRTLSafeKeyCode(KeyCodes.right); }; @@ -285,7 +285,6 @@ export const GroupedListV2FC: React.FC = props => { const [version, setVersion] = React.useState({}); const [toggleVersion, setToggleVersion] = React.useState({}); - // eslint-disable-next-line deprecation/deprecation const { shouldEnterInnerZone = isInnerZoneKeystroke } = focusZoneProps; const listView = React.useMemo(() => { diff --git a/packages/react/src/components/HoverCard/ExpandingCard.base.tsx b/packages/react/src/components/HoverCard/ExpandingCard.base.tsx index b199cb0361d295..3e8ec1a8c373a7 100644 --- a/packages/react/src/components/HoverCard/ExpandingCard.base.tsx +++ b/packages/react/src/components/HoverCard/ExpandingCard.base.tsx @@ -70,7 +70,7 @@ export class ExpandingCardBase extends React.Component): void => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.which === KeyCodes.escape) { this.props.onLeave && this.props.onLeave(ev); } diff --git a/packages/react/src/components/HoverCard/HoverCard.base.tsx b/packages/react/src/components/HoverCard/HoverCard.base.tsx index 7f93ef0c5283ec..fb059fd0223086 100644 --- a/packages/react/src/components/HoverCard/HoverCard.base.tsx +++ b/packages/react/src/components/HoverCard/HoverCard.base.tsx @@ -193,7 +193,7 @@ export class HoverCardBase extends React.Component { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (this._shouldBlockHoverCard() || (ev.type === 'keydown' && !(ev.which === this.props.openHotKey))) { return; } @@ -239,13 +239,13 @@ export class HoverCardBase extends React.Component { } private _onKeyDown = (ev: React.KeyboardEvent): void => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.which === KeyCodes.escape) { this.props.onLeave && this.props.onLeave(ev); } diff --git a/packages/react/src/components/Icon/Icon.base.tsx b/packages/react/src/components/Icon/Icon.base.tsx index 2010c045978299..5e4505ecec16ab 100644 --- a/packages/react/src/components/Icon/Icon.base.tsx +++ b/packages/react/src/components/Icon/Icon.base.tsx @@ -31,7 +31,7 @@ export class IconBase extends React.Component { const { children, className, styles, iconName, imageErrorAs, theme } = this.props; const isPlaceholder = typeof iconName === 'string' && iconName.length === 0; const isImage = - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated !!this.props.imageProps || this.props.iconType === IconType.image || this.props.iconType === IconType.Image; const iconContent = getIconContent(iconName) || {}; const { iconClassName, children: iconContentChildren, mergeImageProps } = iconContent; @@ -55,7 +55,7 @@ export class IconBase extends React.Component { }; const ImageType = (imageLoadError && imageErrorAs) || Image; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const ariaLabel = this.props['aria-label'] || this.props.ariaLabel; const accessibleName = imageProps.alt || ariaLabel || this.props.title; const hasName = !!( diff --git a/packages/react/src/components/Icon/Icon.styles.ts b/packages/react/src/components/Icon/Icon.styles.ts index d7c6c5a4b285e6..f683a57403007b 100644 --- a/packages/react/src/components/Icon/Icon.styles.ts +++ b/packages/react/src/components/Icon/Icon.styles.ts @@ -34,7 +34,7 @@ export const getStyles = (props: IIconStyleProps): IIconStyles => { iconClassName, className, styles && styles.root, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated styles && styles.imageContainer, ], }; diff --git a/packages/react/src/components/Icon/Icon.types.ts b/packages/react/src/components/Icon/Icon.types.ts index c06b7133f2019d..0f6ed6ef687259 100644 --- a/packages/react/src/components/Icon/Icon.types.ts +++ b/packages/react/src/components/Icon/Icon.types.ts @@ -51,7 +51,7 @@ export interface IIconProps extends IBaseProps, React.HTMLAttributes = React.forwardRef< hostId, insertFirst, onLayerDidMount = () => undefined, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated onLayerMounted = () => undefined, onLayerWillUnmount, styles, @@ -216,7 +216,7 @@ export const LayerBase: React.FunctionComponent = React.forwardRef< {layerRef.current && ReactDOM.createPortal( - {/* eslint-disable deprecation/deprecation */} + {/* eslint-disable @typescript-eslint/no-deprecated */} = React.forwardRef< > {children} - {/* eslint-enable deprecation/deprecation */} + {/* eslint-enable @typescript-eslint/no-deprecated */} , layerRef.current, )} diff --git a/packages/react/src/components/Link/Link.test.tsx b/packages/react/src/components/Link/Link.test.tsx index 853e913af8a7c7..91439b8b7eb3ac 100644 --- a/packages/react/src/components/Link/Link.test.tsx +++ b/packages/react/src/components/Link/Link.test.tsx @@ -96,7 +96,7 @@ describe('Link', () => { expect( /ms-Link($| )/.test( ReactDOM.renderToStaticMarkup( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated My Link , diff --git a/packages/react/src/components/MessageBar/MessageBar.base.tsx b/packages/react/src/components/MessageBar/MessageBar.base.tsx index 708771114cce56..e8e6d8731dca75 100644 --- a/packages/react/src/components/MessageBar/MessageBar.base.tsx +++ b/packages/react/src/components/MessageBar/MessageBar.base.tsx @@ -50,7 +50,7 @@ export const MessageBarBase: React.FunctionComponent = React.f actions, className, children, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated overflowButtonAriaLabel, dismissIconProps, styles, diff --git a/packages/react/src/components/MessageBar/MessageBar.types.ts b/packages/react/src/components/MessageBar/MessageBar.types.ts index 46ca8f89d30b7a..e41a2ed4d72f31 100644 --- a/packages/react/src/components/MessageBar/MessageBar.types.ts +++ b/packages/react/src/components/MessageBar/MessageBar.types.ts @@ -41,7 +41,7 @@ export interface IMessageBarProps extends React.HTMLAttributes, Rea * If null, we don't show a dismiss button. * @defaultvalue null */ - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated onDismiss?: (ev?: React.MouseEvent) => any; /** diff --git a/packages/react/src/components/Modal/Modal.base.tsx b/packages/react/src/components/Modal/Modal.base.tsx index 627d401fc44e1e..795344ab95720c 100644 --- a/packages/react/src/components/Modal/Modal.base.tsx +++ b/packages/react/src/components/Modal/Modal.base.tsx @@ -105,7 +105,7 @@ export const ModalBase: React.FunctionComponent = React.forwardRef< firstFocusableSelector, focusTrapZoneProps, forceFocusInsideTrap, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated disableRestoreFocus = props.ignoreExternalFocusing, isBlocking, isAlert, @@ -121,12 +121,12 @@ export const ModalBase: React.FunctionComponent = React.forwardRef< theme, topOffsetFixed, responsiveMode, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated onLayerDidMount, isModeless, dragOptions, onDismissed, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated enableAriaHiddenSiblings, popupProps, } = props; @@ -278,7 +278,7 @@ export const ModalBase: React.FunctionComponent = React.forwardRef< // We need a global handleKeyDown event when we are in the move mode so that we can // handle the key presses and the components inside the modal do not get the events const handleKeyDown = (ev: React.KeyboardEvent): void => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.altKey && ev.ctrlKey && ev.keyCode === KeyCodes.space) { // CTRL + ALT + SPACE is handled during keyUp ev.preventDefault(); @@ -286,13 +286,13 @@ export const ModalBase: React.FunctionComponent = React.forwardRef< return; } - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const newLocal = ev.altKey || ev.keyCode === KeyCodes.escape; if (isModalMenuOpen && newLocal) { setModalMenuClose(); } - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (internalState.isInKeyboardMoveMode && (ev.keyCode === KeyCodes.escape || ev.keyCode === KeyCodes.enter)) { internalState.isInKeyboardMoveMode = false; ev.preventDefault(); @@ -303,7 +303,7 @@ export const ModalBase: React.FunctionComponent = React.forwardRef< let handledEvent = true; const delta = getMoveDelta(ev); - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated switch (ev.keyCode) { /* eslint-disable no-fallthrough */ case KeyCodes.escape: @@ -364,7 +364,7 @@ export const ModalBase: React.FunctionComponent = React.forwardRef< const handleKeyUp = (ev: React.KeyboardEvent): void => { // Needs to handle the CTRL + ALT + SPACE key during keyup due to FireFox bug: // https://bugzilla.mozilla.org/show_bug.cgi?id=1220143 - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.altKey && ev.ctrlKey && ev.keyCode === KeyCodes.space) { if (elementContains(internalState.scrollableContent, ev.target as HTMLElement)) { toggleModalMenuOpen(); @@ -433,7 +433,7 @@ export const ModalBase: React.FunctionComponent = React.forwardRef< } disableRestoreFocus={focusTrapZoneProps?.disableRestoreFocus ?? disableRestoreFocus} forceFocusInsideTrap={(focusTrapZoneProps?.forceFocusInsideTrap ?? forceFocusInsideTrap) && !isModeless} - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated firstFocusableSelector={focusTrapZoneProps?.firstFocusableSelector || firstFocusableSelector} focusPreviouslyFocusedInnerElement={focusTrapZoneProps?.focusPreviouslyFocusedInnerElement ?? true} onBlur={internalState.isInKeyboardMoveMode ? handleExitKeyboardMoveMode : undefined} diff --git a/packages/react/src/components/Modal/Modal.styles.ts b/packages/react/src/components/Modal/Modal.styles.ts index 574c85d2202d07..6094cd02d63c16 100644 --- a/packages/react/src/components/Modal/Modal.styles.ts +++ b/packages/react/src/components/Modal/Modal.styles.ts @@ -116,7 +116,7 @@ export const getStyles = (props: IModalStyleProps): IModalStyles => { padding: '3px 0px', }, keyboardMoveIcon: { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated fontSize: fonts.xLargePlus.fontSize, width: '24px', }, diff --git a/packages/react/src/components/Nav/Nav.base.tsx b/packages/react/src/components/Nav/Nav.base.tsx index 189df5ae062ec9..1eff274bd87165 100644 --- a/packages/react/src/components/Nav/Nav.base.tsx +++ b/packages/react/src/components/Nav/Nav.base.tsx @@ -148,7 +148,7 @@ export class NavBase extends React.Component implements IN private _renderCompositeLink(link: INavLink, linkIndex: number, nestingLevel: number): React.ReactElement<{}> { const divProps: React.HTMLProps = { ...getNativeProps(link, divProperties, ['onClick']) }; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { expandButtonAriaLabel, styles, groups, theme } = this.props; const classNames = getClassNames(styles!, { theme: theme!, @@ -254,7 +254,7 @@ export class NavBase extends React.Component implements IN }; private _renderGroupHeader = (group: IRenderGroupHeaderProps): React.ReactElement<{}> => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { styles, groups, theme, expandButtonAriaLabel } = this.props; const { isExpanded } = group; @@ -267,7 +267,7 @@ export class NavBase extends React.Component implements IN }); // respect deprecated collapseAriaLabel, but default to expandAriaLabel for both states - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const collapseAriaLabel = group.collapseAriaLabel ?? group.expandAriaLabel; const label = (isExpanded ? collapseAriaLabel : group.expandAriaLabel) || expandButtonAriaLabel; diff --git a/packages/react/src/components/Panel/Panel.base.tsx b/packages/react/src/components/Panel/Panel.base.tsx index cf1ab7e072740f..527285aa738ab5 100644 --- a/packages/react/src/components/Panel/Panel.base.tsx +++ b/packages/react/src/components/Panel/Panel.base.tsx @@ -157,7 +157,7 @@ export class PanelBase extends React.Component impleme const { className = '', elementToFocusOnDismiss, - /* eslint-disable deprecation/deprecation */ + /* eslint-disable @typescript-eslint/no-deprecated */ firstFocusableSelector, focusTrapZoneProps, forceFocusInsideTrap, diff --git a/packages/react/src/components/Persona/Persona.base.tsx b/packages/react/src/components/Persona/Persona.base.tsx index 92bf285c051bfb..9a5086b9935328 100644 --- a/packages/react/src/components/Persona/Persona.base.tsx +++ b/packages/react/src/components/Persona/Persona.base.tsx @@ -44,7 +44,7 @@ export const PersonaBase: React.FunctionComponent = React.forward * Deprecation helper for getting text. */ const getText = (): string => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated return props.text || props.primaryText || ''; }; @@ -130,7 +130,7 @@ export const PersonaBase: React.FunctionComponent = React.forward initialsTextColor, isOutOfOffice, onPhotoLoadingStateChange, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated onRenderCoin, onRenderInitials, presence, @@ -192,14 +192,14 @@ export const PersonaBase: React.FunctionComponent = React.forward > {onRenderPersonaCoin(personaCoinProps, onRenderPersonaCoin)} { - /* eslint-disable deprecation/deprecation */ + /* eslint-disable @typescript-eslint/no-deprecated */ (!hidePersonaDetails || size === PersonaSize.size8 || size === PersonaSize.size10 || size === PersonaSize.tiny) && personaDetails - /* eslint-enable deprecation/deprecation */ + /* eslint-enable @typescript-eslint/no-deprecated */ }
); diff --git a/packages/react/src/components/Persona/PersonaCoin/PersonaCoin.base.tsx b/packages/react/src/components/Persona/PersonaCoin/PersonaCoin.base.tsx index d9444f3443acc5..5fdd51988bed2d 100644 --- a/packages/react/src/components/Persona/PersonaCoin/PersonaCoin.base.tsx +++ b/packages/react/src/components/Persona/PersonaCoin/PersonaCoin.base.tsx @@ -106,15 +106,15 @@ export const PersonaCoinBase: React.FunctionComponent = React initialsColor, initialsTextColor, isOutOfOffice, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated onRenderCoin = renderCoin, - // eslint-disable-next-line deprecation/deprecation + onRenderPersonaCoin = onRenderCoin, onRenderInitials = renderPersonaCoinInitials, presence, presenceTitle, presenceColors, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated primaryText, showInitialsUntilImageLoads, text, @@ -155,7 +155,7 @@ export const PersonaCoinBase: React.FunctionComponent = React
{ // Render PersonaCoin if size is not size8. size10 and tiny need to removed after a deprecation cleanup. - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated size !== PersonaSize.size8 && size !== PersonaSize.size10 && size !== PersonaSize.tiny ? (
{shouldRenderInitials && ( @@ -234,7 +234,7 @@ const renderPersonaCoinInitials = ({ allowPhoneInitials, showUnknownPersonaCoin, text, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated primaryText, theme, }: IPersonaCoinProps): JSX.Element => { diff --git a/packages/react/src/components/Persona/PersonaConsts.tsx b/packages/react/src/components/Persona/PersonaConsts.tsx index 325fc33468c915..6376682b9e9615 100644 --- a/packages/react/src/components/Persona/PersonaConsts.tsx +++ b/packages/react/src/components/Persona/PersonaConsts.tsx @@ -38,7 +38,7 @@ export namespace personaPresenceSize { // TODO: remove the deprecated parts in a future major release. export const sizeBoolean = (size: PersonaSize) => ({ isSize8: size === PersonaSize.size8, - /* eslint-disable deprecation/deprecation */ + /* eslint-disable @typescript-eslint/no-deprecated */ isSize10: size === PersonaSize.size10 || size === PersonaSize.tiny, isSize16: size === PersonaSize.size16, isSize24: size === PersonaSize.size24 || size === PersonaSize.extraExtraSmall, @@ -67,7 +67,7 @@ export const sizeToPixels: { [key: number]: number } = { [PersonaSize.size16]: 16, // TODO: deprecated (not in the design specs) [PersonaSize.size24]: 24, [PersonaSize.size28]: 28, // TODO: deprecated (not in the design specs) - /* eslint-enable deprecation/deprecation */ + /* eslint-enable @typescript-eslint/no-deprecated */ [PersonaSize.size32]: 32, [PersonaSize.size40]: 40, [PersonaSize.size48]: 48, diff --git a/packages/react/src/components/Persona/PersonaInitialsColor.ts b/packages/react/src/components/Persona/PersonaInitialsColor.ts index f5fe9c45f87656..c16169c8497995 100644 --- a/packages/react/src/components/Persona/PersonaInitialsColor.ts +++ b/packages/react/src/components/Persona/PersonaInitialsColor.ts @@ -77,7 +77,7 @@ function personaInitialsColorToHexCode(personaInitialsColor: PersonaInitialsColo return '#5C2E91'; case PersonaInitialsColor.orange: return '#CA5010'; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated case PersonaInitialsColor.red: return '#EE1111'; case PersonaInitialsColor.lightRed: @@ -100,7 +100,7 @@ function personaInitialsColorToHexCode(personaInitialsColor: PersonaInitialsColo return '#8E562E'; case PersonaInitialsColor.coolGray: return '#69797E'; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated case PersonaInitialsColor.black: return '#1D1D1D'; case PersonaInitialsColor.gray: @@ -120,7 +120,7 @@ export function initialsColorPropToColorCode(props: IPersonaProps): string { * @returns Hex color string prefixed with # */ export function getPersonaInitialsColor(props: Pick): string { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { primaryText, text } = props; let { initialsColor } = props; let initialsColorCode: string; diff --git a/packages/react/src/components/Pivot/Pivot.base.tsx b/packages/react/src/components/Pivot/Pivot.base.tsx index 9f62ca73599905..70d18af3bc30aa 100644 --- a/packages/react/src/components/Pivot/Pivot.base.tsx +++ b/packages/react/src/components/Pivot/Pivot.base.tsx @@ -41,7 +41,7 @@ const getLinkItems = (props: IPivotProps, pivotId: string): PivotLinkCollection React.Children.forEach(React.Children.toArray(props.children), (child: React.ReactNode, index: number) => { if (isPivotItem(child)) { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { linkText, ...pivotItemProps } = child.props; const itemKey = child.props.itemKey || index.toString(); result.links.push({ @@ -177,7 +177,7 @@ export const PivotBase: React.FunctionComponent = React.forwardRef< }; const onKeyDown = (itemKey: string, ev: React.KeyboardEvent): void => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.which === KeyCodes.enter) { ev.preventDefault(); updateSelectedItem(itemKey); diff --git a/packages/react/src/components/Popup/Popup.tsx b/packages/react/src/components/Popup/Popup.tsx index a55f2e0ab4de38..6d035cb80aecff 100644 --- a/packages/react/src/components/Popup/Popup.tsx +++ b/packages/react/src/components/Popup/Popup.tsx @@ -123,7 +123,7 @@ function useRestoreFocus(props: IPopupProps, root: React.RefObject) { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const shouldHideSiblings = String(props['aria-modal']).toLowerCase() === 'true' && props.enableAriaHiddenSiblings; React.useEffect(() => { @@ -157,7 +157,7 @@ export const Popup: React.FunctionComponent = React.forwardRef | KeyboardEvent): void => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated switch (ev.which) { case KeyCodes.escape: if (onDismiss) { diff --git a/packages/react/src/components/ProgressIndicator/ProgressIndicator.base.tsx b/packages/react/src/components/ProgressIndicator/ProgressIndicator.base.tsx index fe8573e7780827..1e38e297b1471e 100644 --- a/packages/react/src/components/ProgressIndicator/ProgressIndicator.base.tsx +++ b/packages/react/src/components/ProgressIndicator/ProgressIndicator.base.tsx @@ -38,7 +38,7 @@ export class ProgressIndicatorBase extends React.Component = React.forwardRe disabled, getAriaLabel, styles, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated min: minFromProps = props.allowZeroStars ? 0 : 1, max = 5, readOnly, @@ -146,7 +146,7 @@ export const RatingBase: React.FunctionComponent = React.forwardRe }; const onStarKeyDown = (event: React.KeyboardEvent) => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { which } = event; let newRating = starNum; switch (which) { diff --git a/packages/react/src/components/SearchBox/SearchBox.base.tsx b/packages/react/src/components/SearchBox/SearchBox.base.tsx index 6113e66fde8a0e..6a7cb27d61ca6e 100644 --- a/packages/react/src/components/SearchBox/SearchBox.base.tsx +++ b/packages/react/src/components/SearchBox/SearchBox.base.tsx @@ -41,9 +41,9 @@ export const SearchBoxBase: React.FunctionComponent = React.for disabled, underlined, styles, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated labelText, - // eslint-disable-next-line deprecation/deprecation + placeholder = labelText, theme, clearButtonProps = defaultClearButtonProps, @@ -57,7 +57,7 @@ export const SearchBoxBase: React.FunctionComponent = React.for iconProps, role, onChange, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated onChanged, } = props; @@ -156,7 +156,7 @@ export const SearchBoxBase: React.FunctionComponent = React.for }; const onKeyDown = (ev: React.KeyboardEvent) => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated switch (ev.which) { case KeyCodes.escape: customOnEscape?.(ev); diff --git a/packages/react/src/components/SelectedItemsList/BaseSelectedItemsList.tsx b/packages/react/src/components/SelectedItemsList/BaseSelectedItemsList.tsx index 45391a414cc160..bd5e3dc7a13838 100644 --- a/packages/react/src/components/SelectedItemsList/BaseSelectedItemsList.tsx +++ b/packages/react/src/components/SelectedItemsList/BaseSelectedItemsList.tsx @@ -225,7 +225,7 @@ export class BaseSelectedItemsList): void { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.which === KeyCodes.backspace || ev.which === KeyCodes.del) { ev.stopPropagation(); } diff --git a/packages/react/src/components/Shimmer/ShimmerCircle/ShimmerCircle.base.tsx b/packages/react/src/components/Shimmer/ShimmerCircle/ShimmerCircle.base.tsx index 1c0185c4bd4438..f47d36a9ad13e5 100644 --- a/packages/react/src/components/Shimmer/ShimmerCircle/ShimmerCircle.base.tsx +++ b/packages/react/src/components/Shimmer/ShimmerCircle/ShimmerCircle.base.tsx @@ -5,7 +5,7 @@ import type { IShimmerCircleProps, IShimmerCircleStyleProps, IShimmerCircleStyle const getClassNames = classNamesFunction(); export const ShimmerCircleBase: React.FunctionComponent = props => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { height, styles, borderStyle, theme } = props; const classNames = getClassNames(styles!, { theme: theme!, diff --git a/packages/react/src/components/Shimmer/ShimmerCircle/ShimmerCircle.styles.ts b/packages/react/src/components/Shimmer/ShimmerCircle/ShimmerCircle.styles.ts index 590bbfc3e61ef7..f8fe47cfe5a5ee 100644 --- a/packages/react/src/components/Shimmer/ShimmerCircle/ShimmerCircle.styles.ts +++ b/packages/react/src/components/Shimmer/ShimmerCircle/ShimmerCircle.styles.ts @@ -8,7 +8,7 @@ const GlobalClassNames = { }; export function getStyles(props: IShimmerCircleStyleProps): IShimmerCircleStyles { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { height, borderStyle, theme } = props; const { semanticColors } = theme; diff --git a/packages/react/src/components/Shimmer/ShimmerGap/ShimmerGap.base.tsx b/packages/react/src/components/Shimmer/ShimmerGap/ShimmerGap.base.tsx index 08b0b83fa88e0f..2d75b1da5c8d4f 100644 --- a/packages/react/src/components/Shimmer/ShimmerGap/ShimmerGap.base.tsx +++ b/packages/react/src/components/Shimmer/ShimmerGap/ShimmerGap.base.tsx @@ -8,7 +8,7 @@ const getClassNames = classNamesFunction = props => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { height, styles, width = '10px', borderStyle, theme } = props; const classNames = getClassNames(styles!, { diff --git a/packages/react/src/components/Shimmer/ShimmerGap/ShimmerGap.styles.ts b/packages/react/src/components/Shimmer/ShimmerGap/ShimmerGap.styles.ts index d9d1ae91ff1a19..cf8dbddba30dd0 100644 --- a/packages/react/src/components/Shimmer/ShimmerGap/ShimmerGap.styles.ts +++ b/packages/react/src/components/Shimmer/ShimmerGap/ShimmerGap.styles.ts @@ -7,7 +7,7 @@ const GlobalClassNames = { }; export function getStyles(props: IShimmerGapStyleProps): IShimmerGapStyles { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { height, borderStyle, theme } = props; const { semanticColors } = theme; diff --git a/packages/react/src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx b/packages/react/src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx index 511e6c8634cc16..2d3e1bd6285058 100644 --- a/packages/react/src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx +++ b/packages/react/src/components/Shimmer/ShimmerLine/ShimmerLine.base.tsx @@ -8,7 +8,7 @@ const getClassNames = classNamesFunction = props => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { height, styles, width = '100%', borderStyle, theme } = props; const classNames = getClassNames(styles!, { diff --git a/packages/react/src/components/Shimmer/ShimmerLine/ShimmerLine.styles.ts b/packages/react/src/components/Shimmer/ShimmerLine/ShimmerLine.styles.ts index e4096b4831f661..aab86f77cb1686 100644 --- a/packages/react/src/components/Shimmer/ShimmerLine/ShimmerLine.styles.ts +++ b/packages/react/src/components/Shimmer/ShimmerLine/ShimmerLine.styles.ts @@ -11,7 +11,7 @@ const GlobalClassNames = { }; export function getStyles(props: IShimmerLineStyleProps): IShimmerLineStyles { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { height, borderStyle, theme } = props; const { semanticColors } = theme; diff --git a/packages/react/src/components/Slider/useSlider.ts b/packages/react/src/components/Slider/useSlider.ts index bdb30715087204..e72d0f4eaa5af6 100644 --- a/packages/react/src/components/Slider/useSlider.ts +++ b/packages/react/src/components/Slider/useSlider.ts @@ -216,7 +216,7 @@ export const useSlider = (props: ISliderProps, ref: React.ForwardedRef { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const sliderPositionRect: ClientRect = sliderLine.current!.getBoundingClientRect(); const sliderLength: number = !props.vertical ? sliderPositionRect.width : sliderPositionRect.height; const stepLength: number = sliderLength / steps; diff --git a/packages/react/src/components/SpinButton/SpinButton.base.tsx b/packages/react/src/components/SpinButton/SpinButton.base.tsx index 5fc5c254c85b73..816d0a275931d5 100644 --- a/packages/react/src/components/SpinButton/SpinButton.base.tsx +++ b/packages/react/src/components/SpinButton/SpinButton.base.tsx @@ -345,7 +345,7 @@ export const SpinButtonBase: React.FunctionComponent = React.f const handleKeyDown = (ev: React.KeyboardEvent): void => { // eat the up and down arrow keys to keep focus in the spinButton // (especially when a spinButton is inside of a FocusZone) - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.which === KeyCodes.up || ev.which === KeyCodes.down || ev.which === KeyCodes.enter) { ev.preventDefault(); ev.stopPropagation(); @@ -357,7 +357,7 @@ export const SpinButtonBase: React.FunctionComponent = React.f let spinDirection = KeyboardSpinDirection.notSpinning; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated switch (ev.which) { case KeyCodes.up: spinDirection = KeyboardSpinDirection.up; @@ -386,7 +386,7 @@ export const SpinButtonBase: React.FunctionComponent = React.f /** Stop spinning on keyUp if the up or down arrow key fired this event */ const handleKeyUp = React.useCallback( (ev: React.KeyboardEvent): void => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (disabled || ev.which === KeyCodes.up || ev.which === KeyCodes.down) { stop(); return; diff --git a/packages/react/src/components/SpinButton/SpinButton.test.tsx b/packages/react/src/components/SpinButton/SpinButton.test.tsx index 2c2f3023494586..1715d792d89359 100644 --- a/packages/react/src/components/SpinButton/SpinButton.test.tsx +++ b/packages/react/src/components/SpinButton/SpinButton.test.tsx @@ -696,7 +696,7 @@ describe('SpinButton', () => { const onChange = jest.fn(); let keyCode: number | undefined; const onValidate = jest.fn((value: string, event?: React.SyntheticEvent) => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated keyCode = (event as React.KeyboardEvent).which; return value; }); diff --git a/packages/react/src/components/Spinner/Spinner.base.tsx b/packages/react/src/components/Spinner/Spinner.base.tsx index 710ddf11a44794..81ba20450cff1c 100644 --- a/packages/react/src/components/Spinner/Spinner.base.tsx +++ b/packages/react/src/components/Spinner/Spinner.base.tsx @@ -13,7 +13,7 @@ export class SpinnerBase extends React.Component { }; public render() { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { type, size, ariaLabel, ariaLive, styles, label, theme, className, labelPosition } = this.props; const statusMessage = ariaLabel; const nativeProps = getNativeProps>(this.props, divProperties, ['size']); @@ -23,7 +23,7 @@ export class SpinnerBase extends React.Component { // finally goes away we should delete this. let styleSize = size; if (styleSize === undefined && type !== undefined) { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated styleSize = type === SpinnerType.large ? SpinnerSize.large : SpinnerSize.medium; } diff --git a/packages/react/src/components/Spinner/Spinner.types.ts b/packages/react/src/components/Spinner/Spinner.types.ts index 14800c32c87b6f..eb7e36666ff8fa 100644 --- a/packages/react/src/components/Spinner/Spinner.types.ts +++ b/packages/react/src/components/Spinner/Spinner.types.ts @@ -21,7 +21,7 @@ export interface ISpinnerProps extends React.HTMLAttributes { /** * @deprecated Use `size` instead. Will be removed at \>= 2.0.0. */ - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated type?: SpinnerType; /** diff --git a/packages/react/src/components/Stack/Stack.styles.ts b/packages/react/src/components/Stack/Stack.styles.ts index 0a2c8b5d9fe298..ee2346a6fcd44a 100644 --- a/packages/react/src/components/Stack/Stack.styles.ts +++ b/packages/react/src/components/Stack/Stack.styles.ts @@ -30,12 +30,12 @@ export const styles: IStackComponent['styles'] = (props, theme, tokens): IStackS const classNames = getGlobalClassNames(GlobalClassNames, theme); - /* eslint-disable deprecation/deprecation */ + /* eslint-disable @typescript-eslint/no-deprecated */ const childrenGap = tokens && tokens.childrenGap ? tokens.childrenGap : props.gap; const maxHeight = tokens && tokens.maxHeight ? tokens.maxHeight : props.maxHeight; const maxWidth = tokens && tokens.maxWidth ? tokens.maxWidth : props.maxWidth; const padding = tokens && tokens.padding ? tokens.padding : props.padding; - /* eslint-enable deprecation/deprecation */ + /* eslint-enable @typescript-eslint/no-deprecated */ const { rowGap, columnGap } = parseGap(childrenGap, theme); diff --git a/packages/react/src/components/Stack/Stack.test.tsx b/packages/react/src/components/Stack/Stack.test.tsx index e18f76beda414f..998dd3d46b6536 100644 --- a/packages/react/src/components/Stack/Stack.test.tsx +++ b/packages/react/src/components/Stack/Stack.test.tsx @@ -202,7 +202,7 @@ describe('Stack', () => { it('renders horizontal Stack with a gap in rtl context correctly', () => { const component = renderer.create( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated Item 1 diff --git a/packages/react/src/components/Stack/Stack.tsx b/packages/react/src/components/Stack/Stack.tsx index 259f45c7a26fce..30cf4eaea89e5f 100644 --- a/packages/react/src/components/Stack/Stack.tsx +++ b/packages/react/src/components/Stack/Stack.tsx @@ -13,7 +13,7 @@ const StackView: IStackComponent['view'] = props => { const { as: RootType = 'div', disableShrink = false, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated doNotRenderFalsyValues = false, enableScopedSelectors = false, wrap, diff --git a/packages/react/src/components/SwatchColorPicker/ColorPickerGridCell.base.tsx b/packages/react/src/components/SwatchColorPicker/ColorPickerGridCell.base.tsx index 1b7f5b957e787e..5c023c190d3de8 100644 --- a/packages/react/src/components/SwatchColorPicker/ColorPickerGridCell.base.tsx +++ b/packages/react/src/components/SwatchColorPicker/ColorPickerGridCell.base.tsx @@ -67,7 +67,7 @@ const getColorPickerGridCellButtonClassNames = memoizeFunction( export const ColorPickerGridCellBase: React.FunctionComponent = props => { const { item, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated idPrefix = props.id, isRadio, selected = false, diff --git a/packages/react/src/components/SwatchColorPicker/SwatchColorPicker.base.tsx b/packages/react/src/components/SwatchColorPicker/SwatchColorPicker.base.tsx index d2aaaa6ba45532..8aba7a3b805877 100644 --- a/packages/react/src/components/SwatchColorPicker/SwatchColorPicker.base.tsx +++ b/packages/react/src/components/SwatchColorPicker/SwatchColorPicker.base.tsx @@ -68,7 +68,7 @@ export const SwatchColorPickerBase: React.FunctionComponent): void => { if ( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated ev.which === KeyCodes.up || - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated ev.which === KeyCodes.down || - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated ev.which === KeyCodes.left || - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated ev.which === KeyCodes.right ) { setNavigationTimeout(); diff --git a/packages/react/src/components/TeachingBubble/TeachingBubble.base.tsx b/packages/react/src/components/TeachingBubble/TeachingBubble.base.tsx index f50adf04ac1978..a3105f614d053f 100644 --- a/packages/react/src/components/TeachingBubble/TeachingBubble.base.tsx +++ b/packages/react/src/components/TeachingBubble/TeachingBubble.base.tsx @@ -44,10 +44,10 @@ export const TeachingBubbleBase: React.FunctionComponent = const mergedRootRef = useMergedRefs(rootElementRef, forwardedRef); const { calloutProps: setCalloutProps, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated targetElement, onDismiss, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated hasCloseButton = props.hasCloseIcon, isWide, styles, diff --git a/packages/react/src/components/TeachingBubble/TeachingBubbleContent.base.tsx b/packages/react/src/components/TeachingBubble/TeachingBubbleContent.base.tsx index e25d246f429de3..b30cb0ca199ead 100644 --- a/packages/react/src/components/TeachingBubble/TeachingBubbleContent.base.tsx +++ b/packages/react/src/components/TeachingBubble/TeachingBubbleContent.base.tsx @@ -48,7 +48,7 @@ export const TeachingBubbleContentBase: React.FunctionComponent | KeyboardEvent): void => { if (onDismiss) { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.which === KeyCodes.escape) { onDismiss(ev); } diff --git a/packages/react/src/components/TextField/MaskedTextField/MaskedTextField.tsx b/packages/react/src/components/TextField/MaskedTextField/MaskedTextField.tsx index d9108ab0c4c9e9..d978282b2177b4 100644 --- a/packages/react/src/components/TextField/MaskedTextField/MaskedTextField.tsx +++ b/packages/react/src/components/TextField/MaskedTextField/MaskedTextField.tsx @@ -221,7 +221,7 @@ export const MaskedTextField: React.FunctionComponent = R const charsSelected = selectionEnd - selectionStart; const charCount = inputValue.length + charsSelected - displayValue.length; const startPos = selectionStart; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const pastedString = inputValue.substr(startPos, charCount); // Clear any selected characters @@ -252,7 +252,7 @@ export const MaskedTextField: React.FunctionComponent = R // This case is if the user added characters const charCount = inputValue.length - displayValue.length; const startPos = selectionEnd - charCount; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const enteredString = inputValue.substr(startPos, charCount); cursorPos = insertString(internalState.maskCharData, startPos, enteredString); @@ -264,7 +264,7 @@ export const MaskedTextField: React.FunctionComponent = R const charCount = 1; const selectCount = displayValue.length + charCount - inputValue.length; const startPos = selectionEnd - charCount; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const enteredString = inputValue.substr(startPos, charCount); // Clear the selected range @@ -292,7 +292,7 @@ export const MaskedTextField: React.FunctionComponent = R internalState.changeSelectionData = null; if (textField.current && textField.current.value) { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const { keyCode, ctrlKey, metaKey } = ev; // Ignore ctrl and meta keydown diff --git a/packages/react/src/components/TextField/TextField.base.tsx b/packages/react/src/components/TextField/TextField.base.tsx index 36395f784bd3ae..5b7625ce812c43 100644 --- a/packages/react/src/components/TextField/TextField.base.tsx +++ b/packages/react/src/components/TextField/TextField.base.tsx @@ -246,7 +246,7 @@ export class TextFieldBase })); return ( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated
{onRenderLabel(this.props, this._onRenderLabel)} diff --git a/packages/react/src/components/TimePicker/TimePicker.tsx b/packages/react/src/components/TimePicker/TimePicker.tsx index aafe9edf8f7eba..473d207f1ea8ce 100644 --- a/packages/react/src/components/TimePicker/TimePicker.tsx +++ b/packages/react/src/components/TimePicker/TimePicker.tsx @@ -191,7 +191,7 @@ export const TimePicker: React.FunctionComponent = ({ ); const evaluatePressedKey = (event: React.KeyboardEvent) => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const charCode = event.charCode; if ( !onFormatDate && diff --git a/packages/react/src/components/Toggle/Toggle.base.tsx b/packages/react/src/components/Toggle/Toggle.base.tsx index c5413d9f06e138..1d0ed33e5b9d0e 100644 --- a/packages/react/src/components/Toggle/Toggle.base.tsx +++ b/packages/react/src/components/Toggle/Toggle.base.tsx @@ -19,13 +19,13 @@ export const ToggleBase: React.FunctionComponent = React.forwardRe disabled, inlineLabel, label, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated offAriaLabel, offText, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated onAriaLabel, onChange, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated onChanged, onClick: onToggleClick, onText, diff --git a/packages/react/src/components/Tooltip/TooltipHost.base.tsx b/packages/react/src/components/Tooltip/TooltipHost.base.tsx index b769ccafd20edd..966fc56845d877 100644 --- a/packages/react/src/components/Tooltip/TooltipHost.base.tsx +++ b/packages/react/src/components/Tooltip/TooltipHost.base.tsx @@ -67,7 +67,7 @@ export class TooltipHostBase extends React.Component): void => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if ((ev.which === KeyCodes.escape || ev.ctrlKey) && this.state.isTooltipVisible) { this._hideTooltip(); ev.stopPropagation(); diff --git a/packages/react/src/components/WeeklyDayPicker/WeeklyDayPicker.base.tsx b/packages/react/src/components/WeeklyDayPicker/WeeklyDayPicker.base.tsx index 59379d5241fccf..986fc13dfd078c 100644 --- a/packages/react/src/components/WeeklyDayPicker/WeeklyDayPicker.base.tsx +++ b/packages/react/src/components/WeeklyDayPicker/WeeklyDayPicker.base.tsx @@ -280,7 +280,7 @@ export class WeeklyDayPickerBase extends React.Component) => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated switch (ev.which) { case KeyCodes.enter: ev.preventDefault(); @@ -297,7 +297,7 @@ export class WeeklyDayPickerBase extends React.Component void): ((ev: React.KeyboardEvent) => void) => { return (ev: React.KeyboardEvent) => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated switch (ev.which) { case KeyCodes.enter: callback(); diff --git a/packages/react/src/components/pickers/BasePicker.tsx b/packages/react/src/components/pickers/BasePicker.tsx index 2bf94ebfddb693..f9a15be205724e 100644 --- a/packages/react/src/components/pickers/BasePicker.tsx +++ b/packages/react/src/components/pickers/BasePicker.tsx @@ -119,7 +119,7 @@ export class BasePicker> protected SuggestionOfProperType = Suggestions as new (props: ISuggestionsProps) => Suggestions; protected currentPromise: PromiseLike | undefined; protected _ariaMap: IPickerAriaIds; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated private _styledSuggestions = getStyledSuggestions(this.SuggestionOfProperType); private _id: string; private _async: Async; @@ -527,7 +527,7 @@ export class BasePicker> protected onEmptyInputFocus() { const emptyResolveSuggestions = this.props.onEmptyResolveSuggestions ? this.props.onEmptyResolveSuggestions - : // eslint-disable-next-line deprecation/deprecation + : // eslint-disable-next-line @typescript-eslint/no-deprecated this.props.onEmptyInputFocus; // Only attempt to resolve suggestions if it exists @@ -706,7 +706,7 @@ export class BasePicker> }; protected onKeyDown = (ev: React.KeyboardEvent): void => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const keyCode = ev.which; switch (keyCode) { case KeyCodes.escape: @@ -954,7 +954,7 @@ export class BasePicker> protected _shouldFocusZoneEnterInnerZone = (ev: React.KeyboardEvent): boolean => { // If suggestions are shown const up/down keys control them, otherwise allow them through to control the focusZone. if (this.state.suggestionsVisible) { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated switch (ev.which) { case KeyCodes.up: case KeyCodes.down: @@ -962,7 +962,7 @@ export class BasePicker> } } - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.which === KeyCodes.enter) { return true; } @@ -1023,7 +1023,7 @@ export class BasePicker> return (
{ - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated this.getSuggestionsAlert(alertClassName) } {removedItemText} diff --git a/packages/react/src/components/pickers/PeoplePicker/PeoplePickerItems/PeoplePickerItem.types.ts b/packages/react/src/components/pickers/PeoplePicker/PeoplePickerItems/PeoplePickerItem.types.ts index ef05058274fd0f..ba9d4f61182d1c 100644 --- a/packages/react/src/components/pickers/PeoplePicker/PeoplePickerItems/PeoplePickerItem.types.ts +++ b/packages/react/src/components/pickers/PeoplePicker/PeoplePickerItems/PeoplePickerItem.types.ts @@ -118,7 +118,7 @@ export interface IPeoplePickerItemSuggestionStyles { * PeoplePickerItemWithMenu props interface. * @deprecated Do not use. Will be removed in \>= 7.0 */ -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated export interface IPeoplePickerItemWithMenuProps extends IPickerItemProps {} /** diff --git a/packages/react/src/components/pickers/PeoplePicker/PeoplePickerItems/SelectedItemDefault.tsx b/packages/react/src/components/pickers/PeoplePicker/PeoplePickerItems/SelectedItemDefault.tsx index 6d842d969844e9..675e786142ef69 100644 --- a/packages/react/src/components/pickers/PeoplePicker/PeoplePickerItems/SelectedItemDefault.tsx +++ b/packages/react/src/components/pickers/PeoplePicker/PeoplePickerItems/SelectedItemDefault.tsx @@ -45,7 +45,7 @@ export const SelectedItemDefault: (props: IPeoplePickerItemSelectedProps) => JSX
{ const tree = component.toJSON(); expect(tree).toMatchSnapshot(); }); + + it('accepts remove-button-data-id', () => { + const component = renderer.create( + + Red color + , + ); + const tree = component.toJSON(); + expect(tree).toMatchSnapshot(); + }); }); diff --git a/packages/react/src/components/pickers/TagPicker/TagItem.tsx b/packages/react/src/components/pickers/TagPicker/TagItem.tsx index 5bdb2ddb4a910d..cae157e3af2b8a 100644 --- a/packages/react/src/components/pickers/TagPicker/TagItem.tsx +++ b/packages/react/src/components/pickers/TagPicker/TagItem.tsx @@ -25,6 +25,7 @@ export const TagItemBase = (props: ITagItemProps) => { removeButtonAriaLabel, title = typeof props.children === 'string' ? props.children : props.item.name, removeButtonIconProps, + removeButtonProps, } = props; const buttonRef = React.createRef(); @@ -65,6 +66,7 @@ export const TagItemBase = (props: ITagItemProps) => { styles={{ icon: { fontSize: '12px' } }} className={classNames.close} aria-labelledby={`${itemId}-removeLabel ${itemId}-text`} + {...removeButtonProps} />