diff --git a/.devops/templates/tools.yml b/.devops/templates/tools.yml index 7d9e9af92f0fe3..401560f408bdfc 100644 --- a/.devops/templates/tools.yml +++ b/.devops/templates/tools.yml @@ -38,3 +38,9 @@ steps: echo number of CPUs "$(getconf _NPROCESSORS_ONLN)" displayName: Log environment variables (Linux) condition: eq(variables['Agent.OS'], 'Linux') + + # Logs a message when dry run mode is enabled. + - script: | + echo "dry run mode enabled!" + displayName: dry run mode notification + condition: eq(variables.dryRun, true) diff --git a/.devops/templates/variables.yml b/.devops/templates/variables.yml index a72a48c528ab88..277d3b48c7db93 100644 --- a/.devops/templates/variables.yml +++ b/.devops/templates/variables.yml @@ -43,3 +43,6 @@ variables: deployBasePath: ${{ coalesce(parameters.deployBasePath, replace(variables['Build.SourceBranch'], 'refs/', '')) }} skipComponentGovernanceDetection: ${{ parameters.skipComponentGovernanceDetection }} + + # Dry run mode for testing the pipeline without making changes + dryRun: false diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index f96863764909da..f439834d903e6d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -121,6 +121,7 @@ apps/ts-minbar-test-react @microsoft/fluentui-react-build apps/ts-minbar-test-react-components @microsoft/fluentui-react-build apps/vr-tests @microsoft/fluentui-react apps/vr-tests-react-components @microsoft/fluentui-react +apps/vr-tests-react-components/src/stories/Charts @microsoft/charting-team apps/vr-tests-web-components @microsoft/fui-wc apps/ssr-tests @microsoft/fluentui-react apps/pr-deploy-site @microsoft/fluentui-react-build @@ -132,8 +133,9 @@ apps/react-18-tests-v9 @microsoft/fluentui-react-build apps/chart-docsite @microsoft/charting-team #### Packages -packages/azure-themes @Jacqueline-ms @robtaft-ms +packages/azure-themes @Jacqueline-ms packages/react-conformance @microsoft/fluentui-react-build +packages/charts/chart-web-components @microsoft/charting-team packages/charts/react-charting @microsoft/charting-team packages/charts/react-charts-preview/library @microsoft/charting-team packages/charts/react-charts-preview/stories @microsoft/charting-team @@ -191,93 +193,64 @@ common/_common.scss @microsoft/cxe-red @phkuo ## vNext packages packages/react-components/keyboard-keys @microsoft/teams-prg -packages/react-components/react-accordion @microsoft/cxe-prg packages/react-components/react-accordion/library @microsoft/cxe-prg packages/react-components/react-accordion/stories @microsoft/cxe-prg -packages/react-components/react-avatar @microsoft/cxe-prg packages/react-components/react-avatar/library @microsoft/cxe-prg packages/react-components/react-avatar/stories @microsoft/cxe-prg -packages/react-components/react-badge @microsoft/cxe-prg packages/react-components/react-badge/library @microsoft/cxe-prg packages/react-components/react-badge/stories @microsoft/cxe-prg -packages/react-components/react-button @microsoft/cxe-red @khmakoto packages/react-components/react-button/library @microsoft/cxe-red @khmakoto packages/react-components/react-button/stories @microsoft/cxe-red @khmakoto -packages/react-components/react-card @microsoft/cxe-prg @marcosmoura packages/react-components/react-card/library @microsoft/cxe-prg @marcosmoura packages/react-components/react-card/stories @microsoft/cxe-prg @marcosmoura -packages/react-components/react-checkbox @microsoft/cxe-prg packages/react-components/react-checkbox/library @microsoft/cxe-prg packages/react-components/react-checkbox/stories @microsoft/cxe-prg -packages/react-components/react-combobox @microsoft/cxe-prg @microsoft/teams-prg packages/react-components/react-combobox/library @microsoft/cxe-prg @microsoft/teams-prg packages/react-components/react-combobox/stories @microsoft/cxe-prg @microsoft/teams-prg packages/react-components/react-components @microsoft/fluentui-react -packages/react-components/react-dialog @microsoft/teams-prg packages/react-components/react-dialog/library @microsoft/teams-prg packages/react-components/react-dialog/stories @microsoft/teams-prg -packages/react-components/react-divider @microsoft/cxe-prg packages/react-components/react-divider/library @microsoft/cxe-prg packages/react-components/react-divider/stories @microsoft/cxe-prg -packages/react-components/react-field @microsoft/cxe-prg packages/react-components/react-field/library @microsoft/cxe-prg packages/react-components/react-field/stories @microsoft/cxe-prg packages/react-focus @microsoft/cxe-red @khmakoto -packages/react-components/react-image @microsoft/cxe-prg packages/react-components/react-image/library @microsoft/cxe-prg packages/react-components/react-image/stories @microsoft/cxe-prg -packages/react-components/react-input @microsoft/cxe-prg packages/react-components/react-input/library @microsoft/cxe-prg packages/react-components/react-input/stories @microsoft/cxe-prg -packages/react-components/react-label @microsoft/cxe-prg packages/react-components/react-label/library @microsoft/cxe-prg packages/react-components/react-label/stories @microsoft/cxe-prg -packages/react-components/react-link @microsoft/cxe-prg packages/react-components/react-link/library @microsoft/cxe-prg packages/react-components/react-link/stories @microsoft/cxe-prg -packages/react-components/react-menu @microsoft/teams-prg packages/react-components/react-menu/library @microsoft/teams-prg packages/react-components/react-menu/stories @microsoft/teams-prg -packages/react-components/react-popover @microsoft/teams-prg packages/react-components/react-popover/library @microsoft/teams-prg packages/react-components/react-popover/stories @microsoft/teams-prg -packages/react-components/react-portal @microsoft/teams-prg packages/react-components/react-portal/library @microsoft/teams-prg packages/react-components/react-portal/stories @microsoft/teams-prg -packages/react-components/react-provider @microsoft/teams-prg packages/react-components/react-provider/library @microsoft/teams-prg packages/react-components/react-provider/stories @microsoft/teams-prg -packages/react-components/react-radio @microsoft/cxe-red @behowell @spmonahan packages/react-components/react-radio/library @microsoft/cxe-red @behowell @spmonahan packages/react-components/react-radio/stories @microsoft/cxe-red @behowell @spmonahan -packages/react-components/react-select @microsoft/cxe-prg packages/react-components/react-select/library @microsoft/cxe-prg packages/react-components/react-select/stories @microsoft/cxe-prg -packages/react-components/react-slider @microsoft/cxe-prg packages/react-components/react-slider/library @microsoft/cxe-prg packages/react-components/react-slider/stories @microsoft/cxe-prg -packages/react-components/react-spinbutton @microsoft/cxe-prg packages/react-components/react-spinbutton/library @microsoft/cxe-prg packages/react-components/react-spinbutton/stories @microsoft/cxe-prg -packages/react-components/react-spinner @microsoft/cxe-prg packages/react-components/react-spinner/library @microsoft/cxe-prg packages/react-components/react-spinner/stories @microsoft/cxe-prg -packages/react-components/react-switch @microsoft/cxe-prg packages/react-components/react-switch/library @microsoft/cxe-prg packages/react-components/react-switch/stories @microsoft/cxe-prg -packages/react-components/react-tabs @microsoft/cxe-prg @dmytrokirpa packages/react-components/react-tabs/library @microsoft/cxe-prg @dmytrokirpa packages/react-components/react-tabs/stories @microsoft/cxe-prg @dmytrokirpa -packages/react-components/react-text @microsoft/cxe-prg @marcosmoura packages/react-components/react-text/library @microsoft/cxe-prg @marcosmoura packages/react-components/react-text/stories @microsoft/cxe-prg @marcosmoura -packages/react-components/react-textarea @microsoft/cxe-prg packages/react-components/react-textarea/library @microsoft/cxe-prg packages/react-components/react-textarea/stories @microsoft/cxe-prg -packages/react-components/react-tooltip @microsoft/cxe-prg packages/react-components/react-tooltip/library @microsoft/cxe-prg packages/react-components/react-tooltip/stories @microsoft/cxe-prg -packages/react-components/react-toolbar @microsoft/teams-prg @chpalac @ling1726 packages/react-components/react-toolbar/library @microsoft/teams-prg @chpalac @ling1726 packages/react-components/react-toolbar/stories @microsoft/teams-prg @chpalac @ling1726 packages/react-components/react-portal-compat @microsoft/teams-prg @@ -286,88 +259,63 @@ packages/react-components/react-theme-sass @microsoft/teams-prg packages/react-components/theme-designer @microsoft/cxe-red @ms-acalzaretto packages/react-components/global-context @microsoft/teams-prg packages/react-components/babel-preset-global-context @microsoft/teams-prg -packages/react-components/react-table @microsoft/teams-prg packages/react-components/react-table/library @microsoft/teams-prg packages/react-components/react-table/stories @microsoft/teams-prg -packages/react-components/react-progress @microsoft/cxe-prg packages/react-components/react-progress/library @microsoft/cxe-prg packages/react-components/react-progress/stories @microsoft/cxe-prg -packages/react-components/react-persona @microsoft/cxe-prg packages/react-components/react-persona/library @microsoft/cxe-prg packages/react-components/react-persona/stories @microsoft/cxe-prg -packages/react-components/react-tree @microsoft/teams-prg packages/react-components/react-tree/library @microsoft/teams-prg packages/react-components/react-tree/stories @microsoft/teams-prg -packages/react-components/react-virtualizer @microsoft/xc-uxe @Mitch-At-Work packages/react-components/react-virtualizer/library @microsoft/xc-uxe @Mitch-At-Work packages/react-components/react-virtualizer/stories @microsoft/xc-uxe @Mitch-At-Work -packages/react-components/react-skeleton @microsoft/cxe-prg packages/react-components/react-skeleton/library @microsoft/cxe-prg packages/react-components/react-skeleton/stories @microsoft/cxe-prg packages/tokens @microsoft/teams-prg -packages/react-components/react-tags @microsoft/cxe-prg @microsoft/teams-prg packages/react-components/react-tags/library @microsoft/cxe-prg @microsoft/teams-prg packages/react-components/react-tags/stories @microsoft/cxe-prg @microsoft/teams-prg packages/react-components/react-migration-v0-v9/library @microsoft/teams-prg packages/react-components/react-migration-v0-v9/stories @microsoft/teams-prg -packages/react-components/react-datepicker-compat @microsoft/cxe-prg packages/react-components/react-datepicker-compat/library @microsoft/cxe-prg packages/react-components/react-datepicker-compat/stories @microsoft/cxe-prg packages/react-components/react-migration-v8-v9/library @microsoft/cxe-prg @geoffcoxmsft packages/react-components/react-migration-v8-v9/stories @microsoft/cxe-prg @geoffcoxmsft -packages/react-components/react-breadcrumb @microsoft/cxe-prg packages/react-components/react-breadcrumb/library @microsoft/cxe-prg packages/react-components/react-breadcrumb/stories @microsoft/cxe-prg -packages/react-components/react-drawer @microsoft/cxe-prg @marcosmoura packages/react-components/react-drawer/library @microsoft/cxe-prg @marcosmoura packages/react-components/react-drawer/stories @microsoft/cxe-prg @marcosmoura packages/react-components/react-storybook-addon-export-to-sandbox @microsoft/fluentui-react-build packages/react-components/babel-preset-storybook-full-source @microsoft/fluentui-react-build packages/react-components/react-jsx-runtime @microsoft/teams-prg -packages/react-components/react-toast @microsoft/teams-prg packages/react-components/react-toast/library @microsoft/teams-prg packages/react-components/react-toast/stories @microsoft/teams-prg -packages/react-components/react-search @microsoft/cxe-prg packages/react-components/react-search/library @microsoft/cxe-prg packages/react-components/react-search/stories @microsoft/cxe-prg packages/react-components/react-colorpicker-compat @microsoft/cxe-red @sopranopillow -packages/react-components/react-nav-preview @microsoft/cxe-red @microsoft/xc-uxe @mltejera packages/react-components/react-nav-preview/library @microsoft/cxe-red @microsoft/xc-uxe @mltejera packages/react-components/react-nav-preview/stories @microsoft/cxe-red @microsoft/xc-uxe @mltejera -packages/react-components/react-message-bar @microsoft/teams-prg packages/react-components/react-message-bar/library @microsoft/teams-prg packages/react-components/react-message-bar/stories @microsoft/teams-prg -packages/react-components/react-rating @microsoft/cxe-prg packages/react-components/react-rating/library @microsoft/cxe-prg packages/react-components/react-rating/stories @microsoft/cxe-prg -packages/react-components/react-swatch-picker @microsoft/cxe-prg packages/react-components/react-swatch-picker/library @microsoft/cxe-prg packages/react-components/react-swatch-picker/stories @microsoft/cxe-prg -packages/react-components/react-calendar-compat @microsoft/cxe-prg packages/react-components/react-calendar-compat/library @microsoft/cxe-prg packages/react-components/react-calendar-compat/stories @microsoft/cxe-prg -packages/react-components/react-infolabel @microsoft/cxe-prg packages/react-components/react-infolabel/library @microsoft/cxe-prg packages/react-components/react-infolabel/stories @microsoft/cxe-prg -packages/react-components/react-list-preview @microsoft/teams-prg -packages/react-components/react-list-preview/library @microsoft/teams-prg -packages/react-components/react-list-preview/stories @microsoft/teams-prg -packages/react-components/react-motion @microsoft/teams-prg +packages/react-components/react-list/library @microsoft/teams-prg +packages/react-components/react-list/stories @microsoft/teams-prg packages/react-components/react-motion/library @microsoft/teams-prg packages/react-components/react-motion/stories @microsoft/teams-prg -packages/react-components/react-teaching-popover @microsoft/xc-uxe @Mitch-At-Work packages/react-components/react-teaching-popover/library @microsoft/xc-uxe @Mitch-At-Work packages/react-components/react-teaching-popover/stories @microsoft/xc-uxe @Mitch-At-Work -packages/react-components/react-timepicker-compat @microsoft/teams-prg packages/react-components/react-timepicker-compat/library @microsoft/teams-prg packages/react-components/react-timepicker-compat/stories @microsoft/teams-prg -packages/react-components/react-icons-compat @microsoft/cxe-red @tomi-msft packages/react-components/react-icons-compat/library @microsoft/cxe-red @tomi-msft packages/react-components/react-icons-compat/stories @microsoft/cxe-red @tomi-msft -packages/react-components/react-tag-picker @microsoft/teams-prg packages/react-components/react-tag-picker/library @microsoft/teams-prg packages/react-components/react-tag-picker/stories @microsoft/teams-prg -packages/react-components/react-carousel @microsoft/xc-uxe @microsoft/teams-prg @Mitch-At-Work packages/react-components/react-carousel/library @microsoft/xc-uxe @microsoft/teams-prg @Mitch-At-Work packages/react-components/react-carousel/stories @microsoft/xc-uxe @microsoft/teams-prg @Mitch-At-Work packages/react-components/recipes @microsoft/fluentui-react @sopranopillow @@ -430,6 +378,7 @@ packages/react/src/components/WeeklyDayPicker @microsoft/cxe-red packages/react/src/utilities/ThemeProvider @microsoft/cxe-red @dzearing packages/fluent2-theme @microsoft/cxe-red @geoffcoxmsft ## Experiments +packages/react-experiments @microsoft/cxe-red packages/react-experiments/src/components/Signals @ThomasMichon packages/react-experiments/src/components/Tile @ThomasMichon packages/react-experiments/src/components/TileList @ThomasMichon 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/actions/run-publish-vr-screenshot/action.yml b/.github/actions/run-publish-vr-screenshot/action.yml index 8be472a2b66ce0..126e44de7c69d8 100644 --- a/.github/actions/run-publish-vr-screenshot/action.yml +++ b/.github/actions/run-publish-vr-screenshot/action.yml @@ -84,58 +84,64 @@ runs: path: screenshots # ========================================================== - # STEPS BELOW WILL FAIL TO RUN ON GITHUB ACTIONS - see TODOs + # STEPS BELOW WILL FAIL TO RUN ON GITHUB ACTIONS - see @TODOs # ========================================================== + # + # @TODO: will need Federated Identity to be added to tool similarly like we have for monosize azure plugin https://github.com/microsoft/monosize/blob/main/packages/monosize-storage-azure/src/createTableClient.mts#L27 + # - name: VR App - Create Policy + # if: ${{ env.isPR == 'true' && env.vrTestSkip == 'no' }} + # shell: bash + # run: | + # set -exuo pipefail + # npx vr-approval-cli@0.4.11 create-policy --nonBlockingPipelines '{"${{ env.pipelineId }}":{"pipelineStatus": "PENDING","pipelineName": "${{ env.pipelineName }}"}}' --clientType 'FLUENTUI' + # env: + # VR_APP_API_URL: ${{ secrets.VR_APP_API_URL }} + # TENANT_ID: ${{ secrets.TenantId }} + # PRINCIPAL_CLIENT_ID: ${{ secrets.PrincipalClientId }} + # SERVICE_CONNECTION_ID: ${{ secrets.ServiceConnectionId }} + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # TODO: will need Federated Identity to be added to tool similarly like we have for monosize azure plugin https://github.com/microsoft/monosize/blob/main/packages/monosize-storage-azure/src/createTableClient.mts#L27 - - name: VR App - Create Policy - if: ${{ env.isPR == 'true' }} - shell: bash - run: | - set -exuo pipefail - npx vr-approval-cli@0.4.11 create-policy --nonBlockingPipelines '{"${{ env.pipelineId }}":{"pipelineStatus": "PENDING","pipelineName": "${{ env.pipelineName }}"}}' --clientType 'FLUENTUI' - env: - VR_APP_API_URL: ${{ secrets.VR_APP_API_URL }} - TENANT_ID: ${{ secrets.TenantId }} - PRINCIPAL_CLIENT_ID: ${{ secrets.PrincipalClientId }} - SERVICE_CONNECTION_ID: ${{ secrets.ServiceConnectionId }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # @TODO: will need azure/login@v2 to be added to the workflow {@link file://./../../workflows/pr-website-deploy-comment.yml#49} + # - name: Run screenshotdiff + # if: ${{ env.isPR == 'true' && env.vrTestSkip == 'no' }} + # uses: azure/cli@v2 + # env: + # ciDefinitionId is set to 205 because that is the ID of the baseline pipeline (https://uifabric.visualstudio.com/fabricpublic/_build?definitionId=205) used by the master branch + # TODO: not sure how this will be used on GHA cc @evancharlton @TristanWatanabe + # CI_DEFINITION_ID: 205 + # API_TOKEN: ${{ secrets.fabric-public-pipeline-access-PAT }} + # GITHUB_API_TOKEN: ${{ secrets.githubRepoStatusPAT }} + # VR_APP_API_URL: ${{ secrets.VR_APP_API_URL }} + # STORAGE_ACCOUNT_ID: ${{ secrets.StorageAccountId }} + # TENANT_ID: ${{ secrets.TenantId }} + # PRINCIPAL_CLIENT_ID: ${{ secrets.PrincipalClientId }} + # SERVICE_CONNECTION_ID: ${{ secrets.ServiceConnectionId }} + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # with: + # azcliversion: latest + # inlineScript: | + # npx vr-approval-cli@0.4.11 run-diff --screenshotsDirectory ./screenshots --buildType pr --clientType "FLUENTUI" --ciDefinitionId ${{ env.CI_DEFINITION_ID }} --groupName ${{ env.pipelineName }} --locationPrefix ${{ inputs.locationPrefix }} --locationPostfix ${{ inputs.locationPostfix }} --pipelineId ${{ env.pipelineId }} --clientName ${{ inputs.clientName }} --threshold '0.04' --cumThreshold '1' - # TODO: will need azure/login@v2 to be added to the workflow {@ling file://./../../workflows/pr-website-deploy-comment.yml#49} - - name: Run screenshotdiff - if: ${{ env.isPR == 'true' && env.vrTestSkip == 'no' }} - uses: azure/cli@v2 - env: - # ciDefinitionId is set to 205 because that is the ID of the baseline pipeline (https://uifabric.visualstudio.com/fabricpublic/_build?definitionId=205) used by the master branch - # TODO: not sure how this will be used on GHA cc @evancharlton @TristanWatanabe - CI_DEFINITION_ID: 205 - API_TOKEN: ${{ secrets.fabric-public-pipeline-access-PAT }} - GITHUB_API_TOKEN: ${{ secrets.githubRepoStatusPAT }} - VR_APP_API_URL: ${{ secrets.VR_APP_API_URL }} - STORAGE_ACCOUNT_ID: ${{ secrets.StorageAccountId }} - TENANT_ID: ${{ secrets.TenantId }} - PRINCIPAL_CLIENT_ID: ${{ secrets.PrincipalClientId }} - SERVICE_CONNECTION_ID: ${{ secrets.ServiceConnectionId }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - azcliversion: latest - inlineScript: | - npx vr-approval-cli@0.4.11 run-diff --screenshotsDirectory ./screenshots --buildType pr --clientType "FLUENTUI" --ciDefinitionId ${{ env.CI_DEFINITION_ID }} --groupName ${{ env.pipelineName }} --locationPrefix ${{ inputs.locationPrefix }} --locationPostfix ${{ inputs.locationPostfix }} --pipelineId ${{ env.pipelineId }} --clientName ${{ inputs.clientName }} --threshold '0.04' --cumThreshold '1' + # ============ + # NON PR STEPS + # ============ - # TODO: will need azure/login@v2 to be added to the workflow {@ling file://./../../workflows/pr-website-deploy-comment.yml#49} - - name: Run screenshotdiff - update baseline (non PR) - if: ${{ github.event_name != 'pull_request' }} - uses: azure/cli@v2 - env: - API_TOKEN: ${{ secrets.fabric-public-pipeline-access-PAT }} - GITHUB_API_TOKEN: ${{ secrets.githubRepoStatusPAT }} - VR_APP_API_URL: ${{ secrets.VR_APP_API_URL }} - STORAGE_ACCOUNT_ID: ${{ secrets.StorageAccountId }} - TENANT_ID: ${{ secrets.TenantId }} - PRINCIPAL_CLIENT_ID: ${{ secrets.PrincipalClientId }} - SERVICE_CONNECTION_ID: ${{ secrets.ServiceConnectionId }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - azcliversion: latest - inlineScript: | - npx vr-approval-cli@0.4.11 run-diff --buildType release --screenshotsDirectory ./screenshots --clientType "FLUENTUI" --locationPrefix ${{ inputs.locationPrefix }} --locationPostfix ${{ inputs.locationPostfix }} --pipelineId ${{ env.pipelineId }} + # @NOTE: this step runs via ADO from master branch only for now {@link file://./../../../azure-pipelines.vrt-baseline.yml } + + # @TODO: will need azure/login@v2 to be added to the workflow {@link file://./../../workflows/pr-website-deploy-comment.yml#49} + # - name: Run screenshotdiff - update baseline (non PR) + # if: ${{ github.event_name != 'pull_request' }} + # uses: azure/cli@v2 + # env: + # API_TOKEN: ${{ secrets.fabric-public-pipeline-access-PAT }} + # GITHUB_API_TOKEN: ${{ secrets.githubRepoStatusPAT }} + # VR_APP_API_URL: ${{ secrets.VR_APP_API_URL }} + # STORAGE_ACCOUNT_ID: ${{ secrets.StorageAccountId }} + # TENANT_ID: ${{ secrets.TenantId }} + # PRINCIPAL_CLIENT_ID: ${{ secrets.PrincipalClientId }} + # SERVICE_CONNECTION_ID: ${{ secrets.ServiceConnectionId }} + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # with: + # azcliversion: latest + # inlineScript: | + # npx vr-approval-cli@0.4.11 run-diff --buildType release --screenshotsDirectory ./screenshots --clientType "FLUENTUI" --locationPrefix ${{ inputs.locationPrefix }} --locationPostfix ${{ inputs.locationPostfix }} --pipelineId ${{ env.pipelineId }} diff --git a/.github/scripts/prepare-vr-screenshots-for-upload.js b/.github/scripts/prepare-vr-screenshots-for-upload.js new file mode 100644 index 00000000000000..7c0367587796e4 --- /dev/null +++ b/.github/scripts/prepare-vr-screenshots-for-upload.js @@ -0,0 +1,46 @@ +// @ts-check + +const { join } = require('node:path'); +const { existsSync, cpSync, mkdirSync, writeFileSync } = require('node:fs'); +const { createProjectGraphAsync } = require('@nx/devkit'); + +module.exports = main; + +/** + * + * @param {import('../../scripts/triage-bot/src/types.ts').GithubScriptsParams & {config:{projects:string[]}} } options + * @returns + */ +async function main(options) { + const rootDir = 'screenshots'; + const graph = await createProjectGraphAsync(); + + /** + * @type {{[project_name:string]:{path:string}}} + */ + const report = {}; + + options.config.projects.forEach(project => { + const projectConfig = graph.nodes[project]; + const screenshotsPath = join(projectConfig.data.root, 'dist/screenshots'); + + if (!existsSync(screenshotsPath)) { + return; + } + + const destinationFolder = join(rootDir, project); + + mkdirSync(destinationFolder, { recursive: true }); + + cpSync(screenshotsPath, destinationFolder, { + recursive: true, + }); + + console.info(`✅ ${screenshotsPath} contents copied to ${destinationFolder}`); + report[project] = { path: project }; + }); + + writeFileSync(join(rootDir, 'screenshots-report.json'), JSON.stringify(report, null, 2)); + + return rootDir; +} diff --git a/.github/workflows/azure-static-web-apps-deploy.yml b/.github/workflows/azure-static-web-apps-deploy.yml index 1e049feb7b0b2c..bd29d2351ec5a1 100644 --- a/.github/workflows/azure-static-web-apps-deploy.yml +++ b/.github/workflows/azure-static-web-apps-deploy.yml @@ -13,6 +13,7 @@ permissions: jobs: build_and_deploy: + if: ${{ github.repository_owner == 'microsoft' }} runs-on: ubuntu-latest name: Build and Deploy Job steps: diff --git a/.github/workflows/bundle-size-base.yml b/.github/workflows/bundle-size-base.yml index cf71367ac61bc0..1c2aa9fb32bfd4 100644 --- a/.github/workflows/bundle-size-base.yml +++ b/.github/workflows/bundle-size-base.yml @@ -18,6 +18,7 @@ env: jobs: bundle-size-base: + if: ${{ github.repository_owner == 'microsoft' }} # TODO: use macos-14-xlarge (arm) for faster builds once https://github.com/Azure/cli/issues/172 will be fixed runs-on: ubuntu-latest permissions: diff --git a/.github/workflows/bundle-size-comment.yml b/.github/workflows/bundle-size-comment.yml index 9f2c116816e7c4..14715007aec7e8 100644 --- a/.github/workflows/bundle-size-comment.yml +++ b/.github/workflows/bundle-size-comment.yml @@ -8,7 +8,7 @@ on: jobs: comment: runs-on: ubuntu-latest - if: ${{ github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' }} + if: ${{ github.repository_owner == 'microsoft' }} && ${{ github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' }} permissions: pull-requests: write steps: diff --git a/.github/workflows/bundle-size.yml b/.github/workflows/bundle-size.yml index e523e3066e049e..adeabf8c750305 100644 --- a/.github/workflows/bundle-size.yml +++ b/.github/workflows/bundle-size.yml @@ -16,6 +16,7 @@ env: jobs: bundle-size: + if: ${{ github.repository_owner == 'microsoft' }} runs-on: macos-14-xlarge permissions: contents: 'read' diff --git a/.github/workflows/check-packages.yml b/.github/workflows/check-packages.yml index 8fadfbeedb554e..338a77e578bd90 100644 --- a/.github/workflows/check-packages.yml +++ b/.github/workflows/check-packages.yml @@ -5,6 +5,7 @@ on: jobs: dependency-deduplication: runs-on: ubuntu-latest + if: ${{ github.repository_owner == 'microsoft' }} steps: - uses: actions/checkout@v4 with: @@ -37,6 +38,7 @@ jobs: dependency-mismatches: runs-on: ubuntu-latest + if: ${{ github.repository_owner == 'microsoft' }} steps: - uses: actions/checkout@v4 with: @@ -63,6 +65,7 @@ jobs: change-files: runs-on: ubuntu-latest + if: ${{ github.repository_owner == 'microsoft' }} steps: - uses: actions/checkout@v4 with: diff --git a/.github/workflows/check-tooling.yml b/.github/workflows/check-tooling.yml index d43b425484aa17..9004893bb3bc49 100644 --- a/.github/workflows/check-tooling.yml +++ b/.github/workflows/check-tooling.yml @@ -14,6 +14,7 @@ env: jobs: check-tools: + if: ${{ github.repository_owner == 'microsoft' }} strategy: matrix: os: [ubuntu-latest, windows-latest] diff --git a/.github/workflows/create-milestone.yml b/.github/workflows/create-milestone.yml index 36fac805beb64a..14acf3cf83f372 100644 --- a/.github/workflows/create-milestone.yml +++ b/.github/workflows/create-milestone.yml @@ -10,6 +10,7 @@ permissions: jobs: create-milestone: + if: ${{ github.repository_owner == 'microsoft' }} name: Create this month's milestone runs-on: ubuntu-latest steps: diff --git a/.github/workflows/docsite-publish-ghpages.yml b/.github/workflows/docsite-publish-ghpages.yml index d22b389deedd2d..666616fd2f5a13 100644 --- a/.github/workflows/docsite-publish-ghpages.yml +++ b/.github/workflows/docsite-publish-ghpages.yml @@ -10,7 +10,7 @@ on: jobs: check: runs-on: ubuntu-latest - if: ${{ contains(github.event.head_commit.message, 'applying package updates') || github.event_name == 'workflow_dispatch' }} + if: ${{ github.repository_owner == 'microsoft' }} && ${{ contains(github.event.head_commit.message, 'applying package updates') || github.event_name == 'workflow_dispatch' }} outputs: status: ${{ steps.verify-react-components-changed.outputs.any_changed == 'true' || github.event_name == 'workflow_dispatch' }} @@ -37,7 +37,7 @@ jobs: - uses: actions/setup-node@v4 with: - node-version: 20.x + node-version: 20 cache: 'yarn' - name: Install packages @@ -49,9 +49,10 @@ jobs: STORYBOOK_APPINSIGHTS_INSTRUMENTATION_KEY: ${{ secrets.STORYBOOK_APPINSIGHTS_INSTRUMENTATION_KEY }} - name: Upload Pages Artifact - uses: actions/upload-pages-artifact@v1 + uses: actions/upload-pages-artifact@v3 with: path: './apps/public-docsite-v9/dist/storybook/' + deploy: runs-on: ubuntu-latest needs: build @@ -69,4 +70,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v1 + uses: actions/deploy-pages@v4 diff --git a/.github/workflows/pr-housekeeping.yml b/.github/workflows/pr-housekeeping.yml index cc099a3290ad1c..2b6d63086c61da 100644 --- a/.github/workflows/pr-housekeeping.yml +++ b/.github/workflows/pr-housekeeping.yml @@ -9,6 +9,7 @@ permissions: jobs: label: + if: ${{ github.repository_owner == 'microsoft' }} runs-on: ubuntu-latest steps: - uses: actions/labeler@v5 @@ -18,6 +19,7 @@ jobs: configuration-path: .github/labeler.yml assign-to-current-milestone: + if: ${{ github.repository_owner == 'microsoft' }} runs-on: ubuntu-latest steps: - name: Assign to latest milestone diff --git a/.github/workflows/pr-vrt-comment.yml b/.github/workflows/pr-vrt-comment.yml new file mode 100644 index 00000000000000..e60ea899fc1e7f --- /dev/null +++ b/.github/workflows/pr-vrt-comment.yml @@ -0,0 +1,167 @@ +name: VRT CI | Comment on PR +on: + workflow_run: + workflows: ['VRT CI'] + types: + - completed + +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 + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + NX_PARALLEL: 4 # ubuntu-latest = 4-core CPU / 16 GB of RAM | macos-14-xlarge (arm) = 6-core CPU / 14 GB of RAM + NX_PREFER_TS_NODE: true + NX_VERBOSE_LOGGING: true + +jobs: + run_vr_diff: + runs-on: ubuntu-latest + if: ${{ github.repository_owner == 'microsoft' }} && ${{ github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' }} + outputs: + pr_number: ${{ steps.pr_number.outputs.result }} + permissions: + # necessary to write comments to the PR from the vr-approval-cli + pull-requests: write + id-token: write + steps: + - uses: actions/checkout@v4 + with: + sparse-checkout: | + .github + + # downloaded artifacts will contain screenshots from affected project including 'screenshots-report.json' which contains proper image mappings for affected project + # - see @{link file://./../scripts/prepare-vr-screenshots-for-upload.js#43} + # - see @{link file://./pr-vrt.yml#56} + - uses: actions/download-artifact@v4 + with: + name: vrscreenshot + path: ./screenshots + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + - uses: actions/download-artifact@v4 + with: + name: pr-number + path: ./results + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Load PR number + uses: actions/github-script@v7 + id: pr_number + with: + script: | + const run = require('./.github/scripts/validate-pr-number'); + const result = run({filePath:'results/pr.txt'}); + return result; + result-encoding: string + + - name: VR App - Create Policy + run: | + echo "MAKE THIS STEP WORK" + + - name: Login via Azure CLI + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + + - name: Fetch Access Token + run: | + echo "ACCESSTOKEN=$(az account get-access-token --query accessToken --output tsv)" >> $GITHUB_ENV + + - name: Run screenshotdiff + env: + VR_APP_API_URL: 'https://vrapprovaldev2.azurewebsites.net/api/' + STORAGE_ACCOUNT_ID: 'https://onejstestartifactsprod.blob.core.windows.net/' + SYSTEM_ACCESSTOKEN: ${{ env.ACCESSTOKEN }} + TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} + PRINCIPAL_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} + SERVICE_CONNECTION_ID: ${{ secrets.ADO_VRT_SERVICE_CONNECTION_ID }} + GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + echo "MAKE THIS WORK" + npx vr-approval-cli@0.4.11 run-diff --screenshotsDirectory ./screenshots --buildType pr --clientType "FLUENTUI" --threshold '0.04' --cumThreshold '1' + +# 💡 NOTE: +# - following is manually provided setup used in previous ADO pipeline {@link file://./../../azure-pipelines.vrt-baseline.yml } +# - keeping for future reference + +# web_components: +# runs-on: ubuntu-latest +# env: +# pipelineId: '315' +# pipelineName: 'fluent-ui_VRT_Pipeline_web-components' +# steps: +# - uses: actions/checkout@v4 +# with: +# fetch-depth: 0 +# - name: Run and publish VR screenshot +# uses: ./.github/actions/run-publish-vr-screenshot +# with: +# fluentVersion: webcomponents +# vrTestPackageName: 'vr-tests-web-components' +# vrTestPackagePath: 'apps/vr-tests-web-components' +# locationPrefix: 'FluentUI-web-components' +# locationPostfix: 'vrscreenshotwebcomponents' +# clientName: 'fluentui-web-components-v3' + +# react_components: +# runs-on: ubuntu-latest +# env: +# pipelineId: '311' +# pipelineName: 'fluent-ui_VRT_Pipeline_v9' +# steps: +# - uses: actions/checkout@v4 +# with: +# fetch-depth: 0 +# - name: Run and publish VR screenshot +# uses: ./.github/actions/run-publish-vr-screenshot +# with: +# fluentVersion: v9 +# vrTestPackageName: 'vr-tests-react-components' +# vrTestPackagePath: 'apps/vr-tests-react-components' +# locationPrefix: 'fluentuiv9' +# locationPostfix: 'vrscreenshotv9' +# clientName: 'fluentuiv9' + +# react: +# runs-on: ubuntu-latest +# env: +# pipelineId: '312' +# pipelineName: 'fluent-ui_VRT_Pipeline_v8' +# steps: +# - uses: actions/checkout@v4 +# with: +# fetch-depth: 0 +# - name: Run and publish VR screenshot +# uses: ./.github/actions/run-publish-vr-screenshot +# with: +# fluentVersion: v8 +# vrTestPackageName: 'vr-tests' +# vrTestPackagePath: 'apps/vr-tests' +# locationPrefix: 'fluentuiv8' +# locationPostfix: 'vrscreenshotv8' +# clientName: 'fluentuiv8' + +# react_northstar: +# runs-on: ubuntu-latest +# env: +# pipelineId: '313' +# pipelineName: 'fluent-ui_VRT_Pipeline_v0' +# steps: +# - uses: actions/checkout@v4 +# with: +# fetch-depth: 0 +# - name: Run and publish VR screenshot +# uses: ./.github/actions/run-publish-vr-screenshot +# with: +# fluentVersion: v0 +# vrTestPackageName: 'docs' +# vrTestPackagePath: 'packages/fluentui/docs' +# locationPrefix: 'FluentUI-v0' +# locationPostfix: 'vrscreenshotv0' +# clientName: 'FluentUIV0' diff --git a/.github/workflows/pr-vrt.yml b/.github/workflows/pr-vrt.yml index 4e14e107dcca81..90901135c32cb7 100644 --- a/.github/workflows/pr-vrt.yml +++ b/.github/workflows/pr-vrt.yml @@ -1,10 +1,9 @@ name: VRT CI - on: - push: - branches: - - master pull_request: + # TODO: once testing is done enable pull_request on all branches again + branches: + - 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 @@ -12,7 +11,7 @@ concurrency: cancel-in-progress: true env: - NX_PARALLEL: 4 # ubuntu-latest = 4-core CPU / 16 GB of RAM | macos-14-xlarge (arm) = 6-core CPU / 14 GB of RAM + NX_PARALLEL: 6 # ubuntu-latest = 4-core CPU / 16 GB of RAM | macos-14-xlarge (arm) = 6-core CPU / 14 GB of RAM NX_PREFER_TS_NODE: true NX_VERBOSE_LOGGING: true @@ -21,78 +20,56 @@ permissions: actions: 'read' jobs: - web_components: - runs-on: ubuntu-latest - env: - pipelineId: '315' - pipelineName: 'fluent-ui_VRT_Pipeline_web-components' + generate_vrt_screenshots: + if: ${{ github.repository_owner == 'microsoft' }} + runs-on: macos-14-xlarge steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Run and publish VR screenshot - uses: ./.github/actions/run-publish-vr-screenshot - with: - fluentVersion: webcomponents - vrTestPackageName: 'vr-tests-web-components' - vrTestPackagePath: 'apps/vr-tests-web-components' - locationPrefix: 'FluentUI-web-components' - locationPostfix: 'vrscreenshotwebcomponents' - clientName: 'fluentui-web-components-v3' - react_components: - runs-on: ubuntu-latest - env: - pipelineId: '311' - pipelineName: 'fluent-ui_VRT_Pipeline_v9' - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Run and publish VR screenshot - uses: ./.github/actions/run-publish-vr-screenshot + - name: Derive appropriate SHAs for base and head for `nx affected` commands + uses: nrwl/nx-set-shas@v4 with: - fluentVersion: v9 - vrTestPackageName: 'vr-tests-react-components' - vrTestPackagePath: 'apps/vr-tests-react-components' - locationPrefix: 'fluentuiv9' - locationPostfix: 'vrscreenshotv9' - clientName: 'fluentuiv9' + main-branch-name: 'master' - react: - runs-on: ubuntu-latest - env: - pipelineId: '312' - pipelineName: 'fluent-ui_VRT_Pipeline_v8' - steps: - - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: - fetch-depth: 0 - - name: Run and publish VR screenshot - uses: ./.github/actions/run-publish-vr-screenshot + cache: 'yarn' + node-version: '20' + + - run: yarn install --frozen-lockfile + - run: yarn playwright install --with-deps + + - name: Run VR tests (generate screenshots) + run: yarn nx affected -t test-vr --nxBail + + - name: Prepare VR screenshots for upload + uses: actions/github-script@v7 + id: screenshots_root with: - fluentVersion: v8 - vrTestPackageName: 'vr-tests' - vrTestPackagePath: 'apps/vr-tests' - locationPrefix: 'fluentuiv8' - locationPostfix: 'vrscreenshotv8' - clientName: 'fluentuiv8' + script: | + const run = require('./.github/scripts/prepare-vr-screenshots-for-upload'); + const config = { + projects: ['vr-tests-web-components', 'vr-tests-react-components', 'vr-tests', 'docs'] + }; + const result = await run({github,context,core,config}); + return result; + result-encoding: string - react_northstar: - runs-on: ubuntu-latest - env: - pipelineId: '313' - pipelineName: 'fluent-ui_VRT_Pipeline_v0' - steps: - - uses: actions/checkout@v4 + - name: Upload VR screenshots + uses: actions/upload-artifact@v4 with: - fetch-depth: 0 - - name: Run and publish VR screenshot - uses: ./.github/actions/run-publish-vr-screenshot + name: vrscreenshot + retention-days: 1 + path: ${{steps.screenshots_root.outputs.result}} + + - name: Save PR number + run: echo ${{ github.event.number }} > pr.txt + - uses: actions/upload-artifact@v4 with: - fluentVersion: v0 - vrTestPackageName: 'docs' - vrTestPackagePath: 'packages/fluentui/docs' - locationPrefix: 'FluentUI-v0' - locationPostfix: 'vrscreenshotv0' - clientName: 'FluentUIV0' + name: pr-number + retention-days: 1 + if-no-files-found: error + path: | + pr.txt diff --git a/.github/workflows/pr-website-deploy-comment.yml b/.github/workflows/pr-website-deploy-comment.yml index d636e5ad9ddcde..a5ae23eb4be542 100644 --- a/.github/workflows/pr-website-deploy-comment.yml +++ b/.github/workflows/pr-website-deploy-comment.yml @@ -17,7 +17,7 @@ env: jobs: deploy: runs-on: ubuntu-latest - if: ${{ github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' }} + if: ${{ github.repository_owner == 'microsoft' }} && ${{ github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' }} outputs: pr_number: ${{ steps.pr_number.outputs.result }} website_url: ${{ steps.website_url.outputs.id }} diff --git a/.github/workflows/pr-website-deploy.yml b/.github/workflows/pr-website-deploy.yml index 862324e3e5c93f..149b78e0716dec 100644 --- a/.github/workflows/pr-website-deploy.yml +++ b/.github/workflows/pr-website-deploy.yml @@ -16,6 +16,7 @@ env: jobs: bundle: + if: ${{ github.repository_owner == 'microsoft' }} runs-on: macos-14-xlarge permissions: contents: 'read' @@ -37,6 +38,8 @@ jobs: node-version: '20' - run: echo number of CPUs "$(getconf _NPROCESSORS_ONLN)" + - name: NodeJS heap default size + run: node -e 'console.log(v8.getHeapStatistics().heap_size_limit / 1024 / 1024 + " MB");' - run: yarn install --frozen-lockfile diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 91d1fb2e791014..5712801a144c5d 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -23,6 +23,7 @@ env: jobs: main: + if: ${{ github.repository_owner == 'microsoft' }} runs-on: macos-14-xlarge permissions: contents: 'read' @@ -81,6 +82,7 @@ jobs: git diff-index --quiet HEAD -- || exit 1 e2e: + if: ${{ github.repository_owner == 'microsoft' }} # TODO: switch to macos once problematic tests are fixed # https://github.com/microsoft/fluentui/issues/33173 # https://github.com/microsoft/fluentui/issues/33172 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/chart-docsite/.storybook/fix-title.js b/apps/chart-docsite/.storybook/fix-title.js deleted file mode 100644 index 3f72f01ea672c5..00000000000000 --- a/apps/chart-docsite/.storybook/fix-title.js +++ /dev/null @@ -1,36 +0,0 @@ -const fs = require('fs'); -const path = require('path'); - -/** - * - * @param {string} filePath - * @param {string} title - */ -function fixTitle(filePath, title) { - const htmlDocumentPath = path.resolve(__dirname, filePath); - const htmlDocument = fs.readFileSync(htmlDocumentPath, 'utf-8'); - const updatedHtmlDocument = htmlDocument.replace(/.*<\/title>/, `<title>${title}`); - - fs.writeFileSync(htmlDocumentPath, updatedHtmlDocument); -} - -try { - const args = process.argv.slice(2); - const [title, distPath] = args; - - const storybookDistPath = `${distPath}/storybook`; - const indexPath = `${storybookDistPath}/index.html`; - const iframePath = `${storybookDistPath}/iframe.html`; - - console.log(`Rewriting index.html document title to ${title}.`); - fixTitle(indexPath, title); - - console.log(`Rewriting iframe.html document title to ${title}.`); - fixTitle(iframePath, title); - - console.log('Title rewrite complete.'); -} catch (error) { - console.log('Title rewrite failed.'); - console.error(error); - process.exit(1); -} diff --git a/apps/chart-docsite/.storybook/main.ts b/apps/chart-docsite/.storybook/main.ts index 9b3b15ffab102a..d668e75530448e 100644 --- a/apps/chart-docsite/.storybook/main.ts +++ b/apps/chart-docsite/.storybook/main.ts @@ -10,7 +10,7 @@ const config: StorybookConfig = { '../src/**/*.mdx', '../src/**/index.stories.@(js|jsx|ts|tsx)', // packages stories - '../../../packages/charts/*/stories/**/index.stories.@(js|jsx|ts|tsx)', + '../../../packages/charts/react-charts-preview/stories/**/index.stories.@(js|jsx|ts|tsx)', ], }; diff --git a/apps/chart-docsite/.storybook/preview.tsx b/apps/chart-docsite/.storybook/preview.tsx index b6df187f1e33de..0679b799ce18d9 100644 --- a/apps/chart-docsite/.storybook/preview.tsx +++ b/apps/chart-docsite/.storybook/preview.tsx @@ -2,7 +2,8 @@ import type { Preview } from '@storybook/react'; import * as rootPreview from '../../../.storybook/preview'; -import { FluentDocsContainer } from '../../public-docsite-v9/src/DocsComponents/FluentDocsContainer.stories'; +// TODO: These custom Docs implementations should be part of custom SB addon/storybook components package +import { FluentDocsContainer } from '../src/DocsComponents/FluentDocsContainer'; const preview: Preview = { ...rootPreview, diff --git a/apps/chart-docsite/package.json b/apps/chart-docsite/package.json index 99473f0145fabb..405441f57f07dd 100644 --- a/apps/chart-docsite/package.json +++ b/apps/chart-docsite/package.json @@ -2,9 +2,10 @@ "name": "@fluentui/chart-docsite", "version": "1.0.0", "private": true, - "description": "Fluent UI React v9 documentation", + "description": "Fluent UI React Charts Preview documentation", "scripts": { - "build-storybook": "storybook build -o ./dist/storybook --docs && node ./.storybook/fix-title.js 'Fluent UI Charts v9' ../dist", + "build-storybook": "storybook build -o ./dist/storybook --docs", + "postbuild-storybook": "node -r ../../scripts/ts-node/src/register ../../scripts/storybook/src/scripts/rewrite-title.ts --title 'Fluent UI Charts v9' --distPath ./dist/storybook", "clean": "just-scripts clean", "code-style": "just-scripts code-style", "just": "just-scripts", @@ -21,13 +22,10 @@ }, "dependencies": { "@fluentui/react-charts-preview": "*", - "@fluentui/react-components": "*", - "@griffel/react": "^1.5.22", - "@microsoft/applicationinsights-web": "^3", + "@fluentui/react-storybook-addon": "*", + "@fluentui/react-storybook-addon-export-to-sandbox": "*", "react": "17.0.2", "react-dom": "17.0.2", - "react-window": "^1.8.6", - "tslib": "^2.1.0", - "react-hook-form": "^5.7.2" + "tslib": "^2.1.0" } } diff --git a/apps/chart-docsite/project.json b/apps/chart-docsite/project.json index 968d5465317fe1..87965b63e571c4 100644 --- a/apps/chart-docsite/project.json +++ b/apps/chart-docsite/project.json @@ -2,8 +2,8 @@ "name": "chart-docsite", "$schema": "../../node_modules/nx/schemas/project-schema.json", "projectType": "application", - "implicitDependencies": ["tag:type:stories"], - "tags": ["platform:web", "vNext"], + "implicitDependencies": [], + "tags": ["platform:web", "vNext", "charting"], "targets": { "build-storybook": { "dependsOn": [ diff --git a/apps/chart-docsite/src/DocsComponents/FluentDocsContainer.tsx b/apps/chart-docsite/src/DocsComponents/FluentDocsContainer.tsx new file mode 100644 index 00000000000000..118e756ccca4a0 --- /dev/null +++ b/apps/chart-docsite/src/DocsComponents/FluentDocsContainer.tsx @@ -0,0 +1,23 @@ +import * as React from 'react'; +import { DocsContainer, type DocsContextProps } from '@storybook/addon-docs'; +import { type FluentStoryContext } from '@fluentui/react-storybook-addon'; +import { webLightTheme } from '@fluentui/react-theme'; +import { FluentProvider } from '@fluentui/react-provider'; + +interface FluentDocsContainerProps { + context: FluentStoryContext & DocsContextProps; +} + +/** + * A container that wraps storybook's native docs container to add extra components to the docs experience + */ +export const FluentDocsContainer: React.FC = ({ children, context }) => { + return ( + <> + {/** TODO add table of contents */} + + {children} + + + ); +}; diff --git a/apps/perf-test-react-components/package.json b/apps/perf-test-react-components/package.json index 5abb8084ee4da0..f5013b053a5a7c 100644 --- a/apps/perf-test-react-components/package.json +++ b/apps/perf-test-react-components/package.json @@ -21,6 +21,7 @@ "@fluentui/scripts-perf-test-flamegrill": "*", "@fluentui/react-avatar": "*", "@fluentui/react-button": "*", + "@fluentui/react-color-picker-preview": "*", "@fluentui/react-components": "*", "@fluentui/react-field": "*", "@fluentui/react-persona": "*", diff --git a/apps/perf-test-react-components/src/scenarios/ColorPicker.tsx b/apps/perf-test-react-components/src/scenarios/ColorPicker.tsx new file mode 100644 index 00000000000000..4406ac2fe3a9a5 --- /dev/null +++ b/apps/perf-test-react-components/src/scenarios/ColorPicker.tsx @@ -0,0 +1,18 @@ +import * as React from 'react'; +import { ColorPicker, ColorArea, ColorSlider, AlphaSlider } from '@fluentui/react-color-picker-preview'; +import { FluentProvider } from '@fluentui/react-provider'; +import { webLightTheme } from '@fluentui/react-theme'; + +const Scenario = () => ( + + + + + +); + +Scenario.decorator = (props: { children: React.ReactNode }) => ( + {props.children} +); + +export default Scenario; diff --git a/apps/pr-deploy-site/just.config.ts b/apps/pr-deploy-site/just.config.ts index 4a9cff295e94a2..34244cfedaaf2b 100644 --- a/apps/pr-deploy-site/just.config.ts +++ b/apps/pr-deploy-site/just.config.ts @@ -24,6 +24,7 @@ const dependencies = [ '@fluentui/public-docsite', '@fluentui/react', '@fluentui/react-charting', + '@fluentui/chart-web-components', '@fluentui/chart-docsite', '@fluentui/public-docsite-v9', '@fluentui/react-experiments', diff --git a/apps/pr-deploy-site/pr-deploy-site.js b/apps/pr-deploy-site/pr-deploy-site.js index c16475726733a1..ce4b6278494d8b 100644 --- a/apps/pr-deploy-site/pr-deploy-site.js +++ b/apps/pr-deploy-site/pr-deploy-site.js @@ -60,6 +60,12 @@ var siteInfo = [ icon: 'BarChart4', title: 'Charting', }, + { + package: '@fluentui/chart-web-components', + link: './chart-web-components/storybook/index.html', + icon: 'BarChart4', + title: 'Chart web components', + }, { package: '@fluentui/theming-designer', link: './theming-designer/index.html', 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/.storybook/fix-title.js b/apps/public-docsite-v9/.storybook/fix-title.js deleted file mode 100644 index 3f72f01ea672c5..00000000000000 --- a/apps/public-docsite-v9/.storybook/fix-title.js +++ /dev/null @@ -1,36 +0,0 @@ -const fs = require('fs'); -const path = require('path'); - -/** - * - * @param {string} filePath - * @param {string} title - */ -function fixTitle(filePath, title) { - const htmlDocumentPath = path.resolve(__dirname, filePath); - const htmlDocument = fs.readFileSync(htmlDocumentPath, 'utf-8'); - const updatedHtmlDocument = htmlDocument.replace(/.*<\/title>/, `<title>${title}`); - - fs.writeFileSync(htmlDocumentPath, updatedHtmlDocument); -} - -try { - const args = process.argv.slice(2); - const [title, distPath] = args; - - const storybookDistPath = `${distPath}/storybook`; - const indexPath = `${storybookDistPath}/index.html`; - const iframePath = `${storybookDistPath}/iframe.html`; - - console.log(`Rewriting index.html document title to ${title}.`); - fixTitle(indexPath, title); - - console.log(`Rewriting iframe.html document title to ${title}.`); - fixTitle(iframePath, title); - - console.log('Title rewrite complete.'); -} catch (error) { - console.log('Title rewrite failed.'); - console.error(error); - process.exit(1); -} diff --git a/apps/public-docsite-v9/.storybook/main.js b/apps/public-docsite-v9/.storybook/main.js index 379f1e938b203c..adcea0b3463151 100644 --- a/apps/public-docsite-v9/.storybook/main.js +++ b/apps/public-docsite-v9/.storybook/main.js @@ -18,6 +18,10 @@ module.exports = /** @type {Omit + +## Truncation + +Fluent has moved away from building in CSS truncation in components in v9 due to the accessibility concerns that accompany it. There are some ways to handle truncation in an accessible way, though it is important to be aware of the potential pitfalls when doing so. + +Our top recommendation is to use character count-based javascript truncation over CSS truncation, ensuring that strings are never truncated past a reasonable and readable number of characters shown, and also to prefer truncating in the middle of the string instead of at the end. This page goes over a full explanation of why we recommend that approach, and a few potential alternatives. + +### Accessibility traps + +Truncating text based on available width primarily causes problems for people using static page zoom, zoom software, smaller-screen devices, and alternative input methods. These can often combine with eachother to create increasingly difficult barriers to access. Most of those barriers boil down to two specific problems: + +1. Truncation based on width at small screen sizes can quickly render the control useless by showing so few characters that the information cannot be parsed. +2. The full text is often exposed in tooltips which are inaccessable to many users, and often specifically the users who most need it. + +The most common scenarios where a user would experience truncation past the point of understandability are: + +- Small-screen devices +- Static zoom or text size increases, sometimes paired with a zooming software like ZoomText +- Zoom or text size increases on a small-screen device + +All of these cases also increase the likelihood that tooltips will not be accessible. Small-screen devices are usually touchscreens, which do not allow the user to access tooltips on most controls. + +Additionally, static zoom is often paired with screen magnification software, which makes tooltip access much more difficult. The WCAG criterion [1.4.13 Content on Hover or Focus](https://www.w3.org/WAI/WCAG22/Understanding/content-on-hover-or-focus.html) is intended to help make tooltips and other hover content more accessible to magnification users, but it still falls far short in terms of real-world usability. In user studies on tooltips that meet all WCAG requirements as well as keyboard, screen reader, and touch access, one zoom + macOS magnification user had the following to say about our tooltips: + +> "There’s something popping up here, but it’s blending in with the background, and I can’t tell where it starts or begins. I’m so visually confused by all of this, that I would not interact with any of this body text." + +and: + +> "I haaaate hover and things I need to hover over" + +This is why tooltips should generally be short optional hints that are not necessary to the understanding and operation of the UI. If a UI uses width-based truncation for a set of items in e.g. a list, menu, or table that requires some users to hover over every entry to read it, that would drastically slow down those users in the best case scenario, and fully block them in the worst-case scenario. + +There are ways to truncate while avoiding these pitfalls, but they must ensure that users do not lose meaningful information when zooming, and that tooltips are not the primary method of making truncated text available. + +### Accessible truncation approaches + +**1. Truncate the string with javascript based on character count, optionally in the middle rather than end of the string** + +This approach makes it possible to prevent truncation below a minimum number of characters, which can be chosen to ensure the string never shortens past the point of understandability. The other benefit is that javascript truncation enables truncating in the middle of the string in cases where the end contains relevant information as in the case of file names or emails. + +**2. Set a reasonable `min-width` paired with CSS truncation to prevent truncating past usability** + +This approach works best when the truncation is occuring in a table or grid, where the user might expect to need to scroll horizontally to consume all the information. + +The potential pitfall of this approach is that in some places, setting a `min-width` may cause [WCAG Reflow](https://www.w3.org/WAI/WCAG22/Understanding/reflow.html) failures if it causes the page to scroll horizontally when zoomed. + +**3. Only truncate text that is not necessary for the understanding or operation of the UI** + +This is a rare case, since most of the time content that is irrelevant to users should not be displayed. This would need to be evaluated on a case-by-case basis, but a couple examples include: + +- `id` or hash data that is not really intended to be read as text by humans +- Supplementary content, such as a post summary following a post title, where reading the title alone is a reasonable user experience. + +**4. Only truncate based on user actions or settings** + +If truncation occurs as the result of the user resizing UI or choosing a compact view setting (e.g. in an email application), it is fine to truncate purely based on available space. diff --git a/apps/public-docsite-v9/src/Concepts/AdvancedStylingTechniques.stories.mdx b/apps/public-docsite-v9/src/Concepts/AdvancedStylingTechniques.stories.mdx new file mode 100644 index 00000000000000..e373162183a355 --- /dev/null +++ b/apps/public-docsite-v9/src/Concepts/AdvancedStylingTechniques.stories.mdx @@ -0,0 +1,174 @@ +import { Meta, Source } from '@storybook/addon-docs'; + + + +## Advanced styling techniques + +Theming, applying style changes at scale, is a really important part of any design system. Teams should look to tokens and variables first when considering how to change the look and feel of an app. Sometimes more powerful tools are required to accomplish a goal or handle edge cases. This document explains how to leverage the custom style hooks built into Fluent UI React V9. + +Most of the Fluent UI React v9 components are structured using the hooks approach: + +```tsx +export const Button: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useButton_unstable(props, ref); + + useButtonStyles_unstable(state); + useCustomStyleHook_unstable('useButtonStyles_unstable')(state); + + return renderButton_unstable(state); +}) as ForwardRefComponent; +``` + +The pertinent lines are where styles are calculated: + +```ts +useButtonStyles_unstable(state); +useCustomStyleHook_unstable('useButtonStyles_unstable')(state); +``` + +The default styles are defined by `useButtonStyles_unstable` and are packaged with every component. `useCustomStyleHook_unstable` reaches into a `CustomStyleHooksProvider` (if it exists) and calculates any styles that match the component type. + +> 💡See RFC [microsoft/fluentui#25333](https://github.com/microsoft/fluentui/pull/25333) for a detailed explanation. + +For example, an `App.tsx` might look like: + +```tsx +import { Button, FluentProvider, webLightTheme, CustomStyleHooksProvider_unstable } from '@fluentui/react-components'; +import { AlertRegular } from '@fluentui/react-icons'; +import { FANCY_CUSTOM_STYLE_HOOKS } from './FancyAppCustomStyleHooksValue.ts'; + +export function App() { + return ( + + + + + + + ); +} +``` + +A little scaffodling is required to get here first. Define a `useFancyButtonStyles.ts`, and calculate the style similar to how you would for any other Fluent component: + +```ts +import { makeStyles, type ButtonState } from '@fluentui/react-components'; + +const useStyles = makeStyles({ + root: { + // These are all unique to Fancy theme. + border: '2px solid green', + backgroundColor: 'pink', + borderRadius: '64px', + }, + icon: { + color: 'blue', + backgroundColor: 'white', + }, +}); + +export const useFancyButtonStyles = (state: unknown) => { + const buttonState = state as ButtonState; + const styles = useStyles(); + buttonState.root.className = mergeClasses(buttonState.root.className, styles.root); + + if (buttonState.icon) { + buttonState.icon.className = mergeClasses(buttonState.icon.className, styles.icon); + } +}; +``` + +Define the value for `CustomStyleHooksProvider_unstable` in `FancyAppCustomStyleHooksValue.ts` that consumes custom style hooks: + +```ts +import { type CustomStyleHooksContextValue } from '@fluentui/react-components'; +import { useFancyButtonStyles } from './useFancyButtonStyles'; + +export const FANCY_CUSTOM_STYLE_HOOKS: CustomStyleHooksContextValue = { + useButtonStyles_unstable: useFancyButtonStyles, + // ... more component styles as needed for your theme. +}; +``` + +Finally use the `CustomStyleHooksProvider_unstable` in your app: + +```diff +// App.tsx ++ import { FANCY_CUSTOM_STYLE_HOOKS } from './FancyAppCustomStyleHooksValue'; + + ++ + {/* application code ... */} ++ + +``` + +### Nesting and merging custom style hooks + +One caveat is that `CustomStyleHooksProvider` does not automatically merge contexts' values. In an app with 'Smart' styles for example: + +```tsx +export function App() { + return ( + + + + {/* ⚠️ The nested "CustomStyleHooksProvider_unstable" provider completely overwrites the Smart values. */} + {/* I.e. only "useFancyButtonStyles" will be passed down. */} + {/* The app will only look Fancy, but not Smart. It needs both.*/} + + {/* application code ... */} + + + + ); +} +``` + +Applications should make the best decisions for their styles, determining when and how to apply them. If apps have their own custom style hooks and want to adopt others, they can gracefully merge them: + +```tsx +export const useSmancyCustomButtonStyles = (state: unknown) => { + const buttonState = state as ButtonState; + + // "Fancy" comes first + useFancyButtonStyles(buttonState); + // "Smart" comes second, so it will win where there are conflicts + useSmartButtonStyles(buttonState); +}; + +export const SMANCY_CUSTOM_STYLE_HOOKS: CustomStyleHooksContextValue = { + useButtonStyles_unstable: useAppCustomButtonStyles, + // ... more component style overrides +}; +``` + +And finally the App code can be simplified: + +```tsx +export function App() { + return ( + + + {/* application code ... */} + + + + ); +} +``` + +This way, apps can adopt the styles they need at scale while maintaining their own style preferences. diff --git a/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Components/Keytips.stories.mdx b/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Components/Keytips.stories.mdx new file mode 100644 index 00000000000000..6ba69ccdcfa17b --- /dev/null +++ b/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Components/Keytips.stories.mdx @@ -0,0 +1,99 @@ +import { Meta } from '@storybook/addon-docs'; + + + +# Keytips migration + +Both Fluent UI v8 and v9 provide Keytips component. +However, the v9 version has changes in the API and is now part of [Fluent UI contrib](https://github.com/microsoft/fluentui-contrib/tree/main/packages/react-keytips). + +## Props mapping + +### KeytipLayer -> Keytips + +This table maps v8 `KeytipLayer` component props to their v9 `Keytips` equivalents. + +| v8 | v9 | Notes | +| ---------------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | +| `keytipExitSequence` | `exitSequence` | Renamed. Type changed `IKeytipTransitionKey[]` to `string`. Specify single hotkey or combination separated by '+'. | +| `keytipStartSequence` | `startSequence` | Renamed. Type changed `IKeytipTransitionKey[]` to `string`. Specify single hotkey or combination separated by '+'. | +| `keytipReturnSequence` | `returnSequence` | Renamed. Type changed `IKeytipTransitionKey[]` to `string`. Specify single hotkey or combination separated by '+'. | +| `onExitKeytipMode` | `onExitKeytipsMode` | Renamed. Type changed `(ev?: React.KeyboardEvent` `\| React.MouseEvent) => void` to `EventHandler` | +| `onEnterKeytipMode` | `onEnterKeytipsMode` | Renamed. Type changed `(ev?: React.KeyboardEvent` `\| React.MouseEvent) => void` to `EventHandler` | +| `content` | `content` | Unchanged. | +| `styles` | `not supported` | The component holds only logic and does not require styles. | +| `componentRef` | `not supported` | | +| `no equivalent` | `invokeEvent` | New prop, specifies the event that triggers the keytips. | +| `no equivalent` | `startDelay` | New prop, adds delay before entering keytip mode by holding start sequence. | + +### IKeytipProps -> KeytipProps + +This table maps changes between `IKeytipProps` and `KeytipProps` type equivalent in v9. + +| v8 | v9 | v8 type | v9 type | Notes | +| --------------------- | ------------------ | ----------------------------------------------------------------------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | +| `content` | `content` | `string` | `NonNullable>` | Unchanged. | +| `visible` | `visible` | `boolean` | `boolean` | Unchanged. | +| `keySequences` | `keySequences` | `string[]` | `string[]` | Unchanged. | +| `hasMenu` | `hasMenu` | `boolean` | `boolean` | Unchanged. | +| `hasDynamicChildren` | `dynamic` | `boolean` | `boolean` | Renamed. | +| `hasOverflowSubMenu` | `no equivalent` | `boolean` | | Use `hasMenu` instead. | +| `theme` | `no equivalent` | | | Not supported. | +| `overflowSetSequence` | `overflowSequence` | `string[]` | `string[]` | | +| `disabled` | `no equivalent` | `boolean` | | Not supported. v9 keytips do not appear for disabled elements. | +| `callOutProps` | `positioning` | `ICalloutProps` | `PositioningProps` | Read more about our [positioning API](https://react.fluentui.dev/?path=/docs/concepts-developer-positioning-components--docs) | +| `styles` | `no equivalent` | | | | +| `onExecute` | `onExecute` | `(executeTarget: HTMLElement \| null`, `target: HTMLElement \| null) => void` | `ExecuteKeytipEventHandler` | Type changed to match v9 callback typings. | +| `onReturn` | `onReturn` | `(executeTarget: HTMLElement \| null`, `target: HTMLElement \| null) => void` | `ReturnKeytipEventHandler` | Type changed to match v9 callback typings. | + +### useKeytipRef -> useKeytipRef + +| v8 | v9 | Notes | +| ----------------- | --------------- | ------------------------------------------------------------- | +| `keytipProps` | `no equivalent` | Not supported. Use individual props (see `KeytipProps` type). | +| `ariaDescribedBy` | `no equivalent` | Not supported. | +| `disabled` | `no equivalent` | Not supported. Keytips are not shown for disabled elements. | + +### KeytipData -> no equivalent + +### useKeytipData -> no equivalent + +## Examples + +### Basic usage of Keytips with Buttons in v8 + +In v8 some components have `keytipProps` as a part of their props API. + +```tsx +export const KeytipsBasicExampleV8 = () => { + return ( + ; +}; +``` + +For more examples, please refer to the [Keytip documentation](https://react.fluentui.dev/?path=/docs/contrib_packages-react-keytips--docs) and [source code](https://github.com/microsoft/fluentui-contrib/tree/main/packages/react-keytips/stories). diff --git a/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Components/Theme.stories.mdx b/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Components/Theme.stories.mdx index 27f9695af6bcad..5540cc07ea5390 100644 --- a/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Components/Theme.stories.mdx +++ b/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Components/Theme.stories.mdx @@ -21,7 +21,7 @@ Beyond consistency with the latest Fluent Design system, this change provides si #### Portals -To be use v9 components inside v8 components like `Panel` & `Callout`, please enable [portal compatibility](?path=/docs/concepts-migration-from-v8-troubleshooting--page). +To be use v9 components inside v8 components like `Panel` & `Callout`, please enable [portal compatibility](?path=/docs/concepts-migration-from-v8-troubleshooting--docs#portal-compatibility). ### Theme (v8) => Theme (v9) diff --git a/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Troubleshooting.stories.mdx b/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Troubleshooting.stories.mdx index ca164c8fa58076..eb0704d0a068af 100644 --- a/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Troubleshooting.stories.mdx +++ b/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Troubleshooting.stories.mdx @@ -43,7 +43,7 @@ function App() { } ``` -## "I tried uing a layered v8 component like Callout in a layered v9 component like Dialog and my Callout appears beneath my Dialog. What's going on?" +## "I tried using a layered v8 component like Callout in a layered v9 component like Dialog and my Callout appears beneath my Dialog. What's going on?" Both v9 and v8 layers set the same `z-index` value by default, which means the document order will resolve their z-positioning. This can lead to inconsistent behavior because z-positioning depends on the order in which elements appear in the DOM. diff --git a/apps/public-docsite-v9/src/Concepts/Positioning/MatchTargetSize.stories.tsx b/apps/public-docsite-v9/src/Concepts/Positioning/PositioningMatchTargetSize.stories.tsx similarity index 100% rename from apps/public-docsite-v9/src/Concepts/Positioning/MatchTargetSize.stories.tsx rename to apps/public-docsite-v9/src/Concepts/Positioning/PositioningMatchTargetSize.stories.tsx diff --git a/apps/public-docsite-v9/src/Concepts/Positioning/OverflowBoundaryPadding.stories.tsx b/apps/public-docsite-v9/src/Concepts/Positioning/PositioningOverflowBoundaryPadding.stories.tsx similarity index 100% rename from apps/public-docsite-v9/src/Concepts/Positioning/OverflowBoundaryPadding.stories.tsx rename to apps/public-docsite-v9/src/Concepts/Positioning/PositioningOverflowBoundaryPadding.stories.tsx diff --git a/apps/public-docsite-v9/src/Concepts/Positioning/PositioningOverflowBoundaryRect.stories.tsx b/apps/public-docsite-v9/src/Concepts/Positioning/PositioningOverflowBoundaryRect.stories.tsx new file mode 100644 index 00000000000000..fa6b2f21fea84d --- /dev/null +++ b/apps/public-docsite-v9/src/Concepts/Positioning/PositioningOverflowBoundaryRect.stories.tsx @@ -0,0 +1,118 @@ +import * as React from 'react'; +import { + Popover, + PopoverTrigger, + PopoverSurface, + Button, + makeStyles, + tokens, + type PositioningRect, + useIsomorphicLayoutEffect, +} from '@fluentui/react-components'; + +const useClasses = makeStyles({ + area: { + border: `2px solid ${tokens.colorStatusDangerBackground3}`, + padding: '60px 20px 20px 20px', + width: '300px', + height: '300px', + + display: 'flex', + flexDirection: 'column', + alignItems: 'end', + justifyContent: 'space-between', + position: 'relative', + + '::before': { + content: '"Container"', + position: 'absolute', + padding: `${tokens.spacingHorizontalMNudge} ${tokens.spacingHorizontalS}`, + + top: 0, + left: 0, + + color: tokens.colorStatusDangerBackground1, + backgroundColor: tokens.colorStatusDangerBackground3, + }, + }, + boundary: { + width: '320px', + height: '320px', + outline: `2px solid ${tokens.colorBrandBackground}`, + + position: 'absolute', + top: '50px', + left: '10px', + pointerEvents: 'none', + + '::before': { + content: '"Boundary"', + position: 'absolute', + padding: `${tokens.spacingHorizontalMNudge} ${tokens.spacingHorizontalS}`, + + top: 0, + left: 0, + + color: tokens.colorNeutralForegroundOnBrand, + backgroundColor: tokens.colorBrandBackground, + }, + }, +}); + +export const OverflowBoundaryRect = () => { + const classes = useClasses(); + + const boundaryRef = React.useRef(null); + const [boundaryRect, setBoundaryRect] = React.useState(null); + + useIsomorphicLayoutEffect(() => { + setBoundaryRect(boundaryRef.current?.getBoundingClientRect() ?? null); + }, []); + + return ( +
+
+ + + + + + Stays within the defined rect + + + + + + + Stays within the defined rect + +
+ ); +}; + +OverflowBoundaryRect.parameters = { + docs: { + description: { + story: [ + 'Boundaries can be also defined as `Rect` objects. ', + 'This is useful when a boundary is not an actual element, but some kind of computed values.', + ].join('\n'), + }, + }, +}; diff --git a/apps/public-docsite-v9/src/Concepts/Positioning/PositioningShiftToCoverTarget.stories.tsx b/apps/public-docsite-v9/src/Concepts/Positioning/PositioningShiftToCoverTarget.stories.tsx new file mode 100644 index 00000000000000..b6dfb48cadfc0b --- /dev/null +++ b/apps/public-docsite-v9/src/Concepts/Positioning/PositioningShiftToCoverTarget.stories.tsx @@ -0,0 +1,132 @@ +import * as React from 'react'; +import { + Button, + makeStyles, + SpinButton, + Menu, + MenuTrigger, + MenuPopover, + MenuList, + MenuItem, + PositioningImperativeRef, + useMergedRefs, + Checkbox, + RadioGroup, + Field, + Radio, + PositioningProps, +} from '@fluentui/react-components'; + +const useStyles = makeStyles({ + boundary: { + border: '2px dashed red', + width: '300px', + height: '300px', + overflow: 'auto', + resize: 'both', + }, + trigger: { + display: 'block', + width: '150px', + margin: '200px auto', + }, +}); + +const ResizableBoundary = React.forwardRef< + HTMLDivElement, + { + onResize: ResizeObserverCallback; + children: React.ReactNode; + } +>(({ onResize, children }, ref) => { + const containerRef = React.useRef(null); + + React.useEffect(() => { + if (containerRef.current) { + const resizeObserver = new ResizeObserver(onResize); + resizeObserver.observe(containerRef.current); + + return () => { + resizeObserver.disconnect(); + }; + } + }, [onResize]); + + const styles = useStyles(); + + return ( +
+ {children} +
+ ); +}); + +export const CoverTargetForSmallViewport = () => { + const styles = useStyles(); + const [boundaryRef, setBoundaryRef] = React.useState(null); + + const [menuItemCount, setMenuItemCount] = React.useState(6); + + const positioningRef = React.useRef(null); + + const [open, setOpen] = React.useState(false); + const [menuPosition, setMenuPosition] = React.useState('above'); + + return ( + <> +
+ setOpen(data.checked as boolean)} />{' '} + + setMenuPosition(data.value as PositioningProps['position'])} + > + + + + + + value && setMenuItemCount(value)} /> + +
+ { + positioningRef.current?.updatePosition(); + }} + > + + + + + + + {Array.from({ length: menuItemCount }, (_, i) => ( + Item {i} + ))} + + + + + + ); +}; + +CoverTargetForSmallViewport.parameters = { + docs: { + description: { + story: + "`shiftToCoverTarget` is a positioning option that allows the positioned element to shift and cover the target element when there isn't enough space available to fit it.", + }, + }, +}; diff --git a/apps/public-docsite-v9/src/Concepts/Positioning/index.stories.tsx b/apps/public-docsite-v9/src/Concepts/Positioning/index.stories.tsx index eff55288fb5162..e4958cfe29e31e 100644 --- a/apps/public-docsite-v9/src/Concepts/Positioning/index.stories.tsx +++ b/apps/public-docsite-v9/src/Concepts/Positioning/index.stories.tsx @@ -11,12 +11,14 @@ export { AnchorToTarget } from './PositioningAnchorToTarget.stories'; export { ImperativeAnchorTarget } from './PositioningImperativeAnchorTarget.stories'; export { ImperativePositionUpdate } from './PositioningImperativePositionUpdate.stories'; export { OverflowBoundary } from './PositioningOverflowBoundary.stories'; -export { OverflowBoundaryPadding } from './OverflowBoundaryPadding.stories'; +export { OverflowBoundaryRect } from './PositioningOverflowBoundaryRect.stories'; +export { OverflowBoundaryPadding } from './PositioningOverflowBoundaryPadding.stories'; export { FlipBoundary } from './PositioningFlipBoundary.stories'; -export { MatchTargetSize } from './MatchTargetSize.stories'; +export { MatchTargetSize } from './PositioningMatchTargetSize.stories'; export { DisableTransform } from './PositioningDisableTransform.stories'; export { ListenToUpdates } from './PositioningListenToUpdates.stories'; export { AutoSizeForSmallViewport } from './PositioningAutoSize.stories'; +export { CoverTargetForSmallViewport } from './PositioningShiftToCoverTarget.stories'; export { FallbackPositions } from './PositioningFallbackPositions.stories'; export default { diff --git a/apps/public-docsite-v9/src/Concepts/SSR/Remix.stories.mdx b/apps/public-docsite-v9/src/Concepts/SSR/Remix.stories.mdx new file mode 100644 index 00000000000000..04d25ad1d97be9 --- /dev/null +++ b/apps/public-docsite-v9/src/Concepts/SSR/Remix.stories.mdx @@ -0,0 +1,227 @@ +import { Meta } from '@storybook/addon-docs'; + + + +# React Router 7/Remix setup + +## Installation + +1. Create a new React Router 7/Remix project or skip this step if you already have one: + +```bash +npx create-remix@latest fluentui-remix + +# or +npx create-react-router@latest fluentui-react-router +``` + +2. Install dependencies: + +```bash +# Install Fluent UI core packages +npm i @fluentui/react-components @fluentui/react-icons + +# Install required Vite plugins +npm i vite-plugin-cjs-interop @griffel/vite-plugin -D +``` + +## Configuration + +1. Update `vite.config.ts`: + +```ts +// Import Vite plugins +import { cjsInterop } from 'vite-plugin-cjs-interop'; +import griffel from '@griffel/vite-plugin'; + +export default defineConfig(({ command }) => ({ + plugins: [ + reactRouter(), // or remix(), + tsconfigPaths(), + + // Add CJS interop plugin for Fluent UI packages until they are ESM compatible + cjsInterop({ + dependencies: ['@fluentui/react-components'], + }), + // Add Griffel plugin for production optimization + command === 'build' && griffel(), + ], + // Required for Fluent UI icons in SSR + ssr: { + noExternal: ['@fluentui/react-icons'], + }, +})); +``` + +2. Modify `app/root.tsx` to add Fluent UI providers: + +```tsx +// 1. Import Fluent UI dependencies +import { FluentProvider, webLightTheme } from '@fluentui/react-components'; + +export function Layout({ children }: { children: React.ReactNode }) { + return ( + + + + + + + {/* 2. Add insertion point for Fluent UI styles before the . */} + + + + {/* 3. Wrap app content with FluentProvider */} + {children} + + + + + ); +} +``` + +3. Set up SSR: + +- Reveal `app/entry.client.tsx` and `app/entry.server.tsx` files if not already present: + +```bash +npx react-router reveal + +# or + +npx remix reveal +``` + +- and then update the `entry.server.tsx`: + +```tsx +// 1. Import required Fluent UI SSR utilities +import { createDOMRenderer, RendererProvider, renderToStyleElements, SSRProvider } from '@fluentui/react-components'; + +// 2. Define constants for style injection +const FLUENT_UI_INSERTION_POINT_TAG = ``; +const FLUENT_UI_INSERTION_TAG_REGEX = new RegExp(FLUENT_UI_INSERTION_POINT_TAG.replaceAll(' ', '(\\s)*')); + +export default function handleRequest( + request: Request, + responseStatusCode: number, + responseHeaders: Headers, + remixContext: EntryContext, +) { + // 3. Create Fluent UI renderer + const renderer = createDOMRenderer(); + + // ... + + return new Promise((resolve, reject) => { + let shellRendered = false; + // 4. Track style extraction state + let isStyleExtracted = false; + + const { pipe, abort } = renderToPipeableStream( + // 5. Wrap RemixServer with Fluent UI providers + + + + {/* or */} + + , + { + [callbackName]: () => { + shellRendered = true; + const body = new PassThrough({ + // 6. Transform stream to inject Fluent UI styles + transform(chunk, _, callback) { + const str = chunk.toString(); + const style = renderToStaticMarkup(<>{renderToStyleElements(renderer)}); + + if (!isStyleExtracted && FLUENT_UI_INSERTION_TAG_REGEX.test(str)) { + chunk = str.replace(FLUENT_UI_INSERTION_TAG_REGEX, `${FLUENT_UI_INSERTION_POINT_TAG}${style}`); + isStyleExtracted = true; + } + + callback(null, chunk); + }, + }); + // ... + } + } + }); +} +``` + +## Usage Example + +Create or update `app/routes/_index.tsx`: + +```tsx +import { Button, Card, Title1, Body1 } from '@fluentui/react-components'; +import { BookmarkRegular } from '@fluentui/react-icons'; + +export default function Index() { + return ( + + Fluent UI + Remix + Welcome to your new app! + + + ); +} +``` + +## Troubleshooting + +### Common Issues + +1. **SSR Hydration Mismatch** + +``` +Text content does not match server-rendered HTML +``` + +Fix: Check style injection in `entry.server.tsx`. + +2. **Icons Not Rendering in SSR** + +``` +Error: No "exports" main defined in node_modules/@fluentui/react-icons/package.json +``` + +Fix: Add to `vite.config.ts`: + +```ts +ssr: { + noExternal: ["@fluentui/react-icons"], +} +``` + +3. **Module Resolution Errors** + +``` +Cannot use import statement outside a module +``` + +Fix: Add to `vite.config.ts`: + +```ts +cjsInterop({ + dependencies: ["@fluentui/react-components"], +}), +``` + +4. **Development Mode Warning** + +``` +@fluentui/react-provider: There are conflicting ids in your DOM. +Please make sure that you configured your application properly. +Configuration guide: https://aka.ms/fluentui-conflicting-ids +``` + +This warning occurs in development due to [React's StrictMode double rendering](https://react.dev/reference/react/StrictMode#fixing-bugs-found-by-double-rendering-in-development). It can be safely ignored as it doesn't affect production builds. + +### Production Build Optimization + +For production builds, install and configure [`@griffel/vite-plugin`](https://griffel.js.org/react/ahead-of-time-compilation/with-vite) to enable build time pre-computing and transforming styles. 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-v9/src/DocsComponents/FluentDocsContainer.stories.tsx b/apps/public-docsite-v9/src/DocsComponents/FluentDocsContainer.stories.tsx index 3c637a2d0e9ab2..920e91a1273598 100644 --- a/apps/public-docsite-v9/src/DocsComponents/FluentDocsContainer.stories.tsx +++ b/apps/public-docsite-v9/src/DocsComponents/FluentDocsContainer.stories.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -import { DocsContainer, DocsContextProps } from '@storybook/addon-docs'; -import { FluentStoryContext } from '@fluentui/react-storybook-addon'; +import { DocsContainer, type DocsContextProps } from '@storybook/addon-docs'; +import { type FluentStoryContext } from '@fluentui/react-storybook-addon'; import { webLightTheme, FluentProvider } from '@fluentui/react-components'; interface FluentDocsContainerProps { 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-react-components/package.json b/apps/vr-tests-react-components/package.json index 555ce58bd23682..5bbbd17b8d72e8 100644 --- a/apps/vr-tests-react-components/package.json +++ b/apps/vr-tests-react-components/package.json @@ -27,6 +27,7 @@ "@fluentui/react-card": "*", "@fluentui/react-charts-preview": "*", "@fluentui/react-checkbox": "*", + "@fluentui/react-color-picker-preview": "*", "@fluentui/react-combobox": "*", "@fluentui/react-context-selector": "*", "@fluentui/react-datepicker-compat": "*", @@ -56,7 +57,6 @@ "@fluentui/react-spinner": "*", "@fluentui/react-spinbutton": "*", "@fluentui/react-storybook-addon": "*", - "@fluentui/react-storybook-addon-export-to-sandbox": "*", "@fluentui/react-swatch-picker": "*", "@fluentui/react-switch": "*", "@fluentui/react-table": "*", @@ -80,6 +80,7 @@ "@fluentui/react-search": "*", "@fluentui/react-teaching-popover": "*", "@fluentui/react-tag-picker": "*", - "@fluentui/react-carousel": "*" + "@fluentui/react-carousel": "*", + "@fluentui/react-list": "*" } } diff --git a/apps/vr-tests-react-components/project.json b/apps/vr-tests-react-components/project.json index 59d287017dd11e..7601c52aff468c 100644 --- a/apps/vr-tests-react-components/project.json +++ b/apps/vr-tests-react-components/project.json @@ -3,5 +3,10 @@ "$schema": "../../node_modules/nx/schemas/project-schema.json", "projectType": "application", "implicitDependencies": [], - "tags": ["vNext"] + "tags": ["vNext"], + "targets": { + "build-storybook": { + "dependsOn": [{ "projects": ["react-storybook-addon"], "target": "build" }] + } + } } diff --git a/apps/vr-tests-react-components/src/stories/Breadcrumb/utils.tsx b/apps/vr-tests-react-components/src/stories/Breadcrumb/utils.tsx index 490b3f09ec026b..f9439b64fc5400 100644 --- a/apps/vr-tests-react-components/src/stories/Breadcrumb/utils.tsx +++ b/apps/vr-tests-react-components/src/stories/Breadcrumb/utils.tsx @@ -11,13 +11,13 @@ import { bundleIcon, CalendarMonth20Filled, CalendarMonth20Regular } from '@flue const CalendarMonth = bundleIcon(CalendarMonth20Filled, CalendarMonth20Regular); export const steps = new Steps() - .snapshot('default', { cropTo: '.testWrapper' }) + .snapshot('default') .hover('.breadcrumb-sample') - .snapshot('hover', { cropTo: '.testWrapper' }) + .snapshot('hover') .mouseDown('.breadcrumb-sample') - .snapshot('pressed', { cropTo: '.testWrapper' }) + .snapshot('pressed') .focus('.breadcrumb-sample') - .snapshot('focused', { cropTo: '.testWrapper' }) + .snapshot('focused') .end(); export const SampleBreadcrumbButtons = (props: BreadcrumbProps) => ( diff --git a/apps/vr-tests-react-components/src/stories/Button/CompoundButtonDefault.stories.tsx b/apps/vr-tests-react-components/src/stories/Button/CompoundButtonDefault.stories.tsx index 95881ec32b35f8..ec4381c63ed6d3 100644 --- a/apps/vr-tests-react-components/src/stories/Button/CompoundButtonDefault.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Button/CompoundButtonDefault.stories.tsx @@ -9,12 +9,12 @@ import { buttonId } from './utils'; const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular); const steps = new Steps() - .snapshot('default', { cropTo: '.testWrapper' }) + .snapshot('default') // https://github.com/microsoft/fluentui/issues/21998 // .hover('#button-id') // .snapshot('hover', { cropTo: '.testWrapper' }) .mouseDown('#button-id') - .snapshot('pressed', { cropTo: '.testWrapper' }) + .snapshot('pressed') .end(); export default { diff --git a/apps/vr-tests-react-components/src/stories/Button/SplitButton.stories.tsx b/apps/vr-tests-react-components/src/stories/Button/SplitButton.stories.tsx new file mode 100644 index 00000000000000..d8c3548e416151 --- /dev/null +++ b/apps/vr-tests-react-components/src/stories/Button/SplitButton.stories.tsx @@ -0,0 +1,195 @@ +import * as React from 'react'; +import { SplitButton } from '@fluentui/react-button'; +import { bundleIcon, CalendarMonthFilled, CalendarMonthRegular } from '@fluentui/react-icons'; +import type { Meta } from '@storybook/react'; +import { getStoryVariant, withStoryWrightSteps, DARK_MODE, HIGH_CONTRAST, RTL } from '../../utilities'; +import { buttonId, steps, useStyles } from './utils'; + +const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular); + +export default { + title: 'SplitButton Converged', + component: SplitButton, + decorators: [story => withStoryWrightSteps({ story, steps })], +} satisfies Meta; + +export const Default = () => Hello, world; + +export const DefaultRTL = getStoryVariant(Default, RTL); +export const DefaultDarkMode = getStoryVariant(Default, DARK_MODE); +export const DefaultHighContrast = getStoryVariant(Default, HIGH_CONTRAST); + +export const Circular = () => ( + + Hello, world + +); + +export const Square = () => ( + + Hello, world + +); + +export const Rounded = () => ( + + Hello, world + +); + +export const Outline = () => ( + + Hello, world + +); + +export const Primary = () => ( + + Hello, world + +); + +export const PrimaryHighContrast = getStoryVariant(Primary, HIGH_CONTRAST); +export const PrimaryDarkMode = getStoryVariant(Primary, DARK_MODE); + +export const Subtle = () => ( + + Hello, world + +); + +export const SubtleHighContrast = getStoryVariant(Subtle, HIGH_CONTRAST); +export const SubtleDarkMode = getStoryVariant(Subtle, DARK_MODE); + +export const Transparent = () => ( + + Hello, world + +); + +export const TransparentHighContrast = getStoryVariant(Transparent, HIGH_CONTRAST); +export const TransparentDarkMode = getStoryVariant(Transparent, DARK_MODE); + +export const Disabled = () => ( + + Hello, world + +); + +export const DisabledHighContrast = getStoryVariant(Disabled, HIGH_CONTRAST); +export const DisabledDarkMode = getStoryVariant(Disabled, DARK_MODE); + +export const OutlineDisabled = () => ( + + Hello, world + +); + +export const OutlineDisabledHighContrast = getStoryVariant(OutlineDisabled, HIGH_CONTRAST); +export const OutlineDisabledDarkMode = getStoryVariant(OutlineDisabled, DARK_MODE); + +export const PrimaryDisabled = () => ( + + Hello, world + +); + +export const PrimaryDisabledHighContrast = getStoryVariant(PrimaryDisabled, HIGH_CONTRAST); +export const PrimaryDisabledDarkMode = getStoryVariant(PrimaryDisabled, DARK_MODE); + +export const SubtleDisabled = () => ( + + Hello, world + +); + +export const SubtleDisabledHighContrast = getStoryVariant(SubtleDisabled, HIGH_CONTRAST); +export const SubtleDisabledDarkMode = getStoryVariant(SubtleDisabled, DARK_MODE); + +export const TransparentDisabled = () => ( + + Hello, world + +); + +export const TransparentDisabledHighContrast = getStoryVariant(TransparentDisabled, HIGH_CONTRAST); +export const TransparentDisabledDarkMode = getStoryVariant(TransparentDisabled, DARK_MODE); + +export const SizeSmall = () => ( + } size="small"> + Hello, world + +); + +SizeSmall.storyName = 'Size small'; + +export const SizeLarge = () => ( + } size="large"> + Hello, world + +); + +SizeLarge.storyName = 'Size large'; + +export const SizeSmallWithLongTextWrapping = () => { + const styles = useStyles(); + return ( + } size="small"> + Long text wraps after it hits the max width of the component + + ); +}; + +SizeSmallWithLongTextWrapping.storyName = 'Size small - with long text wrapping'; + +export const SizeMediumWithLongTextWrapping = () => { + const styles = useStyles(); + return ( + } size="medium"> + Long text wraps after it hits the max width of the component + + ); +}; + +SizeMediumWithLongTextWrapping.storyName = 'Size medium - with long text wrapping'; + +export const SizeLargeWithLongTextWrapping = () => { + const styles = useStyles(); + return ( + } size="large"> + Long text wraps after it hits the max width of the component + + ); +}; + +SizeLargeWithLongTextWrapping.storyName = 'Size large - with long text wrapping'; + +export const WithIconBeforeContent = () => ( + }> + Hello, world + +); + +WithIconBeforeContent.storyName = 'With icon before content'; + +export const WithIconBeforeContentRTL = getStoryVariant(WithIconBeforeContent, RTL); + +export const WithIconAfterContent = () => ( + } iconPosition="after"> + Hello, world + +); + +WithIconAfterContent.storyName = 'With icon after content'; + +export const WithIconAfterContentRTL = getStoryVariant(WithIconAfterContent, RTL); + +export const IconOnly = () => } />; + +IconOnly.storyName = 'Icon only'; + +export const CircularAndIconOnly = () => } />; + +CircularAndIconOnly.storyName = 'Circular and icon only'; + +export const CircularAndIconOnlyRTL = getStoryVariant(CircularAndIconOnly, RTL); diff --git a/apps/vr-tests-react-components/src/stories/Button/utils.ts b/apps/vr-tests-react-components/src/stories/Button/utils.ts index 651478afafb80e..67e1161345acfa 100644 --- a/apps/vr-tests-react-components/src/stories/Button/utils.ts +++ b/apps/vr-tests-react-components/src/stories/Button/utils.ts @@ -10,9 +10,9 @@ export const useStyles = makeStyles({ }); export const steps = new Steps() - .snapshot('default', { cropTo: '.testWrapper' }) + .snapshot('default') .hover('#button-id') - .snapshot('hover', { cropTo: '.testWrapper' }) + .snapshot('hover') .mouseDown('#button-id') - .snapshot('pressed', { cropTo: '.testWrapper' }) + .snapshot('pressed') .end(); diff --git a/apps/vr-tests-react-components/src/stories/Charts/DonutChart.stories.tsx b/apps/vr-tests-react-components/src/stories/Charts/DonutChart.stories.tsx index d8f99d1ea3d3de..ebe06600298d19 100644 --- a/apps/vr-tests-react-components/src/stories/Charts/DonutChart.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Charts/DonutChart.stories.tsx @@ -29,7 +29,7 @@ export const Basic = () => { return (
{ return (
- +
); }; diff --git a/apps/vr-tests-react-components/src/stories/Charts/LineChart.stories.tsx b/apps/vr-tests-react-components/src/stories/Charts/LineChart.stories.tsx index 13736f225af00b..4896d53a1ca04f 100644 --- a/apps/vr-tests-react-components/src/stories/Charts/LineChart.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Charts/LineChart.stories.tsx @@ -149,7 +149,7 @@ export const Basic = () => { return (
{ return (
withStoryWrightSteps({ story, steps: new Steps().snapshot('default').end() })], +} satisfies Meta; + +export const Default = () => ; + +export const ColorSliders = () => ( + <> + + + +); + +export const AlphaSliders = () => ( + <> + + + + + +); + +export const DefaultDarkMode = getStoryVariant(Default, DARK_MODE); + +export const DefaultHighContrast = getStoryVariant(Default, HIGH_CONTRAST); + +export const DefaultRTL = getStoryVariant(Default, RTL); + +export const Shape = () => ( + <> + + + +); +Shape.storyName = 'shape'; diff --git a/apps/vr-tests-react-components/src/stories/ColorPicker/utils.tsx b/apps/vr-tests-react-components/src/stories/ColorPicker/utils.tsx new file mode 100644 index 00000000000000..b8f5ae6a950f3b --- /dev/null +++ b/apps/vr-tests-react-components/src/stories/ColorPicker/utils.tsx @@ -0,0 +1,29 @@ +import * as React from 'react'; +import { + ColorPicker, + ColorArea, + AlphaSlider, + ColorSlider, + type ColorPickerProps, +} from '@fluentui/react-color-picker-preview'; +import { makeStyles } from '@griffel/react'; + +const useStyles = makeStyles({ + example: { + width: '300px', + display: 'flex', + flexDirection: 'column', + gap: '8px', + }, +}); + +export const SampleColorPicker = (props: ColorPickerProps) => { + const styles = useStyles(); + return ( + + + + + + ); +}; diff --git a/apps/vr-tests-react-components/src/stories/Image/Image.stories.tsx b/apps/vr-tests-react-components/src/stories/Image/Image.stories.tsx index ea795f5994ba8b..b1fdd6cc8135ee 100644 --- a/apps/vr-tests-react-components/src/stories/Image/Image.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Image/Image.stories.tsx @@ -9,9 +9,7 @@ export default { title: 'Image Converged', decorators: [ - (story: () => React.ReactNode) => ( - {story()} - ), + (story: () => React.ReactNode) => {story()}, ], } satisfies Meta; diff --git a/apps/vr-tests-react-components/src/stories/Label.stories.tsx b/apps/vr-tests-react-components/src/stories/Label.stories.tsx index 08919a31d43675..1315aa7d099255 100644 --- a/apps/vr-tests-react-components/src/stories/Label.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Label.stories.tsx @@ -7,9 +7,7 @@ import { DARK_MODE, getStoryVariant, HIGH_CONTRAST, RTL, withStoryWrightSteps } export default { title: 'Label Converged', - decorators: [ - story => withStoryWrightSteps({ story, steps: new Steps().snapshot('default', { cropTo: '.testWrapper' }).end() }), - ], + decorators: [story => withStoryWrightSteps({ story, steps: new Steps().snapshot('default').end() })], } satisfies Meta; export const Root = () => ; diff --git a/apps/vr-tests-react-components/src/stories/Link/utils.tsx b/apps/vr-tests-react-components/src/stories/Link/utils.tsx index 9ad2a30f1ac7af..dcb45302663bfe 100644 --- a/apps/vr-tests-react-components/src/stories/Link/utils.tsx +++ b/apps/vr-tests-react-components/src/stories/Link/utils.tsx @@ -21,25 +21,25 @@ export const InvertedBackground: React.FC<{ children: React.ReactNode }> = ({ ch }; export const steps = new Steps() - .snapshot('default', { cropTo: '.testWrapper' }) + .snapshot('default') .hover('.fui-Link') - .snapshot('hover', { cropTo: '.testWrapper' }) + .snapshot('hover') // This needs to be added so that the focus outline is shown correctly .executeScript("document.getElementsByClassName('fui-Link')[0].setAttribute('data-fui-focus-visible', '')") .focus('.fui-Link') - .snapshot('focused', { cropTo: '.testWrapper' }) + .snapshot('focused') .executeScript("document.getElementsByClassName('fui-Link')[0].removeAttribute('data-fui-focus-visible')") .mouseDown('.fui-Link') - .snapshot('pressed', { cropTo: '.testWrapper' }) + .snapshot('pressed') .mouseUp('.fui-Link') .end(); // Disabled stories use steps without focus so they do not error out on the focused step. export const disabledUnfocusableSteps = new Steps() - .snapshot('default', { cropTo: '.testWrapper' }) + .snapshot('default') .hover('.fui-Link') - .snapshot('hover', { cropTo: '.testWrapper' }) + .snapshot('hover') .mouseDown('.fui-Link') - .snapshot('pressed', { cropTo: '.testWrapper' }) + .snapshot('pressed') .mouseUp('.fui-Link') .end(); diff --git a/apps/vr-tests-react-components/src/stories/Menu/MenuMultilineItems.stories.tsx b/apps/vr-tests-react-components/src/stories/Menu/MenuMultilineItems.stories.tsx new file mode 100644 index 00000000000000..470efdec3b3858 --- /dev/null +++ b/apps/vr-tests-react-components/src/stories/Menu/MenuMultilineItems.stories.tsx @@ -0,0 +1,372 @@ +import * as React from 'react'; +import type { Meta } from '@storybook/react'; +import { Steps } from 'storywright'; +import { + Menu, + MenuTrigger, + MenuPopover, + MenuList, + MenuItem, + MenuGroupHeader, + MenuGroup, + MenuDivider, + MenuSplitGroup, + MenuItemSwitch, + MenuItemCheckbox, +} from '@fluentui/react-menu'; +import { EditFilled, EditRegular, bundleIcon } from '@fluentui/react-icons'; +import { getStoryVariant, RTL, withStoryWrightSteps } from '../../utilities'; + +export default { + title: 'Menu Multiline items', + + decorators: [ + story => + withStoryWrightSteps({ story, steps: new Steps().hover('[role="menuitem"]').snapshot('hover menuitem').end() }), + ], +} satisfies Meta; + +const EditIcon = bundleIcon(EditFilled, EditRegular); + +const TextOnly = () => ( + + Text only + Copy + Copy + +); + +const TextWithIcon = () => ( + + Text with Icon + }>Copy + }> + Copy + + +); + +const TextOnlySubmenu = () => ( + + Text only submenu + + + Open + + + + Open in browser + Open in desktop + + + + + + Open + + + + Open in browser + Open in desktop + + + + +); + +const IconAndSubmenu = () => ( + + Icon and submenu + + + }>Open + + + + Open in browser + Open in desktop + + + + + + }> + Open + + + + + Open in browser + Open in desktop + + + + +); + +const IconAndSecondary = () => ( + + Icon and secondary + } secondaryContent="Ctrl+C"> + Copy + + } subText="Copy text" secondaryContent="Ctrl+C"> + Copy + + +); + +const SplitWithEverything = () => ( + + Split with everything + + + } secondaryContent="Ctrl+N"> + New folder + + + + + + + + New folder + New folder + New folder + + + + + + } subText="Creates a new folder" secondaryContent="Ctrl+N"> + New folder + + + + + + + + New folder + New folder + New folder + + + + +); + +const SplitWithSecondary = () => ( + + Split with secondary + + + New folder + + + + + + + New folder + New folder + New folder + + + + + + + New folder + + + + + + + + New folder + New folder + New folder + + + + +); + +const SplitTextOnly = () => ( + + Split text only + + + New folder + + + + + + + New folder + New folder + New folder + + + + + + New folder + + + + + + + New folder + New folder + New folder + + + + +); + +const SelectableTextOnly = () => ( + + Selectable text only + + Select this thing + + + Select this thing + + +); + +const SelectableWithIcon = () => ( + + Selectable with Icon + }> + Select this thing + + }> + Select this thing + + +); + +const SelectableWithIconAndSecondary = () => ( + + Selectable with icon and secondary + } value="foo" name="bac" secondaryContent="Ctrl+Spacebar"> + Select this thing + + } value="foo" name="bac" subText="Selection" secondaryContent="Ctrl+Spacebar"> + Select this thing + + +); + +const SelectableWithSecondary = () => ( + + Selectable with secondary + + Select this thing + + + Select this thing + + +); + +const SwitchTextOnly = () => ( + + SwitchTextOnly + + Select this thing + + + Select this thing + + +); + +const SwitchWithIcon = () => ( + + SwitchTextOnly + } value="foo" name="switch1"> + Select this thing + + } value="foo" name="switch1" subText="Selection"> + Select this thing + + +); + +const SwitchWithIconAndSecondary = () => ( + + SwitchTextOnly + } value="foo" name="switch2" secondaryContent="Ctrl+Spacebar"> + Select this thing + + } value="foo" name="switch2" subText="Selection" secondaryContent="Ctrl+Spacebar"> + Select this thing + + +); + +export const Default = () => { + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ ); +}; + +Default.storyName = 'default'; + +export const DefaultRTL = getStoryVariant(Default, RTL); diff --git a/apps/vr-tests-react-components/src/stories/MessageBar/MessageBar.stories.tsx b/apps/vr-tests-react-components/src/stories/MessageBar/MessageBar.stories.tsx index b0d4d0cc5bf362..37171428d14ece 100644 --- a/apps/vr-tests-react-components/src/stories/MessageBar/MessageBar.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/MessageBar/MessageBar.stories.tsx @@ -124,15 +124,17 @@ export const Auto = () => { export const Square = () => { return ( - - - Title - Message providing information to the user with actionable insights. Link - - } />}> - - - - +
+ + + Title + Message providing information to the user with actionable insights. Link + + } />}> + + + + +
); }; diff --git a/apps/vr-tests-react-components/src/stories/Positioning/Positioning.stories.tsx b/apps/vr-tests-react-components/src/stories/Positioning/Positioning.stories.tsx index a8bce2012c57d0..3c4cb2047f0cab 100644 --- a/apps/vr-tests-react-components/src/stories/Positioning/Positioning.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Positioning/Positioning.stories.tsx @@ -5,8 +5,9 @@ import { PositioningProps, PositioningVirtualElement, PositioningImperativeRef, + type PositioningRect, } from '@fluentui/react-positioning'; -import { useMergedRefs } from '@fluentui/react-utilities'; +import { useMergedRefs, useIsomorphicLayoutEffect } from '@fluentui/react-utilities'; import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts'; import { Steps, StoryWright } from 'storywright'; @@ -814,11 +815,7 @@ const PositioningEndEvent = () => { }; const TargetDisplayNone = () => { - const positioningRef = React.useRef(null); - const { targetRef, containerRef } = usePositioning({ - positioningRef, - }); - + const { targetRef, containerRef } = usePositioning({}); const [visible, setVisible] = React.useState(true); return ( @@ -843,6 +840,191 @@ const TargetDisplayNone = () => { ); }; +const ShiftToCoverTargetWithAutoSize = () => { + const styles = useStyles(); + const [overflowBoundary, setOverflowBoundary] = React.useState(null); + const { containerRef, targetRef } = usePositioning({ + position: 'below', + overflowBoundary, + shiftToCoverTarget: true, + autoSize: true, + }); + + return ( +
+ + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore + magna aliqua. In fermentum et sollicitudin ac orci phasellus egestas. Facilisi cras fermentum odio eu feugiat + pretium nibh ipsum consequat. Praesent semper feugiat nibh sed pulvinar proin gravida hendrerit lectus. Porta + nibh venenatis cras sed felis eget. Enim sed faucibus turpis in. Non blandit massa enim nec dui nunc mattis. Ut + eu sem integer vitae justo. + +
+ ); +}; + +const ShiftToCoverTargetAsyncContentHorizontal = () => { + const styles = useStyles(); + const [overflowBoundary, setOverflowBoundary] = React.useState(null); + const { containerRef, targetRef } = usePositioning({ + position: 'after', + overflowBoundary, + shiftToCoverTarget: true, + autoSize: true, + }); + + return ( +
+ + + + + + +
+ ); +}; + +const ShiftToCoverTargetAsyncContent = () => { + const styles = useStyles(); + const [overflowBoundary, setOverflowBoundary] = React.useState(null); + const { containerRef, targetRef } = usePositioning({ + position: 'below', + overflowBoundary, + shiftToCoverTarget: true, + autoSize: true, + }); + + return ( +
+ + + + +
+ ); +}; + +const BoundaryRect = () => { + const rectHostRef = React.useRef(null); + + const boundaryRect = React.useMemo( + () => ({ + width: 700, + height: 700, + x: 70, + y: 70, + }), + [], + ); + const { targetRef, containerRef } = usePositioning({ + overflowBoundary: boundaryRect, + + position: 'below', + align: 'end', + }); + + useIsomorphicLayoutEffect(() => { + const rectEl = document.createElement('div'); + + Object.assign(rectEl.style, { + position: 'fixed', + border: '4px solid orange', + boxSizing: 'border-box', + + left: `${boundaryRect.x}px`, + top: `${boundaryRect.y}px`, + width: `${boundaryRect.width}px`, + height: `${boundaryRect.height}px`, + + zIndex: 1, + }); + + rectHostRef.current?.append(rectEl); + + return () => { + rectEl.remove(); + }; + }, [boundaryRect]); + + return ( + <> +
+
+
+ Hello world +
+
+
+
    +
  • + SHOULD BE below gray box as it's a target +
  • +
  • + SHOULD BE inside an orange box as it's a overflowBoundary +
  • +
+
+ + ); +}; + export default { title: 'Positioning', @@ -864,6 +1046,9 @@ export default { ], } satisfies Meta<'div'>; +export const _BoundaryRect = () => ; +_BoundaryRect.storyName = 'using boundary rect'; + export const _PositionAndAlignProps = () => ; _PositionAndAlignProps.storyName = 'position and align props'; @@ -1033,3 +1218,32 @@ export const _TargetDisplayNone = () => ( ); _TargetDisplayNone.storyName = 'Target display none'; + +export const _ShiftToCoverTargetWithAutoSize = () => ; +_ShiftToCoverTargetWithAutoSize.storyName = 'shiftToCoverTarget with autoSize'; + +export const _ShiftToCoverTargetAsyncContent = () => ( + + + +); +_ShiftToCoverTargetAsyncContent.storyName = 'shiftToCoverTarget with autoSize and async content'; + +export const _ShiftToCoverTargetHorizontal = () => ( + + + +); +_ShiftToCoverTargetHorizontal.storyName = 'shiftToCoverTarget with autoSize and async content - horizontal'; diff --git a/apps/vr-tests-react-components/src/stories/ShadowDOM/ShadowDOMDefault.stories.tsx b/apps/vr-tests-react-components/src/stories/ShadowDOM/ShadowDOMDefault.stories.tsx index 2ac6ca52265ef0..7417a564b7da37 100644 --- a/apps/vr-tests-react-components/src/stories/ShadowDOM/ShadowDOMDefault.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/ShadowDOM/ShadowDOMDefault.stories.tsx @@ -41,7 +41,7 @@ export default { }; export const Default = () => ( - + diff --git a/apps/vr-tests-react-components/src/stories/ShadowDOM/ShadowDOMPortal.stories.tsx b/apps/vr-tests-react-components/src/stories/ShadowDOM/ShadowDOMPortal.stories.tsx index 09e443803c5162..15442ac31c509f 100644 --- a/apps/vr-tests-react-components/src/stories/ShadowDOM/ShadowDOMPortal.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/ShadowDOM/ShadowDOMPortal.stories.tsx @@ -10,7 +10,7 @@ export default { }; export const Portal: React.FC = () => ( - + diff --git a/apps/vr-tests-react-components/src/stories/Slider/Slider.stories.tsx b/apps/vr-tests-react-components/src/stories/Slider/Slider.stories.tsx index 477085a483d367..fd57fd1077798e 100644 --- a/apps/vr-tests-react-components/src/stories/Slider/Slider.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Slider/Slider.stories.tsx @@ -3,6 +3,7 @@ import type { Meta } from '@storybook/react'; import { Steps } from 'storywright'; import { Slider } from '@fluentui/react-slider'; import { getStoryVariant, RTL, TestWrapperDecorator, withStoryWrightSteps } from '../../utilities'; +import { SampleCustomizedSlider } from './utils'; export default { title: 'Slider Converged', @@ -31,3 +32,5 @@ export const Vertical100 = () => ; Vertical100.storyName = 'Vertical - 100%'; export const Vertical100RTL = getStoryVariant(Vertical100, RTL); + +export const CustomizedSlider = ; diff --git a/apps/vr-tests-react-components/src/stories/Slider/utils.tsx b/apps/vr-tests-react-components/src/stories/Slider/utils.tsx new file mode 100644 index 00000000000000..b663d99733b1f8 --- /dev/null +++ b/apps/vr-tests-react-components/src/stories/Slider/utils.tsx @@ -0,0 +1,33 @@ +import * as React from 'react'; +import { Slider, sliderCSSVars } from '@fluentui/react-slider'; +import { makeStyles } from '@griffel/react'; +const { sliderProgressColorVar, sliderRailColorVar, sliderThumbColorVar, sliderThumbSizeVar } = sliderCSSVars; + +const useStyles = makeStyles({ + enabled: { + [sliderProgressColorVar]: '#ff0764', + [sliderRailColorVar]: '##242424', + [sliderThumbColorVar]: '#ff0764', + ':hover': { + [sliderThumbColorVar]: '#d60d58', + [sliderProgressColorVar]: '#d60d58', + ':active': { + [sliderThumbColorVar]: '#b91150', + [sliderProgressColorVar]: '#b91150', + }, + }, + }, + thumb: { + [sliderThumbSizeVar]: '16px', + boxShadow: `0 0 0 calc(var(${sliderThumbSizeVar}) * .2) transparent inset`, + '::before': { + content: 'unset', + }, + }, +}); + +export const SampleCustomizedSlider = () => { + const styles = useStyles(); + + return ; +}; diff --git a/apps/vr-tests-react-components/src/stories/SwatchPicker/SwatchPicker.stories.tsx b/apps/vr-tests-react-components/src/stories/SwatchPicker/SwatchPicker.stories.tsx index dea1b91753f6f8..16d4c7e661656a 100644 --- a/apps/vr-tests-react-components/src/stories/SwatchPicker/SwatchPicker.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/SwatchPicker/SwatchPicker.stories.tsx @@ -1,13 +1,14 @@ import * as React from 'react'; import type { Meta } from '@storybook/react'; import { SwatchPicker } from '@fluentui/react-swatch-picker'; -import { SampleSwatchPickerColors, SampleSwatchPickerImages, SampleSwatchPickerGrid, steps } from './utils'; +import { SampleSwatchPickerColors, SampleSwatchPickerImages, SampleSwatchPickerGrid } from './utils'; +import { Steps } from 'storywright'; import { DARK_MODE, getStoryVariant, HIGH_CONTRAST, RTL, withStoryWrightSteps } from '../../utilities'; export default { title: 'SwatchPicker Converged', - decorators: [story => withStoryWrightSteps({ story, steps })], + decorators: [story => withStoryWrightSteps({ story, steps: new Steps().snapshot('default').end() })], } satisfies Meta; export const Default = () => ( @@ -20,7 +21,6 @@ export const Default = () => ( ); -Default.storyName = 'default'; export const DefaultDarkMode = getStoryVariant(Default, DARK_MODE); @@ -64,7 +64,7 @@ export const Shape = () => ( ); -Size.storyName = 'shape'; +Shape.storyName = 'shape'; export const Spacing = () => ( <> @@ -79,4 +79,4 @@ export const Spacing = () => ( ); -Size.storyName = 'spacing'; +Spacing.storyName = 'spacing'; diff --git a/apps/vr-tests-react-components/src/stories/SwatchPicker/utils.tsx b/apps/vr-tests-react-components/src/stories/SwatchPicker/utils.tsx index d39f7b8378a07e..67bc8b5cdef187 100644 --- a/apps/vr-tests-react-components/src/stories/SwatchPicker/utils.tsx +++ b/apps/vr-tests-react-components/src/stories/SwatchPicker/utils.tsx @@ -1,25 +1,14 @@ import * as React from 'react'; -import { Steps } from 'storywright'; import { SwatchPicker, ColorSwatch, - SwatchPickerProps, + type SwatchPickerProps, ImageSwatch, EmptySwatch, SwatchPickerRow, } from '@fluentui/react-swatch-picker'; import { HeartRegular } from '@fluentui/react-icons'; -export const steps = new Steps() - .snapshot('default', { cropTo: '.testWrapper' }) - .hover('.breadcrumb-sample') - .snapshot('hover', { cropTo: '.testWrapper' }) - .mouseDown('.breadcrumb-sample') - .snapshot('pressed', { cropTo: '.testWrapper' }) - .focus('.breadcrumb-sample') - .snapshot('focused', { cropTo: '.testWrapper' }) - .end(); - export const SampleSwatchPickerColors = (props: SwatchPickerProps) => ( diff --git a/apps/vr-tests-react-components/src/stories/Tabs.stories.tsx b/apps/vr-tests-react-components/src/stories/Tabs.stories.tsx index 409afb8012da87..d7cd382029b1e6 100644 --- a/apps/vr-tests-react-components/src/stories/Tabs.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Tabs.stories.tsx @@ -13,11 +13,11 @@ export default { withStoryWrightSteps({ story, steps: new Steps() - .snapshot('default', { cropTo: '.testWrapper' }) + .snapshot('default') .hover('.mouse-target') - .snapshot('hover', { cropTo: '.testWrapper' }) + .snapshot('hover') .mouseDown('.mouse-target') - .snapshot('pressed', { cropTo: '.testWrapper' }) + .snapshot('pressed') .mouseUp('.mouse-target') .end(), }), diff --git a/apps/vr-tests-react-components/src/stories/Tag/InteractionTag.stories.tsx b/apps/vr-tests-react-components/src/stories/Tag/InteractionTag.stories.tsx index 42a839348865fc..373d4a70796d4a 100644 --- a/apps/vr-tests-react-components/src/stories/Tag/InteractionTag.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Tag/InteractionTag.stories.tsx @@ -9,7 +9,7 @@ import { makeStyles } from '@griffel/react'; const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular); -const steps = new Steps().snapshot('default', { cropTo: '.testWrapper' }).end(); +const steps = new Steps().snapshot('default').end(); export default { title: 'InteractionTag Converged', diff --git a/apps/vr-tests-react-components/src/stories/Tag/InteractionTagAppearances.stories.tsx b/apps/vr-tests-react-components/src/stories/Tag/InteractionTagAppearances.stories.tsx index 681b0c8fc5776c..6e6270225d6722 100644 --- a/apps/vr-tests-react-components/src/stories/Tag/InteractionTagAppearances.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Tag/InteractionTagAppearances.stories.tsx @@ -10,16 +10,16 @@ const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular); const contentId = 'content-id'; const dismissButtonId = 'dismiss-button-id'; const steps = new Steps() - .snapshot('default', { cropTo: '.testWrapper' }) + .snapshot('default') .hover(`#${contentId}`) - .snapshot('hover content', { cropTo: '.testWrapper' }) + .snapshot('hover content') .mouseDown(`#${contentId}`) - .snapshot('pressed content', { cropTo: '.testWrapper' }) + .snapshot('pressed content') .mouseUp(`#${contentId}`) .hover(`#${dismissButtonId}`) - .snapshot('hover dismiss', { cropTo: '.testWrapper' }) + .snapshot('hover dismiss') .mouseDown(`#${dismissButtonId}`) - .snapshot('pressed dismiss', { cropTo: '.testWrapper' }) + .snapshot('pressed dismiss') .mouseUp(`#${dismissButtonId}`) .end(); diff --git a/apps/vr-tests-react-components/src/stories/Tag/InteractionTagShape.stories.tsx b/apps/vr-tests-react-components/src/stories/Tag/InteractionTagShape.stories.tsx index 7b539a470bbd66..33d21f8c3494fc 100644 --- a/apps/vr-tests-react-components/src/stories/Tag/InteractionTagShape.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Tag/InteractionTagShape.stories.tsx @@ -8,18 +8,18 @@ import { Steps } from 'storywright'; const contentId = 'content-id'; const dismissButtonId = 'dismiss-button-id'; const steps = new Steps() - .snapshot('default', { cropTo: '.testWrapper' }) + .snapshot('default') // This needs to be added so that the focus outline is shown correctly .executeScript(`document.querySelector('#${contentId}').setAttribute('data-fui-focus-visible', '')`) .focus(`#${contentId}`) - .snapshot('focus content', { cropTo: '.testWrapper' }) + .snapshot('focus content') .executeScript(`document.querySelector('#${contentId}').removeAttribute('data-fui-focus-visible')`) // This needs to be added so that the focus outline is shown correctly .executeScript(`document.querySelector('#${dismissButtonId}').setAttribute('data-fui-focus-visible', '')`) .focus(`#${dismissButtonId}`) - .snapshot('focus dismiss', { cropTo: '.testWrapper' }) + .snapshot('focus dismiss') .executeScript(`document.querySelector('#${dismissButtonId}').removeAttribute('data-fui-focus-visible')`) .end(); diff --git a/apps/vr-tests-react-components/src/stories/Tag/Tag.stories.tsx b/apps/vr-tests-react-components/src/stories/Tag/Tag.stories.tsx index bde3970f43ea83..b028df283f9d66 100644 --- a/apps/vr-tests-react-components/src/stories/Tag/Tag.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Tag/Tag.stories.tsx @@ -8,7 +8,7 @@ import { Steps } from 'storywright'; const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular); -const steps = new Steps().snapshot('default', { cropTo: '.testWrapper' }).end(); +const steps = new Steps().snapshot('default').end(); export default { title: 'Tag Converged', diff --git a/apps/vr-tests-react-components/src/stories/Tag/TagAppearances.stories.tsx b/apps/vr-tests-react-components/src/stories/Tag/TagAppearances.stories.tsx index 0310924ea9fbf7..4d529cc33e1e78 100644 --- a/apps/vr-tests-react-components/src/stories/Tag/TagAppearances.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Tag/TagAppearances.stories.tsx @@ -9,11 +9,11 @@ const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular); const dismissIconId = 'dismiss-icon-id'; const steps = new Steps() - .snapshot('default', { cropTo: '.testWrapper' }) + .snapshot('default') .hover(`#${dismissIconId}}`) - .snapshot('hover', { cropTo: '.testWrapper' }) + .snapshot('hover') .mouseDown(`#${dismissIconId}}`) - .snapshot('pressed', { cropTo: '.testWrapper' }) + .snapshot('pressed') .end(); export default { diff --git a/apps/vr-tests-react-components/src/stories/Tag/TagGroup.stories.tsx b/apps/vr-tests-react-components/src/stories/Tag/TagGroup.stories.tsx index 961347ffbd30e8..f24947feb4ae0f 100644 --- a/apps/vr-tests-react-components/src/stories/Tag/TagGroup.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Tag/TagGroup.stories.tsx @@ -4,7 +4,7 @@ import type { Meta } from '@storybook/react'; import { Steps } from 'storywright'; import { withStoryWrightSteps } from '../../utilities'; -const steps = new Steps().snapshot('default', { cropTo: '.testWrapper' }).end(); +const steps = new Steps().snapshot('default').end(); export default { title: 'TagGroup Converged', diff --git a/apps/vr-tests-react-components/src/stories/Tag/TagShape.stories.tsx b/apps/vr-tests-react-components/src/stories/Tag/TagShape.stories.tsx index 2a0a4611471873..c75840c8287e05 100644 --- a/apps/vr-tests-react-components/src/stories/Tag/TagShape.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Tag/TagShape.stories.tsx @@ -7,11 +7,11 @@ import { Steps } from 'storywright'; const tagId = 'tag-id'; const steps = new Steps() - .snapshot('default', { cropTo: '.testWrapper' }) + .snapshot('default') // This needs to be added so that the focus outline is shown correctly .executeScript(`document.querySelector('#${tagId}').setAttribute('data-fui-focus-visible', '')`) .focus(`#${tagId}`) - .snapshot('focused', { cropTo: '.testWrapper' }) + .snapshot('focused') .executeScript(`document.querySelector('#${tagId}').removeAttribute('data-fui-focus-visible')`) .end(); diff --git a/apps/vr-tests-react-components/src/stories/Textarea/TextareaInteractions.stories.tsx b/apps/vr-tests-react-components/src/stories/Textarea/TextareaInteractions.stories.tsx index 711e3b5f7e4951..7536b4c2c9de39 100644 --- a/apps/vr-tests-react-components/src/stories/Textarea/TextareaInteractions.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Textarea/TextareaInteractions.stories.tsx @@ -18,7 +18,7 @@ export default { .snapshot('hover', { cropTo: '.testWrapper' }) .click('textarea') .wait(250) // needed for bottom focus border animation - .snapshot('focused', { cropTo: '.textWrapper' }) + .snapshot('focused', { cropTo: '.testWrapper' }) .end(), }), ], diff --git a/apps/vr-tests-react-components/src/utilities/index.ts b/apps/vr-tests-react-components/src/utilities/index.ts index 177f1172845a51..4cb4101034aa97 100644 --- a/apps/vr-tests-react-components/src/utilities/index.ts +++ b/apps/vr-tests-react-components/src/utilities/index.ts @@ -1,3 +1,9 @@ -export * from './TestWrapperDecorator'; -export * from './getStoryVariant'; -export * from './withStoryWrightSteps'; +export { + TestWrapperDecorator, + TestWrapperDecoratorFixedWidth, + TestWrapperDecoratorFullWidth, + TestWrapperDecoratorTall, + TestWrapperDecoratorTallFixedWidth, +} from './TestWrapperDecorator'; +export { DARK_MODE, HIGH_CONTRAST, RTL, getStoryVariant } from './getStoryVariant'; +export { withStoryWrightSteps } from './withStoryWrightSteps'; diff --git a/apps/vr-tests-web-components/tsconfig.json b/apps/vr-tests-web-components/tsconfig.json index abfc043cd7b049..746192c737c398 100644 --- a/apps/vr-tests-web-components/tsconfig.json +++ b/apps/vr-tests-web-components/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../../tsconfig.base.wc.json", "compilerOptions": { - "target": "ES2019", "module": "NodeNext", "noEmit": true, "experimentalDecorators": true, 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/apps/vr-tests/src/stories/react-charting/AreaChart.stories.tsx b/apps/vr-tests/src/stories/react-charting/AreaChart.stories.tsx index 457ee679afdec5..f6d8502173a2c4 100644 --- a/apps/vr-tests/src/stories/react-charting/AreaChart.stories.tsx +++ b/apps/vr-tests/src/stories/react-charting/AreaChart.stories.tsx @@ -141,7 +141,7 @@ export const Basic = () => { return (
{ return (
{ return (
ypointMapping[point as string]} diff --git a/apps/vr-tests/src/stories/react-charting/HorizontalBarChart.stories.tsx b/apps/vr-tests/src/stories/react-charting/HorizontalBarChart.stories.tsx index ff2ca9da844aec..c3cd51db8b8faa 100644 --- a/apps/vr-tests/src/stories/react-charting/HorizontalBarChart.stories.tsx +++ b/apps/vr-tests/src/stories/react-charting/HorizontalBarChart.stories.tsx @@ -136,12 +136,7 @@ export const Basic = () => { return (
- +
); }; @@ -345,7 +340,7 @@ export const WithAxis = () => { return (
{ return (
{ ]; const colors = ['#e81123', '#0078d4', '#107c10']; return ( - + ); }; diff --git a/apps/vr-tests/src/stories/react-charting/StackedBarChart.stories.tsx b/apps/vr-tests/src/stories/react-charting/StackedBarChart.stories.tsx index 960adc4b3c67f7..db3792dbde6e1c 100644 --- a/apps/vr-tests/src/stories/react-charting/StackedBarChart.stories.tsx +++ b/apps/vr-tests/src/stories/react-charting/StackedBarChart.stories.tsx @@ -45,14 +45,14 @@ export const Basic = () => { return (

{ return (
{ return (
{ return (
{ <>
+## [8.2.26](https://github.com/microsoft/fluentui/tree/@fluentui/api-docs_v8.2.26) + +Wed, 12 Feb 2025 07:20:51 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/api-docs_v8.2.25..@fluentui/api-docs_v8.2.26) + +### Patches + +- chore: update api-extractor to 7.49.1 ([PR #33692](https://github.com/microsoft/fluentui/pull/33692) by vgenaev@gmail.com) + ## [8.2.25](https://github.com/microsoft/fluentui/tree/@fluentui/api-docs_v8.2.25) Thu, 11 Jul 2024 07:33:36 GMT diff --git a/packages/api-docs/package.json b/packages/api-docs/package.json index 378c8411af0a5c..68462cbf912285 100644 --- a/packages/api-docs/package.json +++ b/packages/api-docs/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/api-docs", - "version": "8.2.25", + "version": "8.2.26", "description": "Transforms API Extractor .api.json files into .page.json files", "repository": { "type": "git", @@ -21,8 +21,8 @@ "@fluentui/scripts-tasks": "*" }, "dependencies": { - "@microsoft/api-extractor-model": "7.28.3", - "@microsoft/tsdoc": "0.14.2", + "@microsoft/api-extractor-model": "7.30.2", + "@microsoft/tsdoc": "0.15.1", "fs-extra": "^8.1.0" } } diff --git a/packages/azure-themes/CHANGELOG.json b/packages/azure-themes/CHANGELOG.json index d5db9f8fe859b6..67fbdc538a429c 100644 --- a/packages/azure-themes/CHANGELOG.json +++ b/packages/azure-themes/CHANGELOG.json @@ -1,6 +1,192 @@ { "name": "@fluentui/azure-themes", "entries": [ + { + "date": "Fri, 21 Feb 2025 07:22:41 GMT", + "tag": "@fluentui/azure-themes_v8.6.124", + "version": "8.6.124", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/azure-themes", + "comment": "Bump @fluentui/react to v8.122.11", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/azure-themes", + "comment": "Bump @fluentui/set-version to v8.2.24", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + } + ] + } + }, + { + "date": "Wed, 19 Feb 2025 07:21:16 GMT", + "tag": "@fluentui/azure-themes_v8.6.123", + "version": "8.6.123", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/azure-themes", + "comment": "Bump @fluentui/react to v8.122.10", + "commit": "8264ce0435583ae69c051f109388005be3c0de2b" + } + ] + } + }, + { + "date": "Wed, 29 Jan 2025 07:21:15 GMT", + "tag": "@fluentui/azure-themes_v8.6.122", + "version": "8.6.122", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/azure-themes", + "comment": "Bump @fluentui/react to v8.122.9", + "commit": "111bf937b3793db68e32a90774b04f3bf61f4be5" + } + ] + } + }, + { + "date": "Wed, 22 Jan 2025 07:21:49 GMT", + "tag": "@fluentui/azure-themes_v8.6.121", + "version": "8.6.121", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/azure-themes", + "comment": "Bump @fluentui/react to v8.122.8", + "commit": "012298d98651800023aac24c591831e9bc51bea2" + } + ] + } + }, + { + "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", + "version": "8.6.119", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/azure-themes", + "comment": "Bump @fluentui/react to v8.122.6", + "commit": "bf60a56cb23b3af90bcb62462c2423468eb9fa3c" + } + ] + } + }, + { + "date": "Wed, 08 Jan 2025 07:21:37 GMT", + "tag": "@fluentui/azure-themes_v8.6.118", + "version": "8.6.118", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/azure-themes", + "comment": "Bump @fluentui/react to v8.122.5", + "commit": "8f763922d713d9ccd35e65db07206c10b170fafd" + } + ] + } + }, + { + "date": "Fri, 03 Jan 2025 07:21:32 GMT", + "tag": "@fluentui/azure-themes_v8.6.117", + "version": "8.6.117", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/azure-themes", + "comment": "Bump @fluentui/react to v8.122.4", + "commit": "7bb97f178d73a470dc438a2b19d165d9d0bd4b51" + } + ] + } + }, + { + "date": "Mon, 30 Dec 2024 07:21:29 GMT", + "tag": "@fluentui/azure-themes_v8.6.116", + "version": "8.6.116", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/azure-themes", + "comment": "Bump @fluentui/react to v8.122.3", + "commit": "681a95a732fe385a70b8d4537dc489acbcd1c21e" + } + ] + } + }, + { + "date": "Mon, 23 Dec 2024 07:22:58 GMT", + "tag": "@fluentui/azure-themes_v8.6.115", + "version": "8.6.115", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/azure-themes", + "comment": "Bump @fluentui/react to v8.122.2", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + } + ] + } + }, + { + "date": "Fri, 13 Dec 2024 07:23:12 GMT", + "tag": "@fluentui/azure-themes_v8.6.114", + "version": "8.6.114", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/azure-themes", + "comment": "Bump @fluentui/react to v8.122.1", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7" + } + ] + } + }, + { + "date": "Thu, 12 Dec 2024 07:22:33 GMT", + "tag": "@fluentui/azure-themes_v8.6.113", + "version": "8.6.113", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/azure-themes", + "comment": "Bump @fluentui/react to v8.122.0", + "commit": "53dd771e70338065810404663cd6219d1b54c1e2" + } + ] + } + }, { "date": "Fri, 22 Nov 2024 07:21:18 GMT", "tag": "@fluentui/azure-themes_v8.6.112", diff --git a/packages/azure-themes/CHANGELOG.md b/packages/azure-themes/CHANGELOG.md index e0eb6f01f7b638..8f86c7ce2a8438 100644 --- a/packages/azure-themes/CHANGELOG.md +++ b/packages/azure-themes/CHANGELOG.md @@ -1,9 +1,118 @@ # Change Log - @fluentui/azure-themes -This log was last generated on Fri, 22 Nov 2024 07:21:18 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 07:22:41 GMT and should not be manually modified. +## [8.6.124](https://github.com/microsoft/fluentui/tree/@fluentui/azure-themes_v8.6.124) + +Fri, 21 Feb 2025 07:22:41 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/azure-themes_v8.6.123..@fluentui/azure-themes_v8.6.124) + +### Patches + +- Bump @fluentui/react to v8.122.11 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/set-version to v8.2.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) + +## [8.6.123](https://github.com/microsoft/fluentui/tree/@fluentui/azure-themes_v8.6.123) + +Wed, 19 Feb 2025 07:21:16 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/azure-themes_v8.6.122..@fluentui/azure-themes_v8.6.123) + +### Patches + +- Bump @fluentui/react to v8.122.10 ([PR #33867](https://github.com/microsoft/fluentui/pull/33867) by beachball) + +## [8.6.122](https://github.com/microsoft/fluentui/tree/@fluentui/azure-themes_v8.6.122) + +Wed, 29 Jan 2025 07:21:15 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/azure-themes_v8.6.121..@fluentui/azure-themes_v8.6.122) + +### Patches + +- Bump @fluentui/react to v8.122.9 ([PR #33713](https://github.com/microsoft/fluentui/pull/33713) by beachball) + +## [8.6.121](https://github.com/microsoft/fluentui/tree/@fluentui/azure-themes_v8.6.121) + +Wed, 22 Jan 2025 07:21:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/azure-themes_v8.6.120..@fluentui/azure-themes_v8.6.121) + +### Patches + +- Bump @fluentui/react to v8.122.8 ([PR #33685](https://github.com/microsoft/fluentui/pull/33685) by beachball) + +## [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 +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/azure-themes_v8.6.118..@fluentui/azure-themes_v8.6.119) + +### Patches + +- Bump @fluentui/react to v8.122.6 ([PR #33148](https://github.com/microsoft/fluentui/pull/33148) by beachball) + +## [8.6.118](https://github.com/microsoft/fluentui/tree/@fluentui/azure-themes_v8.6.118) + +Wed, 08 Jan 2025 07:21:37 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/azure-themes_v8.6.117..@fluentui/azure-themes_v8.6.118) + +### Patches + +- Bump @fluentui/react to v8.122.5 ([PR #33578](https://github.com/microsoft/fluentui/pull/33578) by beachball) + +## [8.6.117](https://github.com/microsoft/fluentui/tree/@fluentui/azure-themes_v8.6.117) + +Fri, 03 Jan 2025 07:21:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/azure-themes_v8.6.116..@fluentui/azure-themes_v8.6.117) + +### Patches + +- Bump @fluentui/react to v8.122.4 ([PR #33529](https://github.com/microsoft/fluentui/pull/33529) by beachball) + +## [8.6.116](https://github.com/microsoft/fluentui/tree/@fluentui/azure-themes_v8.6.116) + +Mon, 30 Dec 2024 07:21:29 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/azure-themes_v8.6.115..@fluentui/azure-themes_v8.6.116) + +### Patches + +- Bump @fluentui/react to v8.122.3 ([PR #33520](https://github.com/microsoft/fluentui/pull/33520) by beachball) + +## [8.6.115](https://github.com/microsoft/fluentui/tree/@fluentui/azure-themes_v8.6.115) + +Mon, 23 Dec 2024 07:22:58 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/azure-themes_v8.6.114..@fluentui/azure-themes_v8.6.115) + +### Patches + +- Bump @fluentui/react to v8.122.2 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) + +## [8.6.114](https://github.com/microsoft/fluentui/tree/@fluentui/azure-themes_v8.6.114) + +Fri, 13 Dec 2024 07:23:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/azure-themes_v8.6.113..@fluentui/azure-themes_v8.6.114) + +### Patches + +- Bump @fluentui/react to v8.122.1 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) + +## [8.6.113](https://github.com/microsoft/fluentui/tree/@fluentui/azure-themes_v8.6.113) + +Thu, 12 Dec 2024 07:22:33 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/azure-themes_v8.6.112..@fluentui/azure-themes_v8.6.113) + +### Patches + +- Bump @fluentui/react to v8.122.0 ([PR #33243](https://github.com/microsoft/fluentui/pull/33243) by beachball) + ## [8.6.112](https://github.com/microsoft/fluentui/tree/@fluentui/azure-themes_v8.6.112) Fri, 22 Nov 2024 07:21:18 GMT diff --git a/packages/azure-themes/package.json b/packages/azure-themes/package.json index 8577a737ab5f70..9afb563e65ed55 100644 --- a/packages/azure-themes/package.json +++ b/packages/azure-themes/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/azure-themes", - "version": "8.6.112", + "version": "8.6.124", "description": "Azure themes for Fluent UI React", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -27,8 +27,8 @@ "@fluentui/scripts-webpack": "*" }, "dependencies": { - "@fluentui/react": "^8.121.13", - "@fluentui/set-version": "^8.2.23", + "@fluentui/react": "^8.122.11", + "@fluentui/set-version": "^8.2.24", "tslib": "^2.1.0" } } diff --git a/packages/charts/chart-web-components/.eslintignore b/packages/charts/chart-web-components/.eslintignore new file mode 100644 index 00000000000000..ba38ef5432888d --- /dev/null +++ b/packages/charts/chart-web-components/.eslintignore @@ -0,0 +1,8 @@ +# don't ever lint node_modules +node_modules +# don't lint build output (make sure it's set to your correct build folder name) +dist +# don't lint coverage output +coverage +# don't lint storybook +.storybook diff --git a/packages/charts/chart-web-components/.eslintrc.json b/packages/charts/chart-web-components/.eslintrc.json new file mode 100644 index 00000000000000..3d5876196e9baa --- /dev/null +++ b/packages/charts/chart-web-components/.eslintrc.json @@ -0,0 +1,74 @@ +{ + "root": true, + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint", "import"], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "prettier", + "plugin:playwright/recommended" + ], + "settings": { + "react": { + "version": "latest" + } + }, + "rules": { + "no-empty": [ + "error", + { + "allowEmptyCatch": true + } + ], + "no-extra-boolean-cast": "off", + "no-prototype-builtins": "off", + "no-fallthrough": "off", + "no-unexpected-multiline": "off", + "no-useless-escape": "off", + "import/order": "error", + "sort-imports": [ + "error", + { + "ignoreCase": true, + "ignoreDeclarationSort": true + } + ], + "comma-dangle": "off", + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-use-before-define": "off", + "@typescript-eslint/no-empty-interface": "error", + "@typescript-eslint/no-empty-object-type": "off", + "@typescript-eslint/no-unsafe-declaration-merging": "off", + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/explicit-function-return-type": "off", + "@typescript-eslint/camelcase": "off", + "@typescript-eslint/no-inferrable-types": "off", + "@typescript-eslint/no-unused-vars": [ + "warn", + { + "args": "none" + } + ], + "@typescript-eslint/no-unused-expressions": "warn", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/naming-convention": [ + "error", + { + "selector": "default", + "format": ["UPPER_CASE", "camelCase", "PascalCase"], + "leadingUnderscore": "allow" + }, + { + "selector": "property", + "format": null // disable for property names because of our foo__expanded convention for JSS + // TODO: I think we can come up with a regex that ignores variables with __ in them + }, + { + "selector": "variable", + "format": null // disable for variable names because of our foo__expanded convention for JSS + // TODO: I think we can come up with a regex that ignores variables with __ in them + } + ] + } +} diff --git a/packages/charts/chart-web-components/.gitignore b/packages/charts/chart-web-components/.gitignore new file mode 100644 index 00000000000000..51511d1f8f36f4 --- /dev/null +++ b/packages/charts/chart-web-components/.gitignore @@ -0,0 +1 @@ +test-results/ diff --git a/packages/charts/chart-web-components/.storybook/docs-root.css b/packages/charts/chart-web-components/.storybook/docs-root.css new file mode 100644 index 00000000000000..b24a61b6161347 --- /dev/null +++ b/packages/charts/chart-web-components/.storybook/docs-root.css @@ -0,0 +1,473 @@ +/* + * Heads Up! + * This file should be kept in sync with the `docs-root.css` file for the React v9 Storybook. + */ + +/* remove the docs wrapper bg to let page bg show through */ +#storybook-docs .sbdocs-wrapper { + background: transparent !important; +} + +/* sb-show-main is missing during page transitions causing a page shift */ +/* todo: cleanup once we no longer inherit docs-root */ +.sb-show-main.sb-main-fullscreen, +.sb-main-fullscreen { + margin: 0; + padding: 0; + display: block; +} + +#storybook-docs .sbdocs-content { + font-family: 'Segoe UI', 'Segoe UI Web (West European)', -apple-system, BlinkMacSystemFont, Roboto, 'Helvetica Neue', + sans-serif; + max-width: 1200px; +} + +#storybook-docs h1.sbdocs-title { + font-size: 44px; + line-height: 60px; + /* identical to box height, or 143% */ + font-weight: 900; + letter-spacing: -0.04em; + color: #000000; +} + +#storybook-docs details { + position: relative; + z-index: 99; +} + +#storybook-docs .sbdocs:not(.sbdocs-preview) p { + font-family: 'Segoe UI', 'Segoe UI Web (West European)', -apple-system, BlinkMacSystemFont, Roboto, 'Helvetica Neue', + sans-serif; + font-size: 18px; + line-height: 27px; + letter-spacing: -0.01em; + color: #000000; + margin-top: 24px; +} + +#storybook-docs .sbdocs-img.featured-image { + max-width: 100%; + margin: 48px 0; + display: block; +} + +#storybook-docs .sbdocs-img { + border-radius: 24px; +} + +#storybook-docs .sbdocs:not(.sbdocs-preview) hr { + margin: 48px 0; + height: 0; + border-top: 1px solid #ebebeb; +} + +#storybook-docs .sbdocs h2 { + font-family: 'Segoe UI', 'Segoe UI Web (West European)', -apple-system, BlinkMacSystemFont, Roboto, 'Helvetica Neue', + sans-serif; + font-size: 24px; + line-height: 28px; + letter-spacing: -0.04em; + color: black; + border-top: 1px solid #ebebeb; + border-bottom: none; + margin: 48px 0 15px 0; + padding: 48px 0 0 0; +} + +#storybook-docs .sbdocs h2 code { + border-radius: 4px; + font-size: 20px; +} + +#storybook-docs .sbdocs-h3 { + font-family: 'Segoe UI', 'Segoe UI Web (West European)', -apple-system, BlinkMacSystemFont, Roboto, 'Helvetica Neue', + sans-serif; + font-size: 18px; + line-height: 24px; + margin: 25px 0 0 0 !important; + letter-spacing: -0.01em; + color: #000000; +} + +#storybook-docs .sbdocs-h3 code { + border-radius: 3px; + font-size: 16px; +} + +/* Only apply to H3s inside of stories which have a parent with an ID */ +#storybook-docs [id] > .sbdocs-h3:before { + content: ''; + display: block; + height: 40px; + margin: -40px 0 0; +} + +#storybook-docs .sbdocs:not(.sbdocs-preview) li { + font-family: 'Segoe UI', 'Segoe UI Web (West European)', -apple-system, BlinkMacSystemFont, Roboto, 'Helvetica Neue', + sans-serif; + font-size: 16px; + line-height: 150%; + letter-spacing: -0.01em; + + /* Neutrals / Web / Gray 200 #1B1A19 */ + color: #1b1a19; + margin-top: 8px; +} + +#storybook-docs .sbdocs:not(.sbdocs-preview) ul { + margin: 12px 0; +} + +#storybook-docs .sbdocs-ul .sbdocs:not(.sbdocs-preview) li { + list-style: none; + position: relative; +} + +#storybook-docs .sbdocs-ul .sbdocs-li::before { + position: absolute; + content: '•'; + color: #8d8d8d; + top: 0; + left: -15px; +} + +#storybook-docs .sbdocs-ol .sbdocs-li::marker { + color: #8d8d8d; +} + +#storybook-docs .sbdocs-preview { + border-radius: 16px; + background: #fff; /* --colorBrandBackgroundInverted */ + padding: 0; + box-shadow: none; + border: 1px solid #d1d1d1; /* --colorNeutralStroke1 */ +} + +/* Apply the currently selected Fluent UI theme to the relevant areas of the docs */ +#storybook-docs .innerZoomElementWrapper > div { + box-sizing: border-box; +} + +/* fix mouse interactions for toolbar on first story */ +#storybook-docs .sbdocs-preview > .os-host { + /* The toolbar sits within the story content area and is position: absolute by default. */ + /* The story content overlays the toolbar making it non-interactive */ + /* We don't use z-index because the toolbar can still sometimes overlay story content (flyout menu) */ + /* The best solution is to use a static toolbar that is always outside the story content and interactive */ + position: static; +} + +#storybook-docs span + .sbdocs .docblock-argstable tbody tr td button { + color: #0078d4; + color: red; +} + +#storybook-docs .docs-story + div { + background: #11100f; +} + +#storybook-docs .sbdocs-content > div:last-child { + margin-bottom: 96px; +} + +#storybook-docs .docs-story > div { + padding: 0; + background: none; +} + +#storybook-docs .docs-story > div:last-child { + right: 31px; + border-radius: 24px; +} + +.docs-story + div > div:last-child { + background: #000000; + box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.25); + border-radius: 5px 5px 0px 0px; + right: 31px; +} + +.docs-story + div > div:last-child > button { + color: white; + font-family: 'Segoe UI', 'Segoe UI Web (West European)', -apple-system, BlinkMacSystemFont, Roboto, 'Helvetica Neue', + sans-serif; + font-size: 14px; + line-height: 150%; + text-align: center; + letter-spacing: -0.01em; +} + +#storybook-docs a.sbdocs-a { + color: #0078d4; + text-decoration: underline; +} + +/* */ +/* Args Table */ +/* */ + +#storybook-docs .docblock-argstable tbody { + box-shadow: none; + border-left: none; + border-right: none; +} + +#storybook-docs .docblock-argstable-head th { + letter-spacing: -0.01em; + color: black; + font-family: 'Segoe UI', 'Segoe UI Web (West European)', -apple-system, BlinkMacSystemFont, Roboto, 'Helvetica Neue', + sans-serif; + font-size: 16px; + line-height: 150%; + font-weight: 600; +} + +#storybook-docs thead.docblock-argstable-head { + border-bottom: 1px solid #edebe9; +} + +#storybook-docs .docblock-argstable tbody tr { + border: none; +} + +#storybook-docs table.docblock-argstable tbody.docblock-argstable-body td, +#storybook-docs .docblock-argstable th { + padding-top: 12px; + padding-bottom: 12px; + padding-left: 16px; +} + +#storybook-docs .docblock-argstable tbody tr td:nth-child(1) span { + font-weight: normal; + font-family: 'Segoe UI', 'Segoe UI Web (West European)', -apple-system, BlinkMacSystemFont, Roboto, 'Helvetica Neue', + sans-serif; + font-size: 16px; + line-height: 130%; + letter-spacing: -0.01em; + color: #616161; +} + +#storybook-docs .docblock-argstable tbody tr td { + vertical-align: top; +} + +#storybook-docs .docblock-argstable-body > tr > td > div > div > button { + color: #0078d4; + line-height: 21px; +} + +#storybook-docs code, +#storybook-docs .docblock-argstable tbody tr td:nth-child(3) > div > span, +#storybook-docs .docblock-argstable-body > tr > td:nth-child(2) > div:nth-child(2) span, +#storybook-docs .docblock-argstable-body > tr > td:nth-child(2) > div:nth-child(1) > div > span, +#storybook-docs .css-16d4d7t { + font-family: 'Cascadia Code', Menlo, 'Courier New', Courier, monospace; + font-style: normal; + font-weight: normal; + font-size: 14px; + line-height: 130%; + letter-spacing: -0.2px; + box-decoration-break: clone; + -webkit-box-decoration-break: clone; +} + +#storybook-docs code.sbdocs-code, +#storybook-docs .sbdocs-p code, +#storybook-docs .sbdocs-li code, +#storybook-docs .docblock-argstable code, +#storybook-docs .docblock-argstable tbody tr td:nth-child(3) > div > span, +#storybook-docs .docblock-argstable-body > tr > td:nth-child(2) > div:nth-child(2) span, +#storybook-docs .docblock-argstable-body > tr > td:nth-child(2) > div:nth-child(1) > div > span, +#storybook-docs .css-16d4d7t { + font-size: 14px; + background: #f0f0f0; + border-radius: 4px; + padding: 1px 4px; + margin: 0 3px 0 3px; + color: black; + border: none; + line-height: 1.5; +} + +#storybook-docs .docblock-argstable code { + white-space: normal; +} + +#storybook-docs code { + padding: 0.1em 0.2em; + display: inline-block; + background-color: rgba(17, 16, 15, 0.1); + border-radius: 2px; + width: fit-content; /* prevent wrapping kebab-case words when they'll fit on one line */ +} + +.os-content-glue { + width: auto !important; +} + +#storybook-docs .sbdocs-preview .prismjs { + overflow: hidden; +} + +#storybook-docs .os-content .prismjs * { + font-family: 'Cascadia Code', Menlo, 'Courier New', Courier, monospace; + font-size: 14px; + line-height: 1.4em; +} + +#storybook-docs .sbdocs-preview .prismjs code { + color: white; + background: #11100f; + margin: 0; + overflow-x: auto; +} + +#storybook-docs .docblock-argstable-body td > div > p, +#storybook-docs .docblock-argstable-body > tr > td:nth-child(2) p, +#storybook-docs .docblock-argstable-body > tr > td:nth-child(2) > div:nth-child(1) > span { + font-family: 'Segoe UI', 'Segoe UI Web (West European)', -apple-system, BlinkMacSystemFont, Roboto, 'Helvetica Neue', + sans-serif; + font-size: 16px; + line-height: 130%; + color: black; + letter-spacing: -0.01em; +} + +#storybook-docs .docblock-argstable tr > :nth-child(1) { + width: 10%; +} + +#storybook-docs .docblock-argstable tr > :nth-child(2) { + width: 60%; +} + +#storybook-docs .os-padding { + z-index: 0; +} + +@font-face { + font-family: 'Segoe UI'; + src: local('Segoe UI Light'), + url(https://c.s-microsoft.com/static/fonts/segoe-ui/west-european/light/latest.woff2) format('woff2'), + url(https://c.s-microsoft.com/static/fonts/segoe-ui/west-european/light/latest.woff) format('woff'), + url(https://c.s-microsoft.com/static/fonts/segoe-ui/west-european/light/latest.ttf) format('truetype'); + font-weight: 100; +} + +@font-face { + font-family: 'Segoe UI'; + src: local('Segoe UI Semilight'), + url(https://c.s-microsoft.com/static/fonts/segoe-ui/west-european/semilight/latest.woff2) format('woff2'), + url(https://c.s-microsoft.com/static/fonts/segoe-ui/west-european/semilight/latest.woff) format('woff'), + url(https://c.s-microsoft.com/static/fonts/segoe-ui/west-european/semilight/latest.ttf) format('truetype'); + font-weight: 200; +} + +@font-face { + font-family: 'Segoe UI'; + src: local('Segoe UI'), + url(https://c.s-microsoft.com/static/fonts/segoe-ui/west-european/normal/latest.woff2) format('woff2'), + url(https://c.s-microsoft.com/static/fonts/segoe-ui/west-european/normal/latest.woff) format('woff'), + url(https://c.s-microsoft.com/static/fonts/segoe-ui/west-european/normal/latest.ttf) format('truetype'); + font-weight: 400; +} + +@font-face { + font-family: 'Segoe UI'; + src: local('Segoe UI Semibold'), + url(https://c.s-microsoft.com/static/fonts/segoe-ui/west-european/semibold/latest.woff2) format('woff2'), + url(https://c.s-microsoft.com/static/fonts/segoe-ui/west-european/semibold/latest.woff) format('woff'), + url(https://c.s-microsoft.com/static/fonts/segoe-ui/west-european/semibold/latest.ttf) format('truetype'); + font-weight: 600; +} + +@font-face { + font-family: 'Segoe UI'; + src: local('Segoe UI Bold'), + url(https://c.s-microsoft.com/static/fonts/segoe-ui/west-european/bold/latest.woff2) format('woff2'), + url(https://c.s-microsoft.com/static/fonts/segoe-ui/west-european/bold/latest.woff) format('woff'), + url(https://c.s-microsoft.com/static/fonts/segoe-ui/west-european/bold/latest.ttf) format('truetype'); + font-weight: 700; +} + +body, +body p, +body ul, +body ul li { + font-family: 'Segoe UI' !important; +} + +h1.fluent { + font-weight: 700; + font-size: 40px; + font-family: 'Segoe UI'; + line-height: 60px; + letter-spacing: -0.16px; +} + +h1 .fluent-version { + display: block; + font-size: 24px; /* --font-size-base-600 */ + line-height: 32px; + color: #707070; /* --color-neutral-foreground-3 */ +} + +h2.fluent { + font-weight: 600; + font-size: 24px; + font-family: 'Segoe UI'; + line-height: 36px; + letter-spacing: -0.16px; +} + +/* Mimic React v9 Provider styles: + * - apply font, background, and foreground colors + * - apply padding for story content + */ +#storybook-docs .innerZoomElementWrapper > div > div { + padding: 48px 24px; + font-family: var(--fontFamilyBase); + background: var(--colorNeutralBackground2); + color: var(--colorNeutralForeground2); +} + +/* + * Theme Switcher + */ +#switches-container { + position: sticky; + display: flex; + gap: 20px; + align-items: center; + padding: 12px; + width: 100%; + top: 0; + box-sizing: border-box; /* keep from overflowing body making x scroll bar*/ + background: #fff; + box-shadow: 0 0 3px rgb(0 0 0 / 22%); + z-index: 10; +} + +#switches-container select { + padding: 5px var(--spacingHorizontalM); + border: var(--strokeWidthThin) solid #d1d1d1 /* --colorNeutralStroke1, without theme switching */; + border-radius: var(--borderRadiusMedium); + font-size: var(--fontSizeBase300); + font-weight: var(--fontWeightSemibold); + line-height: var(--lineHeightBase300); + width: 140px; +} + +.custom-fullscreen #switches-container { + display: none; +} + +.custom-fullscreen .sbdocs-wrapper { + padding: 20px; +} + +.custom-fullscreen .sbdocs-content { + max-width: unset; +} diff --git a/packages/charts/chart-web-components/.storybook/main.cjs b/packages/charts/chart-web-components/.storybook/main.cjs new file mode 100644 index 00000000000000..a608e4b28b9aba --- /dev/null +++ b/packages/charts/chart-web-components/.storybook/main.cjs @@ -0,0 +1,88 @@ +const path = require('path'); +const CircularDependencyPlugin = require('circular-dependency-plugin'); +const { TsconfigPathsPlugin } = require('tsconfig-paths-webpack-plugin'); + +const tsBin = require.resolve('typescript'); +const tsConfigPath = path.resolve(__dirname, '../../../../tsconfig.base.wc.json'); + +const tsPaths = new TsconfigPathsPlugin({ + configFile: tsConfigPath, +}); + +module.exports = + /** @type {import('@storybook/html-webpack5').StorybookConfig} */ + ({ + features: { + // On-demand code splitting is disabled for now, as it causes issues e2e tests. + storyStoreV7: false, + }, + // helpers.stories.ts is a file that contains helper functions for stories, + // and should not be treated as a story itself. + stories: ['../src/**/!(helpers)*.stories.@(ts|mdx)'], + staticDirs: ['../public'], + core: { + disableTelemetry: true, + }, + framework: '@storybook/html-webpack5', + addons: [ + { + name: '@storybook/addon-essentials', + options: { + backgrounds: false, + viewport: false, + toolbars: false, + actions: true, + }, + }, + ], + webpackFinal: async config => { + config.resolve = config.resolve ?? {}; + config.resolve.extensions = config.resolve.extensions ?? []; + config.resolve.plugins = config.resolve.plugins ?? []; + config.module = config.module ?? {}; + config.plugins = config.plugins ?? []; + + config.resolve.extensionAlias = { + '.js': ['.js', '.ts'], + '.mjs': ['.mjs', '.mts'], + }; + config.resolve.extensions.push(...['.ts', '.js']); + config.resolve.plugins.push(tsPaths); + config.module.rules = config.module.rules ?? []; + config.module.rules.push( + { + test: /\.([cm]?ts|tsx)$/, + loader: 'ts-loader', + sideEffects: true, + options: { + transpileOnly: true, + compiler: tsBin, + }, + }, + // Following config is needed to be able to resolve @storybook packages imported in specified files that don't ship valid ESM + // It also enables importing other packages without proper ESM extensions, but that should be avoided ! + // @see https://webpack.js.org/configuration/module/#resolvefullyspecified + { + test: /\.m?js/, + resolve: { fullySpecified: false }, + }, + ); + + config.plugins.push( + new CircularDependencyPlugin({ + exclude: /node_modules/, + failOnError: process.env.NODE_ENV === 'production', + }), + ); + + // Disable ProgressPlugin which logs verbose webpack build progress. Warnings and Errors are still logged. + if (process.env.TF_BUILD) { + config.plugins = config.plugins.filter(value => value && value.constructor.name !== 'ProgressPlugin'); + } + + return config; + }, + docs: { + autodocs: true, + }, + }); diff --git a/packages/charts/chart-web-components/.storybook/manager-head.html b/packages/charts/chart-web-components/.storybook/manager-head.html new file mode 100644 index 00000000000000..5ff3ef7092e609 --- /dev/null +++ b/packages/charts/chart-web-components/.storybook/manager-head.html @@ -0,0 +1,118 @@ + + + + + + diff --git a/packages/charts/chart-web-components/.storybook/manager.mjs b/packages/charts/chart-web-components/.storybook/manager.mjs new file mode 100644 index 00000000000000..73873977355b42 --- /dev/null +++ b/packages/charts/chart-web-components/.storybook/manager.mjs @@ -0,0 +1,14 @@ +import { addons } from '@storybook/manager-api'; +import webcomponentsTheme from './theme.mjs'; + +addons.setConfig({ + previewTabs: { + canvas: { hidden: true }, + }, + enableShortcuts: false, + sidebar: { + showRoots: true, + }, + showPanel: false, + theme: webcomponentsTheme, // override the default Storybook theme with a custom fluent theme +}); diff --git a/packages/charts/chart-web-components/.storybook/preview-body.html b/packages/charts/chart-web-components/.storybook/preview-body.html new file mode 100644 index 00000000000000..93e32a40560db2 --- /dev/null +++ b/packages/charts/chart-web-components/.storybook/preview-body.html @@ -0,0 +1,9 @@ +
+ + +
diff --git a/packages/charts/chart-web-components/.storybook/preview.mjs b/packages/charts/chart-web-components/.storybook/preview.mjs new file mode 100644 index 00000000000000..e7e4cce4c6afb0 --- /dev/null +++ b/packages/charts/chart-web-components/.storybook/preview.mjs @@ -0,0 +1,69 @@ +import { teamsDarkTheme, teamsLightTheme, webDarkTheme, webLightTheme } from '@fluentui/tokens'; +import * as prettier from 'prettier'; +import prettierPluginHTML from 'prettier/parser-html.js'; +import { setTheme } from '@fluentui/web-components'; +import webcomponentsTheme from './theme.mjs'; + +import '../src/index-rollup.js'; +import './docs-root.css'; + +const FAST_EXPRESSION_COMMENTS = //g; // Matches comments that contain FAST expressions + +const themes = { + 'web-light': webLightTheme, + 'web-dark': webDarkTheme, + 'teams-light': teamsLightTheme, + 'teams-dark': teamsDarkTheme, +}; + +function changeTheme(/** @type {Event} */ e) { + setTheme(themes[/** @type {keyof themes} */ (/** @type {HTMLInputElement}*/ (e.target).value)]); +} + +// This is needed in Playwright. +Object.defineProperty(window, 'setTheme', { value: setTheme }); + +document.getElementById('theme-switch')?.addEventListener('change', changeTheme, false); +setTheme(themes['web-light']); + +export const parameters = { + layout: 'fullscreen', + controls: { expanded: true }, + viewMode: 'docs', + previewTabs: { + canvas: { hidden: true }, + }, + options: { + storySort: { + method: 'alphabetical', + }, + }, + docs: { + source: { + // To get around the inability to change Prettier options in the source addon, this transform function + // imports the standalone Prettier and uses it to format the source with the desired options. + transform(/** @type {string} */ src, /** @type {import('@storybook/html').StoryContext} */ storyContext) { + if (!src) { + const fragment = storyContext.originalStoryFn(storyContext.allArgs, storyContext); + if (!(fragment instanceof DocumentFragment) && !(fragment instanceof HTMLElement)) { + return; + } + + const div = document.createElement('div'); + div.append(fragment); + src = div.innerHTML; + } + + src = src.replace(FAST_EXPRESSION_COMMENTS, ''); // remove comments + src = src.replace(/=""/g, ''); // remove values for boolean attributes + src = prettier.format(src, { + htmlWhitespaceSensitivity: 'ignore', + parser: 'html', + plugins: [prettierPluginHTML], + }); + return src; + }, + }, + theme: webcomponentsTheme, // override the default Storybook theme with a custom fluent theme + }, +}; diff --git a/packages/charts/chart-web-components/.storybook/theme.mjs b/packages/charts/chart-web-components/.storybook/theme.mjs new file mode 100644 index 00000000000000..515891480e7a6f --- /dev/null +++ b/packages/charts/chart-web-components/.storybook/theme.mjs @@ -0,0 +1,34 @@ +import { create } from '@storybook/theming'; + +export default create({ + base: 'light', + brandTitle: 'Fluent UI\nChart Web Components', + brandUrl: 'https://github.com/microsoft/fluentui', + + // Toolbar default and active colors + barSelectedColor: '#0078d4', // use msft primary blue default + barTextColor: '#222', + + colorPrimary: '#dedede', + colorSecondary: 'deepskyblue', + + // UI + appBg: '#ffffff', + appContentBg: '#ffffff', + appBorderColor: '#e0e0e0', // use msft gray + appBorderRadius: 4, + + // Typography + fontBase: + '"Segoe UI", "Segoe UI Web (West European)", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif;', + fontCode: 'monospace', + + // Text colors + textColor: '#11100f', + textInverseColor: '#0078d4', // use msft primary blue default + + // Form colors + inputBg: 'white', + inputTextColor: 'black', + inputBorderRadius: 4, +}); diff --git a/packages/charts/chart-web-components/.storybook/tsconfig.json b/packages/charts/chart-web-components/.storybook/tsconfig.json new file mode 100644 index 00000000000000..78905f4f659714 --- /dev/null +++ b/packages/charts/chart-web-components/.storybook/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "noEmit": true, + "types": ["node"] + }, + "include": ["*", "../public", "../src/**/*.stories.*"] +} diff --git a/packages/charts/chart-web-components/CHANGELOG.json b/packages/charts/chart-web-components/CHANGELOG.json new file mode 100644 index 00000000000000..c43d0fa26ee133 --- /dev/null +++ b/packages/charts/chart-web-components/CHANGELOG.json @@ -0,0 +1,123 @@ +{ + "name": "@fluentui/chart-web-components", + "entries": [ + { + "date": "Thu, 13 Feb 2025 04:06:52 GMT", + "tag": "@fluentui/chart-web-components_v0.0.4", + "version": "0.0.4", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/chart-web-components", + "comment": "Bump @fluentui/web-components to v3.0.0-beta.80", + "commit": "cf102ebd054c8a477dba152d4bcad6864c9bb9af" + } + ] + } + }, + { + "date": "Wed, 12 Feb 2025 04:07:31 GMT", + "tag": "@fluentui/chart-web-components_v0.0.3", + "version": "0.0.3", + "comments": { + "none": [ + { + "author": "martinhochel@microsoft.com", + "package": "@fluentui/chart-web-components", + "commit": "5b5091795bd462fe78f1545fd91b21ef6510a45d", + "comment": "chore: add new 'charting' domain tag" + } + ], + "patch": [ + { + "author": "vgenaev@gmail.com", + "package": "@fluentui/chart-web-components", + "commit": "f0f16ea9d7e407f87e4f144a40be8a3c4f2b6369", + "comment": "BREAKING: rename api report file name according to api-extractor change" + } + ] + } + }, + { + "date": "Fri, 07 Feb 2025 04:07:36 GMT", + "tag": "@fluentui/chart-web-components_v0.0.2", + "version": "0.0.2", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/chart-web-components", + "comment": "Bump @fluentui/web-components to v3.0.0-beta.79", + "commit": "da4d05c54ebaae0927060601929213cdc1a5f9eb" + } + ] + } + }, + { + "date": "Tue, 04 Feb 2025 04:07:18 GMT", + "tag": "@fluentui/chart-web-components_v0.0.1", + "version": "0.0.1", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/chart-web-components", + "comment": "Bump @fluentui/web-components to v3.0.0-beta.78", + "commit": "da62e83423063b6ab3ed62e62bcb965f37cf5700" + } + ] + } + }, + { + "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..a29278497bee32 --- /dev/null +++ b/packages/charts/chart-web-components/CHANGELOG.md @@ -0,0 +1,60 @@ +# Change Log - @fluentui/chart-web-components + +This log was last generated on Thu, 13 Feb 2025 04:06:52 GMT and should not be manually modified. + + + +## [0.0.4](https://github.com/microsoft/fluentui/tree/@fluentui/chart-web-components_v0.0.4) + +Thu, 13 Feb 2025 04:06:52 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/chart-web-components_v0.0.3..@fluentui/chart-web-components_v0.0.4) + +### Patches + +- Bump @fluentui/web-components to v3.0.0-beta.80 ([PR #33834](https://github.com/microsoft/fluentui/pull/33834) by beachball) + +## [0.0.3](https://github.com/microsoft/fluentui/tree/@fluentui/chart-web-components_v0.0.3) + +Wed, 12 Feb 2025 04:07:31 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/chart-web-components_v0.0.2..@fluentui/chart-web-components_v0.0.3) + +### Patches + +- BREAKING: rename api report file name according to api-extractor change ([PR #33692](https://github.com/microsoft/fluentui/pull/33692) by vgenaev@gmail.com) + +## [0.0.2](https://github.com/microsoft/fluentui/tree/@fluentui/chart-web-components_v0.0.2) + +Fri, 07 Feb 2025 04:07:36 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/chart-web-components_v0.0.1..@fluentui/chart-web-components_v0.0.2) + +### Patches + +- Bump @fluentui/web-components to v3.0.0-beta.79 ([PR #33795](https://github.com/microsoft/fluentui/pull/33795) by beachball) + +## [0.0.1](https://github.com/microsoft/fluentui/tree/@fluentui/chart-web-components_v0.0.1) + +Tue, 04 Feb 2025 04:07:18 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/chart-web-components_v0.0.0..@fluentui/chart-web-components_v0.0.1) + +### Patches + +- Bump @fluentui/web-components to v3.0.0-beta.78 ([PR #33756](https://github.com/microsoft/fluentui/pull/33756) by beachball) + +## [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/README.md b/packages/charts/chart-web-components/README.md new file mode 100644 index 00000000000000..d0d22e595afee8 --- /dev/null +++ b/packages/charts/chart-web-components/README.md @@ -0,0 +1,26 @@ +# Fluent UI Chart Web Components + +Fluent charts is a set of modern, accessible, interactive and highly customizable visualization library representing the Microsoft design system. The library is built using D3 (Data Driven Documents). + +## Using the library + +Examples and code snippets for the chart components to be added. + +## Contact + +The charting project is actively funded by a small feature team. The team responds within 1-2 business days for any queries or doubts. +You can reach out to the charting team by tagging `@microsoft/charting-team` in [discussion](https://github.com/microsoft/fluentui/discussions) items. + +You could also create issues under the [charting](https://github.com/microsoft/fluentui/labels/Package:%20charting) tag. + +## Contributing + +[![contributions welcome](https://img.shields.io/badge/contributions-welcome-1EAEDB)]() + +A comprehensive contributor and developer guide is available in the charts [wiki](https://aka.ms/fluentChartingWiki). + +## Accessibility + +Our charts have elaborate accessibility support. The charts are WCAG 2.1 MAS C compliant for accessibility. + +More details are covered in the [wiki](https://aka.ms/fluentChartingWiki). diff --git a/packages/charts/chart-web-components/api-extractor.json b/packages/charts/chart-web-components/api-extractor.json new file mode 100644 index 00000000000000..6306744f333074 --- /dev/null +++ b/packages/charts/chart-web-components/api-extractor.json @@ -0,0 +1,3 @@ +{ + "extends": "@fluentui/scripts-api-extractor/api-extractor.wc.json" +} diff --git a/packages/charts/chart-web-components/docs/chart-web-components.api.md b/packages/charts/chart-web-components/docs/chart-web-components.api.md new file mode 100644 index 00000000000000..e5030de441f789 --- /dev/null +++ b/packages/charts/chart-web-components/docs/chart-web-components.api.md @@ -0,0 +1,150 @@ +## API Report File for "@fluentui/chart-web-components" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { ElementStyles } from '@microsoft/fast-element'; +import { ElementViewTemplate } from '@microsoft/fast-element'; +import { FASTElement } from '@microsoft/fast-element'; +import { FASTElementDefinition } from '@microsoft/fast-element'; + +// Warning: (ae-missing-release-tag) "DonutChart" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class DonutChart extends FASTElement { + constructor(); + // (undocumented) + activeLegend: string; + // (undocumented) + protected activeLegendChanged(oldValue: string, newValue: string): void; + // (undocumented) + chartWrapper: HTMLDivElement; + // (undocumented) + connectedCallback(): void; + // Warning: (ae-forgotten-export) The symbol "ChartProps_2" needs to be exported by the entry point index.d.ts + // + // (undocumented) + data: ChartProps_2; + // (undocumented) + elementInternals: ElementInternals; + // (undocumented) + group: SVGGElement; + // (undocumented) + handleLegendClick(legendTitle: string): void; + // (undocumented) + handleLegendMouseoutAndBlur(): void; + // (undocumented) + handleLegendMouseoverAndFocus(legendTitle: string): void; + // (undocumented) + height: number; + // (undocumented) + hideLegends: boolean; + // (undocumented) + hideTooltip: boolean; + // (undocumented) + innerRadius: number; + // (undocumented) + isLegendSelected: boolean; + // (undocumented) + legendListLabel?: string; + // Warning: (ae-forgotten-export) The symbol "Legend" needs to be exported by the entry point index.d.ts + // + // (undocumented) + legends: Legend[]; + // (undocumented) + tooltipProps: { + isVisible: boolean; + legend: string; + yValue: string; + color: string; + xPos: number; + yPos: number; + }; + // (undocumented) + protected tooltipPropsChanged(oldValue: any, newValue: any): void; + // (undocumented) + valueInsideDonut?: string; + // (undocumented) + width: number; +} + +// @public (undocumented) +export const DonutChartDefinition: FASTElementDefinition; + +// @public +export const DonutChartStyles: ElementStyles; + +// Warning: (ae-internal-missing-underscore) The name "DonutChartTemplate" should be prefixed with an underscore because the declaration is marked as @internal +// +// @internal (undocumented) +export const DonutChartTemplate: ElementViewTemplate; + +// @public +export class HorizontalBarChart extends FASTElement { + constructor(); + // (undocumented) + activeLegend: string; + // (undocumented) + protected activeLegendChanged: (oldValue: string, newValue: string) => void; + // (undocumented) + chartContainer: HTMLDivElement; + // (undocumented) + chartTitle?: string; + // (undocumented) + connectedCallback(): void; + // Warning: (ae-forgotten-export) The symbol "ChartProps" needs to be exported by the entry point index.d.ts + // + // (undocumented) + data: ChartProps[]; + // (undocumented) + elementInternals: ElementInternals; + // (undocumented) + handleLegendClick: (legendTitle: string) => void; + // (undocumented) + handleLegendMouseoutAndBlur: () => void; + // (undocumented) + handleLegendMouseoverAndFocus: (legendTitle: string) => void; + // (undocumented) + hideLegends: boolean; + // (undocumented) + hideRatio: boolean; + // (undocumented) + hideTooltip: boolean; + // (undocumented) + isLegendSelected: boolean; + // (undocumented) + legendListLabel?: string; + // (undocumented) + tooltipProps: { + isVisible: boolean; + legend: string; + yValue: string; + color: string; + xPos: number; + yPos: number; + }; + // Warning: (ae-forgotten-export) The symbol "ChartDataPoint" needs to be exported by the entry point index.d.ts + // + // (undocumented) + uniqueLegends: ChartDataPoint[]; + // Warning: (ae-forgotten-export) The symbol "Variant" needs to be exported by the entry point index.d.ts + // + // (undocumented) + variant?: Variant; +} + +// @public +export const HorizontalBarChartDefinition: FASTElementDefinition; + +// @public +export const HorizontalBarChartStyles: ElementStyles; + +// Warning: (ae-internal-missing-underscore) The name "HorizontalBarChartTemplate" should be prefixed with an underscore because the declaration is marked as @internal +// +// @internal (undocumented) +export const HorizontalBarChartTemplate: ElementViewTemplate; + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/charts/chart-web-components/package.json b/packages/charts/chart-web-components/package.json new file mode 100644 index 00000000000000..03493bb2cddfab --- /dev/null +++ b/packages/charts/chart-web-components/package.json @@ -0,0 +1,120 @@ +{ + "name": "@fluentui/chart-web-components", + "description": "A library of Fluent Chart Web Components", + "version": "0.0.4", + "author": { + "name": "Microsoft" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/microsoft/fluentui/tree/master/packages/charts/chart-web-components" + }, + "bugs": { + "url": "https://github.com/Microsoft/fluentui/issues/new/choose" + }, + "type": "module", + "main": "dist/esm/index.js", + "types": "dist/chart-web-components.d.ts", + "unpkg": "dist/chart-web-components.min.js", + "files": [ + "*.md", + "dist/dts/", + "dist/esm/", + "dist/*.js", + "dist/*.d.ts" + ], + "exports": { + ".": { + "types": "./dist/dts/index.d.ts", + "default": "./dist/esm/index.js" + }, + "./utilities.js": { + "types": "./dist/dts/utils/index.d.ts", + "default": "./dist/esm/utils/index.js" + }, + "./*/define.js": { + "types": "./dist/dts/*/*.define.d.ts", + "default": "./dist/esm/*/*.define.js" + }, + "./*/definition.js": { + "types": "./dist/dts/*/*.definition.d.ts", + "default": "./dist/esm/*/*.definition.js" + }, + "./*/options.js": { + "types": "./dist/dts/*/*.options.d.ts", + "default": "./dist/esm/*/*.options.js" + }, + "./*/styles.js": { + "types": "./dist/dts/*/*.styles.d.ts", + "default": "./dist/esm/*/*.styles.js" + }, + "./*/template.js": { + "types": "./dist/dts/*/*.template.d.ts", + "default": "./dist/esm/*/*.template.js" + }, + "./*/index.js": { + "types": "./dist/dts/*/index.d.ts", + "default": "./dist/esm/*/index.js" + }, + "./*.js": { + "types": "./dist/dts/*/define.d.ts", + "default": "./dist/esm/*/define.js" + }, + "./package.json": "./package.json" + }, + "sideEffects": [ + "./dist/esm/**/define.js", + "./dist/chart-web-components.js", + "./dist/chart-web-components.min.js" + ], + "scripts": { + "verify-packaging": "node ./scripts/verify-packaging", + "type-check": "node ./scripts/type-check", + "benchmark": "yarn clean && yarn compile:benchmark && yarn compile && node ./scripts/run-benchmarks", + "compile": "node ./scripts/compile", + "compile:benchmark": "rollup -c rollup.bench.js", + "clean": "node ./scripts/clean dist", + "generate-api": "api-extractor run --local", + "build": "yarn compile && yarn rollup -c && yarn generate-api", + "lint": "eslint . --ext .ts", + "lint:fix": "eslint . --ext .ts --fix", + "format": "prettier -w src/**/*.{ts,html} --ignore-path ../../.prettierignore", + "format:check": "yarn format -c", + "code-style": "yarn format:check && yarn lint", + "start": "yarn start-storybook -p 6006 --docs", + "start-storybook": "storybook dev", + "build-storybook": "storybook build -o ./dist/storybook --docs", + "e2e": "playwright test", + "test:dev": "playwright test" + }, + "devDependencies": { + "@microsoft/fast-element": "2.0.0", + "@fluentui/scripts-api-extractor": "*", + "@tensile-perf/web-components": "~0.2.0", + "@storybook/html": "7.6.20", + "@storybook/html-webpack5": "7.6.20", + "chromedriver": "^125.0.0" + }, + "dependencies": { + "@microsoft/fast-web-utilities": "^6.0.0", + "@fluentui/tokens": "^1.0.0-alpha.21", + "@fluentui/web-components": "^3.0.0-beta.80", + "@types/d3-selection": "^3.0.0", + "@types/d3-shape": "^3.0.0", + "d3-selection": "^3.0.0", + "d3-shape": "^3.0.0", + "tabbable": "^6.2.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "@microsoft/fast-element": "^2.0.0-beta.26 || ^2.0.0" + }, + "beachball": { + "disallowedChangeTypes": [ + "major", + "minor" + ], + "tag": "alpha" + } +} diff --git a/packages/charts/chart-web-components/playwright.config.ts b/packages/charts/chart-web-components/playwright.config.ts new file mode 100644 index 00000000000000..20100ddbc643c1 --- /dev/null +++ b/packages/charts/chart-web-components/playwright.config.ts @@ -0,0 +1,31 @@ +import type { PlaywrightTestConfig } from '@playwright/test'; +import { devices } from '@playwright/test'; + +const config: PlaywrightTestConfig = { + reporter: 'list', + retries: 3, + fullyParallel: process.env.CI ? false : true, + timeout: process.env.CI ? 10000 : 30000, + use: { + baseURL: 'http://localhost:6006/iframe.html', + viewport: { + height: 720, + width: 1280, + }, + }, + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + testMatch: /.*\.spec\.ts$/, + }, + ], + webServer: { + // double-quotes are required for Windows + command: `node -e "import('express').then(({ default: e }) => e().use(e.static('./dist/storybook')).listen(6006))"`, + port: 6006, + reuseExistingServer: process.env.CI ? false : true, + }, +}; + +export default config; diff --git a/packages/charts/chart-web-components/project.json b/packages/charts/chart-web-components/project.json new file mode 100644 index 00000000000000..11b76cd7822be5 --- /dev/null +++ b/packages/charts/chart-web-components/project.json @@ -0,0 +1,10 @@ +{ + "name": "chart-web-components", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "library", + "implicitDependencies": [], + "tags": ["platform:web", "web-components", "charting"], + "targets": { + "e2e": { "dependsOn": ["build-storybook"] } + } +} diff --git a/packages/charts/chart-web-components/public/SegoeUI-VF.ttf b/packages/charts/chart-web-components/public/SegoeUI-VF.ttf new file mode 100644 index 00000000000000..859db801de8fd5 Binary files /dev/null and b/packages/charts/chart-web-components/public/SegoeUI-VF.ttf differ diff --git a/packages/charts/chart-web-components/public/favicon.ico b/packages/charts/chart-web-components/public/favicon.ico new file mode 100644 index 00000000000000..bfe873eb228f98 Binary files /dev/null and b/packages/charts/chart-web-components/public/favicon.ico differ diff --git a/packages/charts/chart-web-components/public/favicon.png b/packages/charts/chart-web-components/public/favicon.png new file mode 100644 index 00000000000000..bfe873eb228f98 Binary files /dev/null and b/packages/charts/chart-web-components/public/favicon.png differ diff --git a/packages/charts/chart-web-components/public/shell.css b/packages/charts/chart-web-components/public/shell.css new file mode 100644 index 00000000000000..21dc2f875e5906 --- /dev/null +++ b/packages/charts/chart-web-components/public/shell.css @@ -0,0 +1,82 @@ +/* This file should stay synchronized with the React v9 storybook styles. */ + +/* sidebar logo (Web Components uses text) */ +.sidebar-header > div:first-of-type { + font-size: 20px; + white-space: break-spaces; + margin-right: 0; +} + +/* remove sidebar shortcuts menu */ +.sidebar-header > div:last-child { + display: none; +} + +/* Add left side background color splash */ +/* colors become distracting in mobile layout so scoped to where sidebar is visible */ +@media (min-width: 600px) { + #storybook-root > div:before { + content: ''; + position: absolute; + top: -200px; + left: -200px; + width: 400px; + height: 400px; + background: #c989e8; + opacity: 0.5; + filter: blur(150px); + } + + /* Add right side background color splash */ + #storybook-root > div:after { + content: ''; + position: absolute; + top: -200px; + right: -200px; + width: 400px; + height: 400px; + background: #b3d4ff; + opacity: 0.5; + filter: blur(150px); + } +} + +/* Give sidebar a transparent white background to match design */ +.sidebar-container { + background: rgba(255, 255, 255, 0.6); +} + +/* remove background preventing color splash from showing */ +#storybook-preview-wrapper { + background: transparent; +} + +/* + * Set position fixed to create a layer and prevent iframe from jumping when content is + * larger than the viewport and the iframe itself + */ +[role='main'] { + position: fixed; + top: 0 !important; +} + +/* remove box shadow style from storybooks wrapper div */ +[role='main'] > div { + box-shadow: none; +} + +/* permanently hide toolbar so animation never appears on page load */ +[role='main'] .os-host { + display: none; +} + +/* stop offset from changing page dimensions when 't' is pressed and toolbar opened */ +[role='main'] > div > div > div { + top: 0 !important; + height: 100% !important; +} + +/* Remove 'Published on Chromatic' banner */ +#back-to-chromatic { + display: none !important; +} diff --git a/packages/charts/chart-web-components/rollup.bench.js b/packages/charts/chart-web-components/rollup.bench.js new file mode 100644 index 00000000000000..3b8e9d8bb711ff --- /dev/null +++ b/packages/charts/chart-web-components/rollup.bench.js @@ -0,0 +1,21 @@ +import { nodeResolve } from '@rollup/plugin-node-resolve'; +import esbuild from 'rollup-plugin-esbuild'; +import commonJS from 'rollup-plugin-commonjs'; + +const plugins = [nodeResolve({ browser: true }), commonJS(), esbuild({ tsconfig: './tsconfig.json' })]; + +export default [ + { + input: { + tokens: './src/utils/benchmark-dependencies/tokens.ts', + }, + output: [ + { + dir: './.tensile/benchmark-dependencies', + format: 'esm', + sourcemap: true, + }, + ], + plugins, + }, +]; diff --git a/packages/charts/chart-web-components/rollup.config.js b/packages/charts/chart-web-components/rollup.config.js new file mode 100644 index 00000000000000..83e86ddda735ee --- /dev/null +++ b/packages/charts/chart-web-components/rollup.config.js @@ -0,0 +1,48 @@ +/** + * This config should be shared for all web-component packages. + * Tracking issue - https://github.com/microsoft/fluentui/issues/33576 + */ + +import { nodeResolve } from '@rollup/plugin-node-resolve'; +import commonJS from 'rollup-plugin-commonjs'; +import esbuild, { minify } from 'rollup-plugin-esbuild'; +import transformTaggedTemplate from 'rollup-plugin-transform-tagged-template'; +import { transformCSSFragment, transformHTMLFragment } from './scripts/transform-fragments'; + +const parserOptions = { + sourceType: 'module', +}; + +export default [ + { + input: 'src/index-rollup.ts', + output: [ + { + file: 'dist/chart-web-components.js', + format: 'esm', + }, + { + file: 'dist/chart-web-components.min.js', + format: 'esm', + plugins: [minify()], + }, + ], + plugins: [ + nodeResolve({ browser: true }), + commonJS(), + esbuild({ + tsconfig: './tsconfig.lib.json', + }), + transformTaggedTemplate({ + tagsToProcess: ['css'], + transformer: transformCSSFragment, + parserOptions, + }), + transformTaggedTemplate({ + tagsToProcess: ['html'], + transformer: transformHTMLFragment, + parserOptions, + }), + ], + }, +]; diff --git a/packages/charts/chart-web-components/scripts/clean.js b/packages/charts/chart-web-components/scripts/clean.js new file mode 100644 index 00000000000000..421e7e53437525 --- /dev/null +++ b/packages/charts/chart-web-components/scripts/clean.js @@ -0,0 +1,53 @@ +/* eslint-disable no-undef */ +/** + * Utility for cleaning directories. + * Usage: node build/clean.js %path% + * + * This script should be shared for all web-component packages. + * Tracking issue - https://github.com/microsoft/fluentui/issues/33576 + */ +import * as path from 'path'; +import * as fsPromises from 'node:fs/promises'; +import yargs from 'yargs'; + +main(); + +/** + * Function to remove a given path + */ +function cleanPath(cleanPath) { + const removePath = path.resolve(process.cwd(), cleanPath); + + const result = fsPromises.rm(removePath, { recursive: true }).then(() => { + console.log(removePath, 'cleaned'); + }); + + return result; +} + +function main() { + const argv = yargs.argv; + + /** + * All paths passed to the clean script + */ + const paths = argv._; + + /** + * Clean all paths + */ + if (!Array.isArray(paths)) { + throw new Error('"paths" must be an array'); + } + + const result = paths.map(cleanPath); + + Promise.all(result) + .then(() => { + console.log('All paths cleaned'); + }) + .catch(error => { + console.error(error); + process.exit(1); + }); +} diff --git a/packages/charts/chart-web-components/scripts/compile.js b/packages/charts/chart-web-components/scripts/compile.js new file mode 100644 index 00000000000000..7eb7a2aa7fc563 --- /dev/null +++ b/packages/charts/chart-web-components/scripts/compile.js @@ -0,0 +1,28 @@ +/* eslint-disable no-undef */ +/** + * This script should be shared for all web-component packages. + * Tracking issue - https://github.com/microsoft/fluentui/issues/33576 + */ + +import { execSync } from 'child_process'; +import chalk from 'chalk'; + +main(); + +function compile() { + try { + console.log(chalk.bold(`🎬 compile:start`)); + + console.log(chalk.blueBright(`compile: running tsc`)); + execSync(`tsc -p tsconfig.lib.json --rootDir ./src --baseUrl .`, { stdio: 'inherit' }); + + console.log(chalk.bold(`🏁 compile:end`)); + } catch (err) { + console.error(err); + process.exit(1); + } +} + +function main() { + compile(); +} diff --git a/packages/charts/chart-web-components/scripts/run-benchmarks.js b/packages/charts/chart-web-components/scripts/run-benchmarks.js new file mode 100644 index 00000000000000..30735810d1d942 --- /dev/null +++ b/packages/charts/chart-web-components/scripts/run-benchmarks.js @@ -0,0 +1,47 @@ +/** + * This script should be shared for all web-component packages. + * Tracking issue - https://github.com/microsoft/fluentui/issues/33576 + */ + +import fs from 'fs/promises'; +import path from 'path'; +import { execSync } from 'child_process'; + +const rootDir = path.join(import.meta.dirname, '..'); +const tensileConfig = 'tensile.config.js'; + +try { + const esmOutput = path.join(rootDir, 'dist', 'esm'); + const items = await fs.readdir(esmOutput); + + // Collect all component folders + const folders = []; + for (const item of items) { + const itemPath = path.join(esmOutput, item); + const stats = await fs.lstat(itemPath); + if (stats.isDirectory()) { + folders.push(item); + } + } + + // Collect all .bench.js files + const benchFiles = []; + for (const folder of folders) { + const folderPath = path.join(esmOutput, folder); + const files = await fs.readdir(folderPath); + const filteredFiles = files.filter(file => file.endsWith('.bench.js')); + benchFiles.push(...filteredFiles.map(file => path.relative(rootDir, path.join(folderPath, file)))); + } + + // Execute tensile for each .bench.js file + for (const file of benchFiles) { + try { + // eslint-disable-next-line no-undef + execSync(`tensile --file ./${file} --config ${tensileConfig} ${process.argv[2]}`, { stdio: 'inherit' }); + } catch (error) { + console.error(`Error executing command for file ${file}: ${error.message}`); + } + } +} catch (error) { + console.error(`Error reading directory: ${error.message}`); +} diff --git a/packages/charts/chart-web-components/scripts/setup-browser.cjs b/packages/charts/chart-web-components/scripts/setup-browser.cjs new file mode 100644 index 00000000000000..5f47d1b5211379 --- /dev/null +++ b/packages/charts/chart-web-components/scripts/setup-browser.cjs @@ -0,0 +1,14 @@ +/* eslint-disable no-undef */ +/** + * + * @param r {__WebpackModuleApi.RequireContext} + * + * This script should be shared for all web-component packages. + * Tracking issue - https://github.com/microsoft/fluentui/issues/33576 + */ +function importAll(r) { + r.keys().forEach(r); +} + +// Explicitly add to browser test +importAll(require.context('../dist/esm', true, /\.spec\.js$/)); diff --git a/packages/charts/chart-web-components/scripts/transform-fragments.js b/packages/charts/chart-web-components/scripts/transform-fragments.js new file mode 100644 index 00000000000000..5387a94fa653d3 --- /dev/null +++ b/packages/charts/chart-web-components/scripts/transform-fragments.js @@ -0,0 +1,34 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type, @typescript-eslint/typedef */ + +/** + * This script should be shared for all web-component packages. + * Tracking issue - https://github.com/microsoft/fluentui/issues/33576 + */ + +/** + * Reduces extra spaces in HTML tagged templates. + * + * @param {string} data - the fragment value + * @returns string + */ +export function transformHTMLFragment(data) { + data = data.replace(/\s*([<>])\s*/g, '$1'); // remove spaces before and after angle brackets + return data.replace(/\s{2,}/g, ' '); // Collapse all sequences to 1 space +} + +/** + * Reduces extra spaces in CSS tagged templates. + * + * Breakdown of this regex: + * (?:\s*\/\*(?:.|\s)+?\*\/\s*) Remove comments (non-capturing) + * (?:;)\s+(?=\}) Remove semicolons and spaces followed by property list end (non-capturing) + * \s+(?=\{) Remove spaces before property list start (non-capturing) + * (?<=:)\s+ Remove spaces after property declarations (non-capturing) + * \s*([{};,])\s* Remove extra spaces before and after braces, semicolons, and commas (captures) + * + * @param {string} data - the fragment value + * @returns string + */ +export function transformCSSFragment(data) { + return data.replace(/(?:\s*\/\*(?:.|\s)+?\*\/\s*)|(?:;)\s+(?=\})|\s+(?=\{)|(?<=:)\s+|\s*([{};,])\s*/g, '$1'); +} diff --git a/packages/charts/chart-web-components/scripts/type-check.js b/packages/charts/chart-web-components/scripts/type-check.js new file mode 100644 index 00000000000000..9d8a4b6c2f4198 --- /dev/null +++ b/packages/charts/chart-web-components/scripts/type-check.js @@ -0,0 +1,63 @@ +// @ts-check + +/** + * This script should be shared for all web-component packages. + * Tracking issue - https://github.com/microsoft/fluentui/issues/33576 + */ + +import fs from 'node:fs'; +import path from 'node:path'; +import { promisify } from 'node:util'; +import { exec } from 'node:child_process'; +import { exit } from 'node:process'; + +const asyncExec = promisify(exec); + +main().catch(err => { + console.error(err); + exit(1); +}); + +/** + * Copied from ${@link 'file://./../../../../scripts/tasks/src/type-check.ts'} + */ +async function main() { + const rootConfig = JSON.parse(fs.readFileSync(path.join(import.meta.dirname, '../tsconfig.json'), 'utf-8')); + + const tsConfigsRefs = getTsConfigs(rootConfig, { spec: false, e2e: false }); + + const asyncQueue = []; + + for (const ref of tsConfigsRefs) { + const program = `tsc -p ${ref} --pretty --noEmit --baseUrl .`; + asyncQueue.push(asyncExec(program)); + } + + return Promise.all(asyncQueue).catch(err => { + console.error(err.stdout); + exit(1); + }); +} + +/** + * @param {{references?: Array<{ path: string }>;}} solutionConfig + * @param {{ spec: boolean, e2e: boolean }} exclude + */ +function getTsConfigs(solutionConfig, exclude) { + const refs = solutionConfig.references ?? []; + /** @type {string[]} */ + const refsPaths = []; + + for (const ref of refs) { + if (exclude.spec && ref.path.includes('spec')) { + continue; + } + if (exclude.e2e && ref.path.includes('cy')) { + continue; + } + + refsPaths.push(ref.path); + } + + return refsPaths; +} diff --git a/packages/charts/chart-web-components/scripts/verify-packaging.js b/packages/charts/chart-web-components/scripts/verify-packaging.js new file mode 100644 index 00000000000000..6cbfc5d9a437b1 --- /dev/null +++ b/packages/charts/chart-web-components/scripts/verify-packaging.js @@ -0,0 +1,79 @@ +// @ts-check +/** + * Copied from ${@link 'file://./../../../../scripts/tasks/src/verify-packaging.ts'} + */ + +/** + * This script should be shared for all web-component packages. + * Tracking issue - https://github.com/microsoft/fluentui/issues/33576 + */ + +import assert from 'node:assert/strict'; +import { spawnSync } from 'node:child_process'; +import { readFileSync } from 'node:fs'; +import path from 'node:path'; + +import micromatch from 'micromatch'; + +main(); + +function main() { + /** + * @see https://docs.npmjs.com/cli/v10/commands/npm-publish#files-included-in-package + */ + const alwaysPublishedFiles = ['LICENSE', 'package.json', 'README.md']; + const rootConfigFiles = [ + 'just.config.[jt]s', + 'jest.config.[jt]s', + '.eslintrc.(js|json)', + 'project.json', + '.babelrc.json', + '.swcrc', + 'tsconfig(.*)?.json', + ]; + const nonProdAssets = ['assets/', 'docs/*', 'temp/*', 'bundle-size/*', '.storybook/*', 'stories/*']; + + verifyPackaging({ alwaysPublishedFiles, nonProdAssets, rootConfigFiles }); +} + +/** + * + * @param {{alwaysPublishedFiles:string[];rootConfigFiles:string[];nonProdAssets:string[]}} options + * @returns + */ + +function verifyPackaging(options) { + const { alwaysPublishedFiles, nonProdAssets, rootConfigFiles } = options; + const root = path.join(import.meta.dirname, '../'); + + /** @type {{ private?: boolean }} */ + const packageJSON = JSON.parse(readFileSync(path.join(root, 'package.json'), 'utf-8')); + + // no need to check if package is not being published yet + if (packageJSON.private) { + return; + } + + const npmPackResult = spawnSync('npm', ['pack', '--dry-run']); + + const processedResult = npmPackResult.output + .toString() + .replace(/\bnpm notice\b\s+[\d.]+[kB]+\s+/gi, '') + .replace(/[ ]+/g, ''); + const processedResultArr = processedResult.split('\n'); + + assert.ok(micromatch(processedResultArr, alwaysPublishedFiles).length, `npm always shipped files`); + assert.equal( + micromatch(processedResultArr, nonProdAssets).length, + 0, + `wont ship non production code related folders/files`, + ); + assert.equal(micromatch(processedResultArr, 'dist/storybook/**').length, 0, `wont ship storybook assets`); + assert.equal(micromatch(processedResultArr, rootConfigFiles).length, 0, `wont ship configuration files`); + assert.ok(micromatch(processedResultArr, 'dist/*.d.ts').length, 'ships rolluped dts'); + assert.ok(micromatch(processedResultArr, 'dist/*.(min.js|js)').length, 'ships rolluped js'); + assert.equal(micromatch(processedResultArr, 'src/*').length, 0, `wont ship source code from "/src"`); + + assert.ok(micromatch(processedResultArr, 'dist/esm/**/*.(js|map)').length, 'ships esm'); + assert.ok(micromatch(processedResultArr, 'dist/dts/**/*.d.ts').length, 'ships types'); +} diff --git a/packages/charts/chart-web-components/src/donut-chart/define.ts b/packages/charts/chart-web-components/src/donut-chart/define.ts new file mode 100644 index 00000000000000..1b8e20ac99e32d --- /dev/null +++ b/packages/charts/chart-web-components/src/donut-chart/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '@fluentui/web-components'; +import { definition } from './donut-chart.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/charts/chart-web-components/src/donut-chart/donut-chart.bench.ts b/packages/charts/chart-web-components/src/donut-chart/donut-chart.bench.ts new file mode 100644 index 00000000000000..5936ecc050474c --- /dev/null +++ b/packages/charts/chart-web-components/src/donut-chart/donut-chart.bench.ts @@ -0,0 +1,12 @@ +import { FluentDesignSystem } from '@fluentui/web-components'; +import { definition } from './donut-chart.definition.js'; + +definition.define(FluentDesignSystem.registry); + +const itemRenderer = () => { + const donutChart = document.createElement('fluent-donut-chart'); + return donutChart; +}; + +export default itemRenderer; +export { tests } from '../utils/benchmark-wrapper.js'; diff --git a/packages/charts/chart-web-components/src/donut-chart/donut-chart.definition.ts b/packages/charts/chart-web-components/src/donut-chart/donut-chart.definition.ts new file mode 100644 index 00000000000000..3cf608dc046483 --- /dev/null +++ b/packages/charts/chart-web-components/src/donut-chart/donut-chart.definition.ts @@ -0,0 +1,18 @@ +import { FluentDesignSystem } from '@fluentui/web-components'; +import { DonutChart } from './donut-chart.js'; +import { styles } from './donut-chart.styles.js'; +import { template } from './donut-chart.template.js'; + +/** + * @public + * @remarks + * HTML Element: `` + */ +export const definition = DonutChart.compose({ + name: `${FluentDesignSystem.prefix}-donut-chart`, + template, + styles, + shadowOptions: { + delegatesFocus: true, + }, +}); diff --git a/packages/charts/chart-web-components/src/donut-chart/donut-chart.options.ts b/packages/charts/chart-web-components/src/donut-chart/donut-chart.options.ts new file mode 100644 index 00000000000000..75f288ca6bd9ea --- /dev/null +++ b/packages/charts/chart-web-components/src/donut-chart/donut-chart.options.ts @@ -0,0 +1,45 @@ +export interface ChartDataPoint { + /** + * Legend text for the datapoint in the chart + */ + legend: string; + + /** + * data the datapoint in the chart + */ + data: number; + + /** + * Color for the legend in the chart. If not provided, it will fallback on the default color palette. + */ + color?: string; + + /** + * Callout data for x axis + * This is an optional prop, If haven;t given legend will take + */ + xAxisCalloutData?: string; + + /** + * Callout data for y axis + * This is an optional prop, If haven't given data will take + */ + yAxisCalloutData?: string; +} + +export interface ChartProps { + /** + * chart title for the chart + */ + chartTitle?: string; + + /** + * data for the points in the chart + */ + chartData: ChartDataPoint[]; +} + +export type Legend = { + title: string; + color: string; +}; diff --git a/packages/charts/chart-web-components/src/donut-chart/donut-chart.spec.ts b/packages/charts/chart-web-components/src/donut-chart/donut-chart.spec.ts new file mode 100644 index 00000000000000..1c48d4677d4cca --- /dev/null +++ b/packages/charts/chart-web-components/src/donut-chart/donut-chart.spec.ts @@ -0,0 +1,139 @@ +import { test } from '@playwright/test'; +import { expect, fixtureURL } from '../helpers.tests.js'; +import type { ChartDataPoint, ChartProps } from './donut-chart.options.js'; + +const points: ChartDataPoint[] = [ + { + legend: 'first', + data: 20000, + }, + { + legend: 'second', + data: 39000, + }, +]; + +const data: ChartProps = { + chartTitle: 'Donut chart basic example', + chartData: points, +}; + +test.describe('Donut-chart - Basic', () => { + test.beforeEach(async ({ page }) => { + await page.goto(fixtureURL('components-donutchart--basic')); + await page.setContent(/* html */ ` +
+ + +
+ `); + await page.waitForFunction(() => customElements.whenDefined('fluent-donut-chart')); + }); + + test('Should render chart properly', async ({ page }) => { + const element = page.locator('fluent-donut-chart'); + const legends = element.locator('.legend-text'); + await expect(legends.nth(0).getByText('first')).toBeVisible(); + await expect(legends.nth(1).getByText('second')).toBeVisible(); + await expect(element.getByText('39,000')).toBeVisible(); + }); + + test('Should render path with proper attributes and css', async ({ page }) => { + const element = page.locator('fluent-donut-chart'); + const arcList = element.locator('.arc'); + await expect(arcList).toHaveCount(2); + await expect(arcList.nth(0)).toHaveAttribute('fill', '#637cef'); + await expect(arcList.nth(0)).toHaveAttribute('aria-label', 'first, 20000.'); + await expect(arcList.nth(0)).toHaveAttribute( + 'd', + 'M-76.547,47.334A90,90,0,0,1,-1.055,-89.994L-1.055,-54.99A55,55,0,0,0,-46.993,28.577Z', + ); + await expect(arcList.nth(0)).toHaveCSS('fill', 'rgb(99, 124, 239)'); + await expect(arcList.nth(0)).toHaveCSS('--borderRadiusMedium', '4px'); + + await expect(arcList.nth(1)).toHaveAttribute('fill', '#e3008c'); + await expect(arcList.nth(1)).toHaveAttribute('aria-label', 'second, 39000.'); + await expect(arcList.nth(1)).toHaveAttribute( + 'd', + 'M1.055,-89.994A90,90,0,1,1,-75.417,49.115L-45.863,30.358A55,55,0,1,0,1.055,-54.99Z', + ); + await expect(arcList.nth(1)).toHaveCSS('fill', 'rgb(227, 0, 140)'); + await expect(arcList.nth(1)).toHaveCSS('--borderRadiusMedium', '4px'); + }); + + test('Should render legends data properly', async ({ page }) => { + const element = page.locator('fluent-donut-chart'); + const legends = element.getByRole('option'); + await expect(legends).toHaveCount(2); + const firstLegend = element.getByRole('option', { name: 'First' }); + const secondLegend = element.getByRole('option', { name: 'Second' }); + await expect(firstLegend).toBeVisible(); + await expect(firstLegend).toHaveText('first'); + await expect(firstLegend).toHaveCSS('--borderRadiusMedium', '4px'); + await expect(secondLegend).toBeVisible(); + await expect(secondLegend).toHaveText('second'); + await expect(secondLegend).toHaveCSS('--borderRadiusMedium', '4px'); + }); + + test('Should update path css values with mouse click event on legend', async ({ page }) => { + const element = page.locator('fluent-donut-chart'); + const firstPath = element.getByLabel('first,'); + const secondPath = element.getByLabel('second,'); + const firstLegend = element.getByRole('option', { name: 'First' }); + //mouse events + await firstLegend.click(); + await expect(firstPath).toHaveCSS('opacity', '1'); + await expect(secondPath).toHaveCSS('opacity', '0.1'); + await firstLegend.click(); + await expect(firstPath).toHaveCSS('opacity', '1'); + await expect(secondPath).toHaveCSS('opacity', '1'); + }); + + test('Should update path css values with mouse hover event on legend', async ({ page }) => { + const element = page.locator('fluent-donut-chart'); + const firstPath = element.getByLabel('first,'); + const secondPath = element.getByLabel('second,'); + const firstLegend = element.getByRole('option', { name: 'First' }); + //mouse events + await firstLegend.dispatchEvent('mouseover'); + await expect(firstPath).toHaveCSS('opacity', '1'); + await expect(secondPath).toHaveCSS('opacity', '0.1'); + await firstLegend.dispatchEvent('mouseout'); + await expect(firstPath).toHaveCSS('opacity', '1'); + await expect(secondPath).toHaveCSS('opacity', '1'); + }); + + test('Should show callout with mouse hover event on path', async ({ page }) => { + const element = page.locator('fluent-donut-chart'); + const firstPath = element.getByLabel('first,'); + const calloutRoot = element.locator('.tooltip'); + await expect(calloutRoot).toHaveCount(0); + await firstPath.dispatchEvent('mouseover'); + await expect(calloutRoot).toHaveCount(1); + await expect(calloutRoot).toHaveCSS('opacity', '1'); + const calloutLegendText = element.locator('.tooltip-legend-text'); + await expect(calloutLegendText).toHaveText('first'); + const calloutContentY = element.locator('.tooltip-content-y'); + await expect(calloutContentY).toHaveText('20000'); + await firstPath.dispatchEvent('mouseout'); + await expect(calloutRoot).not.toHaveCSS('opacity', '0'); + }); + + test('Should update callout data when mouse moved from one path to another path', async ({ page }) => { + const element = page.locator('fluent-donut-chart'); + const firstPath = element.getByLabel('first,'); + const calloutRoot = element.locator('.tooltip'); + await expect(calloutRoot).toHaveCount(0); + await firstPath.dispatchEvent('mouseover'); + await expect(calloutRoot).toHaveCSS('opacity', '1'); + const calloutLegendText = element.locator('.tooltip-legend-text'); + await expect(calloutLegendText).toHaveText('first'); + const calloutContentY = element.locator('.tooltip-content-y'); + await expect(calloutContentY).toHaveText('20000'); + const secondPath = element.getByLabel('second,'); + await secondPath.dispatchEvent('mouseover'); + await expect(calloutRoot).toHaveCSS('opacity', '1'); + await expect(calloutLegendText).toHaveText('second'); + await expect(calloutContentY).toHaveText('39000'); + }); +}); diff --git a/packages/charts/chart-web-components/src/donut-chart/donut-chart.stories.ts b/packages/charts/chart-web-components/src/donut-chart/donut-chart.stories.ts new file mode 100644 index 00000000000000..14177a11c60220 --- /dev/null +++ b/packages/charts/chart-web-components/src/donut-chart/donut-chart.stories.ts @@ -0,0 +1,39 @@ +import { html } from '@microsoft/fast-element'; +import type { Meta, Story, StoryArgs } from '../helpers.stories.js'; +import { renderComponent } from '../helpers.stories.js'; +import { DonutChart as FluentDonutChart } from './donut-chart.js'; +import type { ChartDataPoint, ChartProps } from './donut-chart.options.js'; + +const points: ChartDataPoint[] = [ + { + legend: 'first', + data: 20000, + }, + { + legend: 'second', + data: 39000, + }, +]; + +const data: ChartProps = { + chartTitle: 'Donut chart basic example', + chartData: points, +}; + +const storyTemplate = html>` + + +`; + +export default { + title: 'Components/DonutChart', +} as Meta; + +export const RTL: Story = renderComponent(html>` +
+ + +
+`); + +export const Basic: Story = renderComponent(storyTemplate).bind({}); diff --git a/packages/charts/chart-web-components/src/donut-chart/donut-chart.styles.ts b/packages/charts/chart-web-components/src/donut-chart/donut-chart.styles.ts new file mode 100644 index 00000000000000..5833ddfa60df27 --- /dev/null +++ b/packages/charts/chart-web-components/src/donut-chart/donut-chart.styles.ts @@ -0,0 +1,159 @@ +import { css } from '@microsoft/fast-element'; +import { + borderRadiusMedium, + colorNeutralBackground1, + colorNeutralForeground1, + colorNeutralShadowAmbient, + colorNeutralShadowKey, + colorStrokeFocus1, + colorStrokeFocus2, + colorTransparentStroke, + display, + forcedColorsStylesheetBehavior, + spacingHorizontalL, + spacingHorizontalNone, + spacingHorizontalS, + spacingVerticalL, + spacingVerticalMNudge, + spacingVerticalNone, + spacingVerticalS, + strokeWidthThickest, + strokeWidthThin, + typographyBody1Styles, + typographyCaption1Styles, + typographyTitle2Styles, + typographyTitle3Styles, +} from '@fluentui/web-components'; + +/** + * Styles for the DonutChart component. + * + * @public + */ +export const styles = css` + ${display('inline-block')} + + :host { + ${typographyBody1Styles} + align-items: center; + flex-direction: column; + width: 100%; + height: 100%; + position: relative; + } + + .chart { + box-sizing: content-box; + overflow: visible; + display: block; + } + + .arc.inactive { + opacity: 0.1; + } + + .arc:focus { + outline: none; + stroke-width: ${strokeWidthThin}; + stroke: ${colorStrokeFocus1}; + } + + .arc-outline { + fill: none; + } + + .arc-outline:has(+ .arc:focus) { + stroke-width: ${strokeWidthThickest}; + stroke: ${colorStrokeFocus2}; + } + + .text-inside-donut { + ${typographyTitle3Styles} + fill: ${colorNeutralForeground1}; + } + + .legend-container { + padding-top: ${spacingVerticalL}; + white-space: nowrap; + width: 100%; + align-items: center; + margin: -${spacingVerticalS} ${spacingHorizontalNone} ${spacingVerticalNone} -${spacingHorizontalS}; + flex-wrap: wrap; + display: flex; + } + + .legend { + display: flex; + align-items: center; + cursor: pointer; + border: none; + padding: ${spacingHorizontalS}; + background: none; + text-transform: capitalize; + } + + .legend-rect { + width: 12px; + height: 12px; + margin-inline-end: ${spacingHorizontalS}; + border: ${strokeWidthThin} solid; + } + + .legend-text { + ${typographyCaption1Styles} + color: ${colorNeutralForeground1}; + } + + .legend.inactive .legend-rect { + background-color: transparent !important; + } + + .legend.inactive .legend-text { + opacity: 0.67; + } + + .tooltip { + display: grid; + overflow: hidden; + padding: ${spacingVerticalMNudge} ${spacingHorizontalL}; + background-color: ${colorNeutralBackground1}; + background-blend-mode: normal, luminosity; + border-radius: ${borderRadiusMedium}; + border: 1px solid ${colorTransparentStroke}; + filter: drop-shadow(0 0 2px ${colorNeutralShadowAmbient}) drop-shadow(0 8px 16px ${colorNeutralShadowKey}); + position: absolute; + z-index: 1; + pointer-events: none; + } + + .tooltip-body { + padding-inline-start: ${spacingHorizontalS}; + color: ${colorNeutralForeground1}; + border-inline-start: 4px solid; + } + + .tooltip-legend-text { + ${typographyCaption1Styles} + } + + .tooltip-content-y { + ${typographyTitle2Styles} + } +`.withBehaviors( + forcedColorsStylesheetBehavior(css` + .text-inside-donut { + fill: CanvasText; + } + + .legend-rect, + .tooltip-body { + forced-color-adjust: none; + } + + .tooltip-legend-text, + .tooltip-content-y { + forced-color-adjust: auto; + color: CanvasText; + } + `), +); diff --git a/packages/charts/chart-web-components/src/donut-chart/donut-chart.template.ts b/packages/charts/chart-web-components/src/donut-chart/donut-chart.template.ts new file mode 100644 index 00000000000000..f435e709755c9e --- /dev/null +++ b/packages/charts/chart-web-components/src/donut-chart/donut-chart.template.ts @@ -0,0 +1,70 @@ +import { ElementViewTemplate, html, ref, repeat, when } from '@microsoft/fast-element'; +import type { DonutChart } from './donut-chart.js'; +import type { Legend } from './donut-chart.options.js'; + +/** + * Generates a template for the DonutChart component. + * + * @public + */ +export function donutChartTemplate(): ElementViewTemplate { + return html` + + `; +} + +/** + * @internal + */ +export const template: ElementViewTemplate = donutChartTemplate(); diff --git a/packages/charts/chart-web-components/src/donut-chart/donut-chart.ts b/packages/charts/chart-web-components/src/donut-chart/donut-chart.ts new file mode 100644 index 00000000000000..20d17d6572927b --- /dev/null +++ b/packages/charts/chart-web-components/src/donut-chart/donut-chart.ts @@ -0,0 +1,257 @@ +import { attr, FASTElement, nullableNumberConverter, observable } from '@microsoft/fast-element'; +import { arc as d3Arc, pie as d3Pie, PieArcDatum } from 'd3-shape'; +import { + getColorFromToken, + getNextColor, + getRTL, + jsonConverter, + SVG_NAMESPACE_URI, + validateChartProps, + wrapText, +} from '../utils/chart-helpers.js'; +import type { ChartDataPoint, ChartProps, Legend } from './donut-chart.options.js'; + +export class DonutChart extends FASTElement { + @attr({ converter: nullableNumberConverter }) + public height: number = 200; + + @attr({ converter: nullableNumberConverter }) + public width: number = 200; + + @attr({ attribute: 'hide-legends', mode: 'boolean' }) + public hideLegends: boolean = false; + + @attr({ attribute: 'hide-tooltip', mode: 'boolean' }) + public hideTooltip: boolean = false; + + @attr({ converter: jsonConverter }) + public data!: ChartProps; + + @attr({ attribute: 'inner-radius', converter: nullableNumberConverter }) + public innerRadius: number = 1; + + @attr({ attribute: 'value-inside-donut' }) + public valueInsideDonut?: string; + + @attr({ attribute: 'legend-list-label' }) + public legendListLabel?: string; + + @observable + public legends: Legend[] = []; + + @observable + public activeLegend: string = ''; + protected activeLegendChanged(oldValue: string, newValue: string) { + if (newValue === '') { + this._arcs?.forEach(arc => arc.classList.remove('inactive')); + } else { + this._arcs?.forEach(arc => { + if (arc.getAttribute('data-id') === newValue) { + arc.classList.remove('inactive'); + } else { + arc.classList.add('inactive'); + } + }); + } + + this._updateTextInsideDonut(); + } + + @observable + public isLegendSelected: boolean = false; + + @observable + public tooltipProps = { + isVisible: false, + legend: '', + yValue: '', + color: '', + xPos: 0, + yPos: 0, + }; + protected tooltipPropsChanged(oldValue: any, newValue: any) { + this._updateTextInsideDonut(); + } + + public chartWrapper!: HTMLDivElement; + public group!: SVGGElement; + public elementInternals: ElementInternals = this.attachInternals(); + + private _arcs: SVGPathElement[] = []; + private _isRTL: boolean = false; + private _textInsideDonut?: SVGTextElement; + + constructor() { + super(); + + this.elementInternals.role = 'region'; + } + + public handleLegendMouseoverAndFocus(legendTitle: string) { + if (this.isLegendSelected) { + return; + } + + this.activeLegend = legendTitle; + } + + public handleLegendMouseoutAndBlur() { + if (this.isLegendSelected) { + return; + } + + this.activeLegend = ''; + } + + public handleLegendClick(legendTitle: string) { + if (this.isLegendSelected && this.activeLegend === legendTitle) { + this.activeLegend = ''; + this.isLegendSelected = false; + } else { + this.activeLegend = legendTitle; + this.isLegendSelected = true; + } + } + + connectedCallback() { + super.connectedCallback(); + + validateChartProps(this.data, 'data'); + + this.data.chartData.forEach((dataPoint, index) => { + if (dataPoint.color) { + dataPoint.color = getColorFromToken(dataPoint.color); + } else { + dataPoint.color = getNextColor(index); + } + }); + + this.legends = this._getLegends(); + this._isRTL = getRTL(this); + this.elementInternals.ariaLabel = + this.data.chartTitle || `Donut chart with ${this.data.chartData.length} segments.`; + + this._render(); + } + + private _render() { + const pie = d3Pie() + .value(d => d.data) + .padAngle(0.02); + const arc = d3Arc>() + .innerRadius(this.innerRadius) + .outerRadius((Math.min(this.height, this.width) - 20) / 2); + + pie(this.data.chartData).forEach(arcDatum => { + const arcGroup = document.createElementNS(SVG_NAMESPACE_URI, 'g'); + this.group.appendChild(arcGroup); + + const pathOutline = document.createElementNS(SVG_NAMESPACE_URI, 'path'); + arcGroup.appendChild(pathOutline); + pathOutline.classList.add('arc-outline'); + pathOutline.setAttribute('d', arc(arcDatum)!); + + const path = document.createElementNS(SVG_NAMESPACE_URI, 'path'); + arcGroup.appendChild(path); + this._arcs.push(path); + path.classList.add('arc'); + path.setAttribute('d', arc(arcDatum)!); + path.setAttribute('fill', arcDatum.data.color!); + path.setAttribute('data-id', arcDatum.data.legend); + path.setAttribute('tabindex', '0'); + path.setAttribute('aria-label', `${arcDatum.data.legend}, ${arcDatum.data.data}.`); + path.setAttribute('role', 'img'); + + path.addEventListener('mouseover', event => { + if (this.activeLegend !== '' && this.activeLegend !== arcDatum.data.legend) { + return; + } + + const bounds = this.getBoundingClientRect(); + + this.tooltipProps = { + isVisible: true, + legend: arcDatum.data.legend, + yValue: `${arcDatum.data.data}`, + color: arcDatum.data.color!, + xPos: this._isRTL ? bounds.right - event.clientX : event.clientX - bounds.left, + yPos: event.clientY - bounds.top - 85, + }; + }); + path.addEventListener('focus', event => { + if (this.activeLegend !== '' && this.activeLegend !== arcDatum.data.legend) { + return; + } + + const rootBounds = this.getBoundingClientRect(); + const arcBounds = path.getBoundingClientRect(); + + this.tooltipProps = { + isVisible: true, + legend: arcDatum.data.legend, + yValue: `${arcDatum.data.data}`, + color: arcDatum.data.color!, + xPos: this._isRTL + ? rootBounds.right - arcBounds.left - arcBounds.width / 2 + : arcBounds.left + arcBounds.width / 2 - rootBounds.left, + yPos: arcBounds.top - rootBounds.top - 85, + }; + }); + path.addEventListener('blur', event => { + this.tooltipProps = { isVisible: false, legend: '', yValue: '', color: '', xPos: 0, yPos: 0 }; + }); + }); + + this.addEventListener('mouseleave', () => { + this.tooltipProps = { isVisible: false, legend: '', yValue: '', color: '', xPos: 0, yPos: 0 }; + }); + + if (this.valueInsideDonut) { + this._textInsideDonut = document.createElementNS(SVG_NAMESPACE_URI, 'text'); + this.group.appendChild(this._textInsideDonut); + this._textInsideDonut.classList.add('text-inside-donut'); + this._textInsideDonut.setAttribute('x', '0'); + this._textInsideDonut.setAttribute('y', '0'); + this._textInsideDonut.setAttribute('text-anchor', 'middle'); + this._textInsideDonut.setAttribute('dominant-baseline', 'middle'); + this._updateTextInsideDonut(); + } + } + + private _getLegends(): Legend[] { + return this.data.chartData.map((d, index) => ({ + title: d.legend, + color: d.color!, + })); + } + + private _getTextInsideDonut(valueInsideDonut: string) { + let textInsideDonut = valueInsideDonut; + + if (valueInsideDonut && (this.activeLegend !== '' || this.tooltipProps.isVisible)) { + const highlightedDataPoint = this.data.chartData.find( + dataPoint => + dataPoint.legend === this.activeLegend || + (this.tooltipProps.isVisible && dataPoint.legend === this.tooltipProps.legend), + ); + textInsideDonut = highlightedDataPoint!.yAxisCalloutData ?? highlightedDataPoint!.data.toLocaleString(); + } + + return textInsideDonut; + } + + private _updateTextInsideDonut() { + if (!this._textInsideDonut || !this.valueInsideDonut) { + return; + } + + this._textInsideDonut.textContent = this._getTextInsideDonut(this.valueInsideDonut); + const lineHeight = this._textInsideDonut.getBoundingClientRect().height; + wrapText(this._textInsideDonut, 2 * this.innerRadius); + const lines = this._textInsideDonut.getElementsByTagName('tspan'); + const start = -1 * Math.trunc((lines.length - 1) / 2); + for (let i = 0; i < lines.length; i++) { + lines[i].setAttribute('dy', `${(start + i) * lineHeight}`); + } + } +} diff --git a/packages/charts/chart-web-components/src/donut-chart/index.ts b/packages/charts/chart-web-components/src/donut-chart/index.ts new file mode 100644 index 00000000000000..60e54e1a59b9ba --- /dev/null +++ b/packages/charts/chart-web-components/src/donut-chart/index.ts @@ -0,0 +1,4 @@ +export { definition as DonutChartDefinition } from './donut-chart.definition.js'; +export { DonutChart } from './donut-chart.js'; +export { styles as DonutChartStyles } from './donut-chart.styles.js'; +export { template as DonutChartTemplate } from './donut-chart.template.js'; diff --git a/packages/charts/chart-web-components/src/helpers.stories.ts b/packages/charts/chart-web-components/src/helpers.stories.ts new file mode 100644 index 00000000000000..c885723594b95d --- /dev/null +++ b/packages/charts/chart-web-components/src/helpers.stories.ts @@ -0,0 +1,101 @@ +import type { ElementViewTemplate, FASTElement, ViewTemplate } from '@microsoft/fast-element'; +import type { AnnotatedStoryFn, Args, ComponentAnnotations, Renderer, StoryAnnotations } from '@storybook/csf'; + +/** + * A helper that returns a function to bind a Storybook story to a ViewTemplate. + * + * @param template - The ViewTemplate to render + * @returns - a function to bind a Storybook story + */ +export function renderComponent(template: ViewTemplate): (args: TArgs) => Element | DocumentFragment { + return function (args) { + const storyFragment = new DocumentFragment(); + template.render(args, storyFragment); + if (storyFragment.childElementCount === 1) { + return storyFragment.firstElementChild!; + } + return storyFragment; + }; +} + +export declare interface FASTComponentsRenderer extends Renderer { + canvasElement: FASTElement; + component: typeof FASTElement | string; + storyResult: string | Node | DocumentFragment | ElementViewTemplate; +} + +/** + * A helper that returns a function to bind a Storybook story to a ViewTemplate. + */ +export type FASTFramework = Renderer & { + component: typeof FASTElement; + storyResult: FASTElement | Element | DocumentFragment; +}; + +/** + * Metadata to configure the stories for a component. + */ +export declare type Meta = ComponentAnnotations>; + +/** + * Story object that represents a CSFv3 component example. + * + * @see [Named Story exports](https://storybook.js.org/docs/formats/component-story-format/#named-story-exports) + */ +export declare type StoryObj = StoryAnnotations>; + +/** + * Story function that represents a CSFv2 component example. + */ +export declare type StoryFn = AnnotatedStoryFn; + +/** + * Story function that represents a CSFv2 component example. + * + * NOTE that in Storybook 7.0, this type will be renamed to `StoryFn` and replaced by the current `StoryObj` type. + */ +export declare type Story = StoryFn>; + +/** + * Combined Storybook story args. + */ +export type StoryArgs = Partial> & Args; + +export function generateImage({ + width, + height = width, + backgroundColor = 'rgb(204, 204, 204)', + color = 'rgb(150, 150, 150)', + text = `${width} x ${height}`, +}: { + width: number; + height?: number; + backgroundColor?: string; + color?: string; + text?: string; +}): string { + const canvas = document.createElement('canvas'); + const context = canvas.getContext('2d') as CanvasRenderingContext2D; + + canvas.width = width; + canvas.height = height; + + // Clear the canvas. + context.clearRect(0, 0, canvas.width, canvas.height); + + // get the font size to fit the text + context.font = '1px sans-serif'; + const maxFontSize = Math.max(width / context.measureText(text).width / 2, 7); + + // Draw the background + context.fillStyle = backgroundColor; + context.fillRect(0, 0, canvas.width, canvas.height); + + context.font = `${maxFontSize}px Helvetica, Arial, sans-serif`; + context.textAlign = 'center'; + context.textBaseline = 'middle'; + context.fillStyle = color; + context.fillText(text, canvas.width / 2, canvas.height / 2); + + return canvas.toDataURL('image/png'); +} diff --git a/packages/web-components/src/helpers.tests.ts b/packages/charts/chart-web-components/src/helpers.tests.ts similarity index 100% rename from packages/web-components/src/helpers.tests.ts rename to packages/charts/chart-web-components/src/helpers.tests.ts diff --git a/packages/charts/chart-web-components/src/horizontal-bar-chart/define.ts b/packages/charts/chart-web-components/src/horizontal-bar-chart/define.ts new file mode 100644 index 00000000000000..2af6e03097468c --- /dev/null +++ b/packages/charts/chart-web-components/src/horizontal-bar-chart/define.ts @@ -0,0 +1,4 @@ +import { FluentDesignSystem } from '@fluentui/web-components'; +import { definition } from './horizontal-bar-chart.definition.js'; + +definition.define(FluentDesignSystem.registry); diff --git a/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.bench.ts b/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.bench.ts new file mode 100644 index 00000000000000..14336cd320d46f --- /dev/null +++ b/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.bench.ts @@ -0,0 +1,12 @@ +import { FluentDesignSystem } from '@fluentui/web-components'; +import { definition } from './horizontal-bar-chart.definition.js'; + +definition.define(FluentDesignSystem.registry); + +const itemRenderer = () => { + const horizontalbarchart = document.createElement('fluent-horizontal-bar-chart'); + return horizontalbarchart; +}; + +export default itemRenderer; +export { tests } from '../utils/benchmark-wrapper.js'; diff --git a/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.definition.ts b/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.definition.ts new file mode 100644 index 00000000000000..211c4d0b63c563 --- /dev/null +++ b/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.definition.ts @@ -0,0 +1,20 @@ +import { FluentDesignSystem } from '@fluentui/web-components'; +import { HorizontalBarChart } from './horizontal-bar-chart.js'; +import { styles } from './horizontal-bar-chart.styles.js'; +import { template } from './horizontal-bar-chart.template.js'; + +/** + * The Fluent Textarea Element definition. + * + * @public + * @remarks + * HTML Element: `` + */ +export const definition = HorizontalBarChart.compose({ + name: `${FluentDesignSystem.prefix}-horizontal-bar-chart`, + template, + styles, + shadowOptions: { + delegatesFocus: true, + }, +}); diff --git a/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.options.ts b/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.options.ts new file mode 100644 index 00000000000000..13b6150cc68b63 --- /dev/null +++ b/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.options.ts @@ -0,0 +1,50 @@ +export enum Variant { + PartToWhole = 'part-to-whole', + AbsoluteScale = 'absolute-scale', + SingleBar = 'single-bar', +} + +export interface ChartDataPoint { + /** + * Legend text for the datapoint in the chart + */ + legend: string; + + /** + * data the datapoint in the chart + */ + data: number; + + /** + * total length of bar + */ + total?: number; + + /** + * onClick action for each datapoint in the chart + */ + onClick?: VoidFunction; + + /** + * Color for the legend in the chart. If not provided, it will fallback on the default color palette. + */ + color?: string; + + gradient?: [string, string]; +} + +export interface ChartProps { + /** + * title for the data series + */ + chartSeriesTitle?: string; + + /** + * data for the points in the chart + */ + chartData: ChartDataPoint[]; + + benchmarkData?: number; + + chartDataText?: string; +} diff --git a/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.spec.ts b/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.spec.ts new file mode 100644 index 00000000000000..082758977133f2 --- /dev/null +++ b/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.spec.ts @@ -0,0 +1,730 @@ +import { Locator, test } from '@playwright/test'; +import { expect, fixtureURL } from '../helpers.tests.js'; +import type { ChartDataPoint, ChartProps } from './horizontal-bar-chart.options.js'; + +const chartPoints1: ChartDataPoint[] = [ + { + legend: 'Debit card numbers (EU and USA)', + data: 40, + color: '#0099BC', + }, + { + legend: 'Passport numbers (USA)', + data: 23, + color: '#77004D', + }, + { + legend: 'Social security numbers', + data: 35, + color: '#4F68ED', + }, + { + legend: 'Credit card Numbers', + data: 87, + color: '#AE8C00', + }, + { + legend: 'Tax identification numbers (USA)', + data: 87, + color: '#004E8C', + }, +]; + +const chartPoints2: ChartDataPoint[] = [ + { + legend: 'Debit card numbers (EU and USA)', + data: 40, + color: '#0099BC', + }, + { + legend: 'Passport numbers (USA)', + data: 56, + color: '#77004D', + }, + { + legend: 'Social security numbers', + data: 35, + color: '#4F68ED', + }, + { + legend: 'Credit card Numbers', + data: 92, + color: '#AE8C00', + }, + { + legend: 'Tax identification numbers (USA)', + data: 87, + color: '#004E8C', + }, +]; + +const chartPoints3: ChartDataPoint[] = [ + { + legend: 'Phone Numbers', + data: 40, + color: '#881798', + }, + { + legend: 'Credit card Numbers', + data: 23, + color: '#AE8C00', + }, +]; + +const basicChartTestData: ChartProps[] = [ + { + chartSeriesTitle: 'Monitored First', + chartData: chartPoints1, + }, + { + chartSeriesTitle: 'Monitored Second', + chartData: chartPoints2, + }, + { + chartSeriesTitle: 'Unmonitored', + chartData: chartPoints3, + }, +]; + +const singleBarHBCData = [ + { + chartSeriesTitle: 'one', + chartData: [ + { + legend: 'one', + data: 1543, + total: 15000, + color: '#637cef', + }, + ], + }, + { + chartSeriesTitle: 'two', + chartData: [ + { + legend: 'two', + data: 800, + total: 15000, + color: '#e3008c', + }, + ], + }, + { + chartSeriesTitle: 'three', + chartData: [ + { + legend: 'three', + data: 8888, + total: 15000, + color: '#2aa0a4', + }, + ], + }, + { + chartSeriesTitle: 'four', + chartData: [ + { + legend: 'four', + data: 15888, + total: 15000, + color: '#9373c0', + }, + ], + }, + { + chartSeriesTitle: 'five', + chartData: [ + { + legend: 'five', + data: 11444, + total: 15000, + color: '#13a10e', + }, + ], + }, + { + chartSeriesTitle: 'six', + chartData: [ + { + legend: 'six', + data: 14000, + total: 15000, + color: '#3a96dd', + }, + ], + }, + { + chartSeriesTitle: 'seven', + chartData: [ + { + legend: 'seven', + data: 9855, + total: 15000, + color: '#ca5010', + }, + ], + }, + { + chartSeriesTitle: 'eight', + chartData: [ + { + legend: 'eight', + data: 4250, + total: 15000, + color: '#57811b', + }, + ], + }, +]; + +const singleBarNMVariantData = [ + { + chartSeriesTitle: 'one', + chartData: [ + { + legend: 'one', + data: 1543, + total: 15000, + color: '#637cef', + }, + ], + }, + { + chartSeriesTitle: 'two', + chartData: [ + { + legend: 'two', + data: 800, + total: 15000, + color: '#e3008c', + }, + ], + }, + { + chartSeriesTitle: 'three', + chartData: [ + { + legend: 'three', + data: 8888, + total: 15000, + color: '#2aa0a4', + }, + ], + }, + { + chartSeriesTitle: 'four', + chartData: [ + { + legend: 'four', + data: 15888, + total: 15000, + color: '#9373c0', + }, + ], + }, + { + chartSeriesTitle: 'five', + chartData: [ + { + legend: 'five', + data: 11444, + total: 15000, + color: '#13a10e', + }, + ], + }, + { + chartSeriesTitle: 'six', + chartData: [ + { + legend: 'six', + data: 14000, + total: 15000, + color: '#3a96dd', + }, + ], + }, + { + chartSeriesTitle: 'seven', + chartData: [ + { + legend: 'seven', + data: 9855, + total: 15000, + color: '#ca5010', + }, + ], + }, + { + chartSeriesTitle: 'eight', + chartData: [ + { + legend: 'eight', + data: 4250, + total: 15000, + color: '#57811b', + }, + ], + }, +]; + +const singlePointData = [ + { + chartSeriesTitle: 'one', + chartData: [ + { + legend: 'one', + data: 1543, + total: 15000, + gradient: ['#637cef', '#e3008c'], + }, + ], + }, +]; + +async function expectOptionsToBeVisible(element: Locator, options: string | any[]) { + for (let i = 0; i < options.length; i++) { + await expect(element.getByRole('option', { name: options[i] })).toBeVisible(); + } +} + +test.describe('horizontalbarchart - Basic', () => { + test.beforeEach(async ({ page }) => { + await page.goto(fixtureURL('components-horizontalbarchart--basic')); + await page.setContent(/* html */ ` +
+ + +
+ `); + await page.waitForFunction(() => customElements.whenDefined('fluent-horizontal-bar-chart')); + }); + + test('Should render horizontalbarchart properly', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + await expectOptionsToBeVisible(element, [ + 'Debit card numbers (EU and USA)', + 'Passport numbers (USA)', + 'Social security numbers', + 'Credit card Numbers', + 'Phone Numbers', + ]); + await expect(page.getByText('Monitored First')).toBeVisible(); + await expect(page.getByText('Monitored Second')).toBeVisible(); + await expect(page.getByText('Unmonitored')).toBeVisible(); + }); + + test('Should render legends data properly', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + const legends = element.locator('.legend'); + await expect(legends).toHaveCount(6); + const firstLegend = legends.first(); + await expect(firstLegend.locator('div').first()).toHaveCSS('background-color', 'rgb(0, 153, 188)'); + await expect(firstLegend).toHaveText('Debit card numbers (EU and USA)'); + }); + + test('Should update bar css/opaity when mouse hover on legend', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + const legends = element.locator('.legend'); + await expect(legends).toHaveCount(6); + const firstLegend = legends.first(); + //mouse events + await legends.nth(0).dispatchEvent('mouseover'); + const bars = element.locator('.bar'); + await expect(bars).toHaveCount(12); + for (let i = 0; i < (await bars.count()); i++) { + if (i == 0 || i == 5) { + await expect(bars.nth(i)).toHaveCSS('opacity', '1'); + } else { + await expect(bars.nth(i)).toHaveCSS('opacity', '0.1'); + } + } + }); + + test('Should update bar css/opaity when mouse moved from one legend to another legend', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + const legends = element.locator('.legend'); + await expect(legends).toHaveCount(6); + await legends.nth(0).dispatchEvent('mouseover'); + const bars = element.locator('.bar'); + for (let i = 0; i < (await bars.count()); i++) { + if (i == 0 || i == 5) { + await expect(bars.nth(i)).toHaveCSS('opacity', '1'); + } else { + await expect(bars.nth(i)).toHaveCSS('opacity', '0.1'); + } + } + await legends.nth(0).dispatchEvent('mouseout'); + await legends.nth(1).dispatchEvent('mouseover'); + for (let i = 0; i < (await bars.count()); i++) { + if (i == 1 || i == 6) { + await expect(bars.nth(i)).toHaveCSS('opacity', '1'); + } else { + await expect(bars.nth(i)).toHaveCSS('opacity', '0.1'); + } + } + }); + + test('Should show callout when mouse hover on bar', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + const bars = element.locator('.bar'); + const tooltip = element.locator('.tooltip'); + await expect(tooltip).toHaveCount(0); + await bars.nth(0).dispatchEvent('mouseover'); + await expect(tooltip).toHaveCount(1); + await expect(tooltip.nth(0)).toHaveCSS('opacity', '1'); + await expect(tooltip.nth(0).locator('div').first()).toHaveText('Debit card numbers (EU and USA) 40'); + }); + + test('Should update callout data when mouse moved from one bar to another bar', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + const bars = element.locator('.bar'); + const tooltip = element.locator('.tooltip'); + await expect(tooltip).toHaveCount(0); + await bars.nth(0).dispatchEvent('mouseover'); + await expect(tooltip).toHaveCount(1); + await expect(tooltip.nth(0)).toHaveCSS('opacity', '1'); + await expect(tooltip.nth(0).locator('div').first()).toHaveText('Debit card numbers (EU and USA) 40'); + await bars.nth(0).dispatchEvent('mouseout'); + await bars.nth(1).dispatchEvent('mouseover'); + await expect(tooltip.nth(0)).toHaveCSS('opacity', '1'); + await expect(tooltip.nth(0).locator('div').first()).toHaveText('Passport numbers (USA) 23'); + }); +}); + +test.describe('horizontalbarchart - Single Bar HBC', () => { + test.beforeEach(async ({ page }) => { + await page.goto(fixtureURL('components-horizontalbarchart--single-bar-hbc')); + await page.setContent(/* html */ ` +
+ + +
+ `); + await page.waitForFunction(() => customElements.whenDefined('fluent-horizontal-bar-chart')); + }); + + test('Should render Single Bar HBC properly', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + await expectOptionsToBeVisible(element, ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight']); + const barsTitles = element.locator('.chart-title'); + await expect(barsTitles).toHaveCount(8); + await expect(barsTitles.nth(0)).toHaveText('one'); + await expect(barsTitles.nth(1)).toHaveText('two'); + await expect(barsTitles.nth(2)).toHaveText('three'); + await expect(barsTitles.nth(3)).toHaveText('four'); + await expect(barsTitles.nth(4)).toHaveText('five'); + await expect(barsTitles.nth(5)).toHaveText('six'); + await expect(barsTitles.nth(6)).toHaveText('seven'); + await expect(barsTitles.nth(7)).toHaveText('eight'); + for (let i = 0; i < (await barsTitles.count()); i++) { + await expect(barsTitles.nth(i)).toBeVisible(); + } + }); + + test('Should update bar css/opaity when mouse hover on legend', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + const legends = element.locator('.legend'); + await expect(legends).toHaveCount(8); + //mouse events + await legends.nth(0).dispatchEvent('mouseover'); + const bars = element.locator('.bar'); + await expect(bars).toHaveCount(8); + for (let i = 1; i < (await bars.count()); i++) { + if (i == 0) { + await expect(bars.nth(i)).toHaveCSS('opacity', '1'); + } else { + await expect(bars.nth(i)).toHaveCSS('opacity', '0.1'); + } + } + }); + + test('Should update bar css/opaity when mouse moved from one legend to another legend', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + const legends = element.locator('.legend'); + await expect(legends).toHaveCount(8); + await legends.nth(0).dispatchEvent('mouseover'); + const bars = element.locator('.bar'); + await expect(bars.nth(0)).toHaveCSS('opacity', '1'); + for (let i = 1; i < (await bars.count()); i++) { + if (i == 0) { + await expect(bars.nth(i)).toHaveCSS('opacity', '1'); + } else { + await expect(bars.nth(i)).toHaveCSS('opacity', '0.1'); + } + } + await legends.nth(0).dispatchEvent('mouseout'); + await legends.nth(1).dispatchEvent('mouseover'); + for (let i = 1; i < (await bars.count()); i++) { + if (i == 1) { + await expect(bars.nth(i)).toHaveCSS('opacity', '1'); + } else { + await expect(bars.nth(i)).toHaveCSS('opacity', '0.1'); + } + } + }); + + test('Should update bar css/opaity when mouse click on legend', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + const legends = element.locator('.legend'); + await expect(legends).toHaveCount(8); + await legends.nth(0).click(); + const bars = element.locator('.bar'); + await expect(bars.nth(0)).toHaveCSS('opacity', '1'); + for (let i = 1; i < (await bars.count()); i++) { + if (i == 0) { + await expect(bars.nth(i)).toHaveCSS('opacity', '1'); + } else { + await expect(bars.nth(i)).toHaveCSS('opacity', '0.1'); + } + } + await legends.nth(0).click(); + for (let i = 1; i < (await bars.count()); i++) { + await expect(bars.nth(i)).toHaveCSS('opacity', '1'); + } + }); + + test('Should show callout when mouse hover on bar', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + const bars = element.locator('.bar'); + const tooltip = element.locator('.tooltip'); + await expect(tooltip).toHaveCount(0); + await bars.nth(0).dispatchEvent('mouseover'); + await expect(tooltip).toHaveCount(1); + await expect(tooltip.nth(0)).toHaveCSS('opacity', '1'); + await expect(tooltip.nth(0).locator('div').first()).toHaveText('one 1543'); + }); + + test('Should update callout data when mouse moved from one bar to another bar', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + const bars = element.locator('.bar'); + const tooltip = element.locator('.tooltip'); + await expect(tooltip).toHaveCount(0); + await bars.nth(0).dispatchEvent('mouseover'); + await expect(tooltip).toHaveCount(1); + await expect(tooltip.nth(0)).toHaveCSS('opacity', '1'); + await expect(tooltip.nth(0).locator('div').first()).toHaveText('one 1543'); + await bars.nth(0).dispatchEvent('mouseout'); + await bars.nth(1).dispatchEvent('mouseover'); + await expect(tooltip.nth(0)).toHaveCSS('opacity', '1'); + await expect(tooltip.nth(0).locator('div').first()).toHaveText('two 800'); + }); +}); + +test.describe('horizontalbarchart - Single Bar NM Variant', () => { + test.beforeEach(async ({ page }) => { + await page.goto(fixtureURL('components-horizontalbarchart--single-bar-nm-variant')); + await page.setContent(/* html */ ` +
+ + +
+ `); + await page.waitForFunction(() => customElements.whenDefined('fluent-horizontal-bar-chart')); + }); + + test('Should render Single Bar HBC properly', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + await expectOptionsToBeVisible(element, ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight']); + }); + + test('Should render bars and bar labels properly', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + const bars = element.locator('.bar'); + await expect(bars).toHaveCount(16); + await expect(bars.nth(0)).toHaveCSS('fill', 'rgb(99, 124, 239)'); + await expect(bars.nth(0)).toHaveCSS('opacity', '1'); + await expect(bars.nth(0)).toHaveAttribute(`height`, '12'); + + const firstBarWidth = await bars.nth(0).getAttribute('width'); + const firstBarWidthEmptySpace = await bars.nth(1).getAttribute('width'); + expect(parseFloat(firstBarWidth!)).toBeLessThan(parseFloat(firstBarWidthEmptySpace!)); + expect(parseFloat(firstBarWidth!) + parseFloat(firstBarWidthEmptySpace!)).toBeGreaterThanOrEqual(99); + + const secondBarWidth = await bars.nth(2).getAttribute('width'); + const secondBarWidthEmptySpace = await bars.nth(3).getAttribute('width'); + expect(parseFloat(secondBarWidth!)).toBeLessThan(parseFloat(secondBarWidthEmptySpace!)); + expect(parseFloat(secondBarWidth!) + parseFloat(secondBarWidthEmptySpace!)).toBeGreaterThanOrEqual(99); + + const thirdBarWidth = await bars.nth(4).getAttribute('width'); + const thirdBarWidthEmptySpace = await bars.nth(5).getAttribute('width'); + expect(parseFloat(thirdBarWidth!)).toBeGreaterThan(parseFloat(thirdBarWidthEmptySpace!)); + expect(parseFloat(thirdBarWidth!) + parseFloat(thirdBarWidthEmptySpace!)).toBeGreaterThanOrEqual(99); + + const fourthBarWidth = await bars.nth(6).getAttribute('width'); + const fourthBarWidthEmptySpace = await bars.nth(7).getAttribute('width'); + expect(parseFloat(fourthBarWidth!)).toBeGreaterThan(parseFloat(fourthBarWidthEmptySpace!)); + expect(parseFloat(fourthBarWidth!) + parseFloat(fourthBarWidthEmptySpace!)).toBeGreaterThanOrEqual(99); + + const fifthBarWidth = await bars.nth(8).getAttribute('width'); + const fifthBarWidthEmptySpace = await bars.nth(9).getAttribute('width'); + expect(parseFloat(fifthBarWidth!)).toBeGreaterThan(parseFloat(fifthBarWidthEmptySpace!)); + expect(parseFloat(fifthBarWidth!) + parseFloat(fifthBarWidthEmptySpace!)).toBeGreaterThanOrEqual(99); + + const sixthBarWidth = await bars.nth(10).getAttribute('width'); + const sixthBarWidthEmptySpace = await bars.nth(11).getAttribute('width'); + expect(parseFloat(sixthBarWidth!)).toBeGreaterThan(parseFloat(sixthBarWidthEmptySpace!)); + expect(parseFloat(sixthBarWidth!) + parseFloat(sixthBarWidthEmptySpace!)).toBeGreaterThanOrEqual(98); + + const seventhBarWidth = await bars.nth(12).getAttribute('width'); + const seventhBarWidthEmptySpace = await bars.nth(13).getAttribute('width'); + expect(parseFloat(seventhBarWidth!)).toBeGreaterThan(parseFloat(seventhBarWidthEmptySpace!)); + expect(parseFloat(seventhBarWidth!) + parseFloat(seventhBarWidthEmptySpace!)).toBeGreaterThanOrEqual(99); + + const eigthBarWidth = await bars.nth(14).getAttribute('width'); + const eigthBarWidthEmptySpace = await bars.nth(15).getAttribute('width'); + expect(parseFloat(eigthBarWidth!)).toBeLessThan(parseFloat(eigthBarWidthEmptySpace!)); + expect(parseFloat(eigthBarWidth!) + parseFloat(eigthBarWidthEmptySpace!)).toBeGreaterThanOrEqual(99); + }); + + test('Should update bar css/opaity when mouse hover on legend', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + const legends = element.locator('.legend'); + await expect(legends).toHaveCount(8); + //mouse events + await legends.nth(0).dispatchEvent('mouseover'); + const bars = element.locator('.bar'); + await expect(bars).toHaveCount(16); + for (let i = 1; i < (await bars.count()); i++) { + if (i == 0) { + await expect(bars.nth(i)).toHaveCSS('opacity', '1'); + } else { + await expect(bars.nth(i)).toHaveCSS('opacity', '0.1'); + } + } + }); + + test('Should update bar css/opaity when mouse moved from one legend to another legend', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + const legends = element.locator('.legend'); + await expect(legends).toHaveCount(8); + await legends.nth(0).dispatchEvent('mouseover'); + const bars = element.locator('.bar'); + for (let i = 1; i < (await bars.count()); i++) { + if (i == 0) { + await expect(bars.nth(i)).toHaveCSS('opacity', '1'); + } else { + await expect(bars.nth(i)).toHaveCSS('opacity', '0.1'); + } + } + await legends.nth(0).dispatchEvent('mouseout'); + await legends.nth(1).dispatchEvent('mouseover'); + for (let i = 1; i < (await bars.count()); i++) { + if (i == 2) { + await expect(bars.nth(i)).toHaveCSS('opacity', '1'); + } else { + await expect(bars.nth(i)).toHaveCSS('opacity', '0.1'); + } + } + }); + + test('Should show callout when mouse hover on bar', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + const bars = element.locator('.bar'); + const tooltip = element.locator('.tooltip'); + await expect(tooltip).toHaveCount(0); + await bars.nth(0).dispatchEvent('mouseover'); + await expect(tooltip).toHaveCount(1); + await expect(tooltip.nth(0)).toHaveCSS('opacity', '1'); + await expect(tooltip.nth(0).locator('div').first()).toHaveText('one 1543'); + }); + + test('Should update callout data when mouse moved from one bar to another bar', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + const bars = element.locator('.bar'); + const tooltip = element.locator('.tooltip'); + await expect(tooltip).toHaveCount(0); + await bars.nth(0).dispatchEvent('mouseover'); + await expect(tooltip).toHaveCount(1); + await expect(tooltip.nth(0)).toHaveCSS('opacity', '1'); + await expect(tooltip.nth(0).locator('div').first()).toHaveText('one 1543'); + await bars.nth(0).dispatchEvent('mouseout'); + await bars.nth(2).dispatchEvent('mouseover'); + await expect(tooltip.nth(0)).toHaveCSS('opacity', '1'); + await expect(tooltip.nth(0).locator('div').first()).toHaveText('two 800'); + }); +}); + +test.describe('horizontalbarchart - Single Data Point', () => { + test.beforeEach(async ({ page }) => { + await page.goto(fixtureURL('components-horizontalbarchart--single-data-point')); + await page.setContent(/* html */ ` +
+ + +
+ `); + await page.waitForFunction(() => customElements.whenDefined('fluent-horizontal-bar-chart')); + }); + + test('Should render Single Bar HBC properly', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + await expect(element.getByRole('option', { name: 'one' })).toBeVisible(); + const barsTitles = element.locator('.chart-title'); + await expect(barsTitles).toHaveCount(1); + await expect(barsTitles.nth(0)).toHaveText('one'); + await expect(barsTitles.nth(0)).toBeVisible(); + }); + + test('Should render bars and bar labels properly', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + const bars = element.locator('.bar'); + await expect(bars).toHaveCount(2); + await expect(bars.nth(0)).toHaveCSS('fill', 'url("#gradient-0-0")'); + await expect(bars.nth(0)).toHaveCSS('opacity', '1'); + await expect(bars.nth(0)).toHaveAttribute(`height`, '12'); + const firstBarWidth = await bars.nth(0).getAttribute('width'); + const firstBarWidthEmptySpace = await bars.nth(1).getAttribute('width'); + expect(parseFloat(firstBarWidth!)).toBeLessThan(parseFloat(firstBarWidthEmptySpace!)); + expect(parseFloat(firstBarWidth!) + parseFloat(firstBarWidthEmptySpace!)).toBeGreaterThan(99); + }); + + test('Should update bar css/opaity when mouse hover on legend', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + const legends = element.locator('.legend'); + await expect(legends).toHaveCount(1); + //mouse events + await legends.nth(0).dispatchEvent('mouseover'); + const bars = element.locator('.bar'); + await expect(bars).toHaveCount(2); + await expect(bars.nth(0)).toHaveCSS('opacity', '1'); + await expect(bars.nth(1)).toHaveCSS('opacity', '0.1'); + }); + + test('Should update bar css/opaity when mouse click on legend', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + const legends = element.locator('.legend'); + await legends.nth(0).click(); + const bars = element.locator('.bar'); + await expect(bars.nth(0)).toHaveCSS('opacity', '1'); + await expect(bars.nth(1)).toHaveCSS('opacity', '0.1'); + await legends.nth(0).click(); + await expect(bars.nth(0)).toHaveCSS('opacity', '1'); + await expect(bars.nth(1)).toHaveCSS('opacity', '1'); + }); + + test('Should show callout when mouse hover on bar', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + const bars = element.locator('.bar'); + const tooltip = element.locator('.tooltip'); + await expect(tooltip).toHaveCount(0); + await bars.nth(0).dispatchEvent('mouseover'); + await expect(tooltip).toHaveCount(1); + await expect(tooltip.nth(0)).toHaveCSS('opacity', '1'); + await expect(tooltip.nth(0).locator('div').first()).toHaveText('one 1543'); + }); + + test('Should hide callout when mouve moved to bar offset', async ({ page }) => { + const element = page.locator('fluent-horizontal-bar-chart'); + const bars = element.locator('.bar'); + const tooltip = element.locator('.tooltip'); + await expect(tooltip).toHaveCount(0); + await bars.nth(0).dispatchEvent('mouseover'); + await expect(tooltip).toHaveCount(1); + await expect(tooltip.nth(0)).toHaveCSS('opacity', '1'); + await expect(tooltip.nth(0).locator('div').first()).toHaveText('one 1543'); + await bars.nth(0).dispatchEvent('mouseout'); + await bars.nth(1).dispatchEvent('mouseover'); + await expect(tooltip).toHaveCount(0); + }); +}); diff --git a/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.stories.ts b/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.stories.ts new file mode 100644 index 00000000000000..72f523b84f0f14 --- /dev/null +++ b/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.stories.ts @@ -0,0 +1,389 @@ +import { html } from '@microsoft/fast-element'; +import type { Meta, Story, StoryArgs } from '../helpers.stories.js'; +import { renderComponent } from '../helpers.stories.js'; +import { HorizontalBarChart as FluentHorizontalBarChart } from './horizontal-bar-chart.js'; +import type { ChartDataPoint, ChartProps } from './horizontal-bar-chart.options.js'; +import { Variant } from './horizontal-bar-chart.options.js'; + +const singleBarHBCData = [ + { + chartSeriesTitle: 'one', + chartData: [ + { + legend: 'one', + data: 1543, + total: 15000, + color: '#637cef', + }, + ], + }, + { + chartSeriesTitle: 'two', + chartData: [ + { + legend: 'two', + data: 800, + total: 15000, + color: '#e3008c', + }, + ], + }, + { + chartSeriesTitle: 'three', + chartData: [ + { + legend: 'three', + data: 8888, + total: 15000, + color: '#2aa0a4', + }, + ], + }, + { + chartSeriesTitle: 'four', + chartData: [ + { + legend: 'four', + data: 15888, + total: 15000, + color: '#9373c0', + }, + ], + }, + { + chartSeriesTitle: 'five', + chartData: [ + { + legend: 'five', + data: 11444, + total: 15000, + color: '#13a10e', + }, + ], + }, + { + chartSeriesTitle: 'six', + chartData: [ + { + legend: 'six', + data: 14000, + total: 15000, + color: '#3a96dd', + }, + ], + }, + { + chartSeriesTitle: 'seven', + chartData: [ + { + legend: 'seven', + data: 9855, + total: 15000, + color: '#ca5010', + }, + ], + }, + { + chartSeriesTitle: 'eight', + chartData: [ + { + legend: 'eight', + data: 4250, + total: 15000, + color: '#57811b', + }, + ], + }, +]; + +const singleBarNMVariantData: ChartProps[] = [ + { + chartSeriesTitle: 'one', + chartData: [ + { + legend: 'one', + data: 1543, + total: 15000, + color: '#637cef', + }, + ], + chartDataText: '1.5k/15k hours', + }, + { + chartSeriesTitle: 'two', + chartData: [ + { + legend: 'two', + data: 800, + total: 15000, + color: '#e3008c', + }, + ], + chartDataText: '800/15k hours', + }, + { + chartSeriesTitle: 'three', + chartData: [ + { + legend: 'three', + data: 8888, + total: 15000, + color: '#2aa0a4', + }, + ], + chartDataText: '8.9k/15k hours', + }, + { + chartSeriesTitle: 'four', + chartData: [ + { + legend: 'four', + data: 15888, + total: 15000, + color: '#9373c0', + }, + ], + chartDataText: '16k/15k hours', + }, + { + chartSeriesTitle: 'five', + chartData: [ + { + legend: 'five', + data: 11444, + total: 15000, + color: '#13a10e', + }, + ], + chartDataText: '11k/15k hours', + }, + { + chartSeriesTitle: 'six', + chartData: [ + { + legend: 'six', + data: 14000, + total: 15000, + color: '#3a96dd', + }, + ], + chartDataText: '14k/15k hours', + }, + { + chartSeriesTitle: 'seven', + chartData: [ + { + legend: 'seven', + data: 9855, + total: 15000, + color: '#ca5010', + }, + ], + chartDataText: '9.9k/15k hours', + }, + { + chartSeriesTitle: 'eight', + chartData: [ + { + legend: 'eight', + data: 4250, + total: 15000, + color: '#57811b', + }, + ], + chartDataText: '4.3k/15k hours', + }, +]; + +const chartPoints1: ChartDataPoint[] = [ + { + legend: 'Debit card numbers (EU and USA)', + data: 40, + color: '#0099BC', + }, + { + legend: 'Passport numbers (USA)', + data: 23, + color: '#77004D', + }, + { + legend: 'Social security numbers', + data: 35, + color: '#4F68ED', + }, + { + legend: 'Credit card Numbers', + data: 87, + color: '#AE8C00', + }, + { + legend: 'Tax identification numbers (USA)', + data: 87, + color: '#004E8C', + }, +]; + +const chartPoints2: ChartDataPoint[] = [ + { + legend: 'Debit card numbers (EU and USA)', + data: 40, + color: '#0099BC', + }, + { + legend: 'Passport numbers (USA)', + data: 56, + color: '#77004D', + }, + { + legend: 'Social security numbers', + data: 35, + color: '#4F68ED', + }, + { + legend: 'Credit card Numbers', + data: 92, + color: '#AE8C00', + }, + { + legend: 'Tax identification numbers (USA)', + data: 87, + color: '#004E8C', + }, +]; + +const chartPoints3: ChartDataPoint[] = [ + { + legend: 'Phone Numbers', + data: 40, + color: '#881798', + }, + { + legend: 'Credit card Numbers', + data: 23, + color: '#AE8C00', + }, +]; + +const data: ChartProps[] = [ + { + chartSeriesTitle: 'Monitored First', + chartData: chartPoints1, + }, + { + chartSeriesTitle: 'Monitored Second', + chartData: chartPoints2, + }, + { + chartSeriesTitle: 'Unmonitored', + chartData: chartPoints3, + }, +]; + +const singlePointData = [ + { + chartSeriesTitle: 'one', + chartData: [ + { + legend: 'one', + data: 1543, + total: 15000, + gradient: ['#637cef', '#e3008c'], + }, + ], + }, +]; + +const benchmarkData: ChartProps[] = [ + { + chartSeriesTitle: 'one', + chartData: [ + { + legend: 'one', + data: 10, + total: 100, + color: '#637cef', + }, + ], + benchmarkData: 50, + }, + { + chartSeriesTitle: 'two', + chartData: [ + { + legend: 'two', + data: 30, + total: 200, + color: '#e3008c', + }, + ], + benchmarkData: 30, + }, + { + chartSeriesTitle: 'three', + chartData: [ + { + legend: 'three', + data: 15, + total: 50, + color: '#2aa0a4', + }, + ], + benchmarkData: 5, + }, +]; + +const storyTemplate = html>` + +`; + +export default { + title: 'Components/HorizontalBarChart', +} as Meta; + +export const RTL: Story = renderComponent(html>` +
+
+ +
+
+`); + +export const singleDataPoint: Story = renderComponent(html< + StoryArgs +>` +
+ + +
+`); + +export const Benchmark: Story = renderComponent(html>` + + +`); + +export const singleBarNMVariant: Story = renderComponent(html< + StoryArgs +>` +
+ + +
+`); + +export const singleBarHBC: Story = renderComponent(html>` +
+ + +
+`); + +export const Basic: Story = renderComponent(storyTemplate).bind({}); diff --git a/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.styles.ts b/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.styles.ts new file mode 100644 index 00000000000000..9932537a89f26d --- /dev/null +++ b/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.styles.ts @@ -0,0 +1,190 @@ +import type { ElementStyles } from '@microsoft/fast-element'; +import { css } from '@microsoft/fast-element'; +import { + colorNeutralBackground1, + colorNeutralForeground1, + colorNeutralStrokeAccessible, + display, + forcedColorsStylesheetBehavior, + shadow4, + spacingHorizontalL, + spacingHorizontalNone, + spacingHorizontalS, + spacingHorizontalSNudge, + spacingVerticalL, + spacingVerticalM, + spacingVerticalMNudge, + spacingVerticalNone, + spacingVerticalS, + spacingVerticalXS, + strokeWidthThick, + strokeWidthThickest, + strokeWidthThin, + typographyBody1StrongStyles, + typographyBody1Styles, + typographyCaption1Styles, + typographyTitle2Styles, +} from '@fluentui/web-components'; + +/** + * Styles for the HorizontalBarChart component. + * + * @public + */ +export const styles: ElementStyles = css` + ${display('inline-block')} + + :host { + position: relative; + } + .root { + background-color: ${colorNeutralBackground1}; + width: 100vw; + display: flex; + flex-direction: column; + align-items: center; + position: relative; + } + .tooltip { + ${typographyCaption1Styles} + position: absolute; + z-index: 999; + display: grid; + overflow: hidden; + padding: ${spacingVerticalMNudge} ${spacingHorizontalL}; + backgroundcolor: ${colorNeutralBackground1}; + background-blend-mode: normal, luminosity; + text-align: center; + background: ${colorNeutralBackground1}; + box-shadow: ${shadow4}; + border: ${strokeWidthThick}; + pointer-events: none; + } + .tooltip-line { + padding-inline-start: ${spacingHorizontalS}; + height: 50px; + border-inline-start: ${strokeWidthThickest} solid; + } + .tooltip-legend-text { + ${typographyCaption1Styles} + color: ${colorNeutralForeground1}; + text-align: start; + } + .tooltip-data-y { + ${typographyTitle2Styles} + text-align: start; + } + .bar { + opacity: 1; + } + .bar.inactive { + opacity: 0.1; + } + .bar:focus { + outline: none; + stroke-width: ${strokeWidthThick}; + stroke: black; + } + .svg-chart { + display: block; + overflow: visible; + } + .chart-title { + ${typographyBody1Styles} + display: flex; + justify-content: space-between; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + display: block; + color: ${colorNeutralForeground1}; + margin-bottom: ${spacingHorizontalSNudge}; + } + .legendcontainer { + display: flex; + flex-direction: row; + flex-wrap: wrap; + padding-top: ${spacingVerticalL}; + width: 100%; + align-items: center; + margin: -${spacingVerticalS} ${spacingHorizontalNone} ${spacingVerticalNone} -${spacingHorizontalS}; + } + .legend { + display: flex; + align-items: center; + cursor: pointer; + border: none; + padding: ${spacingHorizontalS}; + background: none; + text-transform: capitalize; + } + .legend-rect { + width: 12px; + height: 12px; + margin-inline-end: ${spacingHorizontalS}; + border: ${strokeWidthThin} solid; + } + .legend-text { + ${typographyCaption1Styles} + color: ${colorNeutralForeground1}; + } + .legend.inactive .legend-rect { + background-color: transparent !important; + } + .legend.inactive .legend-text { + opacity: 0.67; + } + .bar-label { + ${typographyBody1StrongStyles} + fill: ${colorNeutralForeground1}; + } + .chart-title-div { + width: 100%; + display: flex; + justify-content: space-between; + } + .ratio-numerator { + ${typographyBody1StrongStyles} + color: ${colorNeutralForeground1}; + } + .ratio-denominator { + ${typographyBody1StrongStyles} + color: ${colorNeutralForeground1}; + font-weight: bold; + } + .benchmark-container { + position: relative; + height: 7px; + margin-top: -3px; + } + .triangle { + width: 0; + height: 0; + border-left: ${strokeWidthThickest} solid transparent; + border-right: ${strokeWidthThickest} solid transparent; + border-bottom: 7px solid; + border-bottom-color: ${colorNeutralStrokeAccessible}; + margin-bottom: ${spacingVerticalXS}; + position: absolute; + } + .chart-data-text { + ${typographyBody1StrongStyles} + color: ${colorNeutralForeground1}; + } +`.withBehaviors( + forcedColorsStylesheetBehavior(css` + .legend-rect, + .tooltip-line, + .triangle { + forced-color-adjust: none; + } + .tooltip-legend-text, + .tooltip-content-y { + forced-color-adjust: auto; + color: CanvasText; + } + .bar-label { + fill: CanvasText !important; + } + `), +); diff --git a/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.template.ts b/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.template.ts new file mode 100644 index 00000000000000..07d6656bc9be0c --- /dev/null +++ b/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.template.ts @@ -0,0 +1,66 @@ +import { ElementViewTemplate, html, ref, repeat, when } from '@microsoft/fast-element'; +import type { HorizontalBarChart } from './horizontal-bar-chart.js'; +import type { ChartDataPoint } from './horizontal-bar-chart.options.js'; + +/** + * Generates a template for the HorizontalBarChart component. + * + * @public + */ +export function horizontalbarchartTemplate(): ElementViewTemplate { + return html` + + `; +} + +/** + * @internal + */ +export const template: ElementViewTemplate = horizontalbarchartTemplate(); diff --git a/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.ts b/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.ts new file mode 100644 index 00000000000000..718c9ca5b4dcb4 --- /dev/null +++ b/packages/charts/chart-web-components/src/horizontal-bar-chart/horizontal-bar-chart.ts @@ -0,0 +1,462 @@ +import { attr, FASTElement, observable } from '@microsoft/fast-element'; +import { create as d3Create, select as d3Select } from 'd3-selection'; +import { getRTL, jsonConverter, SVG_NAMESPACE_URI, validateChartPropsArray } from '../utils/chart-helpers.js'; +import type { ChartDataPoint, ChartProps } from './horizontal-bar-chart.options.js'; +import { Variant } from './horizontal-bar-chart.options.js'; + +/** + * A Horizontal Bar Chart HTML Element. + * + * @public + */ +export class HorizontalBarChart extends FASTElement { + @attr + public variant?: Variant; + + @attr({ converter: jsonConverter }) + public data!: ChartProps[]; + + @attr({ attribute: 'hide-ratio', mode: 'boolean' }) + public hideRatio: boolean = false; + + @attr({ attribute: 'hide-legends', mode: 'boolean' }) + public hideLegends: boolean = false; + + @attr({ attribute: 'hide-tooltip', mode: 'boolean' }) + public hideTooltip: boolean = false; + + @attr({ attribute: 'legend-list-label' }) + public legendListLabel?: string; + + @attr({ attribute: 'chart-title' }) + public chartTitle?: string; + + @observable + public uniqueLegends: ChartDataPoint[] = []; + + @observable + public activeLegend: string = ''; + protected activeLegendChanged = (oldValue: string, newValue: string) => { + if (newValue === '') { + this._bars?.forEach(bar => bar.classList.remove('inactive')); + } else { + this._bars?.forEach(bar => { + if (bar.getAttribute('barinfo') === newValue) { + bar.classList.remove('inactive'); + } else { + bar.classList.add('inactive'); + } + }); + } + }; + + @observable + public isLegendSelected: boolean = false; + + @observable + public tooltipProps = { + isVisible: false, + legend: '', + yValue: '', + color: '', + xPos: 0, + yPos: 0, + }; + + public chartContainer!: HTMLDivElement; + public elementInternals: ElementInternals = this.attachInternals(); + + private _isRTL: boolean = false; + private _barHeight: number = 12; + private _bars: SVGRectElement[] = []; + + constructor() { + super(); + + this.elementInternals.role = 'region'; + } + + public handleLegendMouseoverAndFocus = (legendTitle: string) => { + if (this.isLegendSelected) { + return; + } + + this.activeLegend = legendTitle; + }; + + public handleLegendMouseoutAndBlur = () => { + if (this.isLegendSelected) { + return; + } + + this.activeLegend = ''; + }; + + public handleLegendClick = (legendTitle: string) => { + if (this.isLegendSelected && this.activeLegend === legendTitle) { + this.activeLegend = ''; + this.isLegendSelected = false; + } else { + this.activeLegend = legendTitle; + this.isLegendSelected = true; + } + }; + + connectedCallback() { + super.connectedCallback(); + + validateChartPropsArray(this.data, 'data'); + + this._isRTL = getRTL(this); + this.elementInternals.ariaLabel = this.chartTitle || `Horizontal bar chart with ${this.data.length} categories.`; + + this._initializeData(); + this._renderChart(); + } + + private _initializeData() { + if (this.variant === Variant.SingleBar) { + this._hydrateData(); + } + this._hydrateLegends(); + } + + private _renderChart() { + const chartContainerDiv = d3Select(this.chartContainer); + chartContainerDiv + .selectAll('div') + .data(this.data!) + .enter() + .append('div') + .each((d, i, nodes) => { + this._createSingleChartBars(d, i, nodes); + }); + } + + private _createSingleChartBars(singleChartData: ChartProps, index: number, nodes: any) { + const singleChartBars = this._createBarsAndLegends(singleChartData!, index); + + // create a div element. Loop through chart bars and add to the div as its children + d3Select(nodes[index]) + .attr('key', index) + .attr('id', `_MSBC_bar-${index}`) + .node()! + .appendChild(singleChartBars.node()); + } + + private _hydrateLegends() { + // Create a map to store unique legends + const uniqueLegendsMap = new Map(); + + // Iterate through all chart points and populate the map + for (const dataSeries of this.data) { + for (const point of dataSeries.chartData!) { + if ((point as any).placeholder === true) { + continue; + } + // Check if the legend is already in the map + if (!uniqueLegendsMap.has(point.legend)) { + uniqueLegendsMap.set(point.legend, { + legend: point.legend, + data: point.data, + color: point.gradient ? point.gradient[0] : point.color, + }); + } + } + } + + // Convert the map values back to an array + this.uniqueLegends = Array.from(uniqueLegendsMap.values()); + } + + private _hydrateData() { + this.data!.forEach(({ chartData }) => { + if (chartData!.length === 1) { + const pointData = chartData![0]; + const newEntry = { + legend: '', + data: Math.max(pointData.total! - pointData.data!, 0), + y: pointData.total!, + color: '#edebe9', + placeholder: true, + }; + chartData!.push(newEntry); + } + }); + } + + private _calculateBarSpacing(): number { + const svgWidth = this.getBoundingClientRect().width; + let barSpacing = 0; + const MARGIN_WIDTH_IN_PX = 3; + if (svgWidth) { + const currentBarSpacing = (MARGIN_WIDTH_IN_PX / svgWidth) * 100; + barSpacing = currentBarSpacing; + } + return barSpacing; + } + + private _createBarsAndLegends(data: ChartProps, barNo?: number) { + const _isRTL = this._isRTL; + const _computeLongestBarTotalValue = () => { + let longestBarTotalValue = 0; + this.data!.forEach(({ chartData }) => { + const barTotalValue = chartData!.reduce((acc: number, point: ChartDataPoint) => acc + (point.data ?? 0), 0); + longestBarTotalValue = Math.max(longestBarTotalValue, barTotalValue); + }); + return longestBarTotalValue; + }; + const longestBarTotalValue = _computeLongestBarTotalValue(); + const noOfBars = + data.chartData?.reduce((count: number, point: ChartDataPoint) => (count += (point.data || 0) > 0 ? 1 : 0), 0) || + 1; + const barSpacingInPercent = this._calculateBarSpacing(); + const totalMarginPercent = barSpacingInPercent * (noOfBars - 1); + // calculating starting point of each bar and it's range + const startingPoint: number[] = []; + const barTotalValue = data.chartData!.reduce((acc: number, point: ChartDataPoint) => acc + (point.data ?? 0), 0); + const total = this.variant === Variant.AbsoluteScale ? longestBarTotalValue : barTotalValue; + + let sumOfPercent = 0; + data.chartData!.map((point: ChartDataPoint, index: number) => { + const pointData = point.data ?? 0; + const currValue = (pointData / total) * 100; + let value = currValue ?? 0; + + if (value < 1 && value !== 0) { + value = 1; + } else if (value > 99 && value !== 100) { + value = 99; + } + sumOfPercent += value; + + return sumOfPercent; + }); + + // Include an imaginary placeholder bar with value equal to + // the difference between longestBarTotalValue and barTotalValue + // while calculating sumOfPercent to get correct scalingRatio for absolute-scale variant + if (this.variant === Variant.AbsoluteScale) { + let value = total === 0 ? 0 : ((total - barTotalValue) / total) * 100; + if (value < 1 && value !== 0) { + value = 1; + } else if (value > 99 && value !== 100) { + value = 99; + } + sumOfPercent += value; + } + + /** + * The %age of the space occupied by the margin needs to subtracted + * while computing the scaling ratio, since the margins are not being + * scaled down, only the data is being scaled down from a higher percentage to lower percentage + * Eg: 95% of the space is taken by the bars, 5% by the margins + * Now if the sumOfPercent is 120% -> This needs to be scaled down to 95%, not 100% + * since that's only space available to the bars + */ + + const scalingRatio = sumOfPercent !== 0 ? sumOfPercent / (100 - totalMarginPercent) : 1; + + let prevPosition = 0; + let value = 0; + + const createBars = (g: SVGGElement, point: ChartDataPoint, index: number) => { + const barHeight = 12; + const pointData = point.data ?? 0; + if (index > 0) { + prevPosition += value; + } + value = (pointData / total) * 100 ? (pointData / total) * 100 : 0; + if (value < 1 && value !== 0) { + value = 1 / scalingRatio; + } else if (value > 99 && value !== 100) { + value = 99 / scalingRatio; + } else { + value = value / scalingRatio; + } + + startingPoint.push(prevPosition); + + const gEle = d3Select(g) // 'this' refers to the current 'g' element + .attr('key', index) + .attr('role', 'img') + .attr('aria-label', pointData); + + let gradientId = ''; + if (point.gradient) { + const defs = document.createElementNS(SVG_NAMESPACE_URI, 'defs'); + gEle.node()!.appendChild(defs); + + const linearGradient = document.createElementNS(SVG_NAMESPACE_URI, 'linearGradient'); + defs.appendChild(linearGradient); + gradientId = `gradient-${barNo}-${index}`; + linearGradient.setAttribute('id', gradientId); + + const stop1 = document.createElementNS(SVG_NAMESPACE_URI, 'stop'); + linearGradient.appendChild(stop1); + stop1.setAttribute('offset', '0%'); + stop1.setAttribute('stop-color', point.gradient[0]); + + const stop2 = document.createElementNS(SVG_NAMESPACE_URI, 'stop'); + linearGradient.appendChild(stop2); + stop2.setAttribute('offset', '100%'); + stop2.setAttribute('stop-color', point.gradient[1]); + } + + const rect = gEle + .append('rect') + .attr('key', index) + .attr('id', `${barNo}-${index}`) + .attr('barinfo', `${point.legend}`) + .attr('class', 'bar') + .attr('style', point.gradient ? `fill:url(#${gradientId})` : `fill:${point.color!}`) + .attr( + 'x', + `${ + _isRTL + ? 100 - startingPoint[index] - value - barSpacingInPercent * index + : startingPoint[index] + barSpacingInPercent * index + }%`, + ) + .attr('y', 0) + .attr('width', value + '%') + .attr('height', barHeight) + .attr('tabindex', 0); + this._bars.push(rect.node()!); + }; + + const containerDiv = d3Create('div').attr('style', 'position: relative'); + + const chartTitleDiv = containerDiv.append('div').attr('class', 'chart-title-div'); + chartTitleDiv + .append('div') + .append('span') + .attr('class', 'chart-title') + .text(data?.chartSeriesTitle ? data?.chartSeriesTitle : ''); + + const showChartDataText = this.variant !== Variant.AbsoluteScale; + // chartData length is always 2 in single-bar variant + const showRatio = !this.hideRatio && data!.chartData!.length === 2; + const getChartData = () => data!.chartData![0].data ?? 0; + + if (showChartDataText) { + if (data.chartDataText) { + const chartTitleRight = document.createElement('div'); + chartTitleDiv.node()!.appendChild(chartTitleRight); + chartTitleRight.classList.add('chart-data-text'); + chartTitleRight.textContent = data.chartDataText; + } else if (showRatio) { + const ratioDiv = chartTitleDiv.append('div').attr('role', 'text'); + const numData = data!.chartData![0].data; + const denomData = data!.chartData![1].data; + const total = numData! + denomData!; + ratioDiv.append('span').attr('class', 'ratio-numerator').text(numData!); + ratioDiv.append('span').attr('class', 'ratio-denominator').text(`/${total!}`); + } + } + + const svgDiv = containerDiv.append('div').attr('style', 'display: flex;'); + const svgEle = svgDiv + .append('svg') + .attr('height', 12) + .attr('width', 100 + '%') + .attr('class', 'svg-chart') + .attr( + 'aria-label', + data?.chartSeriesTitle ?? + `Series with ${data.chartData.length}${data.chartData.length > 1 ? ' stacked' : ''} bars.`, + ) + .selectAll('g') + .data(data.chartData!) + .enter() + .append('g') + .each(function (this, d, i) { + createBars(this, d, i); + }) + .on('mouseover', (event, d) => { + if (d && d.hasOwnProperty('placeholder') && (d as any).placeholder === true) { + return; + } + + const bounds = this.getBoundingClientRect(); + const centerX = window.innerWidth / 2; + const xPos = Math.max(0, Math.min(centerX, window.innerWidth)); + + this.tooltipProps = { + isVisible: true, + legend: d.legend, + yValue: `${d.data}`, + color: d.gradient ? d.gradient[0] : d.color!, + xPos: this._isRTL ? bounds.right - event.clientX : Math.min(event.clientX - bounds.left, xPos), + yPos: event.clientY - bounds.top - 40, + }; + }) + .on('mouseout', () => { + this.tooltipProps = { isVisible: false, legend: '', yValue: '', color: '', xPos: 0, yPos: 0 }; + }); + + if (this.variant === Variant.AbsoluteScale) { + const showLabel = true; + const barLabel = barTotalValue; + if (showLabel) { + if (Math.round((startingPoint[startingPoint.length - 1] || 0) + value + totalMarginPercent) === 100) { + svgDiv + .append('text') + .attr('key', 'text') + .attr('style', 'margin-top: -4.5px; margin-left: 2px;') + .attr('class', 'bar-label') + .attr( + 'x', + `${ + this._isRTL + ? 100 - (startingPoint[startingPoint.length - 1] || 0) - value - totalMarginPercent + : (startingPoint[startingPoint.length - 1] || 0) + value + totalMarginPercent + }%`, + ) + .attr('textAnchor', 'start') + .attr('y', this._barHeight / 2 + 6) + .attr('dominantBaseline', 'central') + .attr('transform', `translate(${this._isRTL ? -4 : 4})`) + .attr('aria-label', `Total: ${barLabel}`) + .attr('role', 'img') + .text(barLabel); + } else { + svgEle + .append('text') + .attr('key', 'text') + .attr('class', 'bar-label') + .attr( + 'x', + `${ + this._isRTL + ? 100 - (startingPoint[startingPoint.length - 1] || 0) - value - totalMarginPercent + : (startingPoint[startingPoint.length - 1] || 0) + value + totalMarginPercent + }%`, + ) + .attr('textAnchor', 'start') + .attr('y', this._barHeight / 2 + 6) + .attr('dominantBaseline', 'central') + .attr('transform', `translate(${this._isRTL ? -4 : 4})`) + .attr('aria-label', `Total: ${barLabel}`) + .attr('role', 'img') + .text(barLabel); + } + } + } + + if (data.benchmarkData) { + const benchmarkContainer = document.createElement('div'); + containerDiv.node()!.appendChild(benchmarkContainer); + benchmarkContainer.classList.add('benchmark-container'); + + const triangle = document.createElement('div'); + benchmarkContainer.appendChild(triangle); + triangle.classList.add('triangle'); + + const benchmarkRatio = (data.benchmarkData / total) * 100; + triangle.style['insetInlineStart'] = `calc(${benchmarkRatio}% - 4px)`; + } + + return containerDiv; + } +} diff --git a/packages/charts/chart-web-components/src/horizontal-bar-chart/index.ts b/packages/charts/chart-web-components/src/horizontal-bar-chart/index.ts new file mode 100644 index 00000000000000..0695516e7dce49 --- /dev/null +++ b/packages/charts/chart-web-components/src/horizontal-bar-chart/index.ts @@ -0,0 +1,4 @@ +export { definition as HorizontalBarChartDefinition } from './horizontal-bar-chart.definition.js'; +export { HorizontalBarChart } from './horizontal-bar-chart.js'; +export { styles as HorizontalBarChartStyles } from './horizontal-bar-chart.styles.js'; +export { template as HorizontalBarChartTemplate } from './horizontal-bar-chart.template.js'; diff --git a/packages/charts/chart-web-components/src/index-rollup.ts b/packages/charts/chart-web-components/src/index-rollup.ts new file mode 100644 index 00000000000000..8726e6a32d0f9e --- /dev/null +++ b/packages/charts/chart-web-components/src/index-rollup.ts @@ -0,0 +1,2 @@ +import './horizontal-bar-chart/define.js'; +import './donut-chart/define.js'; diff --git a/packages/charts/chart-web-components/src/index.ts b/packages/charts/chart-web-components/src/index.ts new file mode 100644 index 00000000000000..9dcd14f29327dc --- /dev/null +++ b/packages/charts/chart-web-components/src/index.ts @@ -0,0 +1,7 @@ +export { + HorizontalBarChart, + HorizontalBarChartDefinition, + HorizontalBarChartStyles, + HorizontalBarChartTemplate, +} from './horizontal-bar-chart/index.js'; +export { DonutChart, DonutChartDefinition, DonutChartStyles, DonutChartTemplate } from './donut-chart/index.js'; diff --git a/packages/charts/chart-web-components/src/utils/benchmark-wrapper.ts b/packages/charts/chart-web-components/src/utils/benchmark-wrapper.ts new file mode 100644 index 00000000000000..3b1807cbff920f --- /dev/null +++ b/packages/charts/chart-web-components/src/utils/benchmark-wrapper.ts @@ -0,0 +1,22 @@ +// eslint-disable-next-line +// @ts-nocheck +import { tests } from '@tensile-perf/web-components'; +import { webLightTheme } from '@fluentui/tokens'; +import { setTheme } from '@fluentui/web-components'; + +const testWrapper = (test: any, args: any) => { + setTheme(webLightTheme); + return test(args); +}; + +const wrappedTests = {}; + +for (const testName of Object.keys(tests)) { + const test = tests[testName]; + + wrappedTests[testName] = (args: any) => { + return testWrapper(test, args); + }; +} + +export { wrappedTests as tests }; diff --git a/packages/charts/chart-web-components/src/utils/chart-helpers.ts b/packages/charts/chart-web-components/src/utils/chart-helpers.ts new file mode 100644 index 00000000000000..45f9ecdb56dd5f --- /dev/null +++ b/packages/charts/chart-web-components/src/utils/chart-helpers.ts @@ -0,0 +1,193 @@ +import type { ValueConverter } from '@microsoft/fast-element'; +import { Direction } from '@microsoft/fast-web-utilities'; +import { getDirection } from '@fluentui/web-components'; + +export const jsonConverter: ValueConverter = { + toView(value: any): string { + return JSON.stringify(value); + }, + fromView(value: string): any { + return JSON.parse(value); + }, +}; + +type Dict = { [key: string]: any }; + +export const validateChartPropsArray = (obj: any, objName: string) => { + if (!Array.isArray(obj)) { + throw TypeError(`Invalid ${objName}: Expected an array.`); + } + + obj.forEach((item, idx) => { + validateChartProps(item, `${objName}[${idx}]`); + }); +}; + +export const validateChartProps = (obj: any, objName: string) => { + if (obj === null || typeof obj !== 'object' || Array.isArray(obj)) { + throw TypeError(`Invalid ${objName}: Expected an object.`); + } + + if (!Array.isArray(obj.chartData)) { + throw TypeError(`Invalid ${objName}.chartData: Expected an array.`); + } + + (obj.chartData as any[]).forEach((item, idx) => { + if (item === null || typeof item !== 'object' || Array.isArray(item)) { + throw TypeError(`Invalid ${objName}.chartData[${idx}]: Expected an object.`); + } + + if (typeof item.legend !== 'string') { + throw TypeError(`Invalid ${objName}.chartData[${idx}].legend: Expected a string.`); + } + + if (typeof item.data !== 'number') { + throw TypeError(`Invalid ${objName}.chartData[${idx}].data: Expected a number.`); + } + }); +}; + +export const DataVizPalette = { + color1: 'qualitative.1', + color2: 'qualitative.2', + color3: 'qualitative.3', + color4: 'qualitative.4', + color5: 'qualitative.5', + color6: 'qualitative.6', + color7: 'qualitative.7', + color8: 'qualitative.8', + color9: 'qualitative.9', + color10: 'qualitative.10', + color11: 'qualitative.21', + color12: 'qualitative.22', + color13: 'qualitative.23', + color14: 'qualitative.24', + color15: 'qualitative.25', + color16: 'qualitative.26', + color17: 'qualitative.27', + color18: 'qualitative.28', + color19: 'qualitative.29', + info: 'semantic.info', + disabled: 'semantic.disabled', + highError: 'semantic.highError', + error: 'semantic.error', + warning: 'semantic.warning', + success: 'semantic.success', + highSuccess: 'semantic.highSuccess', +}; + +/** + * Key: Color code. + * Value: + * Index 0 - Default color / Color for light theme, + * Index 1 - Color for dark theme + */ +type Palette = { [key: string]: string[] }; + +const QualitativePalette: Palette = { + '1': ['#637cef'], // [cornflower.tint10], + '2': ['#e3008c'], // [hotPink.primary], + '3': ['#2aa0a4'], // [teal.tint20], + '4': ['#9373c0'], // [orchid.tint10], + '5': ['#13a10e'], // [lightGreen.primary], + '6': ['#3a96dd'], // [lightBlue.primary], + '7': ['#ca5010'], // [pumpkin.primary], + '8': ['#57811b'], // [lime.shade20], + '9': ['#b146c2'], // [lilac.primary], + '10': ['#ae8c00'], // [gold.shade10], + '21': ['#4f6bed'], // [cornflower.primary], + '22': ['#ea38a6'], // [hotPink.tint20], + '23': ['#038387'], // [teal.primary], + '24': ['#8764b8'], // [orchid.primary], + '25': ['#11910d'], // [lightGreen.shade10], + '26': ['#3487c7'], // [lightBlue.shade10], + '27': ['#d06228'], // [pumpkin.tint10], + '28': ['#689920'], // [lime.shade10], + '29': ['#ba58c9'], // [lilac.tint10], +}; + +const SemanticPalette: Palette = { + info: ['#015cda'], + disabled: ['#dbdbdb', '#4d4d4d'], // [grey[86], grey[30]] + highError: ['#6e0811', '#cc2635'], // [cranberry.shade30, cranberry.tint10], + error: ['#c50f1f', '#dc626d'], // [cranberry.primary, cranberry.tint30], + warning: ['#f7630c', '#f87528'], // [orange.primary, orange.tint10], + success: ['#107c10', '#54b054'], // [green.primary, green.tint30], + highSuccess: ['#094509', '#218c21'], // [green.shade30, green.tint10], +}; + +const Colors: { [key: string]: Palette } = { + qualitative: QualitativePalette, + semantic: SemanticPalette, +}; + +const QUALITATIVE_COLORS = Object.values(QualitativePalette); +const TOKENS = Object.values(DataVizPalette); + +const getThemeSpecificColor = (colors: string[], isDarkTheme: boolean): string => { + if (colors.length === 0) { + return ''; + } + const colorIdx = Number(isDarkTheme); + if (colorIdx < colors.length) { + return colors[colorIdx]; + } + return colors[0]; +}; + +export const getNextColor = (index: number, offset: number = 0, isDarkTheme: boolean = false): string => { + const colors = QUALITATIVE_COLORS[(index + offset) % QUALITATIVE_COLORS.length]; + return getThemeSpecificColor(colors, isDarkTheme); +}; + +export const getColorFromToken = (token: string, isDarkTheme: boolean = false): string => { + if (TOKENS.indexOf(token) >= 0) { + const [paletteName, colorCode] = token.split('.'); + const colors = Colors[paletteName][colorCode]; + return getThemeSpecificColor(colors, isDarkTheme); + } + return token; +}; + +export const getRTL = (rootNode: HTMLElement): boolean => { + return getDirection(rootNode) === Direction.rtl; +}; + +export const SVG_NAMESPACE_URI = 'http://www.w3.org/2000/svg'; + +export const wrapText = (text: SVGTextElement, width: number) => { + if (!text.textContent) { + return; + } + + const words = text.textContent.split(/\s+/).reverse(); + let word: string | undefined; + let line: string[] = []; + let lineNumber = 0; + const lineHeight = text.getBoundingClientRect().height; + const y = text.getAttribute('y') || '0'; + + text.textContent = null; + + let tspan = document.createElementNS(SVG_NAMESPACE_URI, 'tspan'); + text.appendChild(tspan); + tspan.setAttribute('x', '0'); + tspan.setAttribute('y', y); + tspan.setAttribute('dy', `${lineNumber++ * lineHeight}`); + + while ((word = words.pop())) { + line.push(word); + tspan.textContent = line.join(' ') + ' '; + if (tspan.getComputedTextLength() > width && line.length > 1) { + line.pop(); + tspan.textContent = line.join(' ') + ' '; + line = [word]; + tspan = document.createElementNS(SVG_NAMESPACE_URI, 'tspan'); + text.appendChild(tspan); + tspan.setAttribute('x', '0'); + tspan.setAttribute('y', y); + tspan.setAttribute('dy', `${lineNumber++ * lineHeight}`); + tspan.textContent = word; + } + } +}; diff --git a/packages/charts/chart-web-components/tensile.config.js b/packages/charts/chart-web-components/tensile.config.js new file mode 100644 index 00000000000000..f73bbfb19cdd4d --- /dev/null +++ b/packages/charts/chart-web-components/tensile.config.js @@ -0,0 +1,25 @@ +/** + * This config should be shared for all web-component packages. + * Tracking issue - https://github.com/microsoft/fluentui/issues/33576 + */ + +const config = { + // Browsers to test against + browsers: ['chrome'], + + // Importmaps for your test. + // See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap + imports: { + '@tensile-perf/web-components': '/node_modules/@tensile-perf/web-components/lib/index.js', + '@microsoft/fast-element': '/node_modules/@microsoft/fast-element/dist/fast-element.min.js', + '@microsoft/fast-element/utilities.js': '/node_modules/@microsoft/fast-element/dist/esm/utilities.js', + '@microsoft/fast-web-utilities': '/node_modules/@microsoft/fast-web-utilities/dist/index.js', + '@fluentui/tokens': '/tensile-assets/benchmark-dependencies/tokens.js', + '@fluentui/web-components': '/node_modules/@fluentui/web-components/dist/esm/index.js', + 'exenv-es6': '/node_modules/exenv-es6/dist/index.js', + tabbable: '/node_modules/tabbable/dist/index.esm.js', + tslib: '/node_modules/tslib/tslib.es6.js', + }, +}; + +export default config; diff --git a/packages/charts/chart-web-components/tsconfig.api-extractor.json b/packages/charts/chart-web-components/tsconfig.api-extractor.json new file mode 100644 index 00000000000000..e245193e1fb3db --- /dev/null +++ b/packages/charts/chart-web-components/tsconfig.api-extractor.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.lib.json", + "compilerOptions": { + "paths": null, + "baseUrl": "." + } +} diff --git a/packages/charts/chart-web-components/tsconfig.json b/packages/charts/chart-web-components/tsconfig.json new file mode 100644 index 00000000000000..7c023fa3b63590 --- /dev/null +++ b/packages/charts/chart-web-components/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../../../tsconfig.base.wc.json", + "compilerOptions": { + "target": "ES2019", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "experimentalDecorators": true, + "allowJs": true + }, + "files": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./.storybook/tsconfig.json" + } + ] +} diff --git a/packages/charts/chart-web-components/tsconfig.lib.json b/packages/charts/chart-web-components/tsconfig.lib.json new file mode 100644 index 00000000000000..a9ffdf43596828 --- /dev/null +++ b/packages/charts/chart-web-components/tsconfig.lib.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "target": "ES2019", + "module": "NodeNext", + "lib": ["ESNext", "DOM"], + "declaration": true, + "declarationDir": "dist/dts", + "outDir": "dist/esm", + "importHelpers": true + }, + "include": ["src"], + "exclude": ["**/*.stories.*", "**/*.test.*", "**/*.spec.*"] +} diff --git a/packages/charts/chart-web-components/tsconfig.spec.json b/packages/charts/chart-web-components/tsconfig.spec.json new file mode 100644 index 00000000000000..d9bed36588029a --- /dev/null +++ b/packages/charts/chart-web-components/tsconfig.spec.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "NodeNext", + "outDir": "dist/esm", + "types": ["node"] + }, + "include": ["src/**/*.test.*", "src/**/*.spec.*"] +} diff --git a/packages/charts/chart-web-components/tsdoc.json b/packages/charts/chart-web-components/tsdoc.json new file mode 100644 index 00000000000000..0c30fee865df6f --- /dev/null +++ b/packages/charts/chart-web-components/tsdoc.json @@ -0,0 +1,44 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", + "extends": ["@microsoft/api-extractor/extends/tsdoc-base.json"], + "tagDefinitions": [ + { + "tagName": "@slot", + "syntaxKind": "block", + "allowMultiple": true + }, + { + "tagName": "@csspart", + "syntaxKind": "block", + "allowMultiple": true + }, + { + "tagName": "@cssprop", + "syntaxKind": "block", + "allowMultiple": true + }, + { + "tagName": "@cssproperty", + "syntaxKind": "block", + "allowMultiple": true + }, + { + "tagName": "@event", + "syntaxKind": "block", + "allowMultiple": true + }, + { + "tagName": "@fires", + "syntaxKind": "block", + "allowMultiple": true + } + ], + "supportForTags": { + "@slot": true, + "@csspart": true, + "@cssprop": true, + "@cssproperty": true, + "@event": true, + "@fires": true + } +} diff --git a/packages/charts/react-charting/.npmignore b/packages/charts/react-charting/.npmignore index 0cee33274447a8..1f0d2c1f537e77 100644 --- a/packages/charts/react-charting/.npmignore +++ b/packages/charts/react-charting/.npmignore @@ -38,3 +38,4 @@ visualtests !dist docs test-data.ts +src/components/DeclatativeChart/tests/schema diff --git a/packages/charts/react-charting/CHANGELOG.json b/packages/charts/react-charting/CHANGELOG.json index 08df9131eaff16..cfb026f550367b 100644 --- a/packages/charts/react-charting/CHANGELOG.json +++ b/packages/charts/react-charting/CHANGELOG.json @@ -1,6 +1,831 @@ { "name": "@fluentui/react-charting", "entries": [ + { + "date": "Fri, 21 Feb 2025 07:22:41 GMT", + "tag": "@fluentui/react-charting_v5.23.56", + "version": "5.23.56", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/react-focus to v8.9.21", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/theme-samples to v8.7.200", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/set-version to v8.2.24", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/react to v8.122.11", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + } + ] + } + }, + { + "date": "Wed, 19 Feb 2025 07:21:16 GMT", + "tag": "@fluentui/react-charting_v5.23.55", + "version": "5.23.55", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/theme-samples to v8.7.199", + "commit": "8264ce0435583ae69c051f109388005be3c0de2b" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/react to v8.122.10", + "commit": "8264ce0435583ae69c051f109388005be3c0de2b" + } + ] + } + }, + { + "date": "Thu, 13 Feb 2025 07:22:18 GMT", + "tag": "@fluentui/react-charting_v5.23.54", + "version": "5.23.54", + "comments": { + "patch": [ + { + "author": "110246001+krkshitij@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "f9427b8df618f765dbf233c601060a7e123444d0", + "comment": "feat: hide overlapping x-axis tick labels" + } + ] + } + }, + { + "date": "Wed, 12 Feb 2025 07:20:51 GMT", + "tag": "@fluentui/react-charting_v5.23.53", + "version": "5.23.53", + "comments": { + "none": [ + { + "author": "martinhochel@microsoft.com", + "package": "@fluentui/react-charting", + "commit": "5b5091795bd462fe78f1545fd91b21ef6510a45d", + "comment": "chore: add new 'charting' domain tag" + } + ], + "patch": [ + { + "author": "120183316+srmukher@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "90aca06e2500c9dda895c2a220923baf2a602297", + "comment": "fix(react-charting):Fixing error in donut chart" + } + ] + } + }, + { + "date": "Tue, 11 Feb 2025 07:21:12 GMT", + "tag": "@fluentui/react-charting_v5.23.52", + "version": "5.23.52", + "comments": { + "patch": [ + { + "author": "74965306+Anush2303@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "9e72d59c8bea571e3f05e544015de8b0386f4486", + "comment": "fix plotlyAdapterUT cases" + }, + { + "author": "120183316+srmukher@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "f45bd1071de1e3a8aa9c7177438e2559498b7920", + "comment": "Making the tooltip optional" + }, + { + "author": "74965306+Anush2303@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "74464afb1de05f56bd72826b327be0389a4b9818", + "comment": "Heatmap black color fix" + } + ] + } + }, + { + "date": "Wed, 05 Feb 2025 07:16:29 GMT", + "tag": "@fluentui/react-charting_v5.23.51", + "version": "5.23.51", + "comments": { + "patch": [ + { + "author": "120183316+srmukher@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "5f1fb069b5da9c7a104063184eacce1927c06f7c", + "comment": "fix(react-charting): Fixed tooltip position and background on Gauge and Pie charts" + } + ] + } + }, + { + "date": "Fri, 31 Jan 2025 07:21:30 GMT", + "tag": "@fluentui/react-charting_v5.23.50", + "version": "5.23.50", + "comments": { + "patch": [ + { + "author": "120183316+srmukher@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "5a9a15f090aa7d01d5dc2f83ef7d22f91390eed2", + "comment": "Adding transform prop to svg rect" + } + ] + } + }, + { + "date": "Thu, 30 Jan 2025 07:20:49 GMT", + "tag": "@fluentui/react-charting_v5.23.49", + "version": "5.23.49", + "comments": { + "patch": [ + { + "author": "74965306+Anush2303@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "669de2d2ef02d7d455ab968e812f7cf6baf7ec28", + "comment": "Support rounded ticks in declarative charts" + }, + { + "author": "120183316+srmukher@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "fa5549e7d9da4865ac079c8c7b284106813a7e82", + "comment": "Add background to the SVGTooltipText" + }, + { + "author": "74965306+Anush2303@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "82cc27f5d68ca2fa30d906cd50889771e7a18ba8", + "comment": "Fix chart crashes of plotly examples" + } + ] + } + }, + { + "date": "Wed, 29 Jan 2025 07:21:15 GMT", + "tag": "@fluentui/react-charting_v5.23.48", + "version": "5.23.48", + "comments": { + "patch": [ + { + "author": "110246001+krkshitij@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "111bf937b3793db68e32a90774b04f3bf61f4be5", + "comment": "fix: use inline styles in SVG export for better compatibility" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/theme-samples to v8.7.198", + "commit": "111bf937b3793db68e32a90774b04f3bf61f4be5" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/react to v8.122.9", + "commit": "111bf937b3793db68e32a90774b04f3bf61f4be5" + } + ] + } + }, + { + "date": "Mon, 27 Jan 2025 07:20:35 GMT", + "tag": "@fluentui/react-charting_v5.23.47", + "version": "5.23.47", + "comments": { + "patch": [ + { + "author": "74965306+Anush2303@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "ab504b182ef3b6c7594fce9aa91948dac8332dd5", + "comment": "Fix Duplicate keys warning" + }, + { + "author": "110246001+krkshitij@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "57165f4aa96f1417347275e52262f6de755225d5", + "comment": "fix: ensure text elements use the correct font-family in SVG export" + } + ] + } + }, + { + "date": "Fri, 24 Jan 2025 07:20:37 GMT", + "tag": "@fluentui/react-charting_v5.23.46", + "version": "5.23.46", + "comments": { + "patch": [ + { + "author": "74965306+Anush2303@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "0cca67396f110239e39d8cc5de96c9b128ca07de", + "comment": "Centre align gauge chart" + } + ] + } + }, + { + "date": "Thu, 23 Jan 2025 07:21:31 GMT", + "tag": "@fluentui/react-charting_v5.23.45", + "version": "5.23.45", + "comments": { + "patch": [ + { + "author": "74965306+Anush2303@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "82ef8b9000a1223756a4253aacde35fe4eaea401", + "comment": "Support for dashed and dotted line in Declarative chart" + }, + { + "author": "74965306+Anush2303@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "af631b94cfaa3e9a9d79160236a7f0679240777b", + "comment": "Heatmap text color based on contrast ratio" + } + ] + } + }, + { + "date": "Wed, 22 Jan 2025 07:21:49 GMT", + "tag": "@fluentui/react-charting_v5.23.44", + "version": "5.23.44", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/theme-samples to v8.7.197", + "commit": "012298d98651800023aac24c591831e9bc51bea2" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/react to v8.122.8", + "commit": "012298d98651800023aac24c591831e9bc51bea2" + } + ] + } + }, + { + "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", + "version": "5.23.40", + "comments": { + "patch": [ + { + "author": "110246001+krkshitij@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "90ccf40771d9d992b824b52e33fe750a67eda097", + "comment": "feat: center align bars with auto barWidth in plotly mode" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/theme-samples to v8.7.195", + "commit": "bf60a56cb23b3af90bcb62462c2423468eb9fa3c" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/react to v8.122.6", + "commit": "bf60a56cb23b3af90bcb62462c2423468eb9fa3c" + } + ] + } + }, + { + "date": "Wed, 08 Jan 2025 07:21:37 GMT", + "tag": "@fluentui/react-charting_v5.23.39", + "version": "5.23.39", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/theme-samples to v8.7.194", + "commit": "8f763922d713d9ccd35e65db07206c10b170fafd" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/react to v8.122.5", + "commit": "8f763922d713d9ccd35e65db07206c10b170fafd" + } + ] + } + }, + { + "date": "Mon, 06 Jan 2025 07:16:33 GMT", + "tag": "@fluentui/react-charting_v5.23.38", + "version": "5.23.38", + "comments": { + "patch": [ + { + "author": "120183316+srmukher@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "4a38a00cf1396e755104635cca027b62c59ae224", + "comment": "Enabling titles for x and y axes for Declarative charts" + } + ], + "none": [ + { + "author": "132879294+v-baambati@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "ab40feaff6ddc0c75161cc69c849f6b372c1d016", + "comment": "Added test cases to declartive chart examples" + } + ] + } + }, + { + "date": "Fri, 03 Jan 2025 07:21:32 GMT", + "tag": "@fluentui/react-charting_v5.23.37", + "version": "5.23.37", + "comments": { + "patch": [ + { + "author": "74965306+Anush2303@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "0b5ff6e25513a28011ba742c0c479056fcecf68b", + "comment": "Gauge and Pie chart fixes" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/theme-samples to v8.7.193", + "commit": "7bb97f178d73a470dc438a2b19d165d9d0bd4b51" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/react to v8.122.4", + "commit": "7bb97f178d73a470dc438a2b19d165d9d0bd4b51" + } + ] + } + }, + { + "date": "Thu, 02 Jan 2025 07:22:03 GMT", + "tag": "@fluentui/react-charting_v5.23.36", + "version": "5.23.36", + "comments": { + "patch": [ + { + "author": "kumarkshitij@microsoft.com", + "package": "@fluentui/react-charting", + "commit": "6bd14a98fb5bec1eb26dfbada654fc1588249fa8", + "comment": "fix: resolve css variables in svg image data" + } + ] + } + }, + { + "date": "Wed, 01 Jan 2025 07:21:09 GMT", + "tag": "@fluentui/react-charting_v5.23.35", + "version": "5.23.35", + "comments": { + "patch": [ + { + "author": "74965306+Anush2303@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "bf1b91f1fd3cfb580185870b6a4b77738384f9d2", + "comment": "HeatMap chart bug fixes" + }, + { + "author": "120183316+srmukher@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "db1eb859113249615f1de99d409d330231761420", + "comment": "Initialization of state variables and updating for HorizontalBarChartWithAxis chart" + } + ] + } + }, + { + "date": "Tue, 31 Dec 2024 07:21:44 GMT", + "tag": "@fluentui/react-charting_v5.23.34", + "version": "5.23.34", + "comments": { + "patch": [ + { + "author": "120183316+srmukher@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "98e409211ed673c877e45bbff7ccc08a1ccd34de", + "comment": "[Horizontal Bar Chart With Axis] Enable multiple legend selection" + }, + { + "author": "120183316+srmukher@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "d61ac31da90bf8f73f54262e196b3a83b9a85932", + "comment": "[Gauge Chart] Enabling legend multi selection" + } + ] + } + }, + { + "date": "Mon, 30 Dec 2024 07:21:28 GMT", + "tag": "@fluentui/react-charting_v5.23.33", + "version": "5.23.33", + "comments": { + "patch": [ + { + "author": "120183316+srmukher@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "a2f70fd8119df5fe5c255d8e23d9b11e589168ad", + "comment": "[Area Chart] Support legend multi selection [Area Chart] Support legend multi selection" + }, + { + "author": "120183316+srmukher@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "fc4f676790e169455da7391a45f086f76abc19a3", + "comment": "Select multiple legends for Vertical bar chart" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/theme-samples to v8.7.192", + "commit": "681a95a732fe385a70b8d4537dc489acbcd1c21e" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/react to v8.122.3", + "commit": "681a95a732fe385a70b8d4537dc489acbcd1c21e" + } + ] + } + }, + { + "date": "Fri, 27 Dec 2024 07:20:57 GMT", + "tag": "@fluentui/react-charting_v5.23.32", + "version": "5.23.32", + "comments": { + "patch": [ + { + "author": "atishay.jain@microsoft.com", + "package": "@fluentui/react-charting", + "commit": "6a70a11ddb8bac592c4c9b4c12a2705a9ace6686", + "comment": "Support changing legends programatically at runtime and bug fixes" + }, + { + "author": "74965306+Anush2303@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "3e4cc988ffaad3f5e7b0cfa30fb4ba792a0e01c9", + "comment": "Full Yaxis labels in HeatMap chart" + }, + { + "author": "120183316+srmukher@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "864f029751937946ae89425120483d58f2d0875a", + "comment": "Support for multiple legend selection for Vertical Stacked Bar Chart " + }, + { + "author": "74965306+Anush2303@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "99cbe5c9cc9c298d78e10301b37d314b68ba8c52", + "comment": "plotly examples bug fixes" + }, + { + "author": "120183316+srmukher@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "37e5f0bc0cfef1a57d9bd9659217c0ccaabf1030", + "comment": "Enabling multiple legend selection for Grouped Vertical Bar Chart" + } + ] + } + }, + { + "date": "Thu, 26 Dec 2024 07:21:14 GMT", + "tag": "@fluentui/react-charting_v5.23.31", + "version": "5.23.31", + "comments": { + "patch": [ + { + "author": "110246001+krkshitij@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "0dd9a713b54a6d5b5929ac7febd1c7e44c83efca", + "comment": "fix: remove duplicate legends in vertical bar chart" + } + ] + } + }, + { + "date": "Wed, 25 Dec 2024 07:21:55 GMT", + "tag": "@fluentui/react-charting_v5.23.30", + "version": "5.23.30", + "comments": { + "patch": [ + { + "author": "120183316+srmukher@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "fa08fec97a5bc070e2866633c792f7066f0c86e8", + "comment": "Legends multi selection for Donut Charts" + } + ] + } + }, + { + "date": "Mon, 23 Dec 2024 07:22:57 GMT", + "tag": "@fluentui/react-charting_v5.23.29", + "version": "5.23.29", + "comments": { + "patch": [ + { + "author": "110246001+krkshitij@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee", + "comment": "feat: add functionality to export chart as image" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/react-focus to v8.9.20", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/theme-samples to v8.7.191", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/react to v8.122.2", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + } + ] + } + }, + { + "date": "Fri, 20 Dec 2024 07:20:00 GMT", + "tag": "@fluentui/react-charting_v5.23.28", + "version": "5.23.28", + "comments": { + "patch": [ + { + "author": "74965306+Anush2303@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "da882f44f251e7bb80fb969cbe268a942a2df74e", + "comment": "Ensure type safety of dependent fields" + } + ] + } + }, + { + "date": "Wed, 18 Dec 2024 07:20:30 GMT", + "tag": "@fluentui/react-charting_v5.23.27", + "version": "5.23.27", + "comments": { + "patch": [ + { + "author": "74965306+Anush2303@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "870fdfd57db59eb0c549c6c12645fc50130970a4", + "comment": "Enabled Multi Select behaviour of Controlled legends" + }, + { + "author": "120183316+srmukher@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "835c01b1fd7bcdf86d28f95963950e0e5285319c", + "comment": "Mode check for declarative area chart " + } + ] + } + }, + { + "date": "Tue, 17 Dec 2024 07:21:19 GMT", + "tag": "@fluentui/react-charting_v5.23.26", + "version": "5.23.26", + "comments": { + "patch": [ + { + "author": "98592573+AtishayMsft@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "4487ca6a37b19e06ed494e819805c1abfb8c7afa", + "comment": "Add support for controlling legend selection and persisting in json schema" + }, + { + "author": "74965306+Anush2303@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "7b75871739a0639fffc065d649848a356baf1d26", + "comment": "Enable Controlled Legends working in declarative HBC" + } + ] + } + }, + { + "date": "Mon, 16 Dec 2024 07:20:45 GMT", + "tag": "@fluentui/react-charting_v5.23.25", + "version": "5.23.25", + "comments": { + "patch": [ + { + "author": "74965306+Anush2303@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "b5d571f692b983b6eb39a2dc43a8b95016a32a4c", + "comment": "Enable chart selection based on legends in declarative charts" + } + ] + } + }, + { + "date": "Fri, 13 Dec 2024 07:23:11 GMT", + "tag": "@fluentui/react-charting_v5.23.24", + "version": "5.23.24", + "comments": { + "patch": [ + { + "author": "74965306+Anush2303@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "97bb4b60188bc8951730381b54d886764351ec74", + "comment": "Declarative chart bug fixes" + }, + { + "author": "120183316+srmukher@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "23320700a9104667ffab27dfc2b3e6e2243bf927", + "comment": "Adding theme check for dark mode for declarative charts" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/react-focus to v8.9.19", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/theme-samples to v8.7.190", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/react to v8.122.1", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7" + } + ] + } + }, + { + "date": "Thu, 12 Dec 2024 07:22:32 GMT", + "tag": "@fluentui/react-charting_v5.23.23", + "version": "5.23.23", + "comments": { + "patch": [ + { + "author": "120183316+srmukher@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "221a380b189a7ae191cc5c1ee96d07d107800067", + "comment": "Dark mode theme colors for declarative charts" + }, + { + "author": "74965306+Anush2303@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "608336dee79ebb116cc5ed3d0775fc7385a028c8", + "comment": "Add support for controlled selction of legends." + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/theme-samples to v8.7.189", + "commit": "53dd771e70338065810404663cd6219d1b54c1e2" + }, + { + "author": "beachball", + "package": "@fluentui/react-charting", + "comment": "Bump @fluentui/react to v8.122.0", + "commit": "53dd771e70338065810404663cd6219d1b54c1e2" + } + ] + } + }, + { + "date": "Mon, 09 Dec 2024 07:21:03 GMT", + "tag": "@fluentui/react-charting_v5.23.22", + "version": "5.23.22", + "comments": { + "patch": [ + { + "author": "74965306+Anush2303@users.noreply.github.com", + "package": "@fluentui/react-charting", + "commit": "e186b82f297ec893820859c7ed08e2e890a0839e", + "comment": "enable negativeData prop in declarative charts" + } + ] + } + }, { "date": "Fri, 06 Dec 2024 07:21:16 GMT", "tag": "@fluentui/react-charting_v5.23.21", diff --git a/packages/charts/react-charting/CHANGELOG.md b/packages/charts/react-charting/CHANGELOG.md index 3f85aff48301f0..863e8321caf1d1 100644 --- a/packages/charts/react-charting/CHANGELOG.md +++ b/packages/charts/react-charting/CHANGELOG.md @@ -1,9 +1,370 @@ # Change Log - @fluentui/react-charting -This log was last generated on Fri, 06 Dec 2024 07:21:16 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 07:22:41 GMT and should not be manually modified. +## [5.23.56](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.56) + +Fri, 21 Feb 2025 07:22:41 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.55..@fluentui/react-charting_v5.23.56) + +### Patches + +- Bump @fluentui/react-focus to v8.9.21 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/theme-samples to v8.7.200 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/set-version to v8.2.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/react to v8.122.11 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) + +## [5.23.55](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.55) + +Wed, 19 Feb 2025 07:21:16 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.54..@fluentui/react-charting_v5.23.55) + +### Patches + +- Bump @fluentui/theme-samples to v8.7.199 ([PR #33867](https://github.com/microsoft/fluentui/pull/33867) by beachball) +- Bump @fluentui/react to v8.122.10 ([PR #33867](https://github.com/microsoft/fluentui/pull/33867) by beachball) + +## [5.23.54](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.54) + +Thu, 13 Feb 2025 07:22:18 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.53..@fluentui/react-charting_v5.23.54) + +### Patches + +- feat: hide overlapping x-axis tick labels ([PR #33678](https://github.com/microsoft/fluentui/pull/33678) by 110246001+krkshitij@users.noreply.github.com) + +## [5.23.53](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.53) + +Wed, 12 Feb 2025 07:20:51 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.52..@fluentui/react-charting_v5.23.53) + +### Patches + +- fix(react-charting):Fixing error in donut chart ([PR #33814](https://github.com/microsoft/fluentui/pull/33814) by 120183316+srmukher@users.noreply.github.com) + +## [5.23.52](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.52) + +Tue, 11 Feb 2025 07:21:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.51..@fluentui/react-charting_v5.23.52) + +### Patches + +- fix plotlyAdapterUT cases ([PR #33791](https://github.com/microsoft/fluentui/pull/33791) by 74965306+Anush2303@users.noreply.github.com) +- Making the tooltip optional ([PR #33807](https://github.com/microsoft/fluentui/pull/33807) by 120183316+srmukher@users.noreply.github.com) +- Heatmap black color fix ([PR #33751](https://github.com/microsoft/fluentui/pull/33751) by 74965306+Anush2303@users.noreply.github.com) + +## [5.23.51](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.51) + +Wed, 05 Feb 2025 07:16:29 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.50..@fluentui/react-charting_v5.23.51) + +### Patches + +- fix(react-charting): Fixed tooltip position and background on Gauge and Pie charts ([PR #33773](https://github.com/microsoft/fluentui/pull/33773) by 120183316+srmukher@users.noreply.github.com) + +## [5.23.50](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.50) + +Fri, 31 Jan 2025 07:21:30 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.49..@fluentui/react-charting_v5.23.50) + +### Patches + +- Adding transform prop to svg rect ([PR #33748](https://github.com/microsoft/fluentui/pull/33748) by 120183316+srmukher@users.noreply.github.com) + +## [5.23.49](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.49) + +Thu, 30 Jan 2025 07:20:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.48..@fluentui/react-charting_v5.23.49) + +### Patches + +- Support rounded ticks in declarative charts ([PR #33730](https://github.com/microsoft/fluentui/pull/33730) by 74965306+Anush2303@users.noreply.github.com) +- Add background to the SVGTooltipText ([PR #33696](https://github.com/microsoft/fluentui/pull/33696) by 120183316+srmukher@users.noreply.github.com) +- Fix chart crashes of plotly examples ([PR #33735](https://github.com/microsoft/fluentui/pull/33735) by 74965306+Anush2303@users.noreply.github.com) + +## [5.23.48](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.48) + +Wed, 29 Jan 2025 07:21:15 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.47..@fluentui/react-charting_v5.23.48) + +### Patches + +- fix: use inline styles in SVG export for better compatibility ([PR #33713](https://github.com/microsoft/fluentui/pull/33713) by 110246001+krkshitij@users.noreply.github.com) +- Bump @fluentui/theme-samples to v8.7.198 ([PR #33713](https://github.com/microsoft/fluentui/pull/33713) by beachball) +- Bump @fluentui/react to v8.122.9 ([PR #33713](https://github.com/microsoft/fluentui/pull/33713) by beachball) + +## [5.23.47](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.47) + +Mon, 27 Jan 2025 07:20:35 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.46..@fluentui/react-charting_v5.23.47) + +### Patches + +- Fix Duplicate keys warning ([PR #33722](https://github.com/microsoft/fluentui/pull/33722) by 74965306+Anush2303@users.noreply.github.com) +- fix: ensure text elements use the correct font-family in SVG export ([PR #33719](https://github.com/microsoft/fluentui/pull/33719) by 110246001+krkshitij@users.noreply.github.com) + +## [5.23.46](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.46) + +Fri, 24 Jan 2025 07:20:37 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.45..@fluentui/react-charting_v5.23.46) + +### Patches + +- Centre align gauge chart ([PR #33710](https://github.com/microsoft/fluentui/pull/33710) by 74965306+Anush2303@users.noreply.github.com) + +## [5.23.45](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.45) + +Thu, 23 Jan 2025 07:21:31 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.44..@fluentui/react-charting_v5.23.45) + +### Patches + +- Support for dashed and dotted line in Declarative chart ([PR #33694](https://github.com/microsoft/fluentui/pull/33694) by 74965306+Anush2303@users.noreply.github.com) +- Heatmap text color based on contrast ratio ([PR #33659](https://github.com/microsoft/fluentui/pull/33659) by 74965306+Anush2303@users.noreply.github.com) + +## [5.23.44](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.44) + +Wed, 22 Jan 2025 07:21:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.43..@fluentui/react-charting_v5.23.44) + +### Patches + +- Bump @fluentui/theme-samples to v8.7.197 ([PR #33685](https://github.com/microsoft/fluentui/pull/33685) by beachball) +- Bump @fluentui/react to v8.122.8 ([PR #33685](https://github.com/microsoft/fluentui/pull/33685) by beachball) + +## [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 +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.39..@fluentui/react-charting_v5.23.40) + +### Patches + +- feat: center align bars with auto barWidth in plotly mode ([PR #33603](https://github.com/microsoft/fluentui/pull/33603) by 110246001+krkshitij@users.noreply.github.com) +- Bump @fluentui/theme-samples to v8.7.195 ([PR #33148](https://github.com/microsoft/fluentui/pull/33148) by beachball) +- Bump @fluentui/react to v8.122.6 ([PR #33148](https://github.com/microsoft/fluentui/pull/33148) by beachball) + +## [5.23.39](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.39) + +Wed, 08 Jan 2025 07:21:37 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.38..@fluentui/react-charting_v5.23.39) + +### Patches + +- Bump @fluentui/theme-samples to v8.7.194 ([PR #33578](https://github.com/microsoft/fluentui/pull/33578) by beachball) +- Bump @fluentui/react to v8.122.5 ([PR #33578](https://github.com/microsoft/fluentui/pull/33578) by beachball) + +## [5.23.38](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.38) + +Mon, 06 Jan 2025 07:16:33 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.37..@fluentui/react-charting_v5.23.38) + +### Patches + +- Enabling titles for x and y axes for Declarative charts ([PR #33533](https://github.com/microsoft/fluentui/pull/33533) by 120183316+srmukher@users.noreply.github.com) + +## [5.23.37](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.37) + +Fri, 03 Jan 2025 07:21:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.36..@fluentui/react-charting_v5.23.37) + +### Patches + +- Gauge and Pie chart fixes ([PR #33541](https://github.com/microsoft/fluentui/pull/33541) by 74965306+Anush2303@users.noreply.github.com) +- Bump @fluentui/theme-samples to v8.7.193 ([PR #33529](https://github.com/microsoft/fluentui/pull/33529) by beachball) +- Bump @fluentui/react to v8.122.4 ([PR #33529](https://github.com/microsoft/fluentui/pull/33529) by beachball) + +## [5.23.36](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.36) + +Thu, 02 Jan 2025 07:22:03 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.35..@fluentui/react-charting_v5.23.36) + +### Patches + +- fix: resolve css variables in svg image data ([PR #33538](https://github.com/microsoft/fluentui/pull/33538) by kumarkshitij@microsoft.com) + +## [5.23.35](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.35) + +Wed, 01 Jan 2025 07:21:09 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.34..@fluentui/react-charting_v5.23.35) + +### Patches + +- HeatMap chart bug fixes ([PR #33525](https://github.com/microsoft/fluentui/pull/33525) by 74965306+Anush2303@users.noreply.github.com) +- Initialization of state variables and updating for HorizontalBarChartWithAxis chart ([PR #33532](https://github.com/microsoft/fluentui/pull/33532) by 120183316+srmukher@users.noreply.github.com) + +## [5.23.34](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.34) + +Tue, 31 Dec 2024 07:21:44 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.33..@fluentui/react-charting_v5.23.34) + +### Patches + +- [Horizontal Bar Chart With Axis] Enable multiple legend selection ([PR #33484](https://github.com/microsoft/fluentui/pull/33484) by 120183316+srmukher@users.noreply.github.com) +- [Gauge Chart] Enabling legend multi selection ([PR #33524](https://github.com/microsoft/fluentui/pull/33524) by 120183316+srmukher@users.noreply.github.com) + +## [5.23.33](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.33) + +Mon, 30 Dec 2024 07:21:28 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.32..@fluentui/react-charting_v5.23.33) + +### Patches + +- [Area Chart] Support legend multi selection [Area Chart] Support legend multi selection ([PR #33475](https://github.com/microsoft/fluentui/pull/33475) by 120183316+srmukher@users.noreply.github.com) +- Select multiple legends for Vertical bar chart ([PR #33510](https://github.com/microsoft/fluentui/pull/33510) by 120183316+srmukher@users.noreply.github.com) +- Bump @fluentui/theme-samples to v8.7.192 ([PR #33520](https://github.com/microsoft/fluentui/pull/33520) by beachball) +- Bump @fluentui/react to v8.122.3 ([PR #33520](https://github.com/microsoft/fluentui/pull/33520) by beachball) + +## [5.23.32](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.32) + +Fri, 27 Dec 2024 07:20:57 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.31..@fluentui/react-charting_v5.23.32) + +### Patches + +- Support changing legends programatically at runtime and bug fixes ([PR #33519](https://github.com/microsoft/fluentui/pull/33519) by atishay.jain@microsoft.com) +- Full Yaxis labels in HeatMap chart ([PR #33509](https://github.com/microsoft/fluentui/pull/33509) by 74965306+Anush2303@users.noreply.github.com) +- Support for multiple legend selection for Vertical Stacked Bar Chart ([PR #33466](https://github.com/microsoft/fluentui/pull/33466) by 120183316+srmukher@users.noreply.github.com) +- plotly examples bug fixes ([PR #33507](https://github.com/microsoft/fluentui/pull/33507) by 74965306+Anush2303@users.noreply.github.com) +- Enabling multiple legend selection for Grouped Vertical Bar Chart ([PR #33511](https://github.com/microsoft/fluentui/pull/33511) by 120183316+srmukher@users.noreply.github.com) + +## [5.23.31](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.31) + +Thu, 26 Dec 2024 07:21:14 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.30..@fluentui/react-charting_v5.23.31) + +### Patches + +- fix: remove duplicate legends in vertical bar chart ([PR #33518](https://github.com/microsoft/fluentui/pull/33518) by 110246001+krkshitij@users.noreply.github.com) + +## [5.23.30](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.30) + +Wed, 25 Dec 2024 07:21:55 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.29..@fluentui/react-charting_v5.23.30) + +### Patches + +- Legends multi selection for Donut Charts ([PR #33447](https://github.com/microsoft/fluentui/pull/33447) by 120183316+srmukher@users.noreply.github.com) + +## [5.23.29](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.29) + +Mon, 23 Dec 2024 07:22:57 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.28..@fluentui/react-charting_v5.23.29) + +### Patches + +- feat: add functionality to export chart as image ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by 110246001+krkshitij@users.noreply.github.com) +- Bump @fluentui/react-focus to v8.9.20 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) +- Bump @fluentui/theme-samples to v8.7.191 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) +- Bump @fluentui/react to v8.122.2 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) + +## [5.23.28](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.28) + +Fri, 20 Dec 2024 07:20:00 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.27..@fluentui/react-charting_v5.23.28) + +### Patches + +- Ensure type safety of dependent fields ([PR #33486](https://github.com/microsoft/fluentui/pull/33486) by 74965306+Anush2303@users.noreply.github.com) + +## [5.23.27](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.27) + +Wed, 18 Dec 2024 07:20:30 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.26..@fluentui/react-charting_v5.23.27) + +### Patches + +- Enabled Multi Select behaviour of Controlled legends ([PR #33479](https://github.com/microsoft/fluentui/pull/33479) by 74965306+Anush2303@users.noreply.github.com) +- Mode check for declarative area chart ([PR #33467](https://github.com/microsoft/fluentui/pull/33467) by 120183316+srmukher@users.noreply.github.com) + +## [5.23.26](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.26) + +Tue, 17 Dec 2024 07:21:19 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.25..@fluentui/react-charting_v5.23.26) + +### Patches + +- Add support for controlling legend selection and persisting in json schema ([PR #33477](https://github.com/microsoft/fluentui/pull/33477) by 98592573+AtishayMsft@users.noreply.github.com) +- Enable Controlled Legends working in declarative HBC ([PR #33476](https://github.com/microsoft/fluentui/pull/33476) by 74965306+Anush2303@users.noreply.github.com) + +## [5.23.25](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.25) + +Mon, 16 Dec 2024 07:20:45 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.24..@fluentui/react-charting_v5.23.25) + +### Patches + +- Enable chart selection based on legends in declarative charts ([PR #33460](https://github.com/microsoft/fluentui/pull/33460) by 74965306+Anush2303@users.noreply.github.com) + +## [5.23.24](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.24) + +Fri, 13 Dec 2024 07:23:11 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.23..@fluentui/react-charting_v5.23.24) + +### Patches + +- Declarative chart bug fixes ([PR #33426](https://github.com/microsoft/fluentui/pull/33426) by 74965306+Anush2303@users.noreply.github.com) +- Adding theme check for dark mode for declarative charts ([PR #33454](https://github.com/microsoft/fluentui/pull/33454) by 120183316+srmukher@users.noreply.github.com) +- Bump @fluentui/react-focus to v8.9.19 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) +- Bump @fluentui/theme-samples to v8.7.190 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) +- Bump @fluentui/react to v8.122.1 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) + +## [5.23.23](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.23) + +Thu, 12 Dec 2024 07:22:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.22..@fluentui/react-charting_v5.23.23) + +### Patches + +- Dark mode theme colors for declarative charts ([PR #33439](https://github.com/microsoft/fluentui/pull/33439) by 120183316+srmukher@users.noreply.github.com) +- Add support for controlled selction of legends. ([PR #33436](https://github.com/microsoft/fluentui/pull/33436) by 74965306+Anush2303@users.noreply.github.com) +- Bump @fluentui/theme-samples to v8.7.189 ([PR #33243](https://github.com/microsoft/fluentui/pull/33243) by beachball) +- Bump @fluentui/react to v8.122.0 ([PR #33243](https://github.com/microsoft/fluentui/pull/33243) by beachball) + +## [5.23.22](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.22) + +Mon, 09 Dec 2024 07:21:03 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charting_v5.23.21..@fluentui/react-charting_v5.23.22) + +### Patches + +- enable negativeData prop in declarative charts ([PR #33414](https://github.com/microsoft/fluentui/pull/33414) by 74965306+Anush2303@users.noreply.github.com) + ## [5.23.21](https://github.com/microsoft/fluentui/tree/@fluentui/react-charting_v5.23.21) Fri, 06 Dec 2024 07:21:16 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 df25ce137be990..b40734e15b8632 100644 --- a/packages/charts/react-charting/etc/react-charting.api.md +++ b/packages/charts/react-charting/etc/react-charting.api.md @@ -12,6 +12,7 @@ import { IFocusZoneProps } from '@fluentui/react-focus'; import { IHoverCardStyleProps } from '@fluentui/react/lib/HoverCard'; import { IHoverCardStyles } from '@fluentui/react/lib/HoverCard'; import { IOverflowSetProps } from '@fluentui/react/lib/OverflowSet'; +import { IRefObject } from '@fluentui/react/lib/Utilities'; import { IRenderFunction } from '@fluentui/react/lib/Utilities'; import { IStyle } from '@fluentui/react/lib/Styling'; import { IStyle as IStyle_2 } from '@fluentui/react'; @@ -125,6 +126,7 @@ export const DeclarativeChart: React_2.FunctionComponent; // @public export interface DeclarativeChartProps extends React_2.RefAttributes { chartSchema: Schema; + componentRef?: IRefObject; onSchemaChange?: (eventData: Schema) => void; } @@ -198,6 +200,7 @@ export interface IAreaChartProps extends ICartesianChartProps { data: IChartProps; enableGradient?: boolean; enablePerfOptimization?: boolean; + mode?: 'tozeroy' | 'tonexty'; onRenderCalloutPerDataPoint?: IRenderFunction; onRenderCalloutPerStack?: IRenderFunction; // (undocumented) @@ -267,6 +270,7 @@ export interface ICartesianChartProps { // @deprecated chartLabel?: string; className?: string; + componentRef?: IRefObject; customDateTimeFormatter?: (dateTime: Date) => string; dateLocalizeOptions?: Intl.DateTimeFormatOptions; enabledLegendsWrapLines?: boolean; @@ -274,6 +278,7 @@ export interface ICartesianChartProps { focusZonePropsForLegendsInHoverCard?: IFocusZoneProps; height?: number; hideLegend?: boolean; + hideTickOverlap?: boolean; hideTooltip?: boolean; href?: string; // (undocumented) @@ -285,6 +290,7 @@ export interface ICartesianChartProps { noOfCharsToTruncate?: number; parentRef?: HTMLElement | null; rotateXAxisLables?: boolean; + roundedTicks?: boolean; secondaryYAxistitle?: string; secondaryYScaleOptions?: { yMinValue?: number; @@ -298,7 +304,7 @@ export interface ICartesianChartProps { theme?: ITheme; tickFormat?: string; tickPadding?: number; - tickValues?: number[] | Date[]; + tickValues?: number[] | Date[] | string[]; timeFormatLocale?: TimeLocaleDefinition; useUTC?: boolean; width?: number; @@ -352,6 +358,12 @@ export interface ICartesianChartStyles { yAxis?: IStyle; } +// @public (undocumented) +export interface IChart { + // (undocumented) + chartContainer: HTMLElement | null; +} + // @public (undocumented) export interface IChartDataPoint { callOutAccessibilityData?: IAccessibilityProps; @@ -481,6 +493,12 @@ export interface IDataPoint { y: number; } +// @public (undocumented) +export interface IDeclarativeChart { + // (undocumented) + exportAsImage: (opts?: IImageExportOptions) => Promise; +} + // @public (undocumented) export interface IDonutChart { } @@ -488,6 +506,7 @@ export interface IDonutChart { // @public export interface IDonutChartProps extends ICartesianChartProps { calloutProps?: Partial; + componentRef?: IRefObject; culture?: string; data?: IChartProps; enableGradient?: boolean; @@ -536,6 +555,7 @@ export interface IGaugeChartProps { chartValue: number; chartValueFormat?: GaugeValueFormat | ((sweepFraction: [number, number]) => string); className?: string; + componentRef?: IRefObject; culture?: string; enableGradient?: boolean; height?: number; @@ -620,6 +640,7 @@ export interface IGroupedVerticalBarChartProps extends ICartesianChartProps { // @deprecated legendColor?: string; maxBarWidth?: number; + mode?: 'default' | 'plotly'; onRenderCalloutPerDataPoint?: IRenderFunction; roundCorners?: boolean; // @deprecated @@ -704,6 +725,8 @@ export interface IHeatMapChartProps extends Pick; rangeValuesForColorScale: string[]; + showYAxisLables?: boolean; + sortOrder?: 'none' | 'alphabetical'; styles?: IStyleFunctionOrObject; xAxisDateFormatString?: string; xAxisNumberFormatString?: string; @@ -832,6 +855,18 @@ export interface IHorizontalDataPoint { y: number; } +// @public (undocumented) +export interface IImageExportOptions { + // (undocumented) + background?: string; + // (undocumented) + height?: number; + // (undocumented) + scale?: number; + // (undocumented) + width?: number; +} + // @public export interface ILegend { action?: VoidFunction; @@ -876,6 +911,8 @@ export interface ILegendsProps { onLegendHoverCardLeave?: VoidFunction; overflowProps?: Partial; overflowText?: string; + selectedLegend?: string; + selectedLegends?: string[]; shape?: LegendShape; styles?: IStyleFunctionOrObject; theme?: ITheme; @@ -1007,6 +1044,7 @@ export interface ILineDataInVerticalStackedBarChart { data?: number; // (undocumented) legend: string; + lineOptions?: ILineChartLineOptions; useSecondaryYScale?: boolean; // (undocumented) y: number; @@ -1044,7 +1082,7 @@ export interface IModifiedCartesianChartProps extends ICartesianChartProps { createStringYAxis: (yAxisParams: IYAxisParams, dataPoints: string[], isRtl: boolean, barWidth: number | undefined) => ScaleBand; // Warning: (ae-forgotten-export) The symbol "IYAxisParams" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "IAxisData" needs to be exported by the entry point index.d.ts - createYAxis: (yAxisParams: IYAxisParams, isRtl: boolean, axisData: IAxisData, isIntegralDataset: boolean, useSecondaryYScale?: boolean, supportNegativeData?: boolean) => ScaleLinear; + createYAxis: (yAxisParams: IYAxisParams, isRtl: boolean, axisData: IAxisData, isIntegralDataset: boolean, useSecondaryYScale?: boolean, supportNegativeData?: boolean, roundedTicks?: boolean) => ScaleLinear; culture?: string; customizedCallout?: any; datasetForXAxisDomain?: string[]; @@ -1054,7 +1092,7 @@ export interface IModifiedCartesianChartProps extends ICartesianChartProps { getAxisData?: any; getDomainMargins?: (containerWidth: number) => IMargins; // Warning: (ae-forgotten-export) The symbol "IDomainNRange" needs to be exported by the entry point index.d.ts - getDomainNRangeValues: (points: ILineChartPoints[] | IVerticalBarChartDataPoint[] | IVerticalStackedBarDataPoint[] | IHorizontalBarChartWithAxisDataPoint[] | IGroupedVerticalBarChartData[] | IHeatMapChartDataPoint[], margins: IMargins, width: number, chartType: ChartTypes, isRTL: boolean, xAxisType: XAxisTypes, barWidth: number, tickValues: Date[] | number[] | undefined, shiftX: number) => IDomainNRange; + getDomainNRangeValues: (points: ILineChartPoints[] | IVerticalBarChartDataPoint[] | IVerticalStackedBarDataPoint[] | IHorizontalBarChartWithAxisDataPoint[] | IGroupedVerticalBarChartData[] | IHeatMapChartDataPoint[], margins: IMargins, width: number, chartType: ChartTypes, isRTL: boolean, xAxisType: XAxisTypes, barWidth: number, tickValues: Date[] | number[] | string[] | undefined, shiftX: number) => IDomainNRange; getGraphData?: any; getmargins?: (margins: IMargins) => void; getMinMaxOfYAxis: (points: ILineChartPoints[] | IHorizontalBarChartWithAxisDataPoint[] | IVerticalBarChartDataPoint[] | IDataPoint[], yAxisType: YAxisType | undefined) => { @@ -1066,12 +1104,13 @@ export interface IModifiedCartesianChartProps extends ICartesianChartProps { maxOfYVal?: number; onChartMouseLeave?: () => void; points: any; + ref?: IRefObject; showYAxisLables?: boolean; showYAxisLablesTooltip?: boolean; stringDatasetForYAxisDomain?: string[]; svgFocusZoneProps?: IFocusZoneProps; tickParams?: { - tickValues?: number[] | Date[]; + tickValues?: number[] | Date[] | string[]; tickFormat?: string; }; xAxisInnerPadding?: number; @@ -1196,8 +1235,10 @@ export interface ISankeyChartData { export interface ISankeyChartProps { accessibility?: ISankeyChartAccessibilityProps; borderColorsForNodes?: string[]; + calloutProps?: Partial; className?: string; colorsForNodes?: string[]; + componentRef?: IRefObject; data: IChartProps; enableReflow?: boolean; formatNumberOptions?: Intl.NumberFormatOptions; @@ -1432,6 +1473,7 @@ export interface IVerticalBarChartProps extends ICartesianChartProps { lineLegendText?: string; lineOptions?: ILineChartLineOptions; maxBarWidth?: number; + mode?: 'default' | 'plotly'; onRenderCalloutPerDataPoint?: IRenderFunction; roundCorners?: boolean; styles?: IStyleFunctionOrObject; @@ -1484,6 +1526,7 @@ export interface IVerticalStackedBarChartProps extends ICartesianChartProps { isCalloutForStack?: boolean; lineOptions?: ILineChartLineOptions; maxBarWidth?: number; + mode?: 'default' | 'plotly'; onBarClick?: (event: React_2.MouseEvent, data: IVerticalStackedChartProps | IVSChartDataPoint) => void; onRenderCalloutPerDataPoint?: IRenderFunction; onRenderCalloutPerStack?: IRenderFunction; @@ -1601,13 +1644,9 @@ export const PieChart: React_2.FunctionComponent; // @public export const SankeyChart: React_2.FunctionComponent; -// @public (undocumented) +// @public export interface Schema { - accesibilityLabels?: { - [key: string]: string; - }; plotlySchema: any; - selectedLegends?: string[]; } // @public (undocumented) diff --git a/packages/charts/react-charting/package.json b/packages/charts/react-charting/package.json index debcfd7fd67821..009997d0e42987 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.21", + "version": "5.23.56", "description": "React web charting controls for Microsoft fluentui system.", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -39,8 +39,8 @@ "jest-canvas-mock": "2.4.0" }, "dependencies": { - "@fluentui/react-focus": "^8.9.18", - "@fluentui/theme-samples": "^8.7.188", + "@fluentui/react-focus": "^8.9.21", + "@fluentui/theme-samples": "^8.7.200", "@microsoft/load-themed-styles": "^1.10.26", "@types/d3-array": "^3.0.0", "@types/d3-axis": "^3.0.0", @@ -52,7 +52,8 @@ "@types/d3-shape": "^3.0.0", "@types/d3-time-format": "^3.0.0", "@types/d3-time": "^3.0.0", - "@fluentui/set-version": "^8.2.23", + "@types/d3-color": "^3.0.0", + "@fluentui/set-version": "^8.2.24", "d3-array": "^3.0.0", "d3-axis": "^3.0.0", "d3-format": "^3.0.0", @@ -63,10 +64,11 @@ "d3-shape": "^3.0.0", "d3-time-format": "^3.0.0", "d3-time": "^3.0.0", + "d3-color": "^3.0.0", "tslib": "^2.1.0" }, "peerDependencies": { - "@fluentui/react": "^8.121.13", + "@fluentui/react": "^8.122.11", "@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/project.json b/packages/charts/react-charting/project.json index dcd5970664dc95..549d25c76cf64c 100644 --- a/packages/charts/react-charting/project.json +++ b/packages/charts/react-charting/project.json @@ -2,7 +2,7 @@ "name": "react-charting", "$schema": "../../../node_modules/nx/schemas/project-schema.json", "projectType": "library", - "tags": ["v8", "ships-bundle"], + "tags": ["v8", "ships-bundle", "charting"], "implicitDependencies": [], "targets": { "test": { diff --git a/packages/charts/react-charting/src/DeclarativeChart.ts b/packages/charts/react-charting/src/DeclarativeChart.ts index dadcd454679132..ca97cd8fc995f6 100644 --- a/packages/charts/react-charting/src/DeclarativeChart.ts +++ b/packages/charts/react-charting/src/DeclarativeChart.ts @@ -1 +1 @@ -export * from './components/DeclarativeChart/DeclarativeChart'; +export * from './components/DeclarativeChart/index'; 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 fef7e6965c59d7..d4411e51c3d674 100644 --- a/packages/charts/react-charting/src/components/AreaChart/AreaChart.base.tsx +++ b/packages/charts/react-charting/src/components/AreaChart/AreaChart.base.tsx @@ -3,7 +3,13 @@ import { max as d3Max, bisector } from 'd3-array'; import { pointer } from 'd3-selection'; import { select as d3Select } from 'd3-selection'; import { area as d3Area, stack as d3Stack, curveMonotoneX as d3CurveBasis, line as d3Line } from 'd3-shape'; -import { classNamesFunction, find, getId, memoizeFunction } from '@fluentui/react/lib/Utilities'; +import { + classNamesFunction, + find, + getId, + initializeComponentRef, + memoizeFunction, +} from '@fluentui/react/lib/Utilities'; import { IAccessibilityProps, CartesianChart, @@ -35,9 +41,11 @@ import { createStringYAxis, formatDate, getSecureProps, + areArraysEqual, } from '../../utilities/index'; import { ILegend, Legends } from '../Legends/index'; import { DirectionalHint } from '@fluentui/react/lib/Callout'; +import { IChart } from '../../types/index'; const getClassNames = classNamesFunction(); @@ -56,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: {} }; @@ -80,9 +88,10 @@ export interface IAreaChartState extends IBasestate { isShowCalloutPending: boolean; /** focused point */ activePoint: string; + selectedLegends: string[]; } -export class AreaChartBase extends React.Component { +export class AreaChartBase extends React.Component implements IChart { public static defaultProps: Partial = { useUTC: true, }; @@ -93,7 +102,7 @@ export class AreaChartBase extends React.Component; public constructor(props: IAreaChartProps) { super(props); + + initializeComponentRef(this); + this._createSet = memoizeFunction(this._createDataSet); this.state = { - selectedLegend: '', - activeLegend: '', + selectedLegends: props.legendProps?.selectedLegends || [], + activeLegend: undefined, hoverXValue: '', isCalloutVisible: false, refSelected: null, @@ -148,9 +161,16 @@ export class AreaChartBase extends React.Component { @@ -249,6 +270,10 @@ export class AreaChartBase extends React.Component 0 + ? found.values.filter((value: { legend: string }) => selectedLegends.includes(value.legend)) + : found.values; this.setState({ nearestCircleToHighlight, isCalloutVisible: false, @@ -345,9 +375,9 @@ 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, }; }; @@ -466,7 +518,7 @@ export class AreaChartBase extends React.Component { - this._onLegendClick(singleChartData.legend); - }, hoverAction: () => { this._handleChartMouseLeave(); this._onLegendHover(singleChartData.legend); @@ -621,10 +658,26 @@ export class AreaChartBase extends React.Component ); }; + private _onLegendSelectionChange( + selectedLegends: string[], + event: React.MouseEvent, + currentLegend?: ILegend, + ): void { + if (this.props.legendProps?.canSelectMultipleLegends) { + this.setState({ selectedLegends }); + } else { + this.setState({ selectedLegends: selectedLegends.slice(-1) }); + } + if (this.props.legendProps?.onChange) { + this.props.legendProps.onChange(selectedLegends, event, currentLegend); + } + } + private _onDataPointClick = (func: (() => void) | undefined) => { if (func) { func(); @@ -690,7 +743,8 @@ 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 && ( @@ -724,7 +778,7 @@ export class AreaChartBase extends React.Component, index: number) => { + this._data.forEach((singleStackedData: Array, index: number) => { if (points.length === index) { return; } @@ -773,9 +827,10 @@ 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; return ( this._handleFocus(index, pointIndex, circleId)} onBlur={this._handleBlur} {...getSecureProps(pointOptions)} - r={this._getCircleRadius(xDataPoint, circleRadius, circleId)} + r={this._getCircleRadius(xDataPoint, circleRadius, circleId, legend)} role="img" aria-label={this._getAriaLabel(index, pointIndex)} /> @@ -805,8 +860,9 @@ 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( , ); } @@ -870,8 +926,14 @@ export class AreaChartBase extends React.Component { + private _getCircleRadius = (xDataPoint: number, circleRadius: number, circleId: string, legend: string): number => { const { isCircleClicked, nearestCircleToHighlight, activePoint } = this.state; + + // Show the circle if no legends are selected or if the point's legend is in the selected legends + if (!this._legendHighlighted(legend)) { + return 0; + } + if (isCircleClicked && nearestCircleToHighlight === xDataPoint) { return 1; } else if (nearestCircleToHighlight === xDataPoint || activePoint === circleId) { @@ -894,18 +956,24 @@ export class AreaChartBase extends React.Component { - return ( - this.state.selectedLegend === legend || (this.state.selectedLegend === '' && this.state.activeLegend === legend) - ); + return this._getHighlightedLegend().includes(legend!); }; /** * This function checks if none of the legends is selected or hovered. */ private _noLegendHighlighted = () => { - return this.state.selectedLegend === '' && this.state.activeLegend === ''; + return this._getHighlightedLegend().length === 0; }; + private _getHighlightedLegend() { + return this.state.selectedLegends.length > 0 + ? this.state.selectedLegends + : this.state.activeLegend + ? [this.state.activeLegend] + : []; + } + private _addDefaultColors = (lineChartData?: ILineChartPoints[]): ILineChartPoints[] => { return lineChartData ? lineChartData.map((item, index) => { @@ -930,18 +998,26 @@ export class AreaChartBase extends React.Component e.x === modifiedXVal); // Show details in the callout for the focused point only found.values = found.values.filter((e: { y: number }) => e.y === y); + const filteredValues = this._getFilteredLegendValues(found.values); this.setState({ refSelected: `#${circleId}`, isCalloutVisible: true, hoverXValue: xAxisCalloutData ? xAxisCalloutData : formattedDate, - YValueHover: found.values, - stackCalloutProps: found, - dataPointCalloutProps: found, + YValueHover: filteredValues!, + stackCalloutProps: { ...found, values: filteredValues }, + dataPointCalloutProps: { ...found, values: filteredValues }, activePoint: circleId, }); }; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + private _getFilteredLegendValues = (values: any) => { + !this._noLegendHighlighted() + ? values.filter((value: { legend: string }) => this._legendHighlighted(value.legend)) + : values; + }; + private _handleBlur = () => { this.setState({ refSelected: null, 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 19ddb9e8b50c7b..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', () => { @@ -606,6 +616,28 @@ describe('Area chart - Subcomponent legend', () => { expect(firstLegend).toHaveAttribute('aria-selected', 'false'); }, ); + + testWithoutWait( + 'Should select multiple legends on single mouse click on legends', + AreaChart, + { data: chartData, legendProps: { canSelectMultipleLegends: true } }, + container => { + const legend1 = screen.queryByText('legend1')?.closest('button'); + expect(legend1).toBeDefined(); + const legend2 = screen.queryByText('legend2')?.closest('button'); + expect(legend2).toBeDefined(); + + fireEvent.click(legend1!); + fireEvent.click(legend2!); + + // Assert + expect(legend1).toHaveAttribute('aria-selected', 'true'); + expect(legend2).toHaveAttribute('aria-selected', 'true'); + expect(getById(container, /graph-areaChart/i)[0]).toHaveAttribute('fill-opacity', '0.7'); + expect(getById(container, /graph-areaChart/i)[1]).toHaveAttribute('fill-opacity', '0.7'); + expect(getById(container, /graph-areaChart/i)[2]).toHaveAttribute('fill-opacity', '0.1'); + }, + ); }); describe('Area chart - Subcomponent callout', () => { diff --git a/packages/charts/react-charting/src/components/AreaChart/__snapshots__/AreaChart.test.tsx.snap b/packages/charts/react-charting/src/components/AreaChart/__snapshots__/AreaChart.test.tsx.snap index b859fc204700b1..346ed811ff1e27 100644 --- a/packages/charts/react-charting/src/components/AreaChart/__snapshots__/AreaChart.test.tsx.snap +++ b/packages/charts/react-charting/src/components/AreaChart/__snapshots__/AreaChart.test.tsx.snap @@ -176,7 +176,7 @@ exports[`AreaChart - mouse events Should render callout correctly on mouseover 1 onFocus={[Function]} onMouseOut={[Function]} onMouseOver={[Function]} - r={8} + r={0} role="img" stroke="red" strokeWidth={3} @@ -747,7 +747,7 @@ exports[`AreaChart - mouse events Should render customized callout on mouseover onFocus={[Function]} onMouseOut={[Function]} onMouseOver={[Function]} - r={8} + r={0} role="img" stroke="red" strokeWidth={3} @@ -1215,7 +1215,7 @@ exports[`AreaChart - mouse events Should render customized callout per stack on onFocus={[Function]} onMouseOut={[Function]} onMouseOver={[Function]} - r={8} + r={0} role="img" stroke="red" strokeWidth={3} 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`] = `
(); const ChartHoverCard = React.lazy(() => import('../../utilities/ChartHoverCard/ChartHoverCard').then(module => ({ default: module.ChartHoverCard })), ); +const chartTypesToCheck = [ChartTypes.HorizontalBarChartWithAxis, ChartTypes.HeatMapChart]; export interface ICartesianChartState { containerWidth: number; @@ -63,9 +66,12 @@ export interface ICartesianChartState { * 2.Callout * 3.Fit parent Continer */ -export class CartesianChartBase extends React.Component { +export class CartesianChartBase + extends React.Component + implements IChart +{ + public chartContainer: HTMLDivElement; private _classNames: IProcessedStyleSet; - private chartContainer: HTMLDivElement; private legendContainer: HTMLDivElement; private minLegendContainerHeight: number = 32; private xAxisElement: SVGSVGElement | null; @@ -137,14 +143,11 @@ export class CartesianChartBase extends React.Component point.y), - `.${this._classNames.yAxis} text`, + if (chartTypesToCheck.includes(this.props.chartType) && this.props.showYAxisLables && this.yAxisElement) { + const maxYAxisLabelLength = this.calculateMaxYAxisLabelLength( + this.props.chartType, + this.props.points, + this._classNames.yAxis!, ); if (this.state.startFromX !== maxYAxisLabelLength) { this.setState({ @@ -190,14 +193,11 @@ export class CartesianChartBase extends React.Component point.y), - `.${this._classNames.yAxis} text`, + if (chartTypesToCheck.includes(this.props.chartType) && this.props.showYAxisLables && this.yAxisElement) { + const maxYAxisLabelLength = this.calculateMaxYAxisLabelLength( + this.props.chartType, + this.props.points, + this._classNames.yAxis!, ); if (this.state.startFromX !== maxYAxisLabelLength) { this.setState({ @@ -216,6 +216,25 @@ export class CartesianChartBase extends React.Component { + if (chartType === ChartTypes.HeatMapChart) { + return calculateLongestLabelWidth( + points[0].data.map((point: IHeatMapChartDataPoint) => point.y), + `.${className} text`, + ); + } else { + return calculateLongestLabelWidth( + points.map((point: IHorizontalBarChartWithAxisDataPoint) => point.y), + `.${className} text`, + ); + } + }; + public render(): JSX.Element { const { calloutProps, @@ -234,7 +253,7 @@ export class CartesianChartBase extends React.Component )} )} @@ -604,6 +645,8 @@ export class CartesianChartBase extends React.Component )} @@ -619,6 +662,7 @@ export class CartesianChartBase extends React.Component ); } + /** * Dedicated function to return the Callout JSX Element , which can further be used to only call this when * only the calloutprops and charthover props changes. diff --git a/packages/charts/react-charting/src/components/CommonComponents/CartesianChart.types.ts b/packages/charts/react-charting/src/components/CommonComponents/CartesianChart.types.ts index 227d38446e64e9..c8c851aa53ac79 100644 --- a/packages/charts/react-charting/src/components/CommonComponents/CartesianChart.types.ts +++ b/packages/charts/react-charting/src/components/CommonComponents/CartesianChart.types.ts @@ -1,5 +1,5 @@ import * as React from 'react'; -import { IStyleFunctionOrObject } from '@fluentui/react/lib/Utilities'; +import { IRefObject, IStyleFunctionOrObject } from '@fluentui/react/lib/Utilities'; import { ITheme, IStyle } from '@fluentui/react/lib/Styling'; import { IOverflowSetProps } from '@fluentui/react/lib/OverflowSet'; import { IFocusZoneProps, FocusZoneDirection } from '@fluentui/react-focus'; @@ -7,6 +7,7 @@ import { ICalloutProps } from '@fluentui/react/lib/Callout'; import { ILegendsProps } from '../Legends/index'; import { IAccessibilityProps, + IChart, IDataPoint, IGroupedVerticalBarChartData, IHeatMapChartDataPoint, @@ -235,7 +236,7 @@ export interface ICartesianChartProps { * This is a optional parameter if not specified D3 will decide which values appear on the x-axis for you * Please look at https://github.com/d3/d3-scale for more information on how D3 decides what data to appear on the axis of chart */ - tickValues?: number[] | Date[]; + tickValues?: number[] | Date[] | string[]; /** * the format for the data on x-axis. For date object this can be specified to your requirement. Eg: '%m/%d', '%d' @@ -445,6 +446,24 @@ export interface ICartesianChartProps { * Used for enabling negative values in Y axis. */ supportNegativeData?: boolean; + + /** + * @default false + * The prop used to decide rounded ticks on y axis + */ + roundedTicks?: boolean; + + /** + * Optional callback to access the IChart interface. Use this instead of ref for accessing + * the public methods and properties of the component. + */ + componentRef?: IRefObject; + + /** + * Determines whether overlapping x-axis tick labels should be hidden. + * @default false + */ + hideTickOverlap?: boolean; } export interface IYValueHover { @@ -544,7 +563,7 @@ export interface IModifiedCartesianChartProps extends ICartesianChartProps { * Tick params are applicable for date axis only. */ tickParams?: { - tickValues?: number[] | Date[]; + tickValues?: number[] | Date[] | string[]; tickFormat?: string; }; @@ -658,6 +677,7 @@ export interface IModifiedCartesianChartProps extends ICartesianChartProps { isIntegralDataset: boolean, useSecondaryYScale?: boolean, supportNegativeData?: boolean, + roundedTicks?: boolean, ) => ScaleLinear; /** @@ -677,7 +697,7 @@ export interface IModifiedCartesianChartProps extends ICartesianChartProps { isRTL: boolean, xAxisType: XAxisTypes, barWidth: number, - tickValues: Date[] | number[] | undefined, + tickValues: Date[] | number[] | string[] | undefined, shiftX: number, ) => IDomainNRange; @@ -690,4 +710,9 @@ export interface IModifiedCartesianChartProps extends ICartesianChartProps { isRtl: boolean, barWidth: number | undefined, ) => ScaleBand; + + /** + * Callback to access the public methods and properties of the component. + */ + ref?: IRefObject; } diff --git a/packages/charts/react-charting/src/components/DeclarativeChart/DeclarativeChart.tsx b/packages/charts/react-charting/src/components/DeclarativeChart/DeclarativeChart.tsx index 1716212e66fb87..16e4f1a9c72f86 100644 --- a/packages/charts/react-charting/src/components/DeclarativeChart/DeclarativeChart.tsx +++ b/packages/charts/react-charting/src/components/DeclarativeChart/DeclarativeChart.tsx @@ -1,45 +1,49 @@ /* eslint-disable @typescript-eslint/naming-convention */ -/* eslint-disable @typescript-eslint/no-explicit-any */ import * as React from 'react'; +import { useTheme } from '@fluentui/react'; +import { IRefObject } from '@fluentui/react/lib/Utilities'; import { DonutChart } from '../DonutChart/index'; import { VerticalStackedBarChart } from '../VerticalStackedBarChart/index'; +import { PlotData, PlotlySchema } from './PlotlySchema'; import { + isArrayOrTypedArray, + isDateArray, + isNumberArray, + isMonthArray, + sanitizeJson, + updateXValues, transformPlotlyJsonToDonutProps, transformPlotlyJsonToVSBCProps, transformPlotlyJsonToScatterChartProps, transformPlotlyJsonToHorizontalBarWithAxisProps, - isDateArray, - isNumberArray, transformPlotlyJsonToHeatmapProps, transformPlotlyJsonToSankeyProps, transformPlotlyJsonToGaugeProps, transformPlotlyJsonToGVBCProps, transformPlotlyJsonToVBCProps, + isLineData, } from './PlotlySchemaAdapter'; -import { LineChart } from '../LineChart/index'; +import { LineChart, ILineChartProps } from '../LineChart/index'; import { HorizontalBarChartWithAxis } from '../HorizontalBarChartWithAxis/index'; -import { AreaChart } from '../AreaChart/index'; +import { AreaChart, IAreaChartProps } from '../AreaChart/index'; import { HeatMapChart } from '../HeatMapChart/index'; import { SankeyChart } from '../SankeyChart/SankeyChart'; import { GaugeChart } from '../GaugeChart/index'; import { GroupedVerticalBarChart } from '../GroupedVerticalBarChart/index'; import { VerticalBarChart } from '../VerticalBarChart/index'; +import { IImageExportOptions, toImage } from './imageExporter'; +import { IChart } from '../../types/index'; +/** + * DeclarativeChart schema. + * {@docCategory DeclarativeChart} + */ export interface Schema { /** * Plotly schema represented as JSON object */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any plotlySchema: any; - - /** - * The legends selected by the user to persist in the chart - */ - selectedLegends?: string[]; - - /** - * Dictionary for localizing the accessibility labels - */ - accesibilityLabels?: { [key: string]: string }; } /** @@ -56,6 +60,19 @@ export interface DeclarativeChartProps extends React.RefAttributes void; + + /** + * Optional callback to access the IDeclarativeChart interface. Use this instead of ref for accessing + * the public methods and properties of the component. + */ + componentRef?: IRefObject; +} + +/** + * {@docCategory DeclarativeChart} + */ +export interface IDeclarativeChart { + exportAsImage: (opts?: IImageExportOptions) => Promise; } const useColorMapping = () => { @@ -71,49 +88,184 @@ export const DeclarativeChart: React.FunctionComponent = HTMLDivElement, DeclarativeChartProps >((props, forwardedRef) => { - const { plotlySchema } = props.chartSchema; - const xValues = plotlySchema.data[0].x; - const isXDate = isDateArray(xValues); - const isXNumber = isNumberArray(xValues); + const { plotlySchema } = sanitizeJson(props.chartSchema); + const plotlyInput = plotlySchema as PlotlySchema; + let { selectedLegends } = plotlySchema; const colorMap = useColorMapping(); + const theme = useTheme(); + const isDarkTheme = theme?.isInverted ?? false; + const chartRef = React.useRef(null); + + if (!isArrayOrTypedArray(selectedLegends)) { + selectedLegends = []; + } + + const [activeLegends, setActiveLegends] = React.useState(selectedLegends); + const onActiveLegendsChange = (keys: string[]) => { + setActiveLegends(keys); + if (props.onSchemaChange) { + props.onSchemaChange({ plotlySchema: { plotlyInput, selectedLegends: keys } }); + } + }; + + React.useEffect(() => { + // eslint-disable-next-line @typescript-eslint/no-shadow + const { plotlySchema } = sanitizeJson(props.chartSchema); + // eslint-disable-next-line @typescript-eslint/no-shadow + const { selectedLegends } = plotlySchema; + setActiveLegends(selectedLegends ?? []); + }, [props.chartSchema]); + + const multiSelectLegendProps = { + canSelectMultipleLegends: true, + onChange: onActiveLegendsChange, + 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, + }); + }, + [theme], + ); - switch (plotlySchema.data[0].type) { + React.useImperativeHandle( + props.componentRef, + () => ({ + exportAsImage, + }), + [exportAsImage], + ); + + switch (plotlyInput.data[0].type) { case 'pie': - return ; + return ; case 'bar': - const orientation = plotlySchema.data[0].orientation; - if (orientation === 'h') { + const orientation = plotlyInput.data[0].orientation; + if (orientation === 'h' && isNumberArray((plotlyInput.data[0] as PlotData).x)) { return ( - + ); } else { - if (['group', 'overlay'].includes(plotlySchema?.layout?.barmode)) { - return ; + const containsLines = plotlyInput.data.some( + series => series.type === 'scatter' || isLineData(series as Partial), + ); + if (['group', 'overlay'].includes(plotlySchema?.layout?.barmode) && !containsLines) { + return ( + + ); } - return ; + return ( + + ); } case 'scatter': - const isAreaChart = plotlySchema.data.some((series: any) => series.fill === 'tonexty'); - if (isXDate || isXNumber) { + 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 ; + return ; + }; + return checkAndRenderChart(renderChartJsx, isAreaChart); case 'heatmap': - return ; + return ; case 'sankey': - return ; + return ( + + ); case 'indicator': - if (plotlySchema?.data?.[0]?.mode?.includes('gauge')) { - return ; + case 'gauge': + if (plotlyInput.data?.[0]?.mode?.includes('gauge') || plotlyInput.data?.[0]?.type === 'gauge') { + return ( + + ); } - return
Unsupported Schema
; + throw new Error(`Unsupported chart - type: ${plotlyInput.data[0]?.type}, mode: ${plotlyInput.data[0]?.mode}`); case 'histogram': - return ; + return ( + + ); default: - return
Unsupported 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 new file mode 100644 index 00000000000000..5253f3cc717103 --- /dev/null +++ b/packages/charts/react-charting/src/components/DeclarativeChart/DeclarativeChartRTL.test.tsx @@ -0,0 +1,104 @@ +import { render } from '@testing-library/react'; +import { DeclarativeChart } from './index'; +import * as React from 'react'; +import { resetIds } from '../../Utilities'; + +describe('DeclarativeChart', () => { + const mockGetComputedTextLength = jest.fn().mockReturnValue(100); + // Replace the original method with the mock implementation + Object.defineProperty( + Object.getPrototypeOf(document.createElementNS('http://www.w3.org/2000/svg', 'tspan')), + 'getComputedTextLength', + { + value: mockGetComputedTextLength, + }, + ); + + const originalRAF = window.requestAnimationFrame; + + beforeEach(() => { + resetIds(); + + jest.useFakeTimers(); + Object.defineProperty(window, 'requestAnimationFrame', { + writable: true, + value: (callback: FrameRequestCallback) => callback(0), + }); + window.HTMLElement.prototype.getBoundingClientRect = jest.fn().mockReturnValue({ width: 600, height: 350 }); + }); + + afterEach(() => { + jest.useRealTimers(); + window.requestAnimationFrame = originalRAF; + }); + + test('Should render areachart in DeclarativeChart', () => { + // Arrange + const plotlySchema = require('./tests/schema/fluent_area_test.json'); + const { container } = render(); + expect(container).toMatchSnapshot(); + }); + + test('Should render donutchart in DeclarativeChart', () => { + // Arrange + const plotlySchema = require('./tests/schema/fluent_donut_test.json'); + const { container } = render(); + expect(container).toMatchSnapshot(); + }); + + test('Should render gaugechart in DeclarativeChart', () => { + // Arrange + const plotlySchema = require('./tests/schema/fluent_gauge_test.json'); + const { container } = render(); + expect(container).toMatchSnapshot(); + }); + + test('Should render heatmapchart in DeclarativeChart', () => { + // Arrange + const plotlySchema = require('./tests/schema/fluent_heatmap_test.json'); + const { container } = render(); + expect(container).toMatchSnapshot(); + }); + + test('Should render linechart in DeclarativeChart', () => { + // Arrange + const plotlySchema = require('./tests/schema/fluent_line_test.json'); + const { container } = render(); + expect(container).toMatchSnapshot(); + }); + + test('Should render piechart in DeclarativeChart', () => { + // Arrange + const plotlySchema = require('./tests/schema/fluent_pie_test.json'); + const { container } = render(); + expect(container).toMatchSnapshot(); + }); + + test('Should render sankeychart in DeclarativeChart', () => { + // Arrange + const plotlySchema = require('./tests/schema/fluent_sankey_test.json'); + const { container } = render(); + expect(container).toMatchSnapshot(); + }); + + 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..172ed56aa0d0f0 --- /dev/null +++ b/packages/charts/react-charting/src/components/DeclarativeChart/PlotlySchema.ts @@ -0,0 +1,1939 @@ +/* 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' + // adding custom plot types as seen in AI generated plotly schema + | 'gauge'; + +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 cdda8e02c9cd5d..54b10fd5c0edc2 100644 --- a/packages/charts/react-charting/src/components/DeclarativeChart/PlotlySchemaAdapter.ts +++ b/packages/charts/react-charting/src/components/DeclarativeChart/PlotlySchemaAdapter.ts @@ -1,7 +1,6 @@ /* eslint-disable one-var */ /* eslint-disable vars-on-top */ /* eslint-disable no-var */ -/* eslint-disable no-console */ /* eslint-disable @typescript-eslint/no-explicit-any */ import * as React from 'react'; import { bin as d3Bin, extent as d3Extent, sum as d3Sum, min as d3Min, max as d3Max, merge as d3Merge } from 'd3-array'; @@ -18,6 +17,7 @@ import { IHeatMapChartDataPoint, IGroupedVerticalBarChartData, IVerticalBarChartDataPoint, + ISankeyChartData, } from '../../types/IDataPoint'; import { ISankeyChartProps } from '../SankeyChart/index'; import { IVerticalStackedBarChartProps } from '../VerticalStackedBarChart/index'; @@ -25,19 +25,179 @@ import { IHorizontalBarChartWithAxisProps } from '../HorizontalBarChartWithAxis/ import { ILineChartProps } from '../LineChart/index'; import { IAreaChartProps } from '../AreaChart/index'; import { IHeatMapChartProps } from '../HeatMapChart/index'; -import { getNextColor } from '../../utilities/colors'; -import { IGaugeChartProps, IGaugeChartSegment } from '../GaugeChart/index'; +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 { findNumericMinMaxOfY } from '../../utilities/utilities'; +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 dashOptions = { + dot: { + strokeDasharray: '1, 5', + strokeLinecap: 'round', + strokeWidth: '2', + lineBorderWidth: '4', + }, + dash: { + strokeDasharray: '5, 5', + strokeLinecap: 'butt', + strokeWidth: '2', + lineBorderWidth: '4', + }, + longdash: { + strokeDasharray: '10, 5', + strokeLinecap: 'butt', + strokeWidth: '2', + lineBorderWidth: '4', + }, + dashdot: { + strokeDasharray: '5, 5, 1, 5', + strokeLinecap: 'butt', + strokeWidth: '2', + lineBorderWidth: '4', + }, + longdashdot: { + strokeDasharray: '10, 5, 1, 5', + strokeLinecap: 'butt', + strokeWidth: '2', + lineBorderWidth: '4', + }, + solid: { + strokeDasharray: '0', + strokeLinecap: 'butt', + strokeWidth: '2', + lineBorderWidth: '4', + }, +} as const; +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 getColor = (legendLabel: string, colorMap: React.MutableRefObject>): string => { +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; + } + + 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); +}; + +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 : 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: Datum[] | Datum[][] | TypedArray): any[] => { + const presentYear = new Date().getFullYear(); + 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; + }); + for (let i = dates.length - 1; i > 0; i--) { + const currentMonth = dates[i]!.getMonth(); + const previousMonth = dates[i - 1]!.getMonth(); + const currentYear = dates[i]!.getFullYear(); + const previousYear = dates[i - 1]!.getFullYear(); + if (previousMonth >= currentMonth) { + dates[i - 1]!.setFullYear(dates[i]!.getFullYear() - 1); + } else if (previousYear > currentYear) { + dates[i - 1]!.setFullYear(currentYear); + } + } + xValues = (xValues as Datum[]).map((month, index) => { + return `${month} 01, ${dates[index]!.getFullYear()}`; + }); + return xValues; +}; + +export const getColor = ( + legendLabel: string, + colorMap: React.MutableRefObject>, + isDarkTheme?: boolean, +): string => { if (!colorMap.current.has(legendLabel)) { - const nextColor = getNextColor(colorMap.current.size + 1); + const nextColor = getNextColor(colorMap.current.size + 1, 0, isDarkTheme); colorMap.current.set(legendLabel, nextColor); return nextColor; } @@ -45,147 +205,212 @@ export const getColor = (legendLabel: string, colorMap: React.MutableRefObject | 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); + 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 = layout?.width || 440; - const height: number = layout?.height || 220; - const hideLabels = firstData.textinfo ? !['value', 'percent'].includes(firstData.textinfo) : false; - const donutMarginHorizontal = hideLabels ? 0 : 80; - const donutMarginVertical = 40 + (hideLabels ? 0 : 40); + 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; + const donutMarginHorizontal: number = hideLabels ? 0 : 80; + const donutMarginVertical: number = 40 + (hideLabels ? 0 : 40); const innerRadius: number = firstData.hole ? firstData.hole * (Math.min(width - donutMarginHorizontal, height - donutMarginVertical) / 2) : 0; - - const styles: IDonutChartProps['styles'] = { - root: { - '[class^="arcLabel"]': { - fontSize: firstData.textfont?.size, - }, - }, - }; + const { chartTitle } = getTitles(input.layout); return { data: { - chartTitle: layout?.title, + 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, - styles, + showLabelsInPercent: firstData.textinfo ? ['percent', 'label+percent'].includes(firstData.textinfo) : true, }; }; 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'); - data.forEach((series: any, index1: number) => { - series.x?.forEach((x: string | number, index2: number) => { + if (!isNumberArray(series.y)) { + throw new Error('transform to VSBC:: y values should be numeric'); + } + + (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}`; + const legend: string = getLegend(series, index1); + const yVal: number = (series.y?.[index2] as number) ?? 0; if (series.type === 'bar') { - const color = getColor(legend, colorMap); + const color = getColor(legend, colorMap, isDarkTheme); mapXToDataPoints[x].chartData.push({ legend, - data: series.y?.[index2], + data: yVal, color, }); - } else if (series.type === 'line') { - const color = getColor(legend, colorMap); + } else if (series.type === 'scatter' || isLineData(series) || !!fallbackVSBC) { + const color = getColor(legend, colorMap, isDarkTheme); mapXToDataPoints[x].lineData!.push({ legend, - y: series.y?.[index2], + ...(series.line?.dash && dashOptions[series.line.dash] + ? { lineOptions: { ...dashOptions[series.line.dash] } } + : {}), + 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(input.layout); + return { data: Object.values(mapXToDataPoints), - chartTitle: layout?.title, // width: layout?.width, // height: layout?.height, barWidth: 'auto', yMaxValue, + chartTitle, + 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 color = getColor(legend, colorMap); + 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(input.layout); + return { data: Object.values(mapXToDataPoints), - chartTitle: layout?.title, // width: layout?.width, // height: layout?.height, barwidth: 'auto', + chartTitle, + 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(); @@ -210,13 +435,13 @@ 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 = series.name || `Series ${index + 1}`; - const color = getColor(legend, colorMap); + const legend: string = getLegend(series, index); + const color: string = getColor(legend, colorMap, isDarkTheme); let y = bucket.length; if (series.histnorm === 'percent') { @@ -247,44 +472,58 @@ export const transformPlotlyJsonToVBCProps = ( }); }); + const { chartTitle, xAxisTitle, yAxisTitle } = getTitles(input.layout); + return { data: vbcData, - chartTitle: layout?.title, // width: layout?.width, // height: layout?.height, - hideLegend: true, - barWidth: 24, supportNegativeData: true, + chartTitle, + xAxisTitle, + yAxisTitle, + mode: 'plotly', + hideTickOverlap: true, }; }; 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 = series.name || `Series ${index + 1}`; - const lineColor = getColor(legend, colorMap); + 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, + ...(series.line?.dash && dashOptions[series.line.dash] + ? { lineOptions: { ...dashOptions[series.line.dash] } } + : {}), + 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 yMinMaxValues = findNumericMinMaxOfY(chartData); + const { chartTitle, xAxisTitle, yAxisTitle } = getTitles(input.layout); + const chartProps: IChartProps = { - chartTitle: layout.title || '', + chartTitle, lineChartData: chartData, }; @@ -292,115 +531,163 @@ export const transformPlotlyJsonToScatterChartProps = ( return { data: chartProps, supportNegativeData: true, + xAxisTitle, + yAxisTitle, + secondaryYAxistitle: secondaryYAxisValues.secondaryYAxistitle, + secondaryYScaleOptions: secondaryYAxisValues.secondaryYScaleOptions, + mode, + hideTickOverlap: true, } as IAreaChartProps; } else { return { data: chartProps, supportNegativeData: true, + xAxisTitle, + yAxisTitle, + secondaryYAxistitle: secondaryYAxisValues.secondaryYAxistitle, + secondaryYScaleOptions: secondaryYAxisValues.secondaryYScaleOptions, + roundedTicks: true, + yMinValue: yMinMaxValues.startValue, + yMaxValue: yMinMaxValues.endValue, + 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) => { - const color = getColor(yValue, colorMap); + 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(); - - const chartHeight = layout.height || 350; - const margin = layout.margin?.l || 0; - const padding = layout.margin?.pad || 0; - const availableHeight = chartHeight - margin - padding; - const numberOfBars = data[0].y.length; - const gapFactor = 0.5; + .flat() + //reversing the order to invert the Y bars order as required by plotly. + .reverse(); + + 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 = (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(input.layout); + return { data: chartData, - chartTitle: layout.title || '', + chartTitle, + xAxisTitle, + yAxisTitle, + secondaryYAxistitle: + typeof input.layout?.yaxis2?.title === 'string' + ? input.layout?.yaxis2?.title + : input.layout?.yaxis2?.title?.text || '', barHeight, showYAxisLables: true, styles: { root: { height: chartHeight, - width: 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, }); - zMin = Math.min(zMin, zVal); - zMax = Math.max(zMax, zVal); + if (typeof zVal === 'number') { + zMin = Math.min(zMin, zVal); + zMax = Math.max(zMax, zVal); + } }); }); const heatmapData: IHeatMapChartData = { - legend: firstData.name || '', + legend: firstData.name, data: heatmapDataPoints, value: 0, }; - // Convert normalized values to actual values - const domainValuesForColorScale: number[] = firstData.colorscale?.map((arr: any) => arr[0] * (zMax - zMin) + zMin); - const rangeValuesForColorScale: string[] = firstData.colorscale?.map((arr: any) => arr[1]); + // Initialize domain and range to default values + const defaultDomain = [zMin, (zMax + zMin) / 2, 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], domainValuesForColorScale, rangeValuesForColorScale, hideLegend: true, + showYAxisLables: true, + chartTitle, + xAxisTitle, + yAxisTitle, + sortOrder: 'none', + hideTickOverlap: true, }; }; 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(x => x.source !== x.target); // Filter out self-references (circular links) + // 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) => { - const color = getColor(label, colorMap); + nodes: node.label?.map((label: string, index: number) => { + const color = getColor(label, colorMap, isDarkTheme); return { nodeId: index, @@ -413,19 +700,22 @@ export const transformPlotlyJsonToSankeyProps = ( ...validLink, }; }), - }; + } as ISankeyChartData; - const width: number = layout?.width || 440; - const height: number = layout?.height || 220; + const width: number = input.layout?.width ?? 440; + const height: number = input.layout?.height ?? 220; const styles: ISankeyChartProps['styles'] = { root: { - fontSize: layout.font?.size, + ...(input.layout?.font?.size ? { fontSize: input.layout.font?.size } : {}), }, }; const shouldResize: number = width + height; + + const { chartTitle } = getTitles(input.layout); + return { data: { - chartTitle: layout?.title, + chartTitle, SankeyChartData: sankeyChartData, }, width, @@ -437,33 +727,46 @@ 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?.map((step: any, index: number): IGaugeChartSegment => { - const legend = step.name || `Segment ${index + 1}`; - const color = getColor(legend, colorMap); - return { - legend, - size: step.range?.[1] - step.range?.[0], - color, - }; - }); + const segments = firstData.gauge?.steps?.length + ? firstData.gauge.steps.map((step: any, index: number): IGaugeChartSegment => { + const legend = step.name || `Segment ${index + 1}`; + const color = getColor(legend, colorMap, isDarkTheme); + return { + legend, + size: step.range?.[1] - step.range?.[0], + color, + }; + }) + : [ + { + legend: 'Current', + size: firstData.value ?? 0 - (firstData.gauge?.axis?.range?.[0] ?? 0), + color: getColor('Current', colorMap, isDarkTheme), + }, + { + legend: 'Target', + 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); + const color = getColorFromToken(DataVizPalette.success, isDarkTheme); sublabelColor = color; } else { sublabel = `\u25BC ${Math.abs(diff)}`; - const color = getColor(firstData.delta.decreasing?.color || '', colorMap); + const color = getColorFromToken(DataVizPalette.error, isDarkTheme); sublabelColor = color; } } @@ -474,27 +777,50 @@ export const transformPlotlyJsonToGaugeProps = ( }, }; + const { chartTitle } = getTitles(input.layout); + return { segments, - chartValue: firstData.value, - chartTitle: firstData.title?.text, + chartValue: firstData.value ?? 0, + chartTitle, sublabel, // range values can be null - minValue: firstData.gauge?.axis?.range?.[0] ?? undefined, - maxValue: firstData.gauge?.axis?.range?.[1] ?? undefined, - chartValueFormat: () => firstData.value, - width: layout?.width, - height: layout?.height, - hideLegend: true, + 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?.toString() ?? '', + width: input.layout?.width ?? 440, + height: input.layout?.height ?? 220, styles, + variant: firstData.gauge?.steps?.length ? GaugeChartVariant.MultipleSegments : GaugeChartVariant.SingleSegment, }; }; +const MAX_DEPTH = 15; +export const sanitizeJson = (jsonObject: any, depth: number = 0): any => { + if (depth > MAX_DEPTH) { + throw new Error('Maximum json depth exceeded'); + } + + if (typeof jsonObject === 'object' && jsonObject !== null) { + for (const key in jsonObject) { + if (jsonObject.hasOwnProperty(key)) { + if (typeof jsonObject[key] === 'string') { + jsonObject[key] = jsonObject[key].replace(//g, '>'); + } else { + jsonObject[key] = sanitizeJson(jsonObject[key], depth + 1); + } + } + } + } + + return jsonObject; +}; + function isTypedArray(a: any) { return ArrayBuffer.isView(a) && !(a instanceof DataView); } -function isArrayOrTypedArray(a: any) { +export function isArrayOrTypedArray(a: any) { return Array.isArray(a) || isTypedArray(a); } @@ -521,9 +847,6 @@ var baseContainer: any, baseAttrName: any; export function findArrayAttributes(trace: any) { // Init basecontainer and baseAttrName crawlIntoTrace(baseContainer, 0, ''); - for (const attribute of arrayAttributes) { - console.log(attribute); - } } function crawlIntoTrace(container: any, i: number, astrPartial: any) { 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..67c35e1e8482fe --- /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('Should return true when input array contains date in simple date Object format', () => { + expect(isDateArray([new Date(2025, 11, 2), new Date(2025, 10, 2)])).toBe(true); + }); + + test('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 new file mode 100644 index 00000000000000..692f2a5817067e --- /dev/null +++ b/packages/charts/react-charting/src/components/DeclarativeChart/__snapshots__/DeclarativeChartRTL.test.tsx.snap @@ -0,0 +1,27687 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`DeclarativeChart Should render areachart in DeclarativeChart 1`] = ` +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+`; + +exports[`DeclarativeChart Should render donutchart in DeclarativeChart 1`] = ` +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + +
+
+ +
+
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+`; + +exports[`DeclarativeChart Should render gaugechart in DeclarativeChart 1`] = ` +
+
+
+ + + + + 0 + + + 500 + + + + + + + + + + + + ▲ 20 + + + +
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+`; + +exports[`DeclarativeChart Should render heatmapchart in DeclarativeChart 1`] = ` +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + y_0 + + + + + + + + + y_1 + + + + + + + + + y_2 + + + + + + + + + y_3 + + + + + + + + + y_4 + + + + + + + + + y_5 + + + + + + + + + y_6 + + + + + + + + + y_7 + + + + + + + + + y_8 + + + + + + + + + y_9 + + + + + + + + + y_10 + + + + + + + + + y_11 + + + + + + + + + y_12 + + + + + + + + + y_13 + + + + + + + + + y_14 + + + + + + + + + y_15 + + + + + + + + + y_16 + + + + + + + + + y_17 + + + + + + + + + y_18 + + + + + + + + + y_19 + + + + + + + + 1.475 + + + + + + 76.571 + + + + + + 22.444 + + + + + + -11.755 + + + + + + 31.65 + + + + + + -6.747 + + + + + + 10.677 + + + + + + 18.29 + + + + + + 44.042 + + + + + + -0.967 + + + + + + -10.03 + + + + + + 26.331 + + + + + + 23.745 + + + + + + 21.584 + + + + + + -5.055 + + + + + + -12.304 + + + + + + 22.028 + + + + + + 68.761 + + + + + + -11.105 + + + + + + 32.939 + + + + + + 2.009 + + + + + + 68.771 + + + + + + 27.561 + + + + + + -11.973 + + + + + + 27.652 + + + + + + -8.995 + + + + + + 16.012 + + + + + + 27.497 + + + + + + 42.223 + + + + + + 9.143 + + + + + + -9.497 + + + + + + 25.872 + + + + + + 29.591 + + + + + + 17.887 + + + + + + -5.273 + + + + + + -12.232 + + + + + + 25.219 + + + + + + 55.45 + + + + + + -16.161 + + + + + + 32.269 + + + + + + 8.835 + + + + + + 58.634 + + + + + + 32.726 + + + + + + -13.466 + + + + + + 31.313 + + + + + + -1.937 + + + + + + 14.893 + + + + + + 23.63 + + + + + + 41.773 + + + + + + 9.082 + + + + + + -6.035 + + + + + + 26.401 + + + + + + 30.052 + + + + + + 23.834 + + + + + + -3.561 + + + + + + -10.717 + + + + + + 25.987 + + + + + + 55.138 + + + + + + -12.222 + + + + + + 30.769 + + + + + + 9.529 + + + + + + 66.159 + + + + + + 25.727 + + + + + + -16.01 + + + + + + 24.778 + + + + + + -1.283 + + + + + + 19.064 + + + + + + 14.51 + + + + + + 43.571 + + + + + + 7.891 + + + + + + 1.673 + + + + + + 11.217 + + + + + + 25.858 + + + + + + 18.233 + + + + + + -1.542 + + + + + + -9.409 + + + + + + 24.781 + + + + + + 55.729 + + + + + + -6.132 + + + + + + 32.124 + + + + + + 18.359 + + + + + + 66.768 + + + + + + 23.379 + + + + + + -9.222 + + + + + + 28.232 + + + + + + -0.362 + + + + + + 28.916 + + + + + + 11.189 + + + + + + 43.301 + + + + + + 5.001 + + + + + + 1.956 + + + + + + 17.28 + + + + + + 26.179 + + + + + + 21.572 + + + + + + -1.316 + + + + + + -9.439 + + + + + + 18.313 + + + + + + 54.773 + + + + + + -13.619 + + + + + + 34.046 + + + + + + 17.878 + + + + + + 65.616 + + + + + + 21.107 + + + + + + -9.253 + + + + + + 27.88 + + + + + + -2.832 + + + + + + 26.138 + + + + + + 24.926 + + + + + + 41.228 + + + + + + 4.292 + + + + + + 4.714 + + + + + + 16.715 + + + + + + 27.49 + + + + + + 14.998 + + + + + + -1.042 + + + + + + -0.151 + + + + + + 11.563 + + + + + + 54.382 + + + + + + -15.369 + + + + + + 25.019 + + + + + + 9.197 + + + + + + 55.986 + + + + + + 19.688 + + + + + + -1.176 + + + + + + 26.788 + + + + + + -5.207 + + + + + + 29.755 + + + + + + 35.459 + + + + + + 48.543 + + + + + + 3.275 + + + + + + 7.64 + + + + + + 6.615 + + + + + + 27.521 + + + + + + 17.139 + + + + + + -0.713 + + + + + + 3.492 + + + + + + 10.663 + + + + + + 62.797 + + + + + + -7.102 + + + + + + 25.969 + + + + + + 3.674 + + + + + + 55.665 + + + + + + 22.222 + + + + + + -2.187 + + + + + + 28.014 + + + + + + -1.934 + + + + + + 29.164 + + + + + + 44.051 + + + + + + 47.139 + + + + + + -2.533 + + + + + + 2.46 + + + + + + 19.673 + + + + + + 23.436 + + + + + + 18.465 + + + + + + 3.251 + + + + + + 7.464 + + + + + + 5.836 + + + + + + 63.637 + + + + + + -2.318 + + + + + + 28.362 + + + + + + -1.25 + + + + + + 52.075 + + + + + + 16.574 + + + + + + 0.625 + + + + + + 25.671 + + + + + + 2.883 + + + + + + 21.055 + + + + + + 45.55 + + + + + + 54.79 + + + + + + -1.132 + + + + + + -6.837 + + + + + + 15.503 + + + + + + 16.435 + + + + + + 20.053 + + + + + + 2.31 + + + + + + 6.64 + + + + + + 3.455 + + + + + + 54.703 + + + + + + -3.275 + + + + + + 34.698 + + + + + + -0.342 + + + + + + 52.258 + + + + + + 14.63 + + + + + + -1.148 + + + + + + 19.815 + + + + + + -0.36 + + + + + + 22.773 + + + + + + 45.168 + + + + + + 50.906 + + + + + + -4.123 + + + + + + -10.089 + + + + + + 17.771 + + + + + + 17.405 + + + + + + 19.428 + + + + + + 10.155 + + + + + + 9.416 + + + + + + 1.911 + + + + + + 55.503 + + + + + + -1.087 + + + + + + 29.943 + + + + + + 1.332 + + + + + + 45.903 + + + + + + 9.162 + + + + + + -1.294 + + + + + + 21.982 + + + + + + -2.005 + + + + + + 23.758 + + + + + + 42.681 + + + + + + 44.652 + + + + + + -3.233 + + + + + + -11.701 + + + + + + 8.769 + + + + + + 21.48 + + + + + + 11.751 + + + + + + 10.314 + + + + + + 6.045 + + + + + + 0.396 + + + + + + 56.8 + + + + + + 9.687 + + + + + + 29.574 + + + + + + 0.029 + + + + + + 47.894 + + + + + + 13.438 + + + + + + 17.917 + + + + + + 17.039 + + + + + + -4.775 + + + + + + 12.169 + + + + + + 40.423 + + + + + + 37.225 + + + + + + 0.221 + + + + + + -9.687 + + + + + + 10.609 + + + + + + 22.489 + + + + + + 10.669 + + + + + + 13.957 + + + + + + 6.84 + + + + + + 2.067 + + + + + + 54.582 + + + + + + 3.532 + + + + + + 24.533 + + + + + + -7.513 + + + + + + 44.212 + + + + + + 14.48 + + + + + + 17.66 + + + + + + 14.436 + + + + + + -8.631 + + + + + + 18.921 + + + + + + 41.962 + + + + + + 30.993 + + + + + + 0.382 + + + + + + -9.481 + + + + + + 1.627 + + + + + + 20.522 + + + + + + 9.822 + + + + + + 15.658 + + + + + + 12.855 + + + + + + 10.724 + + + + + + 41.765 + + + + + + 2.234 + + + + + + 16.089 + + + + + + -6.878 + + + + + + 44.044 + + + + + + 13.548 + + + + + + 17.74 + + + + + + 15.791 + + + + + + -6.564 + + + + + + 21.499 + + + + + + 38.247 + + + + + + 25.71 + + + + + + 2.225 + + + + + + -10.094 + + + + + + 1.914 + + + + + + 28.854 + + + + + + 9.12 + + + + + + 16.77 + + + + + + 7.358 + + + + + + 5.875 + + + + + + 39.121 + + + + + + 1.342 + + + + + + 16.778 + + + + + + 1.385 + + + + + + 28.889 + + + + + + 12.971 + + + + + + 21.143 + + + + + + 7.466 + + + + + + -2.108 + + + + + + 16.027 + + + + + + 40.708 + + + + + + 25.966 + + + + + + 0.904 + + + + + + -0.672 + + + + + + 2.66 + + + + + + 36.094 + + + + + + 12.792 + + + + + + 16.292 + + + + + + 13.792 + + + + + + 9.901 + + + + + + 36.748 + + + + + + 26.577 + + + + + + 16.005 + + + + + + 10.425 + + + + + + 28.78 + + + + + + 3.274 + + + + + + 8.67 + + + + + + 17.757 + + + + + + -6.897 + + + + + + 17.337 + + + + + + 42.701 + + + + + + 27.376 + + + + + + 10.417 + + + + + + 5.955 + + + + + + 15.043 + + + + + + 32.126 + + + + + + 11.295 + + + + + + 16.313 + + + + + + 15.444 + + + + + + 10.444 + + + + + + 33.076 + + + + + + 22.678 + + + + + + 14.911 + + + + + + 12.733 + + + + + + 24.159 + + + + + + 1.864 + + + + + + 9.195 + + + + + + 19.789 + + + + + + -6.834 + + + + + + 9.969 + + + + + + 46.341 + + + + + + 27.31 + + + + + + 15.452 + + + + + + 6.691 + + + + + + 14.553 + + + + + + 31.321 + + + + + + 9.311 + + + + + + 12.005 + + + + + + 13.06 + + + + + + 10.255 + + + + + + 29.181 + + + + + + 17.203 + + + + + + 15.963 + + + + + + 16.105 + + + + + + 16.816 + + + + + + -1.08 + + + + + + 13.038 + + + + + + 25.071 + + + + + + -6.016 + + + + + + 12.249 + + + + + + 35.618 + + + + + + 20.621 + + + + + + 18.322 + + + + + + 5.106 + + + + + + 20.478 + + + + + + 13.078 + + + + + + 4.271 + + + + + + 10.329 + + + + + + 11.953 + + + + + + 1.551 + + + + + + 28.102 + + + + + + 11.122 + + + + + + 17.272 + + + + + + 18.073 + + + + + + 6.872 + + + + + + 2.633 + + + + + + 8.91 + + + + + + 23.298 + + + + + + 9.184 + + + + + + 18.052 + + + + + + 32.088 + + + + + + 15.863 + + + + + + 20.517 + + + + + + 1.567 + + + + + + 19.031 + + + + + + 12.134 + + + + + + 8.724 + + + + + + 8.972 + + + + + + 9.772 + + + + + + 4.761 + + + + + + 23.827 + + + + + + 14.369 + + + + + + 9.73 + + + + + + 12 + + + + + + 11.697 + + + + + + 7.175 + + + + + + 11.444 + + + + + + 23.649 + + + + + + 10.041 + + + + + + 10.82 + + + + + + 20.84 + + + + + + 14.378 + + + + + + 9.546 + + + + + + 2.117 + + + + + + 24.053 + + + + + + 14.742 + + + + + + 11.223 + + + + + + 2.906 + + + + + + 12.524 + + + + + + 12.426 + + + + + + 15.787 + + + + + + 25.828 + + + + + + 15.884 + + + +
+
+
+`; + +exports[`DeclarativeChart Should render linechart in DeclarativeChart 1`] = ` +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+`; + +exports[`DeclarativeChart Should render piechart in DeclarativeChart 1`] = ` +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+`; + +exports[`DeclarativeChart Should render sankeychart in DeclarativeChart 1`] = ` +
+ +
+`; + +exports[`DeclarativeChart Should render verticalbarchart in DeclarativeChart 1`] = ` +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+`; 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..fa6cf6a1d56e51 --- /dev/null +++ b/packages/charts/react-charting/src/components/DeclarativeChart/__snapshots__/PlotlySchemaAdapterUT.test.tsx.snap @@ -0,0 +1,4938 @@ +// 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, + "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, + "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", + }, + ], + }, + ], + "hideTickOverlap": true, + "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, + "hideTickOverlap": 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", + }, + ], + "hideTickOverlap": true, + "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", + }, + ], + }, + "hideTickOverlap": true, + "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", + }, + ], + }, + "hideTickOverlap": true, + "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, + }, + ], + "hideTickOverlap": true, + "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", + }, + ], + "hideTickOverlap": true, + "mode": "plotly", + "secondaryYAxistitle": undefined, + "secondaryYScaleOptions": undefined, + "xAxisTitle": "", + "yAxisTitle": "", + "yMaxValue": 3400, +} +`; diff --git a/packages/charts/react-charting/src/components/DeclarativeChart/imageExporter.ts b/packages/charts/react-charting/src/components/DeclarativeChart/imageExporter.ts new file mode 100644 index 00000000000000..aa7aa8be6dd123 --- /dev/null +++ b/packages/charts/react-charting/src/components/DeclarativeChart/imageExporter.ts @@ -0,0 +1,273 @@ +import { create as d3Create, select as d3Select, Selection } from 'd3-selection'; +import { resolveCSSVariables } from '../../utilities/index'; + +/** + * {@docCategory DeclarativeChart} + */ +export interface IImageExportOptions { + width?: number; + height?: number; + scale?: number; + background?: string; +} + +export function toImage(chartContainer?: HTMLElement | null, opts: IImageExportOptions = {}): Promise { + return new Promise((resolve, reject) => { + if (!chartContainer) { + return reject(new Error('Chart container is not defined')); + } + + try { + const background = + typeof opts.background === 'string' ? resolveCSSVariables(chartContainer, opts.background) : 'transparent'; + const svg = toSVG(chartContainer, background); + + const svgData = new XMLSerializer().serializeToString(svg.node); + const svgDataUrl = 'data:image/svg+xml;base64,' + btoa(unescapePonyfill(encodeURIComponent(svgData))); + + svgToPng(svgDataUrl, { + width: opts.width || svg.width, + height: opts.height || svg.height, + scale: opts.scale, + }) + .then(resolve) + .catch(reject); + } catch (err) { + return reject(err); + } + }); +} + +const SVG_STYLE_PROPERTIES = ['display', 'fill', 'fill-opacity', 'opacity', 'stroke', 'stroke-width', 'transform']; +const SVG_TEXT_STYLE_PROPERTIES = ['font-family', 'font-size', 'font-weight', 'text-anchor']; + +function toSVG(chartContainer: HTMLElement, background: string) { + const svg = chartContainer.querySelector('svg'); + if (!svg) { + throw new Error('SVG not found'); + } + + const clonedSvg = d3Select(svg.cloneNode(true) as SVGSVGElement) + .attr('width', null) + .attr('height', null) + .attr('viewBox', null); + const svgElements = svg.getElementsByTagName('*'); + const clonedSvgElements = clonedSvg.node()!.getElementsByTagName('*'); + + for (let i = 0; i < svgElements.length; i++) { + if (svgElements[i].tagName.toLowerCase() === 'text') { + copyStyle([...SVG_STYLE_PROPERTIES, ...SVG_TEXT_STYLE_PROPERTIES], svgElements[i], clonedSvgElements[i]); + } else { + copyStyle(SVG_STYLE_PROPERTIES, svgElements[i], clonedSvgElements[i]); + } + } + + const { width: svgWidth, height: svgHeight } = svg.getBoundingClientRect(); + const legendGroup = cloneLegendsToSVG(chartContainer, svgWidth, svgHeight); + const w1 = Math.max(svgWidth, legendGroup.width); + const h1 = svgHeight + legendGroup.height; + + if (legendGroup.node) { + clonedSvg.append(() => legendGroup.node); + } + clonedSvg + .insert('rect', ':first-child') + .attr('x', 0) + .attr('y', 0) + .attr('width', w1) + .attr('height', h1) + .attr('fill', background); + clonedSvg.attr('width', w1).attr('height', h1).attr('viewBox', `0 0 ${w1} ${h1}`); + + return { + node: clonedSvg.node()!, + width: w1, + height: h1, + }; +} + +const LEGEND_RECT_STYLE_PROPERTIES_MAP = { + 'background-color': 'fill', + 'border-color': 'stroke', +}; +const LEGEND_TEXT_STYLE_PROPERTIES_MAP = { + color: 'fill', + 'font-family': 'font-family', + 'font-size': 'font-size', + 'font-weight': 'font-weight', + opacity: 'opacity', +}; + +function cloneLegendsToSVG(chartContainer: HTMLElement, svgWidth: number, svgHeight: number) { + const legendButtons = chartContainer.querySelectorAll(` + button[class^="legend-"], + [class^="legendContainer-"] div[class^="overflowIndicationTextStyle-"], + [class^="legendsContainer-"] div[class^="overflowIndicationTextStyle-"] + `); + if (legendButtons.length === 0) { + return { + node: null, + width: 0, + height: 0, + }; + } + + const legendGroup = d3Create('svg:g'); + let legendX = 0; + let legendY = 8; + let legendLine: Selection[] = []; + const legendLines: (typeof legendLine)[] = []; + const legendLineWidths: number[] = []; + + for (let i = 0; i < legendButtons.length; i++) { + const { width: legendWidth } = legendButtons[i].getBoundingClientRect(); + const legendItem = legendGroup.append('g'); + + legendLine.push(legendItem); + if (legendX + legendWidth > svgWidth && legendLine.length > 1) { + legendLine.pop(); + legendLines.push(legendLine); + legendLineWidths.push(legendX); + + legendLine = [legendItem]; + legendX = 0; + legendY += 32; + } + + let legendText: HTMLDivElement | null; + let textOffset = 0; + + if (legendButtons[i].tagName.toLowerCase() === 'button') { + const legendRect = legendButtons[i].querySelector('[class^="rect"]'); + + legendText = legendButtons[i].querySelector('[class^="text"]'); + legendItem + .append('rect') + .attr('x', legendX + 8) + .attr('y', svgHeight + legendY + 8) + .attr('width', 12) + .attr('height', 12) + .attr('stroke-width', 1) + .call(selection => copyStyle(LEGEND_RECT_STYLE_PROPERTIES_MAP, legendRect!, selection.node()!)); + textOffset = 28; + } else { + legendText = legendButtons[i] as HTMLDivElement; + textOffset = 8; + } + + legendItem + .append('text') + .attr('x', legendX + textOffset) + .attr('y', svgHeight + legendY + 8) + .attr('dominant-baseline', 'hanging') + .text(legendText!.textContent) + .call(selection => copyStyle(LEGEND_TEXT_STYLE_PROPERTIES_MAP, legendText!, selection.node()!)); + legendX += legendWidth; + } + + legendLines.push(legendLine); + legendLineWidths.push(legendX); + legendY += 32; + + const centerLegends = true; + if (centerLegends) { + legendLines.forEach((ln, idx) => { + const offsetX = Math.max((svgWidth - legendLineWidths[idx]) / 2, 0); + ln.forEach(item => { + item.attr('transform', `translate(${offsetX}, 0)`); + }); + }); + } + + return { + node: legendGroup.node(), + width: Math.max(...legendLineWidths), + height: legendY, + }; +} + +function svgToPng(svgDataUrl: string, opts: IImageExportOptions = {}): Promise { + return new Promise((resolve, reject) => { + const scale = opts.scale || 1; + const w0 = opts.width || 300; + const h0 = opts.height || 150; + const w1 = scale * w0; + const h1 = scale * h0; + + const canvas = document.createElement('canvas'); + const img = new Image(); + + canvas.width = w1; + canvas.height = h1; + + img.onload = function () { + const ctx = canvas.getContext('2d'); + if (!ctx) { + return reject(new Error('Canvas context is null')); + } + + ctx.clearRect(0, 0, w1, h1); + ctx.drawImage(img, 0, 0, w1, h1); + + const imgData = canvas.toDataURL('image/png'); + resolve(imgData); + }; + + img.onerror = function (err) { + reject(err); + }; + + img.src = svgDataUrl; + }); +} + +const hex2 = /^[\da-f]{2}$/i; +const hex4 = /^[\da-f]{4}$/i; + +/** + * A ponyfill for the deprecated `unescape` method, taken from the `core-js` library. + * + * Source: {@link https://github.com/zloirock/core-js/blob/167136f479d3b8519953f2e4c534ecdd1031d3cf/packages/core-js/modules/es.unescape.js core-js/packages/core-js/modules/es.unescape.js} + */ +function unescapePonyfill(str: string) { + let result = ''; + const length = str.length; + let index = 0; + let chr; + let part; + while (index < length) { + chr = str.charAt(index++); + if (chr === '%') { + if (str.charAt(index) === 'u') { + part = str.slice(index + 1, index + 5); + if (hex4.exec(part)) { + result += String.fromCharCode(parseInt(part, 16)); + index += 5; + continue; + } + } else { + part = str.slice(index, index + 2); + if (hex2.exec(part)) { + result += String.fromCharCode(parseInt(part, 16)); + index += 2; + continue; + } + } + } + result += chr; + } + return result; +} + +function copyStyle(properties: string[] | Record, fromEl: Element, toEl: Element) { + const styles = getComputedStyle(fromEl); + if (Array.isArray(properties)) { + properties.forEach(prop => { + d3Select(toEl).style(prop, styles.getPropertyValue(prop)); + }); + } else { + Object.entries(properties).forEach(([fromProp, toProp]) => { + d3Select(toEl).style(toProp, styles.getPropertyValue(fromProp)); + }); + } +} diff --git a/packages/charts/react-charting/src/components/DeclarativeChart/index.ts b/packages/charts/react-charting/src/components/DeclarativeChart/index.ts new file mode 100644 index 00000000000000..64d5b58644526d --- /dev/null +++ b/packages/charts/react-charting/src/components/DeclarativeChart/index.ts @@ -0,0 +1,2 @@ +export * from './DeclarativeChart'; +export type { IImageExportOptions } from './imageExporter'; diff --git a/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_area_test.json b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_area_test.json new file mode 100644 index 00000000000000..9bb4f973a4df9a --- /dev/null +++ b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_area_test.json @@ -0,0 +1,104 @@ +{ + "visualizer": "plotly", + "data": [ + { + "fill": "tonexty", + "line": { + "color": "rgba(255, 153, 51, 1.0)", + "width": "1.3" + }, + "mode": "lines", + "name": "a", + "type": "scatter", + "x": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + "y": [ + 0.17048910089864067, 0.05390702725063046, 0.7560889217240573, 0.7393313216390578, 0.7562979443674754, + 0.983908108492343, 0.4552096139092071, 0.751939393026647, 0.42441695150031034, 0.6119820237450841 + ], + "fillcolor": "rgba(255, 153, 51, 0.3)" + }, + { + "fill": "tonexty", + "line": { + "color": "rgba(55, 128, 191, 1.0)", + "width": "1.3" + }, + "mode": "lines", + "name": "b", + "type": "scatter", + "x": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + "y": [ + 1.0921498980687505, 0.628379692444796, 1.6804387333467445, 1.1741874271317159, 1.7098535938519392, + 1.0165440369832146, 0.8201578488720772, 1.019179653143562, 0.5391840333768539, 0.9023036941696878 + ], + "fillcolor": "rgba(55, 128, 191, 0.3)" + }, + { + "fill": "tonexty", + "line": { + "color": "rgba(50, 171, 96, 1.0)", + "width": "1.3" + }, + "mode": "lines", + "name": "c", + "type": "scatter", + "x": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + "y": [ + 1.5084498776097979, 1.0993096327196032, 2.5468884763826125, 1.3139261978658, 1.7288516603693358, + 1.3500413551768342, 1.4111774146124456, 1.1245312639069405, 1.4068617318281056, 0.9236499701488171 + ], + "fillcolor": "rgba(50, 171, 96, 0.3)" + }, + { + "fill": "tonexty", + "line": { + "color": "rgba(128, 0, 128, 1.0)", + "width": "1.3" + }, + "mode": "lines", + "name": "d", + "type": "scatter", + "x": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + "y": [ + 1.912915766078795, 1.6450103381519354, 3.523866933241722, 1.656799203492564, 2.666064160881149, + 2.2985767814076814, 1.6491300653173326, 1.2880873970749964, 2.192375146193222, 1.6271909616796654 + ], + "fillcolor": "rgba(128, 0, 128, 0.3)" + } + ], + "layout": { + "legend": { + "font": { + "color": "#4D5663" + }, + "bgcolor": "#F5F6F9" + }, + "xaxis1": { + "title": "", + "tickfont": { + "color": "#4D5663" + }, + "gridcolor": "#E1E5ED", + "titlefont": { + "color": "#4D5663" + }, + "zerolinecolor": "#E1E5ED" + }, + "yaxis1": { + "title": "", + "tickfont": { + "color": "#4D5663" + }, + "zeroline": false, + "gridcolor": "#E1E5ED", + "titlefont": { + "color": "#4D5663" + }, + "zerolinecolor": "#E1E5ED" + }, + "plot_bgcolor": "#F5F6F9", + "paper_bgcolor": "#F5F6F9" + }, + "frames": [], + "selectedLegends": ["a"] +} diff --git a/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_donut_test.json b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_donut_test.json new file mode 100644 index 00000000000000..41426b2dbbd8ea --- /dev/null +++ b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_donut_test.json @@ -0,0 +1,65 @@ +{ + "visualizer": "plotly", + "data": [ + { + "hole": 0.6, + "type": "pie", + "frame": null, + "marker": { + "line": { + "color": "transparent" + }, + "color": "rgba(31,119,180,1)", + "fillcolor": "rgba(31,119,180,1)" + }, + "labels": [ + "AMC", + "Cadillac", + "Camaro", + "Chrysler", + "Datsun", + "Dodge", + "Duster", + "Ferrari", + "Fiat", + "Ford", + "Honda", + "Hornet", + "Lincoln", + "Lotus", + "Maserati", + "Mazda", + "Merc", + "Pontiac", + "Porsche", + "Toyota", + "Valiant", + "Volvo" + ], + "values": [1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 2, 7, 1, 1, 2, 1, 1] + } + ], + "layout": { + "title": "Donut charts using Plotly", + "xaxis": { + "showgrid": false, + "zeroline": false, + "showticklabels": false + }, + "yaxis": { + "showgrid": false, + "zeroline": false, + "showticklabels": false + }, + "margin": { + "b": 40, + "l": 60, + "r": 10, + "t": 25 + }, + "hovermode": "closest", + "showlegend": true + }, + "frames": [], + "selectedLegends": ["Cadillac"] +} diff --git a/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_gauge_test.json b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_gauge_test.json new file mode 100644 index 00000000000000..c92d0d6c0c9ee7 --- /dev/null +++ b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_gauge_test.json @@ -0,0 +1,36 @@ +{ + "visualizer": "plotly", + "data": [ + { + "type": "indicator", + "mode": "gauge+number+delta", + "value": 420, + "title": { "text": "Speed", "font": { "size": 24 } }, + "delta": { "reference": 400, "increasing": { "color": "RebeccaPurple" } }, + "gauge": { + "axis": { "range": [null, 500], "tickwidth": 1, "tickcolor": "darkblue" }, + "bar": { "color": "darkblue" }, + "bgcolor": "white", + "borderwidth": 2, + "bordercolor": "gray", + "steps": [ + { "range": [0, 250], "color": "cyan" }, + { "range": [250, 400], "color": "royalblue" } + ], + "threshold": { + "line": { "color": "red", "width": 4 }, + "thickness": 0.75, + "value": 490 + } + } + } + ], + "layout": { + "width": 500, + "height": 400, + "margin": { "t": 25, "r": 25, "l": 25, "b": 25 }, + "paper_bgcolor": "lavender", + "font": { "color": "darkblue", "family": "Arial" } + }, + "frames": [] +} 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_heatmap_test.json b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_heatmap_test.json new file mode 100644 index 00000000000000..838e81191b4323 --- /dev/null +++ b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_heatmap_test.json @@ -0,0 +1,221 @@ +{ + "visualizer": "plotly", + "data": [ + { + "type": "heatmap", + "x": [ + "x_0", + "x_1", + "x_2", + "x_3", + "x_4", + "x_5", + "x_6", + "x_7", + "x_8", + "x_9", + "x_10", + "x_11", + "x_12", + "x_13", + "x_14", + "x_15", + "x_16", + "x_17", + "x_18", + "x_19" + ], + "y": [ + "y_0", + "y_1", + "y_2", + "y_3", + "y_4", + "y_5", + "y_6", + "y_7", + "y_8", + "y_9", + "y_10", + "y_11", + "y_12", + "y_13", + "y_14", + "y_15", + "y_16", + "y_17", + "y_18", + "y_19" + ], + "z": [ + [ + 12.0, 11.697147742124411, 7.1748009833505355, 11.443688379214382, 23.648522429525176, 10.040502684649338, + 10.819974608119614, 20.83991840239746, 14.378243279399832, 9.546437633051273, 2.117430162487592, + 24.053122758748437, 14.741753869753929, 11.223068582526338, 2.9058799108357736, 12.523922839169199, + 12.426446278371158, 15.786820017213348, 25.828355052498736, 15.884458175971286 + ], + [ + 18.072596781382654, 6.872368565119988, 2.6331323456979367, 8.910260123844887, 23.29825386450679, + 9.18418261775059, 18.052236884018036, 32.088269277118485, 15.862814449470617, 20.517302217015732, + 1.5668378537843557, 19.031137709612036, 12.133745300119848, 8.724453334098921, 8.972456038301432, + 9.771921362871048, 4.761205803361531, 23.82727745555418, 14.369250386770794, 9.730029718884163 + ], + [ + 16.104827483834423, 16.816096580158092, -1.0796033248100874, 13.037577162924944, 25.071276081749808, + -6.016235615271988, 12.248777535804365, 35.617617939013286, 20.621055215762404, 18.321563171124787, + 5.106104151848498, 20.47764211274059, 13.078423154116999, 4.270904076038434, 10.32885307002288, + 11.953280688550777, 1.5514493835400103, 28.102083355215736, 11.122082151320692, 17.271525748515398 + ], + [ + 12.732656491556462, 24.158612074358526, 1.8639666906231516, 9.195075731494875, 19.788944565361437, + -6.833645216204284, 9.969142303073252, 46.34145242145437, 27.310374393715577, 15.451738777747869, + 6.691398648622392, 14.55281641333698, 31.321025344254267, 9.311054030160307, 12.004790333591908, + 13.059625413572078, 10.25485330260371, 29.181400631242038, 17.203123079730577, 15.96262678993938 + ], + [ + 10.424697200562369, 28.78022939969912, 3.274446200066722, 8.669870516018236, 17.75655781585482, + -6.896721183137775, 17.337127681913973, 42.70107878756259, 27.376076996458107, 10.416788406228507, + 5.9545352540812, 15.043018310072712, 32.12573718137715, 11.294834569956391, 16.313424113247194, + 15.444451104553893, 10.443516068409753, 33.07558322142471, 22.67825393852671, 14.910979364805373 + ], + [ + 1.3848305486418013, 28.88858899620542, 12.971410893817621, 21.143305039916708, 7.466382276034302, + -2.108394838355938, 16.027000754389025, 40.70844626018491, 25.966261645863177, 0.9043901831061678, + -0.6718858579700804, 2.6597070827875093, 36.093975687401766, 12.79240265673884, 16.292076219475025, + 13.792475502830154, 9.90068532879486, 36.74806639404701, 26.577346684827898, 16.005211030243927 + ], + [ + -6.877933971525136, 44.04384439381119, 13.548126342387011, 17.74014481550033, 15.7912983146064, + -6.563883600581922, 21.49865383744765, 38.24729505908534, 25.710457133039732, 2.2251747151953722, + -10.093623877175773, 1.9137585062069147, 28.853944000537858, 9.119846857537635, 16.770107402461807, + 7.3577813910229235, 5.875139865786533, 39.12143717188403, 1.341905660672623, 16.777803239858564 + ], + [ + -7.513284950652834, 44.21182779048812, 14.479713711226983, 17.660499931671584, 14.436062506263415, + -8.630753569571617, 18.920515851612024, 41.961872256649784, 30.992785862263872, 0.3821317782171232, + -9.481337721021028, 1.6266164906990555, 20.52198483872326, 9.822475957217343, 15.658011352744083, + 12.855391500184762, 10.723957376497331, 41.76485494373556, 2.2340479176319485, 16.088953253894616 + ], + [ + 0.02929945240777787, 47.8943258538308, 13.4384038570412, 17.917433759396193, 17.039432522289083, + -4.774743239794282, 12.169188113505435, 40.42317097918186, 37.22474246115934, 0.22091049853526112, + -9.687370268531138, 10.608534707379862, 22.489367975650175, 10.669348146795615, 13.95650541886101, + 6.839552569406474, 2.066756467090924, 54.581934085152405, 3.5319443821756225, 24.532968918280666 + ], + [ + 1.3315750803470996, 45.90255894008207, 9.162060301209916, -1.2943200134022526, 21.982396858443334, + -2.0046315173801657, 23.75776947991829, 42.681396519281044, 44.65189694360409, -3.233129329636757, + -11.7007015295863, 8.768962763531919, 21.48008268870696, 11.750650693071353, 10.314016323078881, + 6.044971885000999, 0.39568846222827236, 56.79992555682459, 9.686881597266042, 29.573837224244713 + ], + [ + -0.34155835630595655, 52.257883472637104, 14.63013635132661, -1.1475310646451669, 19.815434611539906, + -0.3597615447940745, 22.773438522174473, 45.16830973647258, 50.90620858214391, -4.123416917882673, + -10.08874106711032, 17.77058648507848, 17.40525407651549, 19.428287067763215, 10.154808609159593, + 9.41560200751194, 1.9106824056688325, 55.50321452563245, -1.086930629298445, 29.942519927990794 + ], + [ + -1.2496939708148902, 52.0753263525035, 16.573843720560127, 0.6254954059905691, 25.67070005332393, + 2.8833642841959586, 21.05489065711163, 45.54977153406254, 54.790476948309696, -1.1319446806674005, + -6.836880142255078, 15.502730715077965, 16.434991284495794, 20.05330736176254, 2.3102989662620654, + 6.6400837474901095, 3.4554008460006247, 54.703320294165096, -3.275155410653531, 34.69783250602105 + ], + [ + 3.673504371828866, 55.66537870906952, 22.222025244923273, -2.1871046243479864, 28.014054309766728, + -1.9343227464152601, 29.16438526268995, 44.051494895676456, 47.138525452751004, -2.533067604753474, + 2.4604369987892873, 19.673236477344094, 23.43582349379937, 18.46461800040717, 3.2513035287755745, + 7.4638277204597046, 5.836414662127938, 63.63736027633095, -2.3182235215935463, 28.362102774855607 + ], + [ + 9.197351864496074, 55.98556586180058, 19.688495387348357, -1.1757697666321, 26.78831096366896, + -5.206570891432279, 29.755041090905404, 35.45913888587404, 48.543398737558654, 3.274578409778302, + 7.640442280843416, 6.615425581412669, 27.520672134556655, 17.13948338893387, -0.7130168306222968, + 3.4923248627721257, 10.663420634170265, 62.79712211239938, -7.102421907260435, 25.96909143426486 + ], + [ + 17.878378279408615, 65.61603877495548, 21.1073514253479, -9.253213203481765, 27.879670681460908, + -2.8320537701090256, 26.13796211607032, 24.926244822709098, 41.22820882460708, 4.291828909220028, + 4.713688574820864, 16.71505221410986, 27.48982397761371, 14.998235183145638, -1.0419904618770504, + -0.1509352342460648, 11.562765259884168, 54.381939331520186, -15.369316543252658, 25.018616836414115 + ], + [ + 18.3594620989525, 66.76755465163893, 23.378561600159312, -9.221557127656212, 28.23165649899542, + -0.3620931039471351, 28.91643855216486, 11.188848304771073, 43.30138646653476, 5.000880279196099, + 1.955677009677276, 17.279662785715818, 26.178614647552152, 21.57198989722974, -1.3161643920050667, + -9.439334496282449, 18.312638310718047, 54.77270799612626, -13.618633943842825, 34.04601203745518 + ], + [ + 9.52854140993721, 66.15934256222516, 25.727095609917317, -16.01042996598902, 24.77811171644336, + -1.2825355952790376, 19.064261874916085, 14.509555473536986, 43.57067434580797, 7.890650307112603, + 1.6731169765193206, 11.216733394728445, 25.858459074516183, 18.23274943606415, -1.5424885952686824, + -9.408565254995368, 24.78142561950699, 55.72892300395096, -6.132435488791322, 32.12418971970468 + ], + [ + 8.834804620855842, 58.63396530456222, 32.725737544844485, -13.465901648481573, 31.313375862796256, + -1.937020141351771, 14.893297536987049, 23.629750932895455, 41.77269087492713, 9.082388429023517, + -6.034577415215565, 26.401238496860607, 30.051671106505943, 23.834062269627154, -3.561155588342318, + -10.717340944667358, 25.98741506616426, 55.13836837404197, -12.222227236438126, 30.768724196434682 + ], + [ + 2.008683713506029, 68.77074374390875, 27.561261630596558, -11.972754232678293, 27.652138241890253, + -8.994598412149836, 16.01202612993778, 27.496822437992087, 42.223038572972655, 9.14302748045202, + -9.49672264010566, 25.872388552562622, 29.591488992612543, 17.887210405056912, -5.273287251587566, + -12.231659074097587, 25.21878307435221, 55.4498407189013, -16.160855914516, 32.26936734704534 + ], + [ + 1.4746401926975559, 76.5710413276318, 22.444170064560886, -11.754560357801614, 31.65020848831535, + -6.747073251084499, 10.677375854561543, 18.290237353501528, 44.04246479548906, -0.9669084139974888, + -10.02999798650989, 26.331023176529538, 23.744787277420585, 21.58401811955205, -5.054619683005746, + -12.304220941049874, 22.0278850405599, 68.76140423378733, -11.104838839030073, 32.93901719565705 + ] + ], + "colorscale": [ + [0.0, "rgb(158,1,66)"], + [0.1, "rgb(213,62,79)"], + [0.2, "rgb(244,109,67)"], + [0.3, "rgb(253,174,97)"], + [0.4, "rgb(254,224,139)"], + [0.5, "rgb(255,255,191)"], + [0.6, "rgb(230,245,152)"], + [0.7, "rgb(171,221,164)"], + [0.8, "rgb(102,194,165)"], + [0.9, "rgb(50,136,189)"], + [1.0, "rgb(94,79,162)"] + ] + } + ], + "layout": { + "legend": { + "font": { + "color": "#4D5663" + }, + "bgcolor": "#F5F6F9" + }, + "xaxis1": { + "title": "", + "tickfont": { + "color": "#4D5663" + }, + "gridcolor": "#E1E5ED", + "titlefont": { + "color": "#4D5663" + }, + "zerolinecolor": "#E1E5ED" + }, + "yaxis1": { + "title": "", + "tickfont": { + "color": "#4D5663" + }, + "zeroline": false, + "gridcolor": "#E1E5ED", + "titlefont": { + "color": "#4D5663" + }, + "zerolinecolor": "#E1E5ED" + }, + "plot_bgcolor": "#F5F6F9", + "paper_bgcolor": "#F5F6F9" + }, + "frames": [] +} diff --git a/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_horizontalbar_test.json b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_horizontalbar_test.json new file mode 100644 index 00000000000000..23cb372f1e7f0b --- /dev/null +++ b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_horizontalbar_test.json @@ -0,0 +1,87 @@ +{ + "visualizer": "plotly", + "data": [ + { + "uid": "2f399e", + "name": "Votes", + "type": "bar", + "x": [1659, 1067, 671, 597, 504, 418, 407, 390, 378, 274, 255, 243, 203, 169, 79, 65, 42, 35, 35, 25, 17, 11, 10], + "y": [ + "Laravel", + "Symfony2", + "Nette", + "CodeIgniter", + "Yii 2", + "PHPixie", + "Yii 1", + "Zend Framework 2", + "Company Internal Framework", + "Zend Framework 1", + "CakePHP", + "No Framework", + "We use a CMS for everything", + "Phalcon", + "Slim", + "Silex", + "Simple MVC Framework", + "Typo 3", + "Kohana", + "FuelPHP", + "TYPO3 Flow", + "Drupal", + "Aura" + ], + "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": "h" + } + ], + "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_line_test.json b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_line_test.json new file mode 100644 index 00000000000000..3890cb761358e0 --- /dev/null +++ b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_line_test.json @@ -0,0 +1,440 @@ +{ + "visualizer": "plotly", + "data": [ + { + "line": { + "color": "rgba(255, 153, 51, 1.0)", + "width": "1.3" + }, + "mode": "lines", + "name": "Trace 0", + "type": "scatter", + "x": [ + "2015-01-01", + "2015-01-02", + "2015-01-03", + "2015-01-04", + "2015-01-05", + "2015-01-06", + "2015-01-07", + "2015-01-08", + "2015-01-09", + "2015-01-10", + "2015-01-11", + "2015-01-12", + "2015-01-13", + "2015-01-14", + "2015-01-15", + "2015-01-16", + "2015-01-17", + "2015-01-18", + "2015-01-19", + "2015-01-20", + "2015-01-21", + "2015-01-22", + "2015-01-23", + "2015-01-24", + "2015-01-25", + "2015-01-26", + "2015-01-27", + "2015-01-28", + "2015-01-29", + "2015-01-30", + "2015-01-31", + "2015-02-01", + "2015-02-02", + "2015-02-03", + "2015-02-04", + "2015-02-05", + "2015-02-06", + "2015-02-07", + "2015-02-08", + "2015-02-09", + "2015-02-10", + "2015-02-11", + "2015-02-12", + "2015-02-13", + "2015-02-14", + "2015-02-15", + "2015-02-16", + "2015-02-17", + "2015-02-18", + "2015-02-19", + "2015-02-20", + "2015-02-21", + "2015-02-22", + "2015-02-23", + "2015-02-24", + "2015-02-25", + "2015-02-26", + "2015-02-27", + "2015-02-28", + "2015-03-01", + "2015-03-02", + "2015-03-03", + "2015-03-04", + "2015-03-05", + "2015-03-06", + "2015-03-07", + "2015-03-08", + "2015-03-09", + "2015-03-10", + "2015-03-11", + "2015-03-12", + "2015-03-13", + "2015-03-14", + "2015-03-15", + "2015-03-16", + "2015-03-17", + "2015-03-18", + "2015-03-19", + "2015-03-20", + "2015-03-21", + "2015-03-22", + "2015-03-23", + "2015-03-24", + "2015-03-25", + "2015-03-26", + "2015-03-27", + "2015-03-28", + "2015-03-29", + "2015-03-30", + "2015-03-31", + "2015-04-01", + "2015-04-02", + "2015-04-03", + "2015-04-04", + "2015-04-05", + "2015-04-06", + "2015-04-07", + "2015-04-08", + "2015-04-09", + "2015-04-10" + ], + "y": [ + 0.5353935439391206, -0.3510205670171982, -1.3420793330744663, -1.683479706754631, -2.0207368899942826, + 0.006604084375472663, 0.8037048387382045, 1.6685589999803645, 1.2683547027403048, -1.3330462677331034, + -1.8663123665480104, -2.8051461261147357, -4.563508055068453, -3.7591847216910996, -3.5134185618878746, + -5.3419268826351995, -3.332156069299614, -3.5678897362109545, -3.8548236009547465, -4.58628192762981, + -4.116554826788904, -2.7610003378381496, -2.621859111953831, -2.6349689848833315, -2.0581142585936076, + -0.7744078058377932, 0.9002451055355818, 0.8373590393039949, 0.5532093840234236, 1.469976651890828, + 3.1860367266233904, 2.493612510772345, 1.9464391258267615, 1.8807283125005585, 3.0189402685173534, + 4.556005864163605, 5.516442345945973, 4.319606652282435, 6.845756127344204, 7.053236096270982, + 7.681494725458877, 7.526563745782537, 8.858342186205558, 9.021889375014881, 8.209805336778926, + 9.383959972549016, 11.195848970970625, 12.561537445362251, 14.373511358982237, 15.887456275652418, + 14.491455240251522, 15.199461217404735, 16.378844807972094, 14.348345501207364, 14.961597203409823, + 15.457566696478484, 14.942769687687289, 15.721527909780036, 13.091278962257627, 14.295247001092115, + 15.296655272416865, 14.436440585461526, 13.912453188370755, 12.433861225213807, 14.061345247447989, + 13.326092951912521, 13.566974950387175, 12.96345607653163, 12.205278846692087, 11.364010452431279, + 12.120962982512733, 13.570258079014422, 14.613857418348378, 15.48868026864105, 15.421250297066777, + 16.562957844203055, 16.365666723485436, 15.848038393086913, 16.170083705874156, 16.446617416519754, + 15.024371154281331, 14.802238239296665, 13.156751496135007, 14.06168725142282, 14.94588113322983, + 14.127589669913032, 13.885898170515487, 13.692030694564533, 14.943253908206318, 14.529368596515058, + 14.661473471114782, 13.67375983483632, 13.382284458918326, 12.527287002966496, 12.767994473001014, + 12.651030056419879, 12.141617852418765, 13.606694447410502, 13.923089943159189, 14.003348672865656 + ] + }, + { + "line": { + "color": "rgba(55, 128, 191, 1.0)", + "width": "1.3" + }, + "mode": "lines", + "name": "Trace 1", + "type": "scatter", + "x": [ + "2015-01-01", + "2015-01-02", + "2015-01-03", + "2015-01-04", + "2015-01-05", + "2015-01-06", + "2015-01-07", + "2015-01-08", + "2015-01-09", + "2015-01-10", + "2015-01-11", + "2015-01-12", + "2015-01-13", + "2015-01-14", + "2015-01-15", + "2015-01-16", + "2015-01-17", + "2015-01-18", + "2015-01-19", + "2015-01-20", + "2015-01-21", + "2015-01-22", + "2015-01-23", + "2015-01-24", + "2015-01-25", + "2015-01-26", + "2015-01-27", + "2015-01-28", + "2015-01-29", + "2015-01-30", + "2015-01-31", + "2015-02-01", + "2015-02-02", + "2015-02-03", + "2015-02-04", + "2015-02-05", + "2015-02-06", + "2015-02-07", + "2015-02-08", + "2015-02-09", + "2015-02-10", + "2015-02-11", + "2015-02-12", + "2015-02-13", + "2015-02-14", + "2015-02-15", + "2015-02-16", + "2015-02-17", + "2015-02-18", + "2015-02-19", + "2015-02-20", + "2015-02-21", + "2015-02-22", + "2015-02-23", + "2015-02-24", + "2015-02-25", + "2015-02-26", + "2015-02-27", + "2015-02-28", + "2015-03-01", + "2015-03-02", + "2015-03-03", + "2015-03-04", + "2015-03-05", + "2015-03-06", + "2015-03-07", + "2015-03-08", + "2015-03-09", + "2015-03-10", + "2015-03-11", + "2015-03-12", + "2015-03-13", + "2015-03-14", + "2015-03-15", + "2015-03-16", + "2015-03-17", + "2015-03-18", + "2015-03-19", + "2015-03-20", + "2015-03-21", + "2015-03-22", + "2015-03-23", + "2015-03-24", + "2015-03-25", + "2015-03-26", + "2015-03-27", + "2015-03-28", + "2015-03-29", + "2015-03-30", + "2015-03-31", + "2015-04-01", + "2015-04-02", + "2015-04-03", + "2015-04-04", + "2015-04-05", + "2015-04-06", + "2015-04-07", + "2015-04-08", + "2015-04-09", + "2015-04-10" + ], + "y": [ + -2.58404773330316, -1.9162964761259451, -1.8899798841571565, -1.098466181069551, -1.2161136413159992, + -0.9298011508867184, -2.5216450120142193, -1.5547013224314532, -3.1293219775443117, -2.7232351981528025, + -1.704449229625379, -1.2702366750752472, -1.7688923656442583, -1.9810878959630682, -1.0881359248000217, + -0.5214761704035035, -0.639866394654719, -2.258513886233204, -0.8711892253875131, -0.45426547393253053, + -2.4076676391235785, -2.2450025826137097, -2.3488062397069234, -3.2188990647525304, -2.6042445674055594, + -2.9702468803291966, -4.139691822816822, -3.9967022316870042, -4.796271521377118, -5.244924380701339, + -6.965620503609484, -6.430396926773768, -5.234457265252843, -6.181791776690352, -7.3464387119459085, + -7.085650875056526, -6.795217278293396, -6.08725142043377, -5.3416313194169875, -4.900094995211111, + -4.715363010029477, -3.6757033584677927, -5.873900613367271, -7.685787089886274, -8.833149292574403, + -9.373517123532867, -10.519456187180836, -8.012082850355387, -8.556759031756883, -8.78527769843948, + -8.801850250864483, -9.031427690493008, -9.289972806031075, -8.434541044235305, -8.543619303217836, + -9.817816201809572, -9.691704922707196, -9.172230718814316, -10.389025830978015, -9.418276522564378, + -8.844666134378604, -10.649699554950736, -11.433978738990442, -11.022214964648152, -11.156982299530265, + -12.846500605483975, -12.700459270895378, -13.701718476553872, -14.281259852458456, -13.197701892598191, + -13.444607930505104, -12.703127086621702, -12.38184968649959, -13.545422038889187, -12.062411162554307, + -12.190051993521331, -13.801739083658532, -14.198265394729127, -14.29078542197376, -13.45263060195906, + -13.130412206893606, -14.189794518505105, -12.647928857811877, -13.252175401809115, -13.526006774399674, + -13.640567463371012, -13.234252510186453, -12.313307209824384, -11.218557557877709, -10.7821947135954, + -8.89016408336461, -9.662631443485989, -6.909371824212538, -7.048202688582138, -4.971706592042745, + -4.310618310025603, -2.954237793688564, -2.0883264569176156, 1.1805740980198571, 0.5040426644599496 + ] + }, + { + "line": { + "color": "rgba(50, 171, 96, 1.0)", + "width": "1.3" + }, + "mode": "lines", + "name": "Trace 2", + "type": "scatter", + "x": [ + "2015-01-01", + "2015-01-02", + "2015-01-03", + "2015-01-04", + "2015-01-05", + "2015-01-06", + "2015-01-07", + "2015-01-08", + "2015-01-09", + "2015-01-10", + "2015-01-11", + "2015-01-12", + "2015-01-13", + "2015-01-14", + "2015-01-15", + "2015-01-16", + "2015-01-17", + "2015-01-18", + "2015-01-19", + "2015-01-20", + "2015-01-21", + "2015-01-22", + "2015-01-23", + "2015-01-24", + "2015-01-25", + "2015-01-26", + "2015-01-27", + "2015-01-28", + "2015-01-29", + "2015-01-30", + "2015-01-31", + "2015-02-01", + "2015-02-02", + "2015-02-03", + "2015-02-04", + "2015-02-05", + "2015-02-06", + "2015-02-07", + "2015-02-08", + "2015-02-09", + "2015-02-10", + "2015-02-11", + "2015-02-12", + "2015-02-13", + "2015-02-14", + "2015-02-15", + "2015-02-16", + "2015-02-17", + "2015-02-18", + "2015-02-19", + "2015-02-20", + "2015-02-21", + "2015-02-22", + "2015-02-23", + "2015-02-24", + "2015-02-25", + "2015-02-26", + "2015-02-27", + "2015-02-28", + "2015-03-01", + "2015-03-02", + "2015-03-03", + "2015-03-04", + "2015-03-05", + "2015-03-06", + "2015-03-07", + "2015-03-08", + "2015-03-09", + "2015-03-10", + "2015-03-11", + "2015-03-12", + "2015-03-13", + "2015-03-14", + "2015-03-15", + "2015-03-16", + "2015-03-17", + "2015-03-18", + "2015-03-19", + "2015-03-20", + "2015-03-21", + "2015-03-22", + "2015-03-23", + "2015-03-24", + "2015-03-25", + "2015-03-26", + "2015-03-27", + "2015-03-28", + "2015-03-29", + "2015-03-30", + "2015-03-31", + "2015-04-01", + "2015-04-02", + "2015-04-03", + "2015-04-04", + "2015-04-05", + "2015-04-06", + "2015-04-07", + "2015-04-08", + "2015-04-09", + "2015-04-10" + ], + "y": [ + 0.4661114764240781, 1.0610769506804194, 1.0620659379275244, -0.5603096501263787, -0.22966983294858567, + 1.1358334022099883, 1.8697838063194905, 1.8307593169232188, 2.6294937170536055, 1.456439760404607, + 3.571977139947352, 3.305623978930223, 4.369054542737759, 4.134928856846778, 2.525747905079978, 4.45625041538837, + 5.331621195457201, 5.01722152487662, 3.2730061427478807, 2.3895586625726164, 1.5551868349111646, + 0.9222137047406664, -0.2408476097748915, -0.7735805458656726, -0.8871954038346644, -1.9822438634492547, + -0.8886612143982666, -0.7149527896910689, -1.1377284325144619, -1.7585300048885872, -2.8117170543153254, + -2.6809842525932175, -1.6457602974924186, -2.1361202183757593, -3.506112394459107, -3.338531391597358, + -5.511057758779813, -3.5261371875358676, -4.05255557741406, -5.188415501615373, -6.032557392677557, + -5.6858700345353785, -6.667528307767753, -6.733517550988596, -7.0502984033473615, -7.574898212324232, + -7.1843491903366, -6.080355259797091, -6.398354606750326, -6.286331305269291, -7.175762338255774, + -6.6277002690607105, -6.031655281290095, -5.243102836583583, -4.612608200873672, -5.180512683218164, + -5.0321319726702916, -4.567844497333498, -3.347239903958168, -2.5263058621799597, -3.554423668680612, + -1.7466537357472816, 0.08618389027480222, 1.0223852208396356, 2.2260700096326724, 2.976731277433707, + 2.5457541264066235, 2.412842465270771, 2.1270496073872933, 4.350264423349324, 3.6000820362032346, + 3.6547717673422704, 4.29856786980301, 4.61832134099102, 5.1364308299997825, 5.647209819441451, + 6.041357011724418, 4.789997568683162, 6.041650920258338, 5.860878612223213, 5.6050673038102214, + 3.900259274681964, 2.1974477295325476, 0.979239291658772, 0.9769412141062032, 1.1215546396840912, + 1.4131546401228463, -0.5715019565360024, -0.4798030419178908, -0.19867316746947167, -1.3237063703965808, + -1.5132847802948692, -0.9466159703619573, 1.3543877997088902, 1.3745632832250965, 1.2843024279329955, + 1.1384756757773304, 1.841477239971831, 1.0626945214201182, 1.6018849370336259 + ] + } + ], + "layout": { + "legend": { + "font": { + "color": "#4D5663" + }, + "bgcolor": "#F5F6F9" + }, + "xaxis1": { + "title": "", + "tickfont": { + "color": "#4D5663" + }, + "gridcolor": "#E1E5ED", + "titlefont": { + "color": "#4D5663" + }, + "zerolinecolor": "#E1E5ED" + }, + "yaxis1": { + "title": "Price", + "tickfont": { + "color": "#4D5663" + }, + "zeroline": false, + "gridcolor": "#E1E5ED", + "titlefont": { + "color": "#4D5663" + }, + "tickprefix": "$", + "zerolinecolor": "#E1E5ED" + }, + "plot_bgcolor": "#F5F6F9", + "paper_bgcolor": "#F5F6F9" + }, + "frames": [], + "selectedLegends": ["Trace 0", "Trace 1"] +} 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_pie_test.json b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_pie_test.json new file mode 100644 index 00000000000000..60d54178303332 --- /dev/null +++ b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_pie_test.json @@ -0,0 +1,24 @@ +{ + "visualizer": "plotly", + "data": [ + { + "type": "pie", + "marker": { + "line": { + "color": "#000000", + "width": 2 + }, + "colors": ["#FEBFB3", "#E1396C", "#96D38C", "#D0F9B1"] + }, + "textfont": { + "size": 20 + }, + "textinfo": "value", + "hoverinfo": "label+percent", + "labels": ["Oxygen", "Hydrogen", "Carbon_Dioxide", "Nitrogen"], + "values": [4500, 2500, 1053, 500] + } + ], + "layout": {}, + "frames": [] +} diff --git a/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_sankey_test.json b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_sankey_test.json new file mode 100644 index 00000000000000..63ecd3b2ffa88a --- /dev/null +++ b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_sankey_test.json @@ -0,0 +1,79 @@ +{ + "visualizer": "plotly", + "data": [ + { + "link": { + "color": [ + "rgba(253, 227, 212, 0.5)", + "rgba(242, 116, 32, 1)", + "rgba(253, 227, 212, 0.5)", + "rgba(219, 233, 246, 0.5)", + "rgba(73, 148, 206, 1)", + "rgba(219, 233, 246,0.5)", + "rgba(250, 188, 19, 1)", + "rgba(250, 188, 19, 0.5)", + "rgba(250, 188, 19, 0.5)", + "rgba(127, 194, 65, 1)", + "rgba(127, 194, 65, 0.5)", + "rgba(127, 194, 65, 0.5)", + "rgba(211, 211, 211, 0.5)", + "rgba(211, 211, 211, 0.5)", + "rgba(211, 211, 211, 0.5)" + ], + "value": [20, 3, 5, 14, 1, 1, 3, 17, 2, 3, 9, 2, 5, 9, 8], + "source": [0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4], + "target": [5, 6, 7, 5, 6, 7, 5, 6, 7, 5, 6, 7, 5, 6, 7] + }, + "node": { + "pad": 10, + "line": { + "color": "black", + "width": 0 + }, + "color": [ + "#F27420", + "#4994CE", + "#FABC13", + "#7FC241", + "#D3D3D3", + "#8A5988", + "#449E9E", + "#D3D3D3", + null, + null, + null, + null, + null, + null, + null + ], + "label": [ + "Remain+No – 28", + "Leave+No – 16", + "Remain+Yes – 21", + "Leave+Yes – 14", + "Didn’t vote in at least one referendum – 21", + "46 – No", + "39 – Yes", + "14 – Don’t know / would not vote" + ], + "thickness": 30 + }, + "type": "sankey", + "domain": { + "x": [0, 1], + "y": [0, 1] + }, + "orientation": "h", + "valueformat": ".0f" + } + ], + "layout": { + "font": { + "size": 10 + }, + "title": "Scottish Referendum Voters who now want Independence", + "height": 772 + }, + "frames": [] +} diff --git a/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_verticalbar_histogram_test.json b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_verticalbar_histogram_test.json new file mode 100644 index 00000000000000..4745368ea83d93 --- /dev/null +++ b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_verticalbar_histogram_test.json @@ -0,0 +1,702 @@ +{ + "visualizer": "plotly", + "data": [ + { + "uid": "a58c38f5-f6a6-4b4d-8f94-07e5434e2063", + "name": "a", + "type": "histogram", + "x": [ + 1.7992564437777885, 0.05779580359302183, 1.5134306451845885, 0.3914013884637312, -0.11969533034200497, + -0.5139373299202106, 0.32142776505891857, 2.313965687838981, 0.1313874805632831, 3.917327494517987, + 1.4773032646481492, -0.9109227115334932, 0.7599616936194599, 2.1104123608688123, 0.31412192646017323, + 2.0633800190292506, 0.417801977542291, 2.741354310412407, -0.04273212212771793, -1.0996174774744212, + 1.1634605321836873, 0.050435185187588605, 0.8709019344644338, 0.5483759550743046, -0.9632190023703564, + 1.4254673343221542, -0.11834711820656141, 0.7272853323757995, 1.0165475637905812, 1.9600898808756693, + 1.684523196352575, 0.21989073136972614, 1.4373173920954938, 1.35068323813271, 1.2082253229376725, + 1.0024946206107124, 1.0912034859692132, 1.394093750990316, 0.15381570948969037, 1.572778151817132, + 1.3145990861101873, 1.0590366743769009, 0.7378641746889019, 1.4376166187176542, 2.1920348524405986, + 2.8258626879622284, -0.738792921197468, -0.6654164350138787, 0.8832266749764874, 1.0563869413346711, + 2.012291462559541, -0.8081967975015514, -1.1842825882088035, 0.9640286143816317, 1.001083604005719, + 0.823496575437699, 0.07981471961188535, -1.0887151086105633, 2.2813972361639836, 0.8865705596306114, + 0.8657022019728764, -0.16279733641041894, -0.5586597880489619, 0.7382087744796277, 1.0527131459569035, + 1.1428187529021478, 0.09914241999126061, 0.7000511587033809, 0.6150725845961333, 1.250735301284068, + 1.3280548256601055, 1.4186651866714681, 1.5541905345980815, 0.10785164030299477, 2.443004259511542, + 1.9095913702824938, 0.7004419083140948, 1.4113632085994499, 1.4139325035008095, 0.47532535496539086, + 1.9377217880970339, 1.9530293129448117, 2.826030369070281, 1.0188032768441608, 2.4963673283862846, + 1.5002317584300138, 1.6749354318678575, 1.557810338878444, 3.260335742383798, 2.7135036230531187, + -0.7875434249482567, 2.1884165446637294, 1.4148295620644604, 1.4043675796166526, 0.5860810303122439, + 0.5880779684020552, 1.292885245350062, 1.9446057825215435, 1.2681551767507135, 0.6361744786578738, + 2.419010053709061, 1.476506036172426, -0.406984190128878, 1.4883052014477953, 0.2362631775078744, + 2.052457913674718, 0.919126684410074, 0.3627930834038261, 0.9995681055485067, 1.2786851133470762, + 1.88091579608581, 2.307653076107352, 1.9983233226921344, 0.8963257808467161, -0.35477422744941545, + 0.8202205819349409, 0.9877279413898287, -0.33245824354397446, 0.8845371548645357, 0.16429534411459312, + 0.15425988582516792, 1.9092466485573727, 1.6856813757793578, 2.4778913108189924, 1.2264293859196442, + 1.2066934020481703, 0.7094133857792155, -0.6974506712635016, 0.6351965331244696, -0.5745812246342736, + 0.9681806434527394, 1.3721006584092403, 1.3863696537062076, 0.5161064334216514, -0.27925937323389616, + -0.04378152198437446, 3.584261091320433, 0.9124807527304252, 1.0698812014525427, 1.1693505687858963, + -0.35661855152179345, 0.03998168348604492, 0.6511489854178798, 0.4050757350866182, 0.8398416524720245, + -0.3199493956399764, 2.489870130774302, 0.9195697963323227, 0.446272936321951, 0.6293343998549384, + 1.5129447471342545, 2.2875473778527695, 0.47716508695641136, 2.1236906002276745, 1.4828559276369087, + 0.6380262251101524, 2.729430311117608, 2.1176404694918354, 0.7328309112672804, -0.2466211471665054, + 0.2574691202956615, 2.2019663578593898, 1.082082632442427, 1.5172285786551658, 1.3179716266483459, + 0.9352644340838197, 1.9368012654766131, 0.6019067073062221, 0.3676121339524441, 0.6909774354426849, + -0.30274401723879074, -1.3521102868472061, 0.6918937694215814, 1.6292324049460971, 0.1507275531304314, + -0.25220968558062196, -0.31559338640317525, 0.07601910508447174, 0.768824535203562, 1.524675869943278, + 0.5161062518475145, 0.9297123926434617, 0.04298734085876699, 1.683284666747905, 1.1112677270404492, + 1.0671605796105683, -0.9676277150386134, 0.27444284402297925, 1.172868652344203, 0.9615013126991171, + -0.09647067435769441, 3.145379385247912, 0.5555538049386326, 2.3755629446672186, 2.4649835140338716, + -1.2095472925733834, 2.7460173137785904, 0.0541756956951549, 1.0958997065940062, 2.8103268910278505, + 1.7570583127148565, 2.373785054421019, 0.005844170445054031, 0.9313199634004647, 0.5565657574376377, + 1.263138467526412, 2.4412257236660664, 0.8420413733307475, -0.3243568257666718, 0.5485173278748381, + 2.1602571844613827, -0.3013214548367871, 0.6222351937146695, 1.898536544875012, 2.5426161399653937, + -0.44754180053616377, 2.2847454056096153, 1.6260372076971144, 2.010405770332185, -0.18102618787353753, + 3.516018953597978, 1.2177743852240588, 0.9608770156504653, 0.9883239851364751, 0.5560578461000198, + -0.45606879507964715, 2.145285349306212, -0.37930005486618557, 1.7112473046914842, -0.4588888223883527, + 2.8928842799503975, 0.14292799208181584, 0.7352829253915387, 0.7632116961043758, 1.8158856926218883, + 0.19331239277079704, 1.886103944734376, -0.06200921897768907, 0.6285305645271686, 0.956342047579559, + 1.4550323013518107, 1.9239359365679745, 0.6830568015251277, -0.5281812821592153, 0.8718941680183343, + -0.39916517735287127, 1.246049581578422, 0.6218344568230643, 1.256204664683573, 1.2754693222270703, + 1.1672493869167195, -0.2194459527939645, 2.754450459156036, -0.8963591391141821, -0.4571893280808701, + 2.4819434902804094, 0.9645864746055925, 1.0364931785298164, 1.150284233325339, 1.878344167033501, + 2.347962971022697, 0.6715422800115376, 2.3772755272750423, -0.28379549763240175, 1.4532684457778702, + 2.5674129903767025, 2.2946555714497334, 0.7690746832477149, 1.5418418331243509, 0.6560644032509522, + 0.255574087455425, 1.6914180551398617, 1.2719595929524, 0.5056559302899697, 2.3594940732494543, + 1.1903690407317626, 2.1203166777462767, 1.5468301100001858, 0.9983035399538878, 1.3426694633836393, + 1.2530567859889332, -0.058612958303870144, 1.7013481027959663, 2.0671325297544514, 0.5289282652759798, + 1.693717215090481, 1.9561623687030254, 1.8850619277472735, 1.7088780864251623, -0.18425757789538255, + -0.18373679472310434, 2.6738937892593375, 1.5963554731996412, 0.9915311370318989, 0.9358297139086073, + 2.218194962403288, 1.5131686121952947, 0.6842963039363943, 2.6571849088006667, 1.7185669569983792, + 0.406147413712975, 2.9872066492095826, 1.256135794787258, -0.05233846558622712, 3.2502971683620245, + -1.060253995089893, 1.9344116284004147, -1.391209198708665, 1.8336300206896556, 1.2493557837324984, + 2.660080468459796, -0.07533566100611533, 1.2750273643034684, 1.6358548224610199, 0.7737538646212196, + 0.8326351949551917, 0.6048334113573071, 0.07024065729722151, 2.2863421015077208, 3.5576220046921994, + 1.3868904734370509, -0.4233814303255623, 0.8870053717058879, 0.9602326267443417, -0.20761873649244, + 0.8608673256323256, 0.04762383293746508, 1.8298623824151894, 1.8851654479524642, -0.5454173962959787, + 0.48791551024611235, 2.3521458066868943, 1.8512560861689917, 0.2853560659548291, 2.3196619940996364, + -0.8663787664214817, 0.6777231912389844, 2.642024604956757, 1.9006852208902836, 1.584362827552154, + 1.3177340141949063, -0.5531330479564598, 1.3645799493544255, 2.2041108487874235, 0.9739109838009927, + 1.2042520375301562, 0.6904698695650664, 0.8859940196353442, 1.212645286808484, 1.13290564547174, + -1.3101516074201358, 3.130216420210678, 1.8287295799032357, 2.225590468814803, 0.4787508136792987, + -0.5399446731509081, 1.9231558380834213, 2.317765200789225, 2.0938656924871966, 0.648022904920668, + 1.2192152097279316, 1.3071179121799936, 0.36087653490873817, 2.020984355125307, -0.6676209734775458, + 0.2329092663845419, -0.1279210447235133, 1.257991640951116, 1.3362651903384877, 0.7759516583222761, + 1.1141135044065376, -0.20873154134476546, 1.4815676403945832, 0.3645229894316946, 0.4795253059399903, + -0.7616395497522817, -0.8246297762955701, 1.1777003408725564, 1.007643347257193, -0.4399349444288825, + 1.0315144851710472, 0.16629692756239312, -0.5949527106611434, 1.964918822432896, 1.4182711176936047, + 2.1244550205643185, 0.8680413628067739, 0.8182596481508461, 1.5192554377297096, 0.48210227012285, + 1.538965778668858, -0.8834895343868825, 2.229296839993378, 1.3737044269020504, 0.5094151172920589, + -1.0727797638787773, 0.7761725881745586, 1.862121314778132, 1.9488284440304922, 0.29185375993808005, + 0.6384788090956188, -0.3431957087322153, 2.9325408707861884, -0.5680734858758762, 1.3095541355520544, + 1.8146352363354845, 1.478492443854311, 0.9817996426269806, 2.2133822167860697, 0.982838640548402, + 1.2450170632313666, 1.3193736359371244, -1.849316264977697, -0.6889504041818002, 1.040751428210255, + 0.02890269443133786, 3.590110130056901, 0.614449689879796, 1.7889598611077213, 1.5203855018307537, + 0.11560219087913548, 0.6476172637601402, 0.9776316443925304, 0.43639120088595085, 1.9452541571707047, + -0.9128920899928628, 1.8105963045227924, 1.368976170389584, 1.2372397265564588, 0.5232007492971766, + 0.992950260427584, 1.7814003303773465, 0.2987660777209449, 2.4438700525731756, 0.7304148728972943, + 1.9305546115010896, 0.4779804026283916, 1.3761758269096453, 1.1085612186183114, 1.538399508148844, + 0.8263951839132615, 0.31788386853368056, 0.7236430275526036, 2.1563652164636578, 1.796460049711082, + 1.584954489547108, 1.4349337292160382, 0.0025743914839860826, 0.25864142740500595, 0.6216086145857926, + 0.17981395134258327, 0.836340278975011, 0.9223162050338467, 0.7487633192895334, 1.4081533955695802, + 1.1757717479913181, 1.255541770559463, 0.08380876352772215, 1.1182060741735924, 0.9338272530332398, + -0.6145905317441664, 1.0232060948528703, 0.1369411912627122, 2.387108140358447, 1.2260016897691621, + 0.5606967191611573, 0.3020478865727917, 0.6771693300058677, 0.7816963489918528, 0.4010415895324466, + 0.6233883123283104, 0.5727695083340153, -1.1931243506134566, 0.3448007887994159, 1.5848221820090393, + 1.5914175418503587, 1.0543529802763378, 0.23970110132104505, 0.8050916546684623, 3.03870855776943, + 1.83758077023609, 3.639866747514543, 0.06639936058073814, -0.5401390582943686, -0.0551014491131101, + -0.1845360571630339, 1.0814919377215442, 1.0012528137985255, 1.4352871310259006, 0.9829471684470072, + 1.9683436756460164, 0.3685403660141269, -0.36657304635220433, 0.7969766331313638, 0.7573146429710325, + -0.0999127021598627, 1.4218367929227211, 2.4437733635376393, 2.54286390016454, 1.8255964426003177, + 2.059106897349305, -0.14394356122418994, 0.04099842507739737, 0.5775404307711827, 0.8203586535385461, + 0.0889819761695646, 0.6231959813316315, 1.55402923657705, 0.64617596764641, 3.0437353352890164, + 1.8311453472348207, 1.1217623018926788, 1.129221419335285, 1.7247155387917212, -0.0925286589029144, + 0.03166073843786188, 1.6024280010855225, 1.275463787309655, 0.904106062296863, 1.9397803318729219, + 2.767883390841891, 1.1982643524564702, -0.501500241163628, 2.3425217675307373, 1.1597090334070463, + 1.562589228175228, 2.539800869658598, 0.919670262302777, 0.27966487952773234, 0.32439947516731593, + 1.3035617603710143, 2.061532639114384, -0.9807097220175245, 2.4322899716419197, 0.16355014788036393, + 1.109162739662061, 1.997976507527615, 1.9242941436158474, 1.4582163008381643, 3.1138587302433978, + 0.5716087760972477, 2.287502175172394, 1.7518320503775806, 2.4784498461181466, 1.5515443988122533, + 1.1200074031733696, 2.0255245930920553, 1.6711356885534314, 0.6071102010448299, 2.28431478314955, + -0.053302018537180196, 1.0133860679063618, 0.9201784397988596, 1.98628336960116, -0.1942411826064756, + -1.1590599777742536, 1.9758262239782494, 0.28472580634235256, 0.5616336096410678, 2.7963387836761266, + -0.14624850373573262, 0.706932138971843, 0.1534966570543116, 1.5049452484672905, 1.5114555247512003, + 1.0791310961336744, -0.16558294860486322, 1.4694846656975797, 0.8229013337501457, 1.5460648907298757, + 1.2708338866418858, 0.5555076997574024, -0.08212607433940877, 1.3671742386654664, -0.19403907846506763, + 1.072193582335992, 0.4018561884786328, 1.2199426919918257, -0.1339665363838103, -0.723335356475993, + -0.7423722097951817, 0.1267530635051638, -0.3862009836094977, 2.3589998346913674, -0.02431911415854926, + 1.7398835742135796, 1.9521568967386167, 0.37161947662605876, -0.9519304754046578, 1.4093481308861078, + 2.225223153552087, 0.3022941041736126, 1.8498036316384043, 2.111880443036447, 2.0121621002809245, + 1.747958383773942, 1.5329771758782622, 0.5335264867497093, 0.581600757214944, 1.1965173940906473, + 1.274774506412578, 0.3946001045434654, 0.45440428117495435, 2.1987657555362023, 0.8570404560681593, + 0.9154628243187267, 0.12467576527384816, 2.2843043333029254, 0.010242756188474478, 1.0749423620809173, + 0.8519128175499796, -0.7471674166974844, -0.4099515244260885, 1.1942142110927378, -0.84093581646562, + 1.4691853527074428, -1.2464663460169465, -0.09068731986811751, -0.4662269519912998, 0.0976669220458457, + 1.8630019890768656, 1.752685464244165, -0.41680467352111705, -0.38086651497555435, 1.5781062220769029, + 2.1592420149994407, 1.79661117286856, 2.383440685368276, 0.8150201156904069, 0.8317397865207655, + 0.38684108244163606, 0.9934524660859555, 0.30591866796061284, 2.885029411874684, 0.03527978957996181, + -0.11955437429436921, 0.3333074773573744, -1.4943495574601777, 2.957928727064292, 1.8151215770523936, + -1.3356352059513, 1.4524455669186858, 0.8522062240274855, 1.7098980910509671, 2.6601876729595935, + 1.1583937668185982, 1.747771471569599, 1.2922153849981268, -0.29287560293945836, 1.1016244014347931, + 0.7371420484085144, 0.9225945753090563, -0.7186465154174793, 1.7055469107616228, 2.490251965478738, + 0.4513770398626108, 1.3220282180419405, 1.3318536689624074, 1.866985022696895, 1.1780356989238632, + 1.9385524236228453, 0.9409940432770417, 2.293428748560082, 0.5633484001943025, 0.5403796231397502, + 0.5647269232136267, -0.35001480630828863, 1.1987405717452526, 0.5401847906099445, 1.481863314646785, + 0.8991336205862112, 1.5116565153867465, 1.291973904100607, 0.9400939678588855, 0.7331459400843344, + 2.322213619351766, -1.2849176382749712, 1.9299490440456237, 0.23124676800359134, 1.2461795741054449, + 0.03995798367183501, 3.6546662364954794, 0.8734744892825432, 0.33959061138227753, 2.6386275851303544, + 2.009568319607715, 1.7455075390113097, 0.060614273204754765, 0.9062388610403692, 1.958661936361118, + 1.1014189592447032, 0.0912744259233812, 0.08001168053374641, -0.6287985171984807, 1.291092812244582, + 0.9801891561246252, 2.75798911333197, 0.350715158445002, 2.1111413470557103, -0.008494506364157495, + 1.5285008753486364, 0.17790549651765397, 1.2487537632445134, 1.7852684150907752, 2.269797461845079, + -0.5351508658441584, 0.9713830442056057, 2.0986206616172254, -0.4262124283239124, 1.189753656915752, + 1.4425212269968215, -0.016134252858927667, -0.23942578363347033, 2.4986644307284607, 2.2143464307680896, + 1.3149487069230394, -0.4199490289816201, -0.15305610419795324, -0.8645311850786448, 3.047130906299353, + 0.6826588078928438, 2.458961339604746, 1.6663326507036387, 2.632104785858771, 2.5270687595766304, + 1.1565075482614575, 1.7331109607778017, 3.1482032986349204, 1.0149944670579278, 1.1869595916586477, + 0.1604674422165825, 0.8914713906695723, 1.5521967909523975, 0.7498678003378934, 1.6987971021969916, + 1.0419624558120737, 1.7406415172690632, 0.7085470340845715, 1.318598246078236, 2.4507045190594274, + 1.5287196205950446, 1.6453634556320902, 3.567732466566258, 1.3229827513914025, 1.936655615751933, + 1.7368358229883365, 0.20808545316858051, 0.43747862818313055, 0.8682485675368211, 2.009163075564326, + 1.518658787079603, 0.24564656194805112, 1.3167251224371304, -0.3223378419226661, 0.9298039613021007, + 2.0602140681146883, 1.8431778283197322, 1.3482010044071036, 0.37404248706633525, 0.29232500155456065, + 2.6239210737933254, 1.0369292442105913, 1.902603328102535, 2.5387576452274585, 0.653347609132553, + -0.12181078309416815, 1.935453846332126, -0.3782479423368359, 0.18986923608612494, 0.12842495610514504, + 1.1750119298781858, 0.3704398424199754, 1.0837291426204045, -0.12944122986380413, 0.6629724363893394, + 0.2530517876988735, 0.8766962664881424, 1.5520581745839876, 0.0763056701139766, 1.0859890872895461, + 0.26223060032083545, 1.6943312314098193, 2.780117420235435, 2.645036841191493, 0.8868337094821542, + 0.45452972165963, 2.4619620860320826, 0.33691681013793184, 2.2686118836101716, 1.3949911775126076, + 2.4311498313919033, 1.1224087434884498, 2.0256825879323435, 0.7819443942836489, 1.489679918099962, + 0.6325926720677619, 1.2822203145593867, 1.4944062248571939, 0.48742124859761815, 1.4320459696205452, + -0.40607779453841975, 1.7025200757951615, 0.4103322244001608, 1.5745924572586825, 1.8767915748041655, + 1.7743364112150215, 0.5909489248199555, 0.8818636755465233, 2.925838705443318, 2.551562362113197, + 0.8656224686308085, 0.18956888843706154, 1.315516288238658, 2.0716628980275242, 0.312454913330527, + -0.7162750476115645, -0.878833889202943, 0.6947032088727311, 1.6113499604822614, 1.5221335197945036, + -0.27693710623387013, 1.3625873381958498, 1.9219938239534313, 1.115899313148853, -0.20083092421955806, + 1.1172392181523778, 1.6750346489852932, 1.1691036390825618, 1.2029859297289334, 0.9960476064420001, + 1.163147082594017, 1.7216729059442315, 1.7053187204462026, 0.9288524658731798, 2.4130134117445703, + -0.5645287762055669, 0.752559038877406, 1.2524822429584448, 0.9518237340458072, 0.987778178364873, + 1.8370966298464766, 0.3380716077549818, 0.28918275514468506, 0.14217215525970883, -0.9090848279623371, + 0.40634766156726465, 0.45921386931632335, 1.7087209045520104, 1.250530317999317, 1.972209562680899, + 0.6415136042217148, 1.9726881919710766, 2.76829208739649, 0.8039054631656719, 1.8949965483529663, + 0.15378261805266435, 0.21544963667805994, -0.3834139645804886, 1.220774660588252, 2.1797256330399204, + 1.7003382049594125, 2.6467093787686893, 0.1573129905650743, 0.5812419536309282, 1.871112211662461, + 1.6141857208024206, -0.47424685407458633, 1.4605010483426977, 0.8092270115448427, 1.0033274974249866, + -0.0329569488518886, 1.2126655026879285, 1.9276188068986975, 0.7087152200707381, 0.9676340522090375, + 2.4117174500433736, -1.8192499505180293, 1.9932662362621696, 2.163725990682916, 1.453422035663289, + 1.3016012258973018, -0.26651624368846893, 0.366082724493473, 0.7790593376930415, -0.7927095585909734, + 1.8035494381226522, 2.069603923438474, -0.11025020585695855, 0.6254300916941604, 2.256575926355185, + -0.7398783338445107, 0.77744927762638, -0.7158446209448697, -1.0640784039569477, 2.590378986580267, + 2.6416041441499845, 0.7237923374379682, 0.2625840199438514, 2.1497788896908854, 3.170980500671196, + 3.093586996474421, 1.5878412496193177, -1.2717915858558206, 0.7625213487504157, 0.9869353287087176, + 0.7313620474158253, -0.6227714837174114, 1.6063421548427443, 2.3232730862602855, 0.2801983335706967, + 1.5432073434511926, 2.9271386928383176, 0.7603155940661452, 0.6608046350362249, -0.3899995031269252, + 1.2051909467337723, 2.2389001588788884, 0.6734978451462055, 1.2778467500302069, -0.6385455229392984, + 1.1012743861156717, 1.3843929241321444, 1.3285532977853243, 0.8059677726118946, 1.6472880062872002, + 0.5378007664373662, 1.6249581282054781, 1.9966302621321874, 1.360911366339469, 2.496942387812524, + 1.8095366679744727, 1.6995328439388646, 2.144056374409378, 1.84739190122552, 0.413438272515795, + 1.5420480599317428, 2.1829213108801695, 0.6972059619567923, 1.5101983093418478, -0.5966939817503196, + 2.209659821068029, 2.459681316219518, 0.2400013663115046, 0.31681183129057267, 2.709704096824602, + 1.8838926151069417, 0.8279148249788777, 2.7334217378298837, 0.9364157034371372, -1.1898475176979861, + 1.3389140855337702, 1.6284174618016267, 0.687648779097825, -0.3839301101516175, 1.9467908576890625, + 1.247864970102519, -1.7875246408574879, -0.47883653291701567, -0.859685789177576, 1.3770605385271022, + 0.4553439962208815, 1.3412677353767832, 2.109323942959153, 2.1364741062048487, 0.04376501299222957, + 0.9848951379518947, 1.742255746699906, -0.32646085442832495, -0.7969664561561718, -0.0071865050205361936, + -0.265910025841531, 0.4787527972829333, 1.761309426077608, 0.6030658905178332, 1.0595016704078868, + 2.0657775368579596, 2.7935119298810367, 0.42508029781004975, 1.1232277021222228, -0.5429690080865577, + 1.1492073021595637, 0.5148126776490796, 1.663595090677539, 1.162378928463761, 1.777697918065749, + -0.38503682365552394, 1.4044113209655869, 0.4936370242935475, 2.8585799694365104, 1.222035092225946, + 0.5361225813621725, 2.5564604264491617, -0.6788802948010191, 0.691920665723789, -0.5033230665192567, + 1.1463816085018617, 1.4665678739083416, 2.0561290961956233, 2.437979302184922, 0.8907419398415305 + ], + "marker": { + "line": { + "color": "#4D5663", + "width": 1.3 + }, + "color": "rgba(255, 153, 51, 1.0)" + }, + "opacity": 0.8, + "histfunc": "count", + "histnorm": "", + "orientation": "v" + }, + { + "uid": "0da57950-be2f-49b6-a792-f5f8d19f98c8", + "name": "b", + "type": "histogram", + "x": [ + 0.24717017471150998, 0.6508904445322543, -0.8150211824679685, 0.15253966266018137, -1.822991097914981, + -1.2652443361175678, -0.6606912065389405, 1.6348593909273372, 0.7238370107613543, 1.7516432353985738, + -0.23163828338164527, -0.8450825428744152, -0.5844768325120463, 0.8163479149135711, -0.9043241120474963, + -1.033241804482091, -1.1508081459397703, 0.2500849369342386, -1.0722254424042883, -0.3818758815115354, + -0.09184267628308106, -0.8310239788407002, 0.30918710925621823, -0.08817673873215534, -0.194201628422228, + 0.4498720118714331, 0.718739531277941, -1.5212579707304652, 1.2111098007931569, 1.6827079878819076, + -0.32600413461486905, 1.076060629024589, -0.16558954069343906, -0.10463177421592845, 0.5320982232387549, + -0.4057279103394287, -0.5454365137328842, 0.12105913342208229, 0.17312318436829355, 0.3581774505643061, + 1.4053985524637818, 0.7385779072129972, 0.1728993325302504, -0.9642900730742399, -1.95019753096222, + 0.7953017083783489, -1.3267399891454332, 0.16440059785827735, -0.1765065377819852, 0.24884985573797141, + 1.1168155478437398, 0.20189052654469644, 0.13920010611734465, 0.3632414028572216, -0.1860372376109264, + 0.13741016106913026, 1.155795006020221, -0.15205090348919997, 1.482046795462377, -0.21543274684447528, + -0.49368253233804393, -2.833554199866558, -0.8954977369315434, 1.0982651974761002, -0.601677749927168, + -0.626052278975063, 0.8176143112512172, 1.022510974544082, -0.9112534501862416, 1.317749380832231, + -1.935342426198395, 1.0853897247144597, 1.1365568442970788, -0.3371625685944363, 1.3248619549494398, + -0.21792679342945975, -1.3872271391403075, 2.060293685116359, -1.2966809561606407, 1.3389934684176532, + 0.3061307598318823, -1.5477646780903176, -0.7687697828301248, 0.9461943137621243, -1.2552954777182082, + -1.0324634543226863, 1.7469672065096085, -1.922118988337992, 0.813290245474606, -1.581210140425815, + -1.85270906655475, -1.447052388789858, 0.8647306728957707, -1.7074942767636454, 0.09072455997669249, + -0.1434018710397995, -1.3508724761125548, 0.43884416771151313, -0.3923080679859707, -0.484863957186313, + 2.0313414148272684, -1.0770197870466236, 0.5501630453529763, -0.5769021109992696, 0.8723327961817133, + -0.15793816313844766, 0.611569718103245, -0.9279203551660642, 0.8868555305979685, -1.2863958884876252, + -0.9169961989887135, -0.4788021497309598, 0.06737049507226364, 0.06377790502949275, -2.120926699452253, + -0.5706935250597426, -1.4794975393529384, 0.5484514478553956, -1.1289598941330543, -0.46930103800834316, + 0.34415766628755223, 1.0127642384890394, -0.5860617803207959, -0.004361076960960266, -1.4624084412873102, + -1.4876648199262983, 0.0002434034845286234, 0.31404839889437397, -2.853581563401052, -0.6905443983672489, + -1.267505172562291, -0.9743404754720454, 0.5738896150082914, 0.2892135479255045, 0.38574482865232146, + -0.7455721437008832, -1.2387680016704763, -0.10014471002138516, -0.10122547359839233, 0.8381584472113365, + 1.4425872995117839, -0.6474828269639481, 0.42990651953898473, 0.4861226476675611, -0.18365068368518048, + 1.4429115324114752, -1.0077850587603994, 2.170800719986625, -0.7598808679056714, -0.7723883605044803, + 0.6028150682057919, -0.8752896219034508, -0.16019006096227134, -0.5235998887306694, 1.3225687015352434, + -1.0421450720209056, -0.0041099689737157, -1.3744014131425226, 0.684666361539239, 0.4987951683069051, + 0.6476768240541817, 0.1660948804877157, 0.026845896625398567, 0.6486776400327656, 1.589740672914597, + -0.13585507853736203, -0.41944005387169464, 1.9285913498078224, -0.1716076863148993, -0.8830322685894074, + 0.989328997079004, 0.15014887363927917, 2.1073856112319573, -0.09336556072943948, 0.8251907761938161, + 0.03554048954198306, -0.8728308321492795, -0.49617580601481187, -0.2885116765790593, -1.0777480601650007, + 0.49890244290587826, 1.7647872157816171, 0.167148057085774, 0.2230597536567459, 0.6471052411259425, + 1.2511936724955517, -0.47823538558215956, 0.6313427903382485, -0.47266890661496663, -0.922983516646936, + -0.0848870934057788, 0.21357394132950927, 1.1838943792994803, -0.056489154246596535, -1.5350885762084687, + 0.2153807864791426, 1.049613321403998, 0.7913592687180824, 1.0616499979863872, -0.9325579449300242, + -1.6613732101495557, -1.465723136161939, 0.5211126127597852, -1.009383057170543, 1.571047158972572, + -0.7802107101237583, -1.2065713502039144, -0.5754557994153494, 0.18604311654793398, 0.10009144534385224, + 1.6596790297623762, -1.5034877366780703, 0.6024263047885633, 1.845632368638024, 1.3426911554615766, + 1.4144657904497604, -0.4685345744721685, 1.1665703498240583, 0.9466358336326075, 0.23432484112040114, + 2.1896805672517776, 0.10329305161971308, -0.8669993787780316, -0.10122454183853348, -0.3852780039239969, + -0.06537064291267099, 1.7854993711278595, 1.4746600355221693, 0.8180767106832223, 0.03171178302883711, + -0.7311915691326462, -0.5294530336276179, 1.1616967257501902, 1.3235646225716677, 0.8083954782361215, + 0.9346961517158318, -0.15994395076848172, -0.5832060303528012, 1.0861622430620157, -1.9117988696496828, + -0.9541754048854387, 0.5623809356714187, 0.878482328566476, -0.7273251347315781, 0.11780047531825437, + -0.056290707745546203, -0.7118286134963978, 1.8079048773915192, -0.3030024456040709, 0.5113279649836252, + -0.17662124581595143, 0.413556705132392, 0.2508471978756103, -0.957586821591974, -0.5606625261381489, + -1.7969542661952589, -0.17951607976099337, 0.3828429015202436, 1.4006774417602552, 1.2214910092762616, + -0.07276900338292434, 0.6349045670811495, 0.5815165198562923, -1.7149528054623837, -0.4740962394511683, + -0.7869466942867669, -1.4010205601918595, 0.009623074214509732, 0.38528282304379974, 0.27048459355362375, + 0.34456132269340256, 1.0992594911564437, -1.5819614025235795, -0.19966981632576566, 1.1017660413550918, + 1.3529014479021524, 0.5010051267668827, 0.10706917722042782, 1.290128530495684, -1.0145662484581144, + 0.027945456045077168, 0.374354024688417, 1.36879447977263, 0.6216519545839533, -1.0164986094612556, + 0.5659414903893583, 0.9468000823530679, -1.3751379600000448, 0.27224378790257314, 0.7909135762743138, + 0.3327477517188392, -1.266453506806076, 1.5306542311392397, 0.5529182019404896, -0.12734077013114173, + 0.021316009434535307, 0.3683427914836353, -1.0898681944035924, -0.574585420322725, -0.6052695803083427, + 0.14504953500969345, -0.7188118249593387, -0.7424240665468679, 0.07242375779749721, -0.25386890138486606, + 0.5303633323977174, -0.07748202462848244, 1.436851157176041, 1.27477866692964, 1.2034959772374842, + -0.13335536472079937, -0.5709022212004916, 0.9111074446467027, -0.25036530174911453, 0.8433004970647272, + 0.40176998169367084, 0.18884023993105017, 1.8214637574874237, 0.48782388243322516, 1.7750840328750188, + 0.9821456607527446, 0.12490795768041613, -0.5922156078661274, 1.112236853138011, -1.2611554870130486, + -0.2408518516301633, 1.9764903787197086, 0.12675330788317268, 1.9181579072470047, -0.43061356249680777, + -1.1351819355135224, 1.5883510729873451, 1.1459064225143687, -0.9927263683215908, -0.9680013931641662, + 0.11744498097610455, 0.9440814831114352, 0.10369974663800582, 0.22984112616533564, 0.009571988151109828, + -0.09493621270205357, -1.8428048487116817, 0.5294868676175625, 0.01199144841454447, 0.7315376715494402, + 0.47290043222271255, -1.4732838724027217, -1.0110158634871256, 0.5963799590116874, 1.0281078344249033, + 0.544800876348311, -0.3011259232952372, 0.8310387360892563, 0.16305353154352406, 0.48985943424754474, + -0.5903853297373168, 0.4197752541338072, -0.16580714159020726, 0.22881739066986675, 2.0958268094894357, + -1.4389751605502508, -0.1688582882164341, 1.1726387303468975, 1.421359540272095, -2.6612047864446318, + -0.7006199750885447, 1.2061269344417644, 0.3417316124533405, 0.9434594039832892, 0.9299960890943318, + 0.5120228371947173, 0.003242333604216274, 1.6096553180846633, -0.43193376079241225, -1.1237367068747013, + -0.5658877722589758, -0.11588885791734829, 1.5953979989982485, -1.4436032149241773, -0.192029476388627, + 0.5572940794074174, -0.24464074589593135, -0.16721639311299086, -1.0894508749054412, -2.277109291568765, + 0.21380676022263861, -0.6617061559688207, 0.7089747347833567, 0.4050110908077288, -1.3968805210461337, + -0.36187802078563563, -0.5771509850368625, -1.257801154004516, -0.4290707334815261, -0.5198215120663554, + -0.29836464857565254, 0.7401824470342562, -0.4128089214851227, -0.20348139076619104, -1.0263562362711167, + 0.31817308051178456, 1.8579841183697818, 0.5148895042352157, -0.4353551383900013, 0.765813311852205, + 0.6035561820699586, -0.4739478192950353, -0.7692475901310781, -0.038794243644712054, -0.8025040129970537, + 0.039250591991395134, 0.2190634141165833, -0.3398892537374875, -1.2464726884418627, 2.486124957792264, + -0.14399426229065013, -1.9117134120604264, -0.3704382126954436, -1.3714784413211725, 0.19381924458319205, + -0.3380736940358205, -0.7247437191604229, 0.9298117345423975, -0.6050292369282486, -0.13167537549610994, + 1.053645346954542, -0.08972777118469959, -0.726209040728487, -0.19995524124132513, -1.2674274486330859, + -0.3424588271018304, 0.11691070834983977, 0.24944318150448466, 0.05013778775408014, -0.6396352741658524, + -1.5708438000260556, 0.31794465675939165, -0.7550462890650952, 0.3760299864283936, -0.5407500111955571, + 1.3304268330404363, 1.1091191495240815, -1.145079890749212, 1.6530064842355414, 0.1172824123999301, + 0.4966423981925106, -1.2856596729013319, 0.23234458652706752, -0.859951746906971, -0.7875522340854051, + -0.7316618087169465, -0.731120834276107, 0.9764308120953917, 0.8333216830949784, -1.345679402988789, + -0.46636340047136315, -0.7496877749316126, 0.592328275509295, -0.11163403742846677, -1.138744102875518, + 0.16070735045559814, 1.7010245485213378, -1.8672262338066044, 0.1357666765020308, 1.8107695972991298, + -0.6958566157110365, -0.8969990166705052, 0.6588103360003852, -0.4630638419265091, 0.10266863144821196, + 2.018800506760945, -0.39095602576608335, 0.7528888210425931, -0.34198459157504163, -1.350166356032729, + -0.9891360841491725, 0.36517717152325074, 1.0596948843261915, -0.6589593620699395, -0.10051660288942761, + 1.0465286833321448, 0.2832307866183443, 2.4806930703085266, 0.6595275920874967, 0.4014493192281944, + -1.9657309794815039, -0.3717497367109962, -0.00997699141422927, -0.8661256875499859, -2.9001789797938127, + 0.314373489455665, -0.5710092633464785, -1.1985748367275346, 2.2627958814893976, 0.05369546410544602, + 2.2196398580700714, -0.8215159023184033, -1.3170401112033578, -0.2574683969623841, 0.09596626931752447, + -1.1460975323611489, -0.611734580349255, 0.18344931286665336, 0.9873804690275889, -1.1688551298893686, + 0.25938005748776594, 1.4348101350453586, 2.134553755141447, -0.08655125976730663, -0.13233226095169592, + 0.04007552959900407, -1.619062232172446, -0.42322307759132366, 0.7311516980445337, -0.5728539579185726, + -0.8086304917847332, -0.2969440740512066, -1.1060667929650587, 0.730189809378188, 1.0331160110886253, + -0.5482482561159367, -1.6463076806578456, -0.5780429512038785, -0.4148861268298393, 0.6088591382176125, + 0.02837181583750673, 0.8265082449241612, -1.2949355087170702, -0.07321425824798002, 0.643310938237264, + -1.0881351849148093, -0.9037768153070401, -1.055969098661931, -0.5094049180787917, -0.5297798078576355, + 1.0826817387022085, -0.7265213117688585, -0.9471970947871516, 0.09584523855578374, 1.2817823279838951, + 0.933949046732906, -1.2416929044399099, 0.5158698586241993, -0.3391268959927017, 0.07590027719466, + -0.6536215313854338, 0.12613147560600377, -1.2931289988334955, 1.2059267399255136, 0.8221806107128893, + -0.14975612615137332, -1.1357786018438094, 1.1078739799984285, 1.4519656826825322, 0.21425262242229323, + -0.17297494959681592, -0.4125596663091237, -0.43903287968682686, 0.285420305156604, 1.0289819681284869, + 1.30304953472453, 0.6100432183522858, 0.528406941280846, 0.6493695934354875, 0.035431712313638106, + -0.34644690998141164, -0.796504506738752, -0.11828378524729105, -0.16450565452078367, 0.4965399732181898, + 1.8127114994468416, 0.5618612464375041, 0.38908605366841514, 0.9672246798034804, 1.2054945080332318, + -0.7825581755187514, 0.46530849788959566, -0.4653354995343681, -1.2497509312557395, 0.5933954386048551, + 0.9714888969929732, -1.231176922844112, 1.2985644430169883, 0.23332698070444188, -0.9189603270426907, + -0.15901819960804706, -0.04088683592629575, -0.3622566203984889, 1.4034605863680416, -0.9799196744438996, + -1.0082592208707042, 1.5889726313663017, 1.3879867130445946, -0.8651531953942443, 0.8325283251324677, + 0.40283478392364, 0.566734851550195, 1.2354029177554389, 1.9401102987941288, 0.3304164459556951, + -0.44682485854050935, -0.8828573314953989, 0.37309537154182004, 0.6966264193565658, -2.1531470678728075, + 0.5822121309083735, -1.1864975789724992, -0.3467790135902433, 0.06192610280088083, -0.9593013558031604, + 2.314555685603726, -1.5363546389107323, 1.6613624488641603, 0.3068925034822794, 1.0855460271134578, + 2.0362105454916377, -1.954124607535517, 1.8459423197107276, 0.007419854702835407, 0.419613751407409, + -0.8700966275550566, 0.5931832214354316, -1.9814093272532223, -0.689816522318143, 0.7052365581383292, + -1.524097325272836, 0.362738165849644, -1.6027372930389894, -0.575060574549145, -1.0768938817874592, + 1.1122175035586142, -1.1798486870355185, 1.9446179622977855, 1.0862699095645545, -1.4227326226253796, + 0.3723787334721068, -0.7428992713493225, 0.7864313232914981, 2.1817410605724974, -1.1526622137685807, + 0.9943929143067622, 0.6540577793677304, 1.2088354265370456, -0.10770763112738733, -0.5762716050306712, + -0.006312645070578343, -0.6512835043654928, -0.3434385872483015, -0.8047417776910505, -0.8011265980368593, + 0.12057134681295963, -0.1731512640809081, -0.7558497182534891, -0.7045123958339868, -0.2632890683609227, + -0.6752420038236423, -0.6797472545975527, -1.708221079984937, 2.269136570189591, 0.24620846826150533, + -0.0047837274506687, 1.606223647617759, -0.8780964391996585, 1.332735198583268, -0.2048959533958293, + 0.934628171878223, -0.27532977809955067, -0.27455588132982456, -0.21639610710487775, 0.5345512255765458, + 0.9862317869761077, -2.3152953069739546, 0.09355389670471666, -0.43204155084867457, 0.6254203578331745, + -1.4905133828626114, -1.3202404641510304, -0.6516063865631411, 0.7661154967709796, 0.4406880977769576, + -1.0943669801255602, -1.8572301032540994, -0.9692418467996528, 0.5245692293175974, -0.7497058753366137, + 0.9021668708994779, 0.3007171019335282, -0.6342591518432482, -0.2792441835230398, -0.10565009854168868, + 0.08853325137650421, 0.14589445133655635, -1.053227239214965, 1.1507556676103885, -0.7765478928939493, + -0.23488985672206933, -1.35254486184858, 2.002228471684712, 1.0240753479576528, -0.40139546150768485, + 0.7272086104915569, 0.3162000334830568, -0.10206748103875186, -0.0759493104055277, -1.351981985062227, + -0.37386708908599814, 0.41468820700293596, 1.1233372568681472, 0.9263527199129673, 1.4578155418475698, + -0.3007865535002782, -0.3600881776880989, 0.3226539586267199, 1.1098550947492214, 1.1902688892659261, + -1.046805648066965, -0.41310650501429486, 0.8354658073631973, 0.8009402332786113, -2.092424014571576, + 0.6162429136025703, -0.4070185673243271, 0.08738651084358477, -0.3917986470825591, 0.2722375030922986, + -0.678773385712444, -0.20645698047130176, -2.2156600429107574, -0.5778332890010393, -1.2842358484380072, + 0.32257953783010224, -2.432858313204693, -0.21423785852399502, 0.09234088836669363, 1.8723459353954737, + 0.3116027334442146, 0.5725449534928352, -1.0103789833472068, 0.5425900942297627, -0.6087760672370536, + 0.35887541633607845, -0.8340110899194649, -1.2458907118620843, 1.7117345997353934, -0.21171419703849706, + -0.35171224122255734, -0.14027885465667442, -0.49496650372210144, -0.8765230988961866, -0.527273221722177, + -0.17221423474549502, -1.327694105838922, -2.63950303958468, 1.5825653543957154, -0.14288640047785348, + -0.557611113063478, 0.06725764129452667, -1.6536371632721105, -0.19546948004173959, 0.19232399992043536, + 0.7318406525044582, -1.3514857758605863, 1.2272059704043077, -0.24872731316036867, 0.2521799247909455, + -0.6480325392596458, 0.6036292834079413, 0.5022129251488993, 0.14136376883128368, -0.7670223176536054, + -1.4214881053797948, -1.9414270362384096, 0.08145049873345955, -0.806035657676726, 0.9608213954093567, + -0.9888633886037648, 2.2112268803714366, 0.5784051206947785, -1.295227278104692, -0.7406381599007316, + 1.7308546647336565, 0.016725605731691903, -0.9052732161641754, -0.4789529787584098, -0.15432755338701978, + -0.04898802662344806, -0.5513603394650693, -0.26377536441039356, -1.2509975972995118, -0.5849060036538883, + -0.15927667307001395, -0.5436270419872595, 0.679685435138932, -0.8208598900271087, 1.3837192377620806, + 0.9879899569172869, 0.2799267850370644, 0.7059195073750612, 0.993631776168359, -0.4845235515263151, + 0.6749006865873656, -0.17871734605336176, 0.8873958986148749, -0.594433358812157, 1.604346571383979, + 0.12679610429203095, 0.8603049362023704, -0.10074065627060232, 1.5396010150001553, 0.6262501635567194, + 0.7191613741728022, 1.9244064607744034, -0.6512029373916618, -0.5935549526627856, 0.7632944585929242, + -1.0442292098266002, 1.9599701672744536, 0.375098066715715, -0.11590637875839228, -2.3451953718123777, + 0.6760722165505332, 0.3503901593514392, -0.3445163409530079, -0.08514400254261564, 0.6121936626258342, + -2.4693877739428465, 0.2448164872319753, -1.1042772536120682, 1.3162595585525276, -0.8776037228248692, + 0.9362227162529728, 0.56223899681111, -1.710417520124907, -0.548470389690448, 0.7321328252784692, + 1.4294325751184078, -0.2995398735486935, -0.21351370576547218, 2.602231485978111, 0.4589018617695131, + 0.36898045304134924, 0.2912043023683997, 0.4010253554844599, 0.80547924759533, 1.8472949776621252, + -0.7092753091139703, 0.27165352791123987, -1.1287400305084936, 0.19717804833192729, -1.3564106169358068, + -1.7894240524437912, -1.643775986040349, 0.786385810356323, 1.4727014535795917, 1.7161717759563184, + 0.29577036647413113, -0.5907536545009835, 1.4853031565565995, -0.6572252651585306, 1.734761724237341, + 0.11648552668593488, -0.5341496084509058, -0.2702734086163261, -0.8589555538893968, -0.3316241849295669, + 0.7730434318388038, -0.9021650524512336, -2.047073717684312, -0.613282181087793, 0.10850979779007049, + 0.0021574667286730197, 1.0248849795219361, 0.20052591910291115, 0.255049300773108, -1.0355101690802482, + -1.5067399763475955, -0.7324291766906069, -0.6615400833686695, 1.3714047199068402, -0.544224802566983, + -0.3888391511490841, -0.5701860395684584, -1.0768981124832804, 0.17783738618734676, 0.8684015805657804, + -0.6288391364145552, -0.1809346616394548, 0.47893376870625703, -0.22645317633115575, -0.6232234184570332, + 0.7190848473201449, -1.383822708846083, 0.6760106198175666, 0.2547795395493637, -0.4592728609104206, + -1.0720063809749247, -0.5097336442488316, 0.2210945722858165, 0.0054940755442051915, -0.2682202416730527, + 0.8832895236943469, 0.22035015534807104, -0.28323135681321404, 0.0596942381726312, 0.2951001441099985, + 1.4294566636751351, -1.8415718234294567, -0.4287767535621176, 0.02235146702729841, -0.19623394005718553, + 0.348486936660908, -0.45028713499693546, 0.5109081477837931, 0.80404587857595, -0.9576612954106148, + -0.49846557170623607, -0.5282676532693787, -0.9023668605060903, 0.718948342727176, -0.19721998877492158, + -0.3493854959489624, -0.6015698899368381, -1.25739592661238, 0.4615703609944283, -1.522793551670885, + 0.835813231026569, -0.9632684667531055, 0.5949002940876471, 0.6801241316046363, 0.16239126239994003, + 1.7871127739698363, -0.11179200301594365, -0.11479877273726007, -0.017768269564701518, -0.04595864622714386, + 0.03186982221174247, -0.8924472246573419, 0.3773470645824399, 0.9343193851877845, 0.17678950535993326, + -0.30349579978993296, -2.2195811995137253, -0.7605603587531623, 1.4519878601632827, -0.21168645510474787, + -1.3446956935225252, -0.46883579885368554, -0.5480783626043464, -0.03826750777339118, 0.9230210091643275, + -0.8117667649758827, 0.032921144936808824, -0.14694781434160942, 0.2732522186016428, -0.28307590066421495, + -0.44035510547379314, 0.19961818762280978, 0.7607227206679584, -0.006421047821733644, 1.083672671799983, + 1.5248123800083784, 0.3631357175074549, -0.7881724782716621, -0.021303921700341504, 0.3656975257174558, + -1.7438786191751867, 0.47970946679448107, 0.06584509630219254, 0.46921648575314345, 1.487324405065218, + 0.3054584986671542, -0.27013805573980154, 0.0834218511987659, 1.7877651910559618, -1.2286892517506403, + 0.32603468731673657, 0.019401575698656824, 1.9968485902846984, 0.15967674516314148, 0.7436323535351307, + -2.8799070515793095, -1.1338904523418378, -1.100245904375071, -0.0922766913171747, 0.8567663128968322, + -1.032886450676613, 1.3115985566628139, 1.1525099783356643, -0.11952472894818086, 1.2133481193955682, + -1.6139892679614278, 0.5593529445952521, 0.03763293886276376, 0.2543879239408883, 1.8960846406593528, + -0.36933998733459217, 0.030822422117507603, -0.2169001686850376, 1.216550357293351, -1.2454685329663429 + ], + "marker": { + "line": { + "color": "#4D5663", + "width": 1.3 + }, + "color": "rgba(55, 128, 191, 1.0)" + }, + "opacity": 0.8, + "histfunc": "count", + "histnorm": "", + "orientation": "v" + }, + { + "uid": "bca37da1-d2b1-4232-852f-692208ab0ddc", + "name": "c", + "type": "histogram", + "x": [ + -1.3721691025663127, -0.055559399376507335, -1.5268281942267183, -2.3068542674634456, -1.634184001814117, + -0.3846139031707887, -1.3079057664033003, -1.8023900909842059, -0.39685654971775064, -0.9700764293361207, + -3.2252225103122267, -1.7541857307474733, 0.0726472328611778, -1.5283169557075813, -1.3593556129862843, + 1.5558842316123753, 1.5610253445169122, 0.09028942809703233, 0.28093976501896134, -0.9182817541696389, + -1.9474806097659059, -2.0693260145236847, -0.45087692755871533, -1.8396030238223577, -2.1821234736201496, + -1.7956456323308654, -0.8745919002311255, -1.4732294253636655, -1.5737199778097795, -2.0906249949790143, + 1.0783802824223598, -0.7678270898396788, -1.0946846976537616, -1.046599528798077, -0.8258573773450975, + -1.5460788519494995, -2.1630006294431947, -1.388458285688274, 0.09949416034153025, -0.26407962471920354, + -2.0116724321714665, -1.1161186530636875, -1.0972262957231433, -0.8357971082590953, -2.018948703126203, + -0.8851490574451603, -2.0200714198352854, -2.3139194145001594, -1.4757584101325891, 0.1952031661446023, + -0.5351517186507875, -1.66560485060405, -1.3159939110426362, 0.2055271353320851, -1.3286683182712768, + -0.6553833950543407, -1.8348198357522545, -1.1236037854819074, -2.037333587620921, -1.5231036110152445, + 0.0015785003944064346, 0.3118845183872452, -1.3213434209817232, -2.59313517540774, -0.11810410239181168, + 0.2921985012132666, -0.38043971158559675, -1.468381118608244, -0.16369778566586812, -1.6336221818136065, + -0.7572978365912203, 0.6641565846049517, -1.220252118627534, -0.8154670127389112, -0.0897976181988589, + -1.5880733281432204, -1.2509923023222245, -0.4192922526791726, -2.3225468986520568, -2.0253298993423408, + -0.4290532305770398, -1.1977392221576755, -1.3838501545669573, -2.6238531018805245, -1.2885072454796083, + -1.916117519861287, 0.49751232615024654, 0.5071573582737465, -0.39751362691791936, -1.4508245759564813, + -1.646509459850566, -0.3383917987017795, -2.5107896735130497, 0.03600842053269737, -0.3983685165767131, + -0.28142941855349723, 0.06219032812404279, 0.3832282128653597, 0.38774306844429707, -0.401165065304515, + -1.8961349155045868, -1.1281485419777995, -1.2204537732694851, 0.016857943429609668, -0.5343481749103374, + -0.6957789100928999, -1.4779097361903588, -0.10242592465829503, -1.178035586259421, -1.1940105002218764, + -0.9947212873423706, -1.3040549520348677, -0.4051649584181839, -0.7765046829126945, -0.34435224450413926, + 0.04441960267815537, -0.6952306059471409, -1.058042298770127, -0.08635706637291973, -2.832741379159513, + -1.8998952880491287, -0.9738688010384593, -1.3637478522094972, -1.9355410528538726, -2.774762751231963, + -2.0315828421390094, -2.980112601746968, -1.9575110225639811, -2.9096467039164926, 0.47809106569539916, + -1.661977503856854, -0.8961885571663387, -1.9134037122836427, -0.23193651358388878, 0.08165709423300394, + -2.482870860074078, -1.96828466998516, -1.5322032992246175, -1.6689067529433346, -1.3351481174823425, + -0.8516115688396445, -0.7339995760204281, -1.9430537021848133, -0.4328442506196758, 0.10256393100866767, + -1.3241552620453252, -2.0045125417246696, -1.3779453786538645, -0.6695286356597974, -0.17058636859790466, + -1.2765829416959678, -1.5535631513543708, -2.7285348332885286, -0.6299559011464553, -1.8902328466232938, + -0.9276768809042669, -1.6497709133600353, -1.0618062450466585, -1.0066034534580057, -0.8494835499746591, + -2.009675484436862, -0.8134004936825887, -1.484546835466223, -0.15535055275656773, -1.4880777397513252, + -0.6461589999346729, -2.2025767797108995, -0.85119023698206, -1.475635325571694, 0.054604081680369676, + -0.785465646283342, -2.482787454019869, -0.16493764400379196, -0.4364734417180497, -1.7278626535709787, + -0.4262864074998003, -2.791637498043028, -1.8032708606695502, -3.692849409869771, 1.4197074620595336, + -0.416428757909329, -2.1607999385316132, 0.9542191140069787, -0.5927848884050715, -0.8985398212812252, + -1.3547420976264428, -1.7879617356981379, -1.4779542665269938, 0.01894480910055263, -2.40279186297451, + -2.155388436073219, -2.123907609669101, -0.7079854235311156, -0.17629501948813497, -1.0135748660632262, + -1.4754803667629681, 2.020177127299421, 0.8013292388780942, -2.833370047254127, -0.0978191198585373, + -0.3694686458085179, 0.6401525353818942, -2.0046850507544325, -0.38905555381567836, 0.4758070341542575, + -0.8107549565355064, -1.3251314805090533, -0.6784912523451041, -0.08319184234925925, 0.12721485100954188, + -1.9900204409846958, -0.7814909494567001, -1.4705279900528296, -0.803250692851796, -1.130794997965504, + 0.25230694048103874, 0.5199168196536541, -1.9786653648387027, -1.2211384258135853, -1.3517419103173696, + -3.4512978463909665, -1.9360717294758634, 0.5963912150553532, -1.1651298420764546, -0.2677546976333205, + -0.990895840864774, -2.1772940505953535, -1.5589533017848485, -0.3066763105649537, -1.8982997283228218, + -1.253720565121647, 0.5629754017025879, -1.1040122218251722, -1.9368546708049457, -1.3242008335482496, + -2.7062714121523195, -2.1391981970095966, -2.218253186488092, 1.1410270066999946, -2.678909237004068, + -2.1034224312463294, -0.09001599702788532, -1.3861573050466973, 0.4309077992086905, -1.7676825412793904, + -0.0797806410671209, -0.8090051979442361, -0.7191278109578347, -0.9238956958829518, -1.8708997613343679, + 0.46095881707891295, -1.4536735037571336, -2.445594948796697, -0.2855854013850947, -0.03849810471243953, + -1.2183907927612219, -1.995087499009896, -0.9176306629521732, -1.2638394287812242, 0.077172621282108, + 0.04861488534812297, -0.30524012004496914, -1.8949252726263692, 0.023717843789584858, -2.5801121114537313, + -2.283902994947505, -0.46450062592334085, -2.1998680928956937, -1.2843448610035528, -1.126315694880292, + -2.432925891698704, -0.367152071466476, -2.164981253605186, -0.5334011550101527, -2.786447010560285, + -1.099818527279702, -2.7516911620520363, -0.9539562331918541, -1.3224389623514698, -2.619116218456747, + -1.7191710355640561, -3.777617047477266, -2.1935428708556928, -1.699724575290813, 0.6929416544115212, + -1.3539595899257533, -1.2529510944317774, -1.8834081647183984, -0.005871959851251662, -2.498168585350884, + -0.6837689553252978, -2.447918564998174, -2.700046089939507, -1.2512548276022328, -1.180103465948875, + -0.6745266138319896, -1.694132877765691, -0.6507546125707508, -1.4418864389567574, -1.449350386945441, + -1.569698037860454, -1.6843242108560887, 1.0044495680644663, -2.5399103605869326, -1.5874435162334335, + -0.7414223377353278, -1.0537593201669275, -1.3890836031486868, -1.326026300142044, -0.7377990409785633, + -1.4979789890154254, -0.22374257362344796, -1.9517507921497392, -1.1347968771877917, 0.22880256288448653, + -1.736615362819471, -0.36169567991921336, 0.29802511349728866, -1.1759317372642917, -1.8317746807202653, + -1.3980910647528513, -0.9679729038438629, -2.188642187037331, -0.6864718785343349, 0.5820529535218586, + -1.3580261254829886, -1.2622040836377058, -1.3557743007571226, -2.908293520800397, -0.3448754298378769, + -1.1526652109415496, -1.5934890521574867, -2.2221100507530887, 0.017479147130040618, -1.3811326387025953, + -1.6943593970638644, -0.9702549626687003, -0.24525292165645185, -0.6608534276160445, -0.9833578758804171, + -1.2945705777471932, -2.36049903048858, -2.2698537032955013, -1.1551419419096713, -1.0552067877268103, + -0.4876668982851452, -0.2035337072525697, -0.9835963509135919, -0.5432875259567532, -0.7914287117149585, + -1.341411946663011, -1.7308073385525318, -1.3962899230417753, -1.2365695711118063, -0.9042643443167073, + -2.1369244455411875, -1.3599935533093839, -0.5058539175626544, -1.670170321009285, -1.0088914079208409, + 0.07018092936523601, -1.0827754716271776, -0.5991804639605015, 0.1401322493708208, -1.6486680062383055, + -1.2750941077857323, -1.6837272833160504, -0.6011266389845524, -0.3274793036409187, 0.029010292968833173, + -1.3882366390349945, -0.5075063169355418, -0.6493350286568689, -0.4477212254195304, -1.8670121692713302, + -0.8031744131053922, 0.10801220946780377, -2.936208371432426, -0.7109240417542275, -1.4298519202740991, + -0.8764647178633191, -0.4640577205233887, -1.033261936513611, -0.953289413008573, 0.061973421504680326, + -0.5954082591620979, -1.042538006941682, 0.03288725198127018, -0.5628770423474097, -0.9772475675650726, + -1.8889861166589759, -0.2360177097593531, -0.4773314455110471, 0.9563051144957551, -1.764236902867438, + -1.4829353170125787, -1.7350241779207698, 0.06947306087263394, -1.259706502557687, -0.24488414667518832, + -1.2940708028028618, -0.9755578244936758, 0.8150477017721629, -1.4611568247532158, -1.060819830085969, + -0.9666059811130792, -1.3075979008188319, -1.219709407688154, -1.0883755083766424, -0.5747772839893712, + -0.8553887283888298, -0.9192036464570015, 0.45548779863308675, 0.7547105979934952, -0.8865365278524578, + -1.8009874773541936, -0.528537610675502, -0.7499910830746261, -3.2986233385129298, -1.2391359644004039, + -0.3632123579613139, -2.5567304481426922, -0.8407543280684374, -1.2006596950428974, -0.3787376576620276, + -1.3246425189618736, -0.2762648141925589, -1.2363144264827277, -1.953620507954525, -0.5961866591447944, + -0.044336279714322524, 0.2415783546852961, -1.777748453186145, -1.739701114993259, -2.5893487997650846, + 0.08700023353879716, -1.37480446462179, -1.5701989818906141, 0.5105608669465533, -0.45226993539550564, + -0.19926961594633918, -0.926726438313498, 0.5777644293004638, -0.33618851935402694, 0.2393873678082148, + -1.1288232153198792, -2.5074426231375213, -1.8002992905892659, -3.4245122964829338, -0.8023044493490923, + -1.1974330984296095, -0.3357462114971166, 0.37817678645694186, -0.49323098037655666, -0.4127996612469408, + -0.6406202086504156, -1.6563557427506468, 0.4633774242852158, -1.2209465185721853, -0.6894423759078302, + -2.929050866151614, -0.48765480823262564, -1.6081625649920623, -0.32260456985236996, -2.6384771645208565, + -2.0290061863629605, -1.4783112585712392, 1.028219393928909, -0.7145735693099435, 0.369307819800063, + -1.7337918460463222, -0.9917950648752052, -0.1540866375897113, -3.2939616468356467, -1.079915844557645, + -1.828103260028421, -1.980118847879334, -0.8748554333352151, -1.4011336786661035, -2.242446179173559, + -0.2846074217252871, 0.8440029105915643, -1.0107895257595352, 0.5653629014717787, -0.3849189700300143, + -2.212766042054662, -2.1577685361600563, -1.4020552230953316, -0.5575923172826729, 0.46273146588096603, + -1.2885826022940081, -2.073319253557398, -2.241273594370717, -0.3965872673430061, 0.25085868757376506, + -1.1191735990893479, -0.2965795072377787, 0.24324287988868498, -0.31915479947497805, -0.8258205128987507, + -0.5625764935288391, -0.4461605149661202, 0.5308667799414253, -0.8199261681060447, -1.5271962967573556, + -0.731812220324271, -2.78142405454335, -0.8386172591713924, -1.1496360248484385, -4.077972955543203, + -0.85919072067522, -1.232528151481586, -0.3568493518702913, -1.2362516958942082, 0.9107837045928298, + -3.5750955576174137, -0.4732835493633839, -0.6168539018244226, -0.15120174034641454, -0.6449541101808536, + -1.3164860680183814, 0.5101763909427215, -1.1812577692090085, 0.012353526916064839, -1.0110424827656033, + -0.8184183183112443, -1.563550553352174, -1.3282525577448678, -0.06361632893693991, -2.46315916567206, + -1.312362512719348, -0.46295665246596773, -1.8475307047880378, -1.468202945955817, -0.41409273383648804, + -1.6250863040687822, -0.5498583768028471, -2.6738261565354606, -1.148944832763543, 0.9987575171781369, + -0.7948021627538889, -0.8826768732878423, -0.580385466810923, -0.6017348419812086, -0.08175092778263271, + -0.8735650443548355, -1.7377052841039147, -0.05951247766929535, -2.5206528416011285, -1.7933764768977571, + -2.1718451946572817, -2.6274675994435706, 0.5205005610128361, -1.9806370820239985, -0.8807279117427522, + -2.432841515030087, -0.748939313165398, 0.31611569814275464, -0.8148985868509955, -1.4026280350502227, + -1.6013686350781144, 0.6339168219424205, -0.28161093286260885, -2.6506070625821074, 0.13553562924182194, + -1.1287819710517693, -2.526653678233955, -1.1311711249586727, -0.5520419315880483, -0.7309003147176323, + -2.517742050257219, -0.9936273593978716, -0.5235760322338299, 0.5721018567815837, -0.5300438906332414, + -0.44848706816480066, 0.35776681763356843, -1.933363464839536, -1.1785943085205282, -1.6501913181686465, + -3.060224291525813, 0.2702457317255429, -2.272160941630532, 0.30346150603381283, 0.3946743254607872, + -1.9075888617360115, -0.5981434674443455, -1.241845217529431, -0.9370268620764487, -0.7188818418730767, + -2.227967836902054, -0.6928272950335687, -1.2227002021106779, -1.0724097014966452, -0.7131777917899929, + -1.208150119061548, -1.12344165930703, -2.679458622182234, 0.1463341815775252, -1.6688446476552858, + -1.1057760740577252, -1.8603194400717316, -0.8905371422583319, -1.8369619069208918, -2.3500462422848334, + -1.8102327985342048, -1.8949542385624145, -0.1806230123782191, 0.07997150231582584, -1.6418937689287256, + 1.3060829242327436, 0.5952698528842291, -1.629899089883911, 1.4375380852237019, -0.8683462469016244, + -1.2269953701942853, -2.662225866502311, 0.6798637500185873, -1.209755941254261, 0.4810254748073448, + 0.5945481807494748, -1.5924214306455715, -1.1524294743176549, -2.5055576419676573, -2.3699988946068595, + -0.997248328754261, -2.3888447706809774, -2.9449957058075613, -1.2797650114082701, 2.051842826175498, + -1.7234112998138316, -1.8457947710724092, -1.3016722124005162, -1.840162492752853, -1.2762629377568593, + -1.5052261476393114, -0.035616086702407235, -1.4189034568044891, -2.014394249248568, -0.9895438258021106, + -1.5874610700106082, -2.026733550048122, -0.7356426029470489, -1.6228297498965238, -0.02332524680257908, + 0.011744283768103436, -1.61817389659358, -2.2505906282150763, -2.1359237098529325, 0.33465173630555745, + -3.6123182883724305, 0.273851132065587, 0.498526952110528, -0.5581223350863056, -2.0769393392562274, + 1.6499049956230203, -2.3628941638601573, -0.5420612027018491, 0.6703376229205162, -0.7330884006675499, + -2.230267566673785, -1.3712696517756524, -2.0971002438753876, 0.717998185225404, -2.189097573408178, + -0.25830252113901675, -2.664212998478091, -0.4964384092505931, -2.538870477199072, -0.335762769433682, + -0.7898126210038179, -1.0399972162760738, -2.7580599033568998, -0.8053393201352314, -0.945080289465978, + -1.2894029177647366, -1.5380324534123, -2.1894125904938644, 0.6539594330431009, 0.8558240299869107, + -1.740056104278665, -0.7201908428875745, -1.2233022389528911, -0.24787360904223954, -2.225725138525614, + -1.3655297970019202, -2.1126881646807334, -1.0294888763913745, -0.5450081629795172, -1.9247379309306285, + -1.42910868623237, -0.003333689362976733, -1.7923194564117377, -0.3097849598879948, -1.5849841701261829, + -1.1828885209895261, -1.2441301679141574, -0.588407455787975, -0.830282659928214, 0.19085276560318754, + -1.5192463474753033, 0.9216136501691112, -0.5618773735266807, -1.6217407973078202, 0.15069300759655713, + -2.2478102025850966, -1.104686222901333, -0.35002006536618424, -1.0373824532203293, -0.1598063506400922, + -1.0790750392511248, 1.701012850046574, -0.9229538063335045, 1.1959867075553041, -1.1768103909238807, + -1.4561565422498342, -1.883474476875869, -0.3066893681471934, -0.3270185695592427, -1.4193522821614148, + -1.1420644092442227, 0.9362812318211942, -2.1889037381962955, -2.9395680697270823, -1.2138340101245977, + -2.0418391352438503, -0.5904981891486472, -1.1338292645805876, -2.543867223407066, -0.44720937589427145, + 1.0780376621289678, -2.141855881358829, -1.9741289698406734, -0.9771656862721642, -2.947972479473184, + -2.1353718905004486, -0.6701365163149446, -2.4536558593563593, 0.9014340669686851, -0.05449631629054996, + -1.0348301769216184, -1.5068203670137883, -2.037144596188011, -0.8689331750931241, -2.5529571396994037, + -1.6746838972317617, -1.788399118113161, -1.3153156728694546, -0.02611008918006874, -2.0704706823781707, + -0.0056345452665147455, 0.26041260361568663, -2.499831912792179, -1.8233189877724567, -1.3997253068896698, + -0.5530687176680478, -1.0666662028068734, -0.4811281763177122, -2.242169412329508, -1.7388894392032088, + -0.2591171485099074, 0.7605489545283295, -1.0270234270521226, -2.521294719171065, 1.6907833979389992, + 0.08549624568900471, -0.7402503111402801, -1.1134529642565645, -0.6581871093122293, -0.8913892193235218, + -0.9265175944728868, -1.9080912998455966, -0.21454953805384125, 0.40467955418682533, -2.3276254188418983, + -1.0739216145589245, 0.078228369075241, -1.2111541845292937, -1.259760237524373, -0.7520481417138568, + -1.177019005282897, -1.430339918540043, -0.43612494439197036, -2.217717500358626, -0.3155491309839894, + -0.5205921337804112, -0.9458678892551595, 0.0503805231560257, -1.4743859382629263, 0.20271451579504673, + -0.8994029064568643, -0.7064054069704604, -0.7110794089377301, 0.015719164391638563, -1.8370901247414797, + -1.2324860392507537, -1.1286199397991803, -2.4319889517849322, -1.4228853996822708, -0.7222813314437293, + -0.6502863790345612, -2.686191765283013, -1.1281506529568466, -1.0012062548644451, -0.6555651585037365, + -1.074182772527097, -1.1602261465838468, -1.8529779652010765, -1.1119211258447765, -2.3703419417543383, + 0.30207647084134903, -1.954176337914605, -1.2073333228773628, -1.092060476564429, -1.0548138557032536, + -0.6267453242810681, -2.0593646730501107, -1.7869146163293053, -2.903716277764994, -1.4738316789722, + -0.6724716541908342, 0.591411176762122, 0.3662476926629563, -0.7118675333080166, -2.2245992995267088, + -1.5811412814942547, 0.024995490031355372, -1.400295289398434, -1.2089530029544329, -0.4355610429155642, + -0.376319936884969, -0.7004463663294085, -1.9088615016938033, -2.28979139263122, -1.6320594627079827, + -0.9026727398055358, -2.4259290570051206, -0.8255529961627095, 0.5725969753702853, -1.4341344014271677, + 0.7624855218108073, -2.4286148764759212, -0.6278173809820697, -1.8932378623893606, -0.31348774646200306, + -1.9114676829064812, -1.089583513857778, -1.2842402933892338, 0.009911689063820006, -1.346098474173008, + -1.1960940813367598, -3.381286296926733, -3.111124405106455, -0.9304964288211657, -0.08855208605288856, + -0.36527314555500423, 0.39019417521376587, -1.56223132509813, 0.7522883306124404, -1.4875793600258327, + -1.793897301517104, -0.6795072484845849, -1.4931481513719203, -0.22788075005070563, -1.258902980699591, + -0.31162140826902285, -0.36783020156016566, -1.675799465093641, -0.5605011116671625, -0.05705757948199308, + -2.5050807119175955, -0.9767161030064456, -1.3279656351716438, -1.6768392485755637, -2.5218432706814884, + -2.3458615389379602, -1.2328468072983776, -0.7576406703837554, -2.309611385526755, -1.4945338848063732, + 0.3275460150135001, 0.2407156064572875, 0.4430676617927174, 0.2638934892799809, -1.3740958887427734, + 0.09985095557209833, -0.9216307768147894, 0.0021080772099093537, -2.473294479661514, -2.2583670081520433, + -0.25129036285952155, -0.6034711257111849, -0.673127457570911, -1.4500304227548653, -0.24144786540613183, + -0.14714641724930866, -2.2098168058915544, -1.3138570263825955, 0.056372119815397026, -1.6158989028367103, + -0.3412137017330066, -0.8241210719100278, -0.7662464378023374, 0.6786644814103511, -1.4347942941994545, + -0.3630272019711722, -2.3016418617840166, -0.21873947904887237, -1.3980465685215668, -1.2053117019233848, + 0.5259348077720865, -2.292442026500872, -2.283806718272591, -1.0274435701690168, 1.517554766415623, + 0.9969617939437518, -0.40230090907496197, -1.8287276700911366, -2.0469342502309296, -0.8644342805479912, + -0.9448341202447865, -0.5827750571777882, -0.9294385572005888, 0.2649767441381585, 0.5488638507999921, + -0.18705707501325408, 1.1943773712484247, -0.32393108757576894, -1.7819451617773696, -1.1625512815641572, + -1.1500482866848236, 0.15931827681501143, -0.8571245099639894, -0.8727155829023823, -1.6915429144216847, + -1.4659061503720845, -1.8136696617393409, -1.1916835128535197, -0.18646983800226857, -0.9746016632966369, + 0.0441404734955706, -0.3571058100228609, -0.13220154580257748, 0.5923510536976886, -2.9072563692591773, + -0.5017541389196247, -1.4482912067964298, -0.40828235397574364, 0.13508484372240548, -1.028213812504773, + -0.6603131786148183, 0.11802831790719437, -0.641712812158213, -2.1705519104555897, -0.8082694627624906, + -0.9985992001762029, -0.2435008557603222, -4.054654851235098, 1.402447553323587, -0.7310555708428181, + -1.1177172225573382, -1.8112819525180628, 0.3650188052951131, -0.335639531557298, -0.3687495818314138, + -2.411256847882121, -1.3668089822005067, -1.1560697629044099, -0.3006218189779164, -0.8725594773319494, + -1.37131745765896, -0.13835619199516525, -1.053887227444031, -0.2513625905613912, -1.482225291904533, + -0.02990661443215925, -1.3729348796554084, -1.0835751584623232, 0.27419312071920054, -2.1835219980440828, + 0.9422833588892365, -1.7508840633156373, -0.9631773346765894, 0.19871943079385535, -1.996189334079257, + -1.856454869108322, 0.004550549836906059, -0.36920103382902136, -0.07208379431175183, 0.17664155826254557, + -0.22336765886440946, -1.223766589561458, -1.0145754013153465, -0.12722082001247914, -0.1808245376360691, + -2.0211259056306234, -1.252720041997945, -2.1078618086082996, -0.11691765437730128, -0.39964726471277723 + ], + "marker": { + "line": { + "color": "#4D5663", + "width": 1.3 + }, + "color": "rgba(50, 171, 96, 1.0)" + }, + "opacity": 0.8, + "histfunc": "count", + "histnorm": "", + "orientation": "v" + } + ], + "layout": { + "title": { + "font": { + "color": "#4D5663" + } + }, + "xaxis": { + "title": { + "font": { + "color": "#4D5663" + }, + "text": "" + }, + "showgrid": true, + "tickfont": { + "color": "#4D5663" + }, + "gridcolor": "#E1E5ED", + "zerolinecolor": "#E1E5ED" + }, + "yaxis": { + "title": { + "font": { + "color": "#4D5663" + }, + "text": "" + }, + "showgrid": true, + "tickfont": { + "color": "#4D5663" + }, + "gridcolor": "#E1E5ED", + "zerolinecolor": "#E1E5ED" + }, + "legend": { + "font": { + "color": "#4D5663" + }, + "bgcolor": "#F5F6F9" + }, + "barmode": "overlay" + }, + "frames": [] +} diff --git a/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_verticalbar_test.json b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_verticalbar_test.json new file mode 100644 index 00000000000000..98a7dd5c94f174 --- /dev/null +++ b/packages/charts/react-charting/src/components/DeclarativeChart/tests/schema/fluent_verticalbar_test.json @@ -0,0 +1,79 @@ +{ + "visualizer": "plotly", + "data": [ + { + "type": "bar", + "x": [ + 78.31759529851323, 98.09122764296625, 117.86485998741925, 137.63849233187221, 157.41212467632522, + 177.18575702077828, 196.95938936523132, 216.7330217096843, 236.5066540541373, 256.28028639859036 + ], + "y": [0, 0, 0, 33, 84, 250, 304, 221, 85, 23], + "xaxis": "x1", + "yaxis": "y1", + "marker": { + "line": { + "width": 1 + }, + "color": "#0000FF" + }, + "opacity": 1, + "orientation": "v" + }, + { + "type": "bar", + "x": [ + 86.22704823629445, 106.00068058074744, 125.77431292520045, 145.54794526965344, 165.32157761410645, + 185.09520995855948, 204.8688423030125, 224.64247464746552, 244.41610699191853, 264.18973933637153 + ], + "y": [9, 51, 177, 283, 264, 162, 47, 6, 1, 0], + "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/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/Arc/Arc.tsx b/packages/charts/react-charting/src/components/DonutChart/Arc/Arc.tsx index 7d7baef9680452..c034bcf1932a3c 100644 --- a/packages/charts/react-charting/src/components/DonutChart/Arc/Arc.tsx +++ b/packages/charts/react-charting/src/components/DonutChart/Arc/Arc.tsx @@ -31,12 +31,14 @@ export class Arc extends React.Component { } public render(): JSX.Element { - const { arc, href, focusedArcId } = this.props; + const { arc, href, focusedArcId, activeArc } = this.props; const getClassNames = classNamesFunction(); - const id = this.props.uniqText! + this.props.data!.data.legend!.replace(/\s+/, '') + this.props.data!.data.data; + const id = + this.props.uniqText! + + (typeof this.props.data!.data.legend === 'string' ? this.props.data!.data.legend.replace(/\s+/g, '') : '') + + this.props.data!.data.data; const opacity: number = - this.props.activeArc === this.props.data!.data.legend || this.props.activeArc === '' ? 1 : 0.1; - + activeArc && activeArc.length > 0 ? (activeArc.includes(this.props.data?.data.legend!) ? 1 : 0.1) : 1; const startAngle = this.props.data?.startAngle ?? 0; const endAngle = (this.props.data?.endAngle ?? 0) - startAngle; const cornerRadius = this.props.roundCorners ? 3 : 0; @@ -70,7 +72,9 @@ export class Arc extends React.Component { d={arc.cornerRadius(cornerRadius)(this.props.data)} onFocus={this._onFocus.bind(this, this.props.data!.data, id)} className={classNames.root} - data-is-focusable={this.props.activeArc === this.props.data!.data.legend || this.props.activeArc === ''} + data-is-focusable={ + this._shouldHighlightArc(this.props.data!.data.legend!) || this.props.activeArc?.length === 0 + } onMouseOver={this._hoverOn.bind(this, this.props.data!.data)} onMouseMove={this._hoverOn.bind(this, this.props.data!.data)} onMouseLeave={this._hoverOff} @@ -123,13 +127,18 @@ export class Arc extends React.Component { return point.callOutAccessibilityData?.ariaLabel || (legend ? `${legend}, ` : '') + `${yValue}.`; }; - private _renderArcLabel = (className: string) => { - const { arc, data, innerRadius, outerRadius, showLabelsInPercent, totalValue, hideLabels, activeArc } = this.props; + private _shouldHighlightArc = (legend?: string): boolean => { + const { activeArc } = this.props; + // If no activeArc is provided, highlight all arcs. Otherwise, only highlight the arcs that are active. + return !activeArc || activeArc.length === 0 || legend === undefined || activeArc.includes(legend); + }; + private _renderArcLabel = (className: string) => { + const { arc, data, innerRadius, outerRadius, showLabelsInPercent, totalValue, hideLabels } = this.props; if ( hideLabels || Math.abs(data!.endAngle - data!.startAngle) < Math.PI / 12 || - (activeArc !== data!.data.legend && activeArc !== '') + !this._shouldHighlightArc(data!.data.legend!) ) { return null; } diff --git a/packages/charts/react-charting/src/components/DonutChart/Arc/Arc.types.ts b/packages/charts/react-charting/src/components/DonutChart/Arc/Arc.types.ts index 6de0cdd0afc774..6bff5071cd7e66 100644 --- a/packages/charts/react-charting/src/components/DonutChart/Arc/Arc.types.ts +++ b/packages/charts/react-charting/src/components/DonutChart/Arc/Arc.types.ts @@ -73,7 +73,7 @@ export interface IArcProps { /** * Active Arc for chart */ - activeArc?: string; + activeArc?: string[]; /** * internal prop for href 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 95041e3f7841e3..5fc0da02192505 100644 --- a/packages/charts/react-charting/src/components/DonutChart/DonutChart.base.tsx +++ b/packages/charts/react-charting/src/components/DonutChart/DonutChart.base.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { classNamesFunction, getId } from '@fluentui/react/lib/Utilities'; +import { classNamesFunction, getId, initializeComponentRef } from '@fluentui/react/lib/Utilities'; import { ScaleOrdinal } from 'd3-scale'; import { IProcessedStyleSet } from '@fluentui/react/lib/Styling'; import { Callout, DirectionalHint } from '@fluentui/react/lib/Callout'; @@ -7,8 +7,15 @@ import { FocusZone, FocusZoneDirection, FocusZoneTabbableElements } from '@fluen import { IAccessibilityProps, ChartHoverCard, ILegend, Legends } from '../../index'; import { Pie } from './Pie/index'; import { IChartDataPoint, IDonutChartProps, IDonutChartStyleProps, IDonutChartStyles } from './index'; -import { getAccessibleDataObject, getColorFromToken, getNextColor, getNextGradient } from '../../utilities/index'; +import { + getAccessibleDataObject, + getColorFromToken, + getNextColor, + getNextGradient, + areArraysEqual, +} from '../../utilities/index'; import { convertToLocaleString } from '../../utilities/locale-util'; +import { IChart } from '../../types/index'; const getClassNames = classNamesFunction(); const LEGEND_CONTAINER_HEIGHT = 40; @@ -24,12 +31,12 @@ export interface IDonutChartState { xCalloutValue?: string; yCalloutValue?: string; focusedArcId?: string; - selectedLegend: string; dataPointCalloutProps?: IChartDataPoint; callOutAccessibilityData?: IAccessibilityProps; + selectedLegends: string[]; } -export class DonutChartBase extends React.Component { +export class DonutChartBase extends React.Component implements IChart { public static defaultProps: Partial = { innerRadius: 0, hideLabels: true, @@ -63,18 +70,21 @@ export class DonutChartBase extends React.Component d.data! >= 0)); - const valueInsideDonut = this._valueInsideDonut(this.props.valueInsideDonut!, chartData!); - + const valueInsideDonut = + this.props.innerRadius !== 0 ? this._valueInsideDonut(this.props.valueInsideDonut!, chartData!) : ''; return !this._isChartEmpty() ? ( @@ -1978,6 +1979,7 @@ exports[`DonutChart snapShot testing Should render arc labels 1`] = ` 45.0k +
@@ -2544,6 +2546,7 @@ exports[`DonutChart snapShot testing Should render arc labels in percentage form 43% +
@@ -3149,6 +3152,7 @@ exports[`DonutChart snapShot testing Should render gradients on arcs 1`] = ` /> +
@@ -3667,6 +3671,7 @@ exports[`DonutChart snapShot testing Should render rounded corners on arcs 1`] = role="img" /> +
@@ -4703,6 +4708,7 @@ exports[`DonutChart snapShot testing renders DonutChart correctly without color role="img" /> +
@@ -5221,6 +5227,7 @@ exports[`DonutChart snapShot testing renders enabledLegendsWrapLines correctly 1 role="img" /> +
@@ -5739,6 +5746,7 @@ exports[`DonutChart snapShot testing renders hideLegend correctly 1`] = ` role="img" /> +
@@ -5874,6 +5882,7 @@ exports[`DonutChart snapShot testing renders hideTooltip correctly 1`] = ` role="img" /> +
@@ -6392,23 +6401,7 @@ exports[`DonutChart snapShot testing renders value inside onf the pie 1`] = ` role="img" /> - - 1,000 - +
diff --git a/packages/charts/react-charting/src/components/GaugeChart/GaugeChart.base.tsx b/packages/charts/react-charting/src/components/GaugeChart/GaugeChart.base.tsx index 2913d3bebf2383..7a3dffbeefd7d9 100644 --- a/packages/charts/react-charting/src/components/GaugeChart/GaugeChart.base.tsx +++ b/packages/charts/react-charting/src/components/GaugeChart/GaugeChart.base.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { arc as d3Arc } from 'd3-shape'; -import { classNamesFunction, getId, getRTL } from '@fluentui/react/lib/Utilities'; +import { classNamesFunction, getId, getRTL, initializeComponentRef } from '@fluentui/react/lib/Utilities'; import { IGaugeChartProps, IGaugeChartSegment, @@ -13,6 +13,7 @@ import { IProcessedStyleSet } from '@fluentui/react/lib/Styling'; import { convertToLocaleString } from '../../utilities/locale-util'; import { Points, + areArraysEqual, formatValueWithSIPrefix, getAccessibleDataObject, getColorFromToken, @@ -26,6 +27,7 @@ import { Callout, DirectionalHint } from '@fluentui/react/lib/Callout'; import { IYValueHover } from '../../index'; import { SVGTooltipText } from '../../utilities/SVGTooltipText'; import { select as d3Select } from 'd3-selection'; +import { IChart } from '../../types/index'; const GAUGE_MARGIN = 16; const LABEL_WIDTH = 36; @@ -105,7 +107,7 @@ interface IYValue extends Omit { } export interface IGaugeChartState { hoveredLegend: string; - selectedLegend: string; + selectedLegends: string[]; focusedElement?: string; // eslint-disable-next-line @typescript-eslint/no-explicit-any calloutTarget: any; @@ -120,7 +122,7 @@ export interface IExtendedSegment extends IGaugeChartSegment { end: number; } -export class GaugeChartBase extends React.Component { +export class GaugeChartBase extends React.Component implements IChart { private _classNames: IProcessedStyleSet; private _isRTL: boolean; private _innerRadius: number; @@ -136,12 +138,14 @@ export class GaugeChartBase extends React.Component { const { hideMinMax, chartTitle, sublabel } = this.props; @@ -481,13 +497,6 @@ export class GaugeChartBase extends React.Component { - if (this.state.selectedLegend === segment.legend) { - this.setState({ selectedLegend: '' }); - } else { - this.setState({ selectedLegend: segment.legend }); - } - }, hoverAction: () => { this.setState({ hoveredLegend: segment.legend }); }, @@ -499,11 +508,32 @@ export class GaugeChartBase extends React.Component - +
); }; + private _onLegendSelectionChange( + selectedLegends: string[], + event: React.MouseEvent, + currentLegend?: ILegend, + ): void { + if (this.props.legendProps?.canSelectMultipleLegends) { + this.setState({ selectedLegends }); + } else { + this.setState({ selectedLegends: selectedLegends.slice(-1) }); + } + if (this.props.legendProps?.onChange) { + this.props.legendProps.onChange(selectedLegends, event, currentLegend); + } + } + /** * This function checks if the given legend is highlighted or not. * A legend can be highlighted in 2 ways: @@ -511,18 +541,24 @@ export class GaugeChartBase extends React.Component { - return ( - this.state.selectedLegend === legend || (this.state.selectedLegend === '' && this.state.hoveredLegend === legend) - ); + return this._getHighlightedLegend().includes(legend!); }; /** * This function checks if none of the legends is selected or hovered. */ private _noLegendHighlighted = () => { - return this.state.selectedLegend === '' && this.state.hoveredLegend === ''; + return this._getHighlightedLegend().length === 0; }; + private _getHighlightedLegend() { + return this.state.selectedLegends.length > 0 + ? this.state.selectedLegends + : this.state.hoveredLegend + ? [this.state.hoveredLegend] + : []; + } + private _handleFocus = (focusEvent: React.FocusEvent, focusedElement: string) => { this._showCallout(focusEvent.target, focusedElement, true); }; @@ -565,9 +601,7 @@ export class GaugeChartBase extends React.Component { theme.fonts.medium, 'ms-GaugeChart', { + alignItems: 'center', + display: 'flex', + flexDirection: 'column', width: '100%', height: '100%', }, diff --git a/packages/charts/react-charting/src/components/GaugeChart/GaugeChart.test.tsx b/packages/charts/react-charting/src/components/GaugeChart/GaugeChart.test.tsx index a5871964a0d9c7..c741b2dd726157 100644 --- a/packages/charts/react-charting/src/components/GaugeChart/GaugeChart.test.tsx +++ b/packages/charts/react-charting/src/components/GaugeChart/GaugeChart.test.tsx @@ -419,6 +419,24 @@ describe('GaugeChart interaction and accessibility tests', () => { } } }); + + it(`should highlight multiple segments when the legend multi select is enabled`, () => { + const { container } = render( + , + ); + + fireEvent.click(screen.getByText(segments[0].legend)); + fireEvent.click(screen.getByText(segments[1].legend)); + const segs = container.querySelectorAll('[class^="segment"]'); + expect(segs[0]).toHaveStyle('fill-opacity: 1'); + expect(segs[1]).toHaveStyle('fill-opacity: 1'); + expect(segs[2]).toHaveStyle('fill-opacity: 0.1'); + }); }); describe('Gauge Chart - axe-core', () => { diff --git a/packages/charts/react-charting/src/components/GaugeChart/GaugeChart.types.ts b/packages/charts/react-charting/src/components/GaugeChart/GaugeChart.types.ts index 648dc7abeca07d..9374a764dc3cad 100644 --- a/packages/charts/react-charting/src/components/GaugeChart/GaugeChart.types.ts +++ b/packages/charts/react-charting/src/components/GaugeChart/GaugeChart.types.ts @@ -1,7 +1,7 @@ import { IStyle, ITheme } from '@fluentui/react/lib/Styling'; -import { IStyleFunctionOrObject } from '@fluentui/react/lib/Utilities'; +import { IRefObject, IStyleFunctionOrObject } from '@fluentui/react/lib/Utilities'; import { ILegendsProps } from '../Legends/index'; -import { IAccessibilityProps } from '../../types/index'; +import { IAccessibilityProps, IChart } from '../../types/index'; import { ICalloutProps } from '@fluentui/react/lib/Callout'; /** @@ -168,6 +168,12 @@ export interface IGaugeChartProps { * @default false */ roundCorners?: boolean; + + /** + * Optional callback to access the IChart interface. Use this instead of ref for accessing + * the public methods and properties of the component. + */ + componentRef?: IRefObject; } /** diff --git a/packages/charts/react-charting/src/components/GaugeChart/__snapshots__/GaugeChart.test.tsx.snap b/packages/charts/react-charting/src/components/GaugeChart/__snapshots__/GaugeChart.test.tsx.snap index 41ff22e9be5407..b000897d82e23c 100644 --- a/packages/charts/react-charting/src/components/GaugeChart/__snapshots__/GaugeChart.test.tsx.snap +++ b/packages/charts/react-charting/src/components/GaugeChart/__snapshots__/GaugeChart.test.tsx.snap @@ -9,6 +9,9 @@ exports[`GaugeChart interaction and accessibility tests should show a callout wh { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; + align-items: center; + display: flex; + flex-direction: column; font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; font-size: 14px; font-weight: 400; @@ -828,6 +831,9 @@ exports[`GaugeChart snapshot tests should not render min and max values of the g { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; + align-items: center; + display: flex; + flex-direction: column; font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; font-size: 14px; font-weight: 400; @@ -1372,6 +1378,9 @@ exports[`GaugeChart snapshot tests should not render the legends when the hideLe { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; + align-items: center; + display: flex; + flex-direction: column; font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; font-size: 14px; font-weight: 400; @@ -1563,6 +1572,9 @@ exports[`GaugeChart snapshot tests should render GaugeChart correctly 1`] = ` { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; + align-items: center; + display: flex; + flex-direction: column; font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; font-size: 14px; font-weight: 400; @@ -2152,6 +2164,9 @@ exports[`GaugeChart snapshot tests should render GaugeChart correctly in dark th { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; + align-items: center; + display: flex; + flex-direction: column; font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; font-size: 14px; font-weight: 400; @@ -2729,6 +2744,9 @@ exports[`GaugeChart snapshot tests should render GaugeChart correctly when the l { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; + align-items: center; + display: flex; + flex-direction: column; font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; font-size: 14px; font-weight: 400; @@ -3305,6 +3323,9 @@ exports[`GaugeChart snapshot tests should render a color from DataVizPalette for { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; + align-items: center; + display: flex; + flex-direction: column; font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; font-size: 14px; font-weight: 400; @@ -3758,6 +3779,9 @@ exports[`GaugeChart snapshot tests should render a placeholder segment when the { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; + align-items: center; + display: flex; + flex-direction: column; font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; font-size: 14px; font-weight: 400; @@ -4210,6 +4234,9 @@ exports[`GaugeChart snapshot tests should render the chart title correctly 1`] = { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; + align-items: center; + display: flex; + flex-direction: column; font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; font-size: 14px; font-weight: 400; @@ -4800,6 +4827,9 @@ exports[`GaugeChart snapshot tests should render the chart value in fraction for { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; + align-items: center; + display: flex; + flex-direction: column; font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; font-size: 14px; font-weight: 400; @@ -5376,6 +5406,9 @@ exports[`GaugeChart snapshot tests should render the sublabel correctly 1`] = ` { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; + align-items: center; + display: flex; + flex-direction: column; font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; font-size: 14px; font-weight: 400; diff --git a/packages/charts/react-charting/src/components/GroupedVerticalBarChart/GroupedVerticalBarChart.base.tsx b/packages/charts/react-charting/src/components/GroupedVerticalBarChart/GroupedVerticalBarChart.base.tsx index 97d08b9e3a0dd8..7b0f476bbfeb9d 100644 --- a/packages/charts/react-charting/src/components/GroupedVerticalBarChart/GroupedVerticalBarChart.base.tsx +++ b/packages/charts/react-charting/src/components/GroupedVerticalBarChart/GroupedVerticalBarChart.base.tsx @@ -3,7 +3,14 @@ import { max as d3Max } from 'd3-array'; import { select as d3Select } from 'd3-selection'; import { Axis as D3Axis } from 'd3-axis'; import { scaleBand as d3ScaleBand, scaleLinear as d3ScaleLinear } from 'd3-scale'; -import { classNamesFunction, getId, getRTL, memoizeFunction, warnDeprecations } from '@fluentui/react/lib/Utilities'; +import { + classNamesFunction, + getId, + getRTL, + initializeComponentRef, + memoizeFunction, + warnDeprecations, +} from '@fluentui/react/lib/Utilities'; import { IProcessedStyleSet, IPalette } from '@fluentui/react/lib/Styling'; import { DirectionalHint } from '@fluentui/react/lib/Callout'; import { FocusZoneDirection } from '@fluentui/react-focus'; @@ -24,6 +31,8 @@ import { createStringYAxis, getNextGradient, getNextColor, + areArraysEqual, + calculateLongestLabelWidth, } from '../../utilities/index'; import { IAccessibilityProps, @@ -39,6 +48,7 @@ import { IRefArrayData, Legends, } from '../../index'; +import { IChart } from '../../types/index'; const COMPONENT_NAME = 'GROUPED VERTICAL BAR CHART'; const getClassNames = classNamesFunction(); @@ -65,12 +75,13 @@ export interface IGroupedVerticalBarChartState extends IBasestate { dataPointCalloutProps?: IGVBarChartSeriesPoint; callOutAccessibilityData?: IAccessibilityProps; calloutLegend: string; + selectedLegends: string[]; } -export class GroupedVerticalBarChartBase extends React.Component< - IGroupedVerticalBarChartProps, - IGroupedVerticalBarChartState -> { +export class GroupedVerticalBarChartBase + extends React.Component + implements IChart +{ public static defaultProps: Partial = { maxBarWidth: 24, }; @@ -100,16 +111,20 @@ export class GroupedVerticalBarChartBase extends React.Component< private _groupWidth: number; private _xAxisInnerPadding: number; private _xAxisOuterPadding: number; + private _cartesianChartRef: React.RefObject; public constructor(props: IGroupedVerticalBarChartProps) { super(props); + + initializeComponentRef(this); + this._createSet = memoizeFunction((data: IGroupedVerticalBarChartData[]) => this._createDataSetOfGVBC(data)); this.state = { color: '', dataForHoverCard: 0, isCalloutVisible: false, refSelected: null, - selectedLegend: '', + selectedLegends: props.legendProps?.selectedLegends || [], xCalloutValue: '', yCalloutValue: '', YValueHover: [], @@ -129,6 +144,15 @@ export class GroupedVerticalBarChartBase extends React.Component< this._tooltipId = getId('GVBCTooltipId_'); this._emptyChartId = getId('_GVBC_empty'); this._domainMargin = MIN_DOMAIN_MARGIN; + this._cartesianChartRef = React.createRef(); + } + + public componentDidUpdate(prevProps: IGroupedVerticalBarChartProps): void { + if (!areArraysEqual(prevProps.legendProps?.selectedLegends, this.props.legendProps?.selectedLegends)) { + this.setState({ + selectedLegends: this.props.legendProps?.selectedLegends || [], + }); + } } public render(): React.ReactNode { @@ -203,6 +227,7 @@ export class GroupedVerticalBarChartBase extends React.Component< xAxisOuterPadding: this._xAxisOuterPadding, })} barwidth={this._barWidth} + ref={this._cartesianChartRef} /* eslint-disable react/jsx-no-bind */ children={() => { return {this._groupedVerticalBarGraph}; @@ -218,6 +243,10 @@ export class GroupedVerticalBarChartBase extends React.Component< ); } + public get chartContainer(): HTMLElement | null { + return this._cartesianChartRef.current?.chartContainer || null; + } + private _getMinMaxOfYAxis = () => { return { startValue: 0, endValue: 0 }; }; @@ -307,7 +336,7 @@ export class GroupedVerticalBarChartBase extends React.Component< this.setState({ refSelected: mouseEvent, /** Show the callout if highlighted bar is hovered and Hide it if unhighlighted bar is hovered */ - isCalloutVisible: this.state.selectedLegend === '' || this.state.selectedLegend === pointData.legend, + isCalloutVisible: this._noLegendHighlighted() || this._legendHighlighted(pointData.legend), calloutLegend: pointData.legend, dataForHoverCard: pointData.data, color: pointData.color, @@ -343,7 +372,7 @@ export class GroupedVerticalBarChartBase extends React.Component< this.setState({ refSelected: obj.refElement, /** Show the callout if highlighted bar is focused and Hide it if unhighlighted bar is focused */ - isCalloutVisible: this.state.selectedLegend === '' || this.state.selectedLegend === pointData.legend, + isCalloutVisible: this._noLegendHighlighted() || this._legendHighlighted(pointData.legend), calloutLegend: pointData.legend, dataForHoverCard: pointData.data, color: pointData.color, @@ -555,18 +584,6 @@ export class GroupedVerticalBarChartBase extends React.Component< }); }; - private _onLegendClick(legendTitle: string): void { - if (this.state.selectedLegend === legendTitle) { - this.setState({ - selectedLegend: '', - }); - } else { - this.setState({ - selectedLegend: legendTitle, - }); - } - } - private _onLegendHover(legendTitle: string): void { this.setState({ activeLegend: legendTitle, @@ -598,9 +615,6 @@ export class GroupedVerticalBarChartBase extends React.Component< const legend: ILegend = { title: point.legend, color, - action: () => { - this._onLegendClick(point.legend); - }, hoverAction: () => { this._handleChartMouseLeave(); this._onLegendHover(point.legend); @@ -620,10 +634,26 @@ export class GroupedVerticalBarChartBase extends React.Component< enabledWrapLines={this.props.enabledLegendsWrapLines} focusZonePropsInHoverCard={this.props.focusZonePropsForLegendsInHoverCard} {...this.props.legendProps} + onChange={this._onLegendSelectionChange.bind(this)} /> ); }; + private _onLegendSelectionChange( + selectedLegends: string[], + event: React.MouseEvent, + currentLegend?: ILegend, + ): void { + if (this.props.legendProps?.canSelectMultipleLegends) { + this.setState({ selectedLegends }); + } else { + this.setState({ selectedLegends: selectedLegends.slice(-1) }); + } + if (this.props.legendProps?.onChange) { + this.props.legendProps.onChange(selectedLegends, event, currentLegend); + } + } + private _getAxisData = (yAxisData: IAxisData) => { if (yAxisData && yAxisData.yAxisDomainValues.length) { const { yAxisDomainValues: domainValue } = yAxisData; @@ -638,19 +668,24 @@ export class GroupedVerticalBarChartBase extends React.Component< * 2. hovering: if there is no selected legend and the user hovers over it */ private _legendHighlighted = (legendTitle: string) => { - return ( - this.state.selectedLegend === legendTitle || - (this.state.selectedLegend === '' && this.state.activeLegend === legendTitle) - ); + return this._getHighlightedLegend().includes(legendTitle!); }; /** * This function checks if none of the legends is selected or hovered. */ private _noLegendHighlighted = () => { - return this.state.selectedLegend === '' && this.state.activeLegend === ''; + return this._getHighlightedLegend().length === 0; }; + private _getHighlightedLegend() { + return this.state.selectedLegends.length > 0 + ? this.state.selectedLegends + : this.state.activeLegend + ? [this.state.activeLegend] + : []; + } + private _getAriaLabel = (point: IGVBarChartSeriesPoint, xAxisPoint: string): string => { const xValue = point.xAxisCalloutData || xAxisPoint; const legend = point.legend; @@ -661,21 +696,22 @@ export class GroupedVerticalBarChartBase extends React.Component< private _getDomainMargins = (containerWidth: number): IMargins => { this._domainMargin = MIN_DOMAIN_MARGIN; + /** Total width available to render the bars */ + const totalWidth = + containerWidth - (this.margins.left! + MIN_DOMAIN_MARGIN) - (this.margins.right! + MIN_DOMAIN_MARGIN); + /** Rate at which the space between the groups changes wrt the group width */ + const groupGapRate = this._xAxisInnerPadding / (1 - this._xAxisInnerPadding); + if (this._xAxisType === XAxisTypes.StringAxis) { if (isScalePaddingDefined(this.props.xAxisOuterPadding)) { // Setting the domain margin for string x-axis to 0 because the xAxisOuterPadding prop is now available // to adjust the space before the first group and after the last group. this._domainMargin = 0; } else if (this.props.barwidth !== 'auto') { - /** Total width available to render the bars */ - const totalWidth = - containerWidth - (this.margins.left! + MIN_DOMAIN_MARGIN) - (this.margins.right! + MIN_DOMAIN_MARGIN); // Update the bar width so that when CartesianChart rerenders, // the following calculations don't use the previous bar width. this._barWidth = getBarWidth(this.props.barwidth, this.props.maxBarWidth); const groupWidth = (this._keys.length + (this._keys.length - 1) * BAR_GAP_RATE) * this._barWidth; - /** Rate at which the space between the groups changes wrt the group width */ - const groupGapRate = this._xAxisInnerPadding / (1 - this._xAxisInnerPadding); /** Total width required to render the groups. Directly proportional to group width */ const reqWidth = (this._xAxisLabels.length + (this._xAxisLabels.length - 1) * groupGapRate) * groupWidth; @@ -683,6 +719,21 @@ export class GroupedVerticalBarChartBase extends React.Component< // Center align the chart by setting equal left and right margins for domain this._domainMargin = MIN_DOMAIN_MARGIN + (totalWidth - reqWidth) / 2; } + } else if (this.props.mode === 'plotly' && this._xAxisLabels.length > 1) { + // Calculate the remaining width after rendering groups at their maximum allowable width + const groupBandwidth = totalWidth / (this._xAxisLabels.length + (this._xAxisLabels.length - 1) * groupGapRate); + const barBandwidth = groupBandwidth / (this._keys.length + (this._keys.length - 1) * BAR_GAP_RATE); + const barWidth = getBarWidth(this.props.barwidth, this.props.maxBarWidth, barBandwidth); + const groupWidth = (this._keys.length + (this._keys.length - 1) * BAR_GAP_RATE) * barWidth; + let reqWidth = (this._xAxisLabels.length + (this._xAxisLabels.length - 1) * groupGapRate) * groupWidth; + const margin1 = (totalWidth - reqWidth) / 2; + + // Calculate the remaining width after accounting for the space required to render x-axis labels + const step = calculateLongestLabelWidth(this._xAxisLabels) + 20; + reqWidth = (this._xAxisLabels.length - this._xAxisInnerPadding) * step; + const margin2 = (totalWidth - reqWidth) / 2; + + this._domainMargin = MIN_DOMAIN_MARGIN + Math.max(0, Math.min(margin1, margin2)); } } diff --git a/packages/charts/react-charting/src/components/GroupedVerticalBarChart/GroupedVerticalBarChart.types.tsx b/packages/charts/react-charting/src/components/GroupedVerticalBarChart/GroupedVerticalBarChart.types.tsx index 1a8f43ac0822c3..050d9ea4c99cf3 100644 --- a/packages/charts/react-charting/src/components/GroupedVerticalBarChart/GroupedVerticalBarChart.types.tsx +++ b/packages/charts/react-charting/src/components/GroupedVerticalBarChart/GroupedVerticalBarChart.types.tsx @@ -121,6 +121,12 @@ export interface IGroupedVerticalBarChartProps extends ICartesianChartProps { * The prop used to enable rounded corners for the chart. */ roundCorners?: boolean; + + /** + * Specifies the mode of the chart. + * @default 'default' + */ + mode?: 'default' | 'plotly'; } /** diff --git a/packages/charts/react-charting/src/components/GroupedVerticalBarChart/GroupedVerticalBarChartRTL.test.tsx b/packages/charts/react-charting/src/components/GroupedVerticalBarChart/GroupedVerticalBarChartRTL.test.tsx index 5797d95beeb161..b6ed4f6f7ef092 100644 --- a/packages/charts/react-charting/src/components/GroupedVerticalBarChart/GroupedVerticalBarChartRTL.test.tsx +++ b/packages/charts/react-charting/src/components/GroupedVerticalBarChart/GroupedVerticalBarChartRTL.test.tsx @@ -139,6 +139,206 @@ const chartPoints = [ }, ]; +const dataGVBC = [ + { + name: 'Jan - Mar', + series: [ + { + key: 'series1', + data: 33000, + color: DefaultPalette.blue, + legend: '2022', + xAxisCalloutData: '2022/04/30', + yAxisCalloutData: '29%', + callOutAccessibilityData: { + ariaLabel: 'Group Jan - Mar 1 of 4, Bar series 1 of 2 2022, x value 2022/04/30, y value 29%', + }, + }, + { + key: 'series2', + data: 44000, + color: DefaultPalette.green, + legend: '2023', + xAxisCalloutData: '2023/04/30', + yAxisCalloutData: '44%', + callOutAccessibilityData: { + ariaLabel: 'Group Jan - Mar 1 of 4, Bar series 2 of 2 2023, x value 2023/04/30, y value 44%', + }, + }, + { + key: 'series3', + data: 54000, + color: DefaultPalette.red, + legend: '2024', + xAxisCalloutData: '2024/04/30', + yAxisCalloutData: '44%', + callOutAccessibilityData: { + ariaLabel: 'Group Jan - Mar 1 of 4, Bar series 3 of 4 2022, x value 2024/04/30, y value 44%', + }, + }, + { + key: 'series4', + data: 24000, + color: DefaultPalette.yellow, + legend: '2021', + xAxisCalloutData: '2021/04/30', + yAxisCalloutData: '44%', + callOutAccessibilityData: { + ariaLabel: 'Group Jan - Mar 1 of 4, Bar series 4 of 4 2021, x value 2021/04/30, y value 44%', + }, + }, + ], + }, + { + name: 'Apr - Jun', + series: [ + { + key: 'series1', + data: 33000, + color: DefaultPalette.blue, + legend: '2022', + xAxisCalloutData: '2022/05/30', + yAxisCalloutData: '29%', + callOutAccessibilityData: { + ariaLabel: 'Group Apr - Jun 2 of 4, Bar series 1 of 2 2022, x value 2022/05/30, y value 29%', + }, + }, + { + key: 'series2', + data: 3000, + color: DefaultPalette.green, + legend: '2023', + xAxisCalloutData: '2023/05/30', + yAxisCalloutData: '3%', + callOutAccessibilityData: { + ariaLabel: 'Group Apr - Jun 2 of 4, Bar series 2 of 2 2023, x value 2023/05/30, y value 3%', + }, + }, + { + key: 'series3', + data: 9000, + color: DefaultPalette.red, + legend: '2024', + xAxisCalloutData: '2024/05/30', + yAxisCalloutData: '3%', + callOutAccessibilityData: { + ariaLabel: 'Group Apr - Jun 2 of 4, Bar series 3 of 4 2024, x value 2024/05/30, y value 3%', + }, + }, + { + key: 'series4', + data: 12000, + color: DefaultPalette.yellow, + legend: '2021', + xAxisCalloutData: '2021/05/30', + yAxisCalloutData: '3%', + callOutAccessibilityData: { + ariaLabel: 'Group Apr - Jun 2 of 4, Bar series 4 of 4 2021, x value 2021/05/30, y value 3%', + }, + }, + ], + }, + + { + name: 'Jul - Sep', + series: [ + { + key: 'series1', + data: 14000, + color: DefaultPalette.blue, + legend: '2022', + xAxisCalloutData: '2022/06/30', + yAxisCalloutData: '13%', + callOutAccessibilityData: { + ariaLabel: 'Group Jul - Sep 3 of 4, Bar series 1 of 2 2022, x value 2022/06/30, y value 13%', + }, + }, + { + key: 'series2', + data: 50000, + color: DefaultPalette.green, + legend: '2023', + xAxisCalloutData: '2023/06/30', + yAxisCalloutData: '50%', + callOutAccessibilityData: { + ariaLabel: 'Group Jul - Sep 3 of 4, Bar series 2 of 2 2023, x value 2023/06/30, y value 50%', + }, + }, + { + key: 'series3', + data: 60000, + color: DefaultPalette.red, + legend: '2024', + xAxisCalloutData: '2024/06/30', + yAxisCalloutData: '50%', + callOutAccessibilityData: { + ariaLabel: 'Group Jul - Sep 3 of 4, Bar series 3 of 4 2024, x value 2024/06/30, y value 50%', + }, + }, + { + key: 'series4', + data: 10000, + color: DefaultPalette.yellow, + legend: '2021', + xAxisCalloutData: '2021/06/30', + yAxisCalloutData: '50%', + callOutAccessibilityData: { + ariaLabel: 'Group Jul - Sep 3 of 4, Bar series 4 of 4 2021, x value 2021/06/30, y value 50%', + }, + }, + ], + }, + { + name: 'Oct - Dec', + series: [ + { + key: 'series1', + data: 33000, + color: DefaultPalette.blue, + legend: '2022', + xAxisCalloutData: '2022/07/30', + yAxisCalloutData: '29%', + callOutAccessibilityData: { + ariaLabel: 'Group Oct - Dec 4 of 4, Bar series 1 of 2 2022, x value 2022/07/30, y value 29%', + }, + }, + { + key: 'series2', + data: 3000, + color: DefaultPalette.green, + legend: '2023', + xAxisCalloutData: '2023/07/30', + yAxisCalloutData: '3%', + callOutAccessibilityData: { + ariaLabel: 'Group Oct - Dec 4 of 4, Bar series 2 of 2 2023, x value 2023/07/30, y value 3%', + }, + }, + { + key: 'series3', + data: 6000, + color: DefaultPalette.red, + legend: '2024', + xAxisCalloutData: '2024/07/30', + yAxisCalloutData: '3%', + callOutAccessibilityData: { + ariaLabel: 'Group Oct - Dec 4 of 4, Bar series 3 of 4 2024, x value 2024/07/30, y value 3%', + }, + }, + { + key: 'series4', + data: 15000, + color: DefaultPalette.yellow, + legend: '2021', + xAxisCalloutData: '2021/07/30', + yAxisCalloutData: '3%', + callOutAccessibilityData: { + ariaLabel: 'Group Oct - Dec 4 of 4, Bar series 4 of 4 2021, x value 2021/07/30, y value 3%', + }, + }, + ], + }, +]; + describe('Grouped Vertical bar chart rendering', () => { beforeEach(updateChartWidthAndHeight); afterEach(sharedAfterEach); @@ -350,6 +550,40 @@ describe('Grouped vertical bar chart - Subcomponent Legends', () => { expect(bars[5]).toHaveAttribute('opacity', ''); }, ); + + testWithoutWait( + 'Should select multiple legends on click', + GroupedVerticalBarChart, + { data: dataGVBC, legendProps: { canSelectMultipleLegends: true } }, + container => { + const firstLegend = screen.queryByText('2023')?.closest('button'); + const secondLegend = screen.queryByText('2024')?.closest('button'); + + expect(firstLegend).toBeDefined(); + expect(secondLegend).toBeDefined(); + + fireEvent.click(firstLegend!); + fireEvent.click(secondLegend!); + + // Assert + expect(firstLegend).toHaveAttribute('aria-selected', 'true'); + expect(secondLegend).toHaveAttribute('aria-selected', 'true'); + + const bars = screen.getAllByText((content, element) => element!.tagName.toLowerCase() === 'rect'); + expect(bars[0]).toHaveAttribute('opacity', '0.1'); + expect(bars[1]).toHaveAttribute('opacity', ''); + expect(bars[2]).toHaveAttribute('opacity', ''); + expect(bars[3]).toHaveAttribute('opacity', '0.1'); + expect(bars[4]).toHaveAttribute('opacity', '0.1'); + expect(bars[5]).toHaveAttribute('opacity', ''); + expect(bars[6]).toHaveAttribute('opacity', ''); + expect(bars[7]).toHaveAttribute('opacity', '0.1'); + expect(bars[8]).toHaveAttribute('opacity', '0.1'); + expect(bars[9]).toHaveAttribute('opacity', ''); + expect(bars[10]).toHaveAttribute('opacity', ''); + expect(bars[11]).toHaveAttribute('opacity', '0.1'); + }, + ); }); describe('Grouped vertical bar chart - Subcomponent callout', () => { diff --git a/packages/charts/react-charting/src/components/HeatMapChart/HeatMapChart.base.tsx b/packages/charts/react-charting/src/components/HeatMapChart/HeatMapChart.base.tsx index 33f52b77f6a13a..22732cbeed9275 100644 --- a/packages/charts/react-charting/src/components/HeatMapChart/HeatMapChart.base.tsx +++ b/packages/charts/react-charting/src/components/HeatMapChart/HeatMapChart.base.tsx @@ -1,7 +1,7 @@ import { CartesianChart, IChildProps, IModifiedCartesianChartProps } from '../../components/CommonComponents/index'; -import { IAccessibilityProps, IHeatMapChartData, IHeatMapChartDataPoint } from '../../types/IDataPoint'; +import { IAccessibilityProps, IChart, IHeatMapChartData, IHeatMapChartDataPoint } from '../../types/IDataPoint'; import { scaleLinear as d3ScaleLinear } from 'd3-scale'; -import { classNamesFunction, getId, memoizeFunction } from '@fluentui/react/lib/Utilities'; +import { classNamesFunction, getId, initializeComponentRef, memoizeFunction } from '@fluentui/react/lib/Utilities'; import { FocusZoneDirection } from '@fluentui/react-focus'; import { DirectionalHint } from '@fluentui/react/lib/Callout'; import { IProcessedStyleSet } from '@fluentui/react/lib/Styling'; @@ -20,10 +20,12 @@ import { IDomainNRange, domainRangeOfXStringAxis, createStringYAxis, + resolveCSSVariables, } from '../../utilities/utilities'; import { Target } from '@fluentui/react'; import { format as d3Format } from 'd3-format'; import { timeFormat as d3TimeFormat } from 'd3-time-format'; +import { getColorContrast } from '../../utilities/colors'; type DataSet = { dataSet: RectanglesGraphData; @@ -87,7 +89,7 @@ export interface IHeatMapChartState { callOutAccessibilityData?: IAccessibilityProps; } const getClassNames = classNamesFunction(); -export class HeatMapChartBase extends React.Component { +export class HeatMapChartBase extends React.Component implements IChart { private _classNames: IProcessedStyleSet; private _stringXAxisDataPoints: string[]; private _stringYAxisDataPoints: string[]; @@ -114,8 +116,14 @@ export class HeatMapChartBase extends React.Component; + public constructor(props: IHeatMapChartProps) { super(props); + + initializeComponentRef(this); + /** * below funciton creates a new data set from the prop * @data and also finds all the unique x-axis datapoints @@ -133,7 +141,7 @@ export class HeatMapChartBase extends React.Component this._createNewDataSet(data, xDate, xNum, yDate, yNum), ); this.state = { - selectedLegend: '', + selectedLegend: props.legendProps?.selectedLegend ?? '', activeLegend: '', isCalloutVisible: false, target: null, @@ -145,6 +153,15 @@ export class HeatMapChartBase extends React.Component { @@ -231,6 +255,10 @@ export class HeatMapChartBase extends React.Component { return { startValue: 0, endValue: 0 }; }; @@ -250,7 +278,7 @@ export class HeatMapChartBase extends React.Component { + this.margins = margins; + }; + private _getOpacity = (legendTitle: string): string => { const opacity = this._legendHighlighted(legendTitle) || this._noLegendHighlighted() ? '1' : '0.1'; return opacity; @@ -326,6 +358,12 @@ export class HeatMapChartBase extends React.Component { + return color === this.props.theme!.semanticColors.bodyText + ? this.props.theme!.semanticColors.bodyBackground + : this.props.theme!.semanticColors.bodyText; + }; + /** * This is the function which is responsible for * drawing the rectangle in the graph and also @@ -343,12 +381,24 @@ export class HeatMapChartBase extends React.Component { let rectElement: JSX.Element; const id = `x${xAxisDataPoint}y${yAxisDataPoint}`; - if (this._dataSet[yAxisDataPoint][index]?.x === xAxisDataPoint) { + if ( + this._dataSet[yAxisDataPoint][index]?.x === xAxisDataPoint && + typeof this._dataSet[yAxisDataPoint][index]?.value === 'number' + ) { /** * dataPointObject is an object where it contains information on single * data point such as x, y , value, rectText property of the rectangle */ const dataPointObject = this._dataSet[yAxisDataPoint][index]; + let styleRules = ''; + let foregroundColor = this.props.theme!.semanticColors.bodyText; + if (this.chartContainer) { + styleRules = resolveCSSVariables(this.chartContainer!, foregroundColor); + } + const contrastRatio = getColorContrast(styleRules, this._colorScale(dataPointObject.value)); + if (contrastRatio < 3) { + foregroundColor = this._getInvertedTextColor(foregroundColor); + } rectElement = ( {convertToLocaleString(dataPointObject.rectText, this.props.culture)} @@ -579,7 +630,11 @@ export class HeatMapChartBase extends React.Component { if (this._xAxisType === XAxisTypes.StringAxis) { - return (a.x as string).toLowerCase() > (b.x as string).toLowerCase() ? 1 : -1; + return this.props.sortOrder === 'none' + ? 0 + : (a.x as string).toLowerCase() > (b.x as string).toLowerCase() + ? 1 + : -1; } else if (this._xAxisType === XAxisTypes.DateAxis) { return (a.x as Date).getTime() - (b.x as Date).getTime(); } else if (this._xAxisType === XAxisTypes.NumericAxis) { @@ -662,7 +717,7 @@ export class HeatMapChartBase extends React.Component b.toLowerCase() ? 1 : -1; + return this.props.sortOrder === 'none' ? 0 : a.toLowerCase() > b.toLowerCase() ? 1 : -1; } }); xAxisPoints = unFormattedXAxisDataPoints.map((xPoint: string) => { @@ -689,7 +744,7 @@ export class HeatMapChartBase extends React.Component b.toLowerCase() ? 1 : -1; + return this.props.sortOrder === 'none' ? 0 : a.toLowerCase() > b.toLowerCase() ? 1 : -1; } }); yAxisPoints = unFormattedYAxisDataPoints.map((yPoint: string) => { diff --git a/packages/charts/react-charting/src/components/HeatMapChart/HeatMapChart.styles.ts b/packages/charts/react-charting/src/components/HeatMapChart/HeatMapChart.styles.ts index 49ac43d30a0d0b..d4b005062e412c 100644 --- a/packages/charts/react-charting/src/components/HeatMapChart/HeatMapChart.styles.ts +++ b/packages/charts/react-charting/src/components/HeatMapChart/HeatMapChart.styles.ts @@ -9,7 +9,6 @@ export const getHeatMapChartStyles = (props: IHeatMapChartStyleProps): IHeatMapC theme.fonts.medium, { pointerEvents: 'none', - fill: theme.palette.white, fontWeight: FontWeights.semibold, }, ], diff --git a/packages/charts/react-charting/src/components/HeatMapChart/HeatMapChart.types.ts b/packages/charts/react-charting/src/components/HeatMapChart/HeatMapChart.types.ts index 178f3aa7dfa378..2dcc3dbee94fd5 100644 --- a/packages/charts/react-charting/src/components/HeatMapChart/HeatMapChart.types.ts +++ b/packages/charts/react-charting/src/components/HeatMapChart/HeatMapChart.types.ts @@ -108,6 +108,16 @@ export interface IHeatMapChartProps extends Pick - 10 + + + 10 + - 20 + + + 20 + @@ -802,13 +828,13 @@ exports[`HeatMapChart snapshot tests should render HeatMapChart correctly with n { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; - fill: #ffffff; font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; font-size: 14px; font-weight: 600; pointer-events: none; } dominant-baseline="middle" + fill="#323130" text-anchor="middle" transform="translate(143.11881188118812, 57.49009900990099)" /> @@ -832,13 +858,13 @@ exports[`HeatMapChart snapshot tests should render HeatMapChart correctly with n { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; - fill: #ffffff; font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; font-size: 14px; font-weight: 600; pointer-events: none; } dominant-baseline="middle" + fill="#323130" text-anchor="middle" transform="translate(143.11881188118812, 57.49009900990099)" /> @@ -862,13 +888,13 @@ exports[`HeatMapChart snapshot tests should render HeatMapChart correctly with n { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; - fill: #ffffff; font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; font-size: 14px; font-weight: 600; pointer-events: none; } dominant-baseline="middle" + fill="#323130" text-anchor="middle" transform="translate(143.11881188118812, 57.49009900990099)" /> @@ -892,13 +918,13 @@ exports[`HeatMapChart snapshot tests should render HeatMapChart correctly with n { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; - fill: #ffffff; font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; font-size: 14px; font-weight: 600; pointer-events: none; } dominant-baseline="middle" + fill="#323130" text-anchor="middle" transform="translate(143.11881188118812, 57.49009900990099)" /> @@ -1334,9 +1360,22 @@ exports[`HeatMapChart snapshot tests should render axis labels correctly When cu - yPoint p1 + + + yPoint p1 + - yPoint p2 + + + yPoint p2 + @@ -1376,13 +1428,13 @@ exports[`HeatMapChart snapshot tests should render axis labels correctly When cu { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; - fill: #ffffff; font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; font-size: 14px; font-weight: 600; pointer-events: none; } dominant-baseline="middle" + fill="#323130" text-anchor="middle" transform="translate(143.11881188118812, 57.49009900990099)" > @@ -1408,13 +1460,13 @@ exports[`HeatMapChart snapshot tests should render axis labels correctly When cu { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; - fill: #ffffff; font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; font-size: 14px; font-weight: 600; pointer-events: none; } dominant-baseline="middle" + fill="#323130" text-anchor="middle" transform="translate(143.11881188118812, 57.49009900990099)" > @@ -1440,13 +1492,13 @@ exports[`HeatMapChart snapshot tests should render axis labels correctly When cu { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; - fill: #ffffff; font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; font-size: 14px; font-weight: 600; pointer-events: none; } dominant-baseline="middle" + fill="#323130" text-anchor="middle" transform="translate(143.11881188118812, 57.49009900990099)" > @@ -1472,13 +1524,13 @@ exports[`HeatMapChart snapshot tests should render axis labels correctly When cu { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; - fill: #ffffff; font-family: 'Segoe UI', 'Segoe UI Web (West European)', 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica Neue', sans-serif; font-size: 14px; font-weight: 600; pointer-events: none; } dominant-baseline="middle" + fill="#323130" text-anchor="middle" transform="translate(143.11881188118812, 57.49009900990099)" > diff --git a/packages/charts/react-charting/src/components/HorizontalBarChart/HorizontalBarChart.base.tsx b/packages/charts/react-charting/src/components/HorizontalBarChart/HorizontalBarChart.base.tsx index e772604c570007..50db899116eac8 100644 --- a/packages/charts/react-charting/src/components/HorizontalBarChart/HorizontalBarChart.base.tsx +++ b/packages/charts/react-charting/src/components/HorizontalBarChart/HorizontalBarChart.base.tsx @@ -163,6 +163,7 @@ export class HorizontalBarChartBase extends React.Component(); @@ -54,14 +56,15 @@ export interface IHorizontalBarChartWithAxisState extends IBasestate { callOutAccessibilityData?: IAccessibilityProps; // eslint-disable-next-line @typescript-eslint/no-explicit-any tooltipElement?: any; + selectedLegends: string[]; } type ColorScale = (_p?: number) => string; -export class HorizontalBarChartWithAxisBase extends React.Component< - IHorizontalBarChartWithAxisProps, - IHorizontalBarChartWithAxisState -> { +export class HorizontalBarChartWithAxisBase + extends React.Component + implements IChart +{ private _points: IHorizontalBarChartWithAxisDataPoint[]; private _barHeight: number; private _colors: string[]; @@ -77,22 +80,29 @@ export class HorizontalBarChartWithAxisBase extends React.Component< private _xAxisType: XAxisTypes; private _yAxisType: YAxisType; private _calloutAnchorPoint: IHorizontalBarChartWithAxisDataPoint | null; + private _cartesianChartRef: React.RefObject; public constructor(props: IHorizontalBarChartWithAxisProps) { super(props); + + initializeComponentRef(this); + this.state = { color: '', dataForHoverCard: 0, isCalloutVisible: false, - isLegendSelected: false, + isLegendSelected: + (props.legendProps?.selectedLegends && props.legendProps.selectedLegends.length > 0) || + props.legendProps?.selectedLegend !== undefined, isLegendHovered: false, refSelected: null, - selectedLegendTitle: '', + selectedLegendTitle: props.legendProps?.selectedLegend ?? '', xCalloutValue: '', yCalloutValue: '', activeXdataPoint: null, YValueHover: [], hoverXValue: '', + selectedLegends: props.legendProps?.selectedLegends || [], }; this._calloutId = getId('callout'); this._tooltipId = getId('HBCWATooltipID_'); @@ -105,6 +115,15 @@ export class HorizontalBarChartWithAxisBase extends React.Component< this.props.data! && this.props.data!.length > 0 ? (getTypeOfAxis(this.props.data![0].y, false) as YAxisType) : YAxisType.StringAxis; + this._cartesianChartRef = React.createRef(); + } + + public componentDidUpdate(prevProps: IHorizontalBarChartWithAxisProps): void { + if (!areArraysEqual(prevProps.legendProps?.selectedLegends, this.props.legendProps?.selectedLegends)) { + this.setState({ + selectedLegends: this.props.legendProps?.selectedLegends || [], + }); + } } public render(): JSX.Element { @@ -163,6 +182,7 @@ export class HorizontalBarChartWithAxisBase extends React.Component< getGraphData={this._getGraphData} getAxisData={this._getAxisData} onChartMouseLeave={this._handleChartMouseLeave} + ref={this._cartesianChartRef} /* eslint-disable react/jsx-no-bind */ children={(props: IChildProps) => { return ( @@ -175,6 +195,10 @@ export class HorizontalBarChartWithAxisBase extends React.Component< ); } + public get chartContainer(): HTMLElement | null { + return this._cartesianChartRef.current?.chartContainer || null; + } + private _getDomainNRangeValues = ( points: IHorizontalBarChartWithAxisDataPoint[], margins: IMargins, @@ -336,8 +360,7 @@ export class HorizontalBarChartWithAxisBase extends React.Component< const { YValueHover, hoverXValue } = this._getCalloutContentForBar(point); if ( - (this.state.isLegendSelected === false || - (this.state.isLegendSelected && this.state.selectedLegendTitle === point.legend)) && + (this.state.isLegendSelected === false || this._isLegendHighlighted(point.legend)) && this._calloutAnchorPoint !== point ) { this._calloutAnchorPoint = point; @@ -379,8 +402,8 @@ export class HorizontalBarChartWithAxisBase extends React.Component< color: string, ): void => { if ( - this.state.isLegendSelected === false || - (this.state.isLegendSelected && this.state.selectedLegendTitle === point.legend) + (this.state.isLegendSelected === false || this._isLegendHighlighted(point.legend)) && + this._calloutAnchorPoint !== point ) { const { YValueHover, hoverXValue } = this._getCalloutContentForBar(point); this._refArray.forEach((obj: IRefArrayData, index: number) => { @@ -457,7 +480,7 @@ export class HorizontalBarChartWithAxisBase extends React.Component< const bars = sortedBars.map((point: IHorizontalBarChartWithAxisDataPoint, index: number) => { let shouldHighlight = true; if (this.state.isLegendHovered || this.state.isLegendSelected) { - shouldHighlight = this.state.selectedLegendTitle === point.legend; + shouldHighlight = this._isLegendHighlighted(point.legend); } this._classNames = getClassNames(this.props.styles!, { theme: this.props.theme!, @@ -583,6 +606,15 @@ export class HorizontalBarChartWithAxisBase extends React.Component< const { xBarScale, yBarScale } = this._getScales(containerHeight, containerWidth, false); const { useSingleColor = false } = this.props; const bars = this._points.map((point: IHorizontalBarChartWithAxisDataPoint, index: number) => { + let shouldHighlight = true; + if (this.state.isLegendHovered || this.state.isLegendSelected) { + shouldHighlight = this._isLegendHighlighted(point.legend); + } + this._classNames = getClassNames(this.props.styles!, { + theme: this.props.theme!, + legendColor: this.state.color, + shouldHighlight, + }); const barHeight: number = Math.max(yBarScale(point.y), 0); if (barHeight < 1) { return ; @@ -627,6 +659,7 @@ export class HorizontalBarChartWithAxisBase extends React.Component< @@ -688,28 +721,8 @@ export class HorizontalBarChartWithAxisBase extends React.Component< }); }; - private _onLegendClick(customMessage: string): void { - if (this.state.isLegendSelected) { - if (this.state.selectedLegendTitle === customMessage) { - this.setState({ - isLegendSelected: false, - selectedLegendTitle: customMessage, - }); - } else { - this.setState({ - selectedLegendTitle: customMessage, - }); - } - } else { - this.setState({ - isLegendSelected: true, - selectedLegendTitle: customMessage, - }); - } - } - private _onLegendHover(customMessage: string): void { - if (this.state.isLegendSelected === false) { + if (!this._isLegendSelected()) { this.setState({ isLegendHovered: true, selectedLegendTitle: customMessage, @@ -718,11 +731,11 @@ export class HorizontalBarChartWithAxisBase extends React.Component< } private _onLegendLeave(isLegendFocused?: boolean): void { - if (!!isLegendFocused || this.state.isLegendSelected === false) { + if (!!isLegendFocused || !this._isLegendSelected()) { this.setState({ isLegendHovered: false, selectedLegendTitle: '', - isLegendSelected: isLegendFocused ? false : this.state.isLegendSelected, + isLegendSelected: isLegendFocused ? false : this._isLegendSelected(), }); } } @@ -749,9 +762,6 @@ export class HorizontalBarChartWithAxisBase extends React.Component< const legend: ILegend = { title: point.legend!, color, - action: () => { - this._onLegendClick(point.legend!); - }, hoverAction: () => { this._handleChartMouseLeave(); this._onLegendHover(point.legend!); @@ -770,11 +780,58 @@ export class HorizontalBarChartWithAxisBase extends React.Component< focusZonePropsInHoverCard={this.props.focusZonePropsForLegendsInHoverCard} overflowText={this.props.legendsOverflowText} {...this.props.legendProps} + onChange={this._onLegendSelectionChange.bind(this)} /> ); return legends; }; + private _isLegendSelected = (): boolean => { + return this.state.isLegendSelected!; + }; + + /** + * This function checks if the given legend is highlighted or not. + * A legend can be highlighted in 2 ways: + * 1. selection: if the user clicks on it + * 2. hovering: if there is no selected legend and the user hovers over it + */ + private _isLegendHighlighted = (legend?: string) => { + return this._getHighlightedLegend().includes(legend!); + }; + + private _getHighlightedLegend() { + return this.state.selectedLegends.length > 0 + ? this.state.selectedLegends + : this.state.selectedLegendTitle + ? [this.state.selectedLegendTitle] + : []; + } + + private _onLegendSelectionChange( + selectedLegends: string[], + event: React.MouseEvent, + currentLegend?: ILegend, + ): void { + if (this.props.legendProps?.canSelectMultipleLegends) { + this.setState({ + selectedLegends, + selectedLegendTitle: currentLegend?.title!, + }); + } else { + this.setState({ + selectedLegends: selectedLegends.slice(-1), + selectedLegendTitle: currentLegend?.title!, + }); + } + this.setState({ + isLegendSelected: selectedLegends.length > 0, + }); + if (this.props.legendProps?.onChange) { + this.props.legendProps.onChange(selectedLegends, event, currentLegend); + } + } + private _getAxisData = (yAxisData: IAxisData) => { if (yAxisData && yAxisData.yAxisDomainValues.length) { // For HBCWA x and y Values are swapped diff --git a/packages/charts/react-charting/src/components/HorizontalBarChartWithAxis/HorizontalBarChartWithAxisRTL.test.tsx b/packages/charts/react-charting/src/components/HorizontalBarChartWithAxis/HorizontalBarChartWithAxisRTL.test.tsx index 6975206a6447ac..f19db37b54b68e 100644 --- a/packages/charts/react-charting/src/components/HorizontalBarChartWithAxis/HorizontalBarChartWithAxisRTL.test.tsx +++ b/packages/charts/react-charting/src/components/HorizontalBarChartWithAxis/HorizontalBarChartWithAxisRTL.test.tsx @@ -169,6 +169,31 @@ describe('Horizontal bar chart with axis- Subcomponent Legends', () => { expect(legendsAfterClickEvent[3]).toHaveAttribute('aria-selected', 'false'); }, ); + + testWithoutWait( + 'Should select multiple legends on multiple mouse click on legends', + HorizontalBarChartWithAxis, + { data: chartPointsHBCWA, legendProps: { canSelectMultipleLegends: true } }, + container => { + // const legends = screen.getAllByText((content, element) => element!.tagName.toLowerCase() === 'button'); + const legend1 = screen.getByText('Grapes')?.closest('button'); + const legend2 = screen.getByText('Apples')?.closest('button'); + + expect(legend1).toBeDefined(); + expect(legend2).toBeDefined(); + + fireEvent.click(legend1!); + fireEvent.click(legend2!); + const legendsAfterClickEvent = screen.getAllByText( + (content, element) => element!.tagName.toLowerCase() === 'button', + ); + // Assert + expect(legendsAfterClickEvent[0]).toHaveAttribute('aria-selected', 'false'); + expect(legendsAfterClickEvent[1]).toHaveAttribute('aria-selected', 'true'); + expect(legendsAfterClickEvent[2]).toHaveAttribute('aria-selected', 'true'); + expect(legendsAfterClickEvent[3]).toHaveAttribute('aria-selected', 'false'); + }, + ); }); describe('Horizontal bar chart with axis - Subcomponent callout', () => { diff --git a/packages/charts/react-charting/src/components/HorizontalBarChartWithAxis/__snapshots__/HorizontalBarChartWithAxis.test.tsx.snap b/packages/charts/react-charting/src/components/HorizontalBarChartWithAxis/__snapshots__/HorizontalBarChartWithAxis.test.tsx.snap index eeabb9f133817c..ae589f61329a71 100644 --- a/packages/charts/react-charting/src/components/HorizontalBarChartWithAxis/__snapshots__/HorizontalBarChartWithAxis.test.tsx.snap +++ b/packages/charts/react-charting/src/components/HorizontalBarChartWithAxis/__snapshots__/HorizontalBarChartWithAxis.test.tsx.snap @@ -2128,6 +2128,11 @@ exports[`HorizontalBarChartWithAxis snapShot testing renders showToolTipForYAxis { /** Boolean variable to check if one or more legends are selected */ private _isLegendSelected = false; + public static getDerivedStateFromProps(newProps: ILegendsProps, prevState: ILegendState): ILegendState { + const { selectedLegend, selectedLegends } = newProps; + + if (newProps.canSelectMultipleLegends && selectedLegends !== undefined) { + return { + ...prevState, + selectedLegends: selectedLegends.reduce( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (combinedDict: any, key: any) => ({ [key]: true, ...combinedDict }), + {}, + ), + }; + } + + if (!newProps.canSelectMultipleLegends && selectedLegend !== undefined) { + return { + ...prevState, + selectedLegends: { [selectedLegend]: true }, + }; + } + + return prevState; + } + public constructor(props: ILegendsProps) { super(props); - let defaultSelectedLegends = {}; + //let defaultSelectedLegends = {}; + const initialSelectedLegends = props.selectedLegends ?? props.defaultSelectedLegends; + const initialSelectedLegend = props.selectedLegend ?? props.defaultSelectedLegend; + let selectedLegendsState = {}; + if (props.canSelectMultipleLegends) { - defaultSelectedLegends = - props.defaultSelectedLegends?.reduce((combinedDict, key) => ({ [key]: true, ...combinedDict }), {}) || {}; - } else if (props.defaultSelectedLegend) { - defaultSelectedLegends = { [props.defaultSelectedLegend]: true }; + selectedLegendsState = + (initialSelectedLegends ?? [])?.reduce( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (combineDict: any, key: any) => ({ [key]: true, ...combineDict }), + {}, + ) || {}; + } else if (initialSelectedLegend) { + selectedLegendsState = { [initialSelectedLegend]: true }; } this.state = { activeLegend: '', isHoverCardVisible: false, - selectedLegends: defaultSelectedLegends, + selectedLegends: selectedLegendsState, }; } @@ -164,11 +196,11 @@ export class LegendsBase extends React.Component { }; /** - * This function will get called when there is an ability to - * select multiple legends - * @param legend ILegend + * Get the new selected legends based on the legend that was clicked when multi-select is enabled. + * @param legend The legend that was clicked + * @returns An object with the new selected legend(s) state data. */ - private _canSelectMultipleLegends = (legend: ILegend): { [key: string]: boolean } => { + private _getNewSelectedLegendsForMultiselect = (legend: ILegend): { [key: string]: boolean } => { let selectedLegends = { ...this.state.selectedLegends }; if (selectedLegends[legend.title]) { // Delete entry for the deselected legend to make @@ -181,37 +213,27 @@ export class LegendsBase extends React.Component { selectedLegends = {}; } } - this.setState({ selectedLegends }); return selectedLegends; }; /** - * This function will get called when there is - * ability to select only single legend - * @param legend ILegend + * Get the new selected legends based on the legend that was clicked when single-select is enabled. + * @param legend The legend that was clicked + * @returns An object with the new selected legend state data. */ - private _canSelectOnlySingleLegend = (legend: ILegend): boolean => { - if (this.state.selectedLegends[legend.title]) { - this.setState({ selectedLegends: {} }); - return false; - } else { - this.setState({ selectedLegends: { [legend.title]: true } }); - return true; - } + private _getNewSelectedLegendsForSingleSelect = (legend: ILegend): { [key: string]: boolean } => { + return this.state.selectedLegends[legend.title] ? {} : { [legend.title]: true }; }; private _onClick = (legend: ILegend, event: React.MouseEvent): void => { const { canSelectMultipleLegends = false } = this.props; - let selectedLegends: string[] = []; - if (canSelectMultipleLegends) { - const nextSelectedLegends = this._canSelectMultipleLegends(legend); - selectedLegends = Object.keys(nextSelectedLegends); - } else { - const isSelected = this._canSelectOnlySingleLegend(legend); - selectedLegends = isSelected ? [legend.title] : []; - } - this.props.onChange?.(selectedLegends, event, legend); + const nextSelectedLegends = canSelectMultipleLegends + ? this._getNewSelectedLegendsForMultiselect(legend) + : this._getNewSelectedLegendsForSingleSelect(legend); + + this.setState({ selectedLegends: nextSelectedLegends }); + this.props.onChange?.(Object.keys(nextSelectedLegends), event, legend); legend.action?.(); }; diff --git a/packages/charts/react-charting/src/components/Legends/Legends.test.tsx b/packages/charts/react-charting/src/components/Legends/Legends.test.tsx index f5d1a23be67f3f..6a96d5023a49f7 100644 --- a/packages/charts/react-charting/src/components/Legends/Legends.test.tsx +++ b/packages/charts/react-charting/src/components/Legends/Legends.test.tsx @@ -234,3 +234,27 @@ describe('Legends - multi Legends', () => { expect(renderedLegends?.length).toBe(2); }); }); + +describe('Legends - controlled legend selection', () => { + beforeEach(sharedBeforeEach); + afterEach(sharedAfterEach); + it('follows updates in the selectedLegends prop', () => { + wrapper = mount(); + let renderedLegends = wrapper.getDOMNode().querySelectorAll('button[aria-selected="true"]'); + expect(renderedLegends?.length).toBe(1); + + wrapper.setProps({ selectedLegends: [legends[1].title, legends[2].title] }); + renderedLegends = wrapper.getDOMNode().querySelectorAll('button[aria-selected="true"]'); + expect(renderedLegends?.length).toBe(2); + }); + + it('follows updates in the selectedLegend prop', () => { + wrapper = mount(); + let renderedLegends = wrapper.getDOMNode().querySelectorAll('button[aria-selected="true"]'); + expect(renderedLegends?.length).toBe(1); + + wrapper.setProps({ selectedLegend: legends[1].title }); + renderedLegends = wrapper.getDOMNode().querySelectorAll('button[aria-selected="true"]'); + expect(renderedLegends?.length).toBe(1); + }); +}); diff --git a/packages/charts/react-charting/src/components/Legends/Legends.types.ts b/packages/charts/react-charting/src/components/Legends/Legends.types.ts index e72c320799930f..9955bfa1e2e18d 100644 --- a/packages/charts/react-charting/src/components/Legends/Legends.types.ts +++ b/packages/charts/react-charting/src/components/Legends/Legends.types.ts @@ -226,18 +226,55 @@ export interface ILegendsProps { onChange?: (selectedLegends: string[], event: React.MouseEvent, currentLegend?: ILegend) => void; /** - * Keys (title) that will be initially used to set selected items. - * This prop is used for multiSelect scenarios. - * In other cases, defaultSelectedLegend should be used. + * Keys (title) that will be initially used to set selected items. This prop is used for multi-select scenarios when + * canSelectMultipleLegends is true; for single-select, use defaultSelectedLegend. + * + * Updating this prop does not change the selection after the component has been initialized. For controlled + * selections, use selectedLegends instead. + * + * @see selectedLegends for setting the selected legends in controlled mode. + * @see defaultSelectedLegend for setting the initially selected legend when canSelectMultipleLegends is false. */ defaultSelectedLegends?: string[]; /** - * Key that will be initially used to set selected item. - * This prop is used for singleSelect scenarios. + * Key that will be initially used to set selected item. This prop is used for single-select scenarios when + * canSelectMultipleLegends is false or unspecified; for multi-select, use defaultSelectedLegends. + * + * Updating this prop does not change the selection after the component has been initialized. For controlled + * selections, use selectedLegend instead. + * + * @see selectedLegend for setting the selected legend in controlled mode. + * @see defaultSelectedLegends for setting the initially selected legends when canSelectMultipleLegends is true. */ defaultSelectedLegend?: string; + /** + * Keys (title) that will be used to set selected items in multi-select scenarios when canSelectMultipleLegends is + * true. For single-select, use selectedLegend. + * + * When this prop is provided, the component is controlled and does not automatically update the selection based on + * user interactions; the parent component must update the value passed to this property by handling the onChange + * event. + * + * @see defaultSelectedLegends for setting the initially-selected legends in uncontrolled mode. + * @see selectedLegends for setting the selected legends when `canSelectMultipleLegends` is `true`. + */ + selectedLegends?: string[]; + + /** + * Key (title) that will be used to set the selected item in single-select scenarios when canSelectMultipleLegends is + * false or unspecified. For multi-select, use selectedLegends. + * + * When this prop is provided, the component is controlled and does not automatically update the selection based on + * user interactions; the parent component must update the value passed to this property by handling the onChange + * event. + * + * @see defaultSelectedLegend for setting the initially-selected legend in uncontrolled mode. + * @see selectedLegend for setting the selected legend when `canSelectMultipleLegends` is `false`. + */ + selectedLegend?: string; + /** * The shape for the legend. */ diff --git a/packages/charts/react-charting/src/components/LineChart/LineChart.base.tsx b/packages/charts/react-charting/src/components/LineChart/LineChart.base.tsx index 65d04ab60e1d23..b5d75148d6560c 100644 --- a/packages/charts/react-charting/src/components/LineChart/LineChart.base.tsx +++ b/packages/charts/react-charting/src/components/LineChart/LineChart.base.tsx @@ -4,7 +4,14 @@ import { select as d3Select, pointer } from 'd3-selection'; import { bisector } from 'd3-array'; import { ILegend, Legends } from '../Legends/index'; import { line as d3Line, curveLinear as d3curveLinear } from 'd3-shape'; -import { classNamesFunction, getId, find, memoizeFunction, getRTL } from '@fluentui/react/lib/Utilities'; +import { + classNamesFunction, + getId, + find, + memoizeFunction, + getRTL, + initializeComponentRef, +} from '@fluentui/react/lib/Utilities'; import { IAccessibilityProps, CartesianChart, @@ -41,7 +48,9 @@ import { domainRangeOfNumericForAreaChart, createStringYAxis, formatDate, + areArraysEqual, } from '../../utilities/index'; +import { IChart } from '../../types/index'; type NumericAxis = D3Axis; const getClassNames = classNamesFunction(); @@ -146,7 +155,7 @@ export interface ILineChartState extends IBasestate { activeLine: number | null; } -export class LineChartBase extends React.Component { +export class LineChartBase extends React.Component implements IChart { public static defaultProps: Partial = { enableReflow: true, useUTC: true, @@ -178,19 +187,23 @@ export class LineChartBase extends React.Component; constructor(props: ILineChartProps) { super(props); + + initializeComponentRef(this); + this.state = { hoverXValue: '', activeLegend: '', YValueHover: [], refSelected: '', - selectedLegend: '', + selectedLegend: props.legendProps?.selectedLegend ?? '', isCalloutVisible: false, - selectedLegendPoints: [], + selectedLegendPoints: this._injectIndexPropertyInLineChartData(this.props.data.lineChartData, true), selectedColorBarLegend: [], - isSelectedLegend: false, + isSelectedLegend: (this.props.legendProps?.selectedLegends?.length ?? 0) > 0, activePoint: '', nearestCircleToHighlight: null, activeLine: null, @@ -210,6 +223,7 @@ export class LineChartBase extends React.Component this._createLegends(data)); this._firstRenderOptimization = true; this._emptyChartId = getId('_LineChart_empty'); + this._cartesianChartRef = React.createRef(); props.eventAnnotationProps && props.eventAnnotationProps.labelHeight && @@ -217,8 +231,19 @@ export class LineChartBase extends React.Component 0, + }); + } + /** note that height and width are not used to resize or set as dimesions of the chart, - * fitParentContainer is responisble for setting the height and width or resizing of the svg/chart + * fitParentContainer is responsible for setting the height and width or resizing of the svg/chart */ if ( prevProps.height !== this.props.height || @@ -293,6 +318,7 @@ export class LineChartBase extends React.Component { @@ -349,6 +375,10 @@ export class LineChartBase extends React.Component { + private _injectIndexPropertyInLineChartData = ( + lineChartData?: ILineChartPoints[], + isFilterSelectedLegends: boolean = false, + ): LineChartDataWithIndex[] | [] => { const { allowMultipleShapesForPoints = false } = this.props; - return lineChartData - ? lineChartData.map((item: ILineChartPoints, index: number) => { + // Apply filter only if isPropChange is true + const filteredData = isFilterSelectedLegends + ? lineChartData?.filter( + (item: ILineChartPoints) => + this.props.legendProps?.selectedLegends?.includes(item.legend) || + this.props.legendProps?.selectedLegend === item.legend, + ) + : lineChartData; + return filteredData + ? filteredData.map((item: ILineChartPoints, index: number) => { let color: string; // isInverted property is applicable to v8 themes only if (typeof item.color === 'undefined') { @@ -1045,7 +1086,8 @@ export class LineChartBase extends React.Component Math.PI ? -10 : 10), + y: labelY + (angle > Math.PI / 2 && angle < (3 * Math.PI) / 2 ? 10 : -10), dominantBaseline: angle > Math.PI / 2 && angle < (3 * Math.PI) / 2 ? 'hanging' : 'auto', textAnchor: (!this._isRTL && angle > Math.PI) || (this._isRTL && angle < Math.PI) ? 'end' : 'start', 'aria-label': `${data?.data.x}-${convertToLocaleString(data?.data.y, culture)}`, diff --git a/packages/charts/react-charting/src/components/PieChart/PieChart.base.tsx b/packages/charts/react-charting/src/components/PieChart/PieChart.base.tsx index 74ead8471f7294..80d2de51787324 100644 --- a/packages/charts/react-charting/src/components/PieChart/PieChart.base.tsx +++ b/packages/charts/react-charting/src/components/PieChart/PieChart.base.tsx @@ -33,6 +33,7 @@ export class PieChartBase extends React.Component { const TEXT_MAX_WIDTH = 40; const TEXT_LINE_HEIGHT = 16; + const PADDING = 4; /** * The radius for the pie chart is computed based on the space available inside the svg @@ -47,8 +48,8 @@ export class PieChartBase extends React.Component { {this.props.chartTitle &&

{this.props.chartTitle}

} A-50 @@ -115,8 +115,8 @@ exports[`PieChart snapShot testing renders PieChart correctly 1`] = ` onMouseEnter={[Function]} onMouseLeave={[Function]} textAnchor="end" - x={-112.00757625617408} - y={112.85079911643227} + x={-122.00757625617408} + y={122.85079911643227} > B-25 @@ -159,8 +159,8 @@ exports[`PieChart snapShot testing renders PieChart correctly 1`] = ` onMouseEnter={[Function]} onMouseLeave={[Function]} textAnchor="end" - x={-112.57042780891464} - y={-112.2893529365894} + x={-122.57042780891464} + y={-122.2893529365894} > C-25 @@ -197,12 +197,12 @@ exports[`PieChart snapShot testing renders with colors, width and height data co onMouseDownCapture={[Function]} > A-50 @@ -286,8 +286,8 @@ exports[`PieChart snapShot testing renders with colors, width and height data co onMouseEnter={[Function]} onMouseLeave={[Function]} textAnchor="end" - x={-94.39632212784481} - y={95.1069627773706} + x={-104.39632212784481} + y={105.1069627773706} > B-25 @@ -330,8 +330,8 @@ exports[`PieChart snapShot testing renders with colors, width and height data co onMouseEnter={[Function]} onMouseLeave={[Function]} textAnchor="end" - x={-94.87067500877083} - y={-94.63379429876088} + x={-104.87067500877083} + y={-104.63379429876088} > C-25 diff --git a/packages/charts/react-charting/src/components/PieChart/__snapshots__/PieChartRTL.test.tsx.snap b/packages/charts/react-charting/src/components/PieChart/__snapshots__/PieChartRTL.test.tsx.snap index 60f87516205833..0f2674efaa835e 100644 --- a/packages/charts/react-charting/src/components/PieChart/__snapshots__/PieChartRTL.test.tsx.snap +++ b/packages/charts/react-charting/src/components/PieChart/__snapshots__/PieChartRTL.test.tsx.snap @@ -37,12 +37,12 @@ exports[`Pie chart rendering Should re-render the Pie chart with data 2`] = ` > A-50 @@ -116,8 +116,8 @@ exports[`Pie chart rendering Should re-render the Pie chart with data 2`] = ` id="tooltip-host7" tabindex="-1" text-anchor="end" - x="-112.00757625617408" - y="112.85079911643227" + x="-122.00757625617408" + y="122.85079911643227" > B-25 @@ -155,8 +155,8 @@ exports[`Pie chart rendering Should re-render the Pie chart with data 2`] = ` id="tooltip-host10" tabindex="-1" text-anchor="end" - x="-112.57042780891464" - y="-112.2893529365894" + x="-122.57042780891464" + y="-122.2893529365894" > C-25 @@ -194,12 +194,12 @@ exports[`PieChart snapShot testing renders PieChart correctly 1`] = ` onMouseDownCapture={[Function]} > A-50 @@ -283,8 +283,8 @@ exports[`PieChart snapShot testing renders PieChart correctly 1`] = ` onMouseEnter={[Function]} onMouseLeave={[Function]} textAnchor="end" - x={-112.00757625617408} - y={112.85079911643227} + x={-122.00757625617408} + y={122.85079911643227} > B-25 @@ -327,8 +327,8 @@ exports[`PieChart snapShot testing renders PieChart correctly 1`] = ` onMouseEnter={[Function]} onMouseLeave={[Function]} textAnchor="end" - x={-112.57042780891464} - y={-112.2893529365894} + x={-122.57042780891464} + y={-122.2893529365894} > C-25 @@ -365,12 +365,12 @@ exports[`PieChart snapShot testing renders with colors, width and height data co onMouseDownCapture={[Function]} > A-50 @@ -454,8 +454,8 @@ exports[`PieChart snapShot testing renders with colors, width and height data co onMouseEnter={[Function]} onMouseLeave={[Function]} textAnchor="end" - x={-94.39632212784481} - y={95.1069627773706} + x={-104.39632212784481} + y={105.1069627773706} > B-25 @@ -498,8 +498,8 @@ exports[`PieChart snapShot testing renders with colors, width and height data co onMouseEnter={[Function]} onMouseLeave={[Function]} textAnchor="end" - x={-94.87067500877083} - y={-94.63379429876088} + x={-104.87067500877083} + y={-104.63379429876088} > C-25 diff --git a/packages/charts/react-charting/src/components/SankeyChart/SankeyChart.base.tsx b/packages/charts/react-charting/src/components/SankeyChart/SankeyChart.base.tsx index fb016e4d44e905..810b06acac2859 100644 --- a/packages/charts/react-charting/src/components/SankeyChart/SankeyChart.base.tsx +++ b/packages/charts/react-charting/src/components/SankeyChart/SankeyChart.base.tsx @@ -7,6 +7,7 @@ import { format, getId, getRTL, + initializeComponentRef, memoizeFunction, } from '@fluentui/react/lib/Utilities'; import { sum as d3Sum } from 'd3-array'; @@ -14,7 +15,7 @@ import { SankeyGraph, SankeyLayout, sankey as d3Sankey, sankeyJustify, sankeyRig import { BaseType, Selection as D3Selection, select, selectAll } from 'd3-selection'; import { area as d3Area, curveBumpX as d3CurveBasis } from 'd3-shape'; import * as React from 'react'; -import { IBasestate, SLink, SNode } from '../../types/IDataPoint'; +import { IBasestate, IChart, SLink, SNode } from '../../types/IDataPoint'; import { ChartHoverCard } from '../../utilities/ChartHoverCard/ChartHoverCard'; import { IChartHoverCardProps } from '../../utilities/ChartHoverCard/ChartHoverCard.types'; import { IMargins } from '../../utilities/utilities'; @@ -574,12 +575,12 @@ type AccessibilityRenderer = { // to a function component. This will require a significant refactor of the code in this file. // https://stackoverflow.com/questions/60223362/fast-way-to-convert-react-class-component-to-functional-component // I am concerned that doing so would break this contract, making it difficult for consuming code. -export class SankeyChartBase extends React.Component { +export class SankeyChartBase extends React.Component implements IChart { public static defaultProps: Partial = { enableReflow: true, }; - private chartContainer: HTMLDivElement; + public chartContainer: HTMLDivElement; private _reqID: number; private readonly _calloutId: string; private readonly _linkId: string; @@ -628,6 +629,9 @@ export class SankeyChartBase extends React.Component; + + /** + * props for the callout in the chart + */ + calloutProps?: Partial; } /** diff --git a/packages/charts/react-charting/src/components/StackedBarChart/MultiStackedBarChart.base.tsx b/packages/charts/react-charting/src/components/StackedBarChart/MultiStackedBarChart.base.tsx index 44e426a05f7118..2b23989b914a2e 100644 --- a/packages/charts/react-charting/src/components/StackedBarChart/MultiStackedBarChart.base.tsx +++ b/packages/charts/react-charting/src/components/StackedBarChart/MultiStackedBarChart.base.tsx @@ -148,6 +148,7 @@ export class MultiStackedBarChartBase extends React.Component string; -export class VerticalBarChartBase extends React.Component { +export class VerticalBarChartBase + extends React.Component + implements IChart +{ public static defaultProps: Partial = { maxBarWidth: 24, useUTC: true, @@ -102,16 +109,20 @@ export class VerticalBarChartBase extends React.Component; public constructor(props: IVerticalBarChartProps) { super(props); + + initializeComponentRef(this); + this.state = { color: '', dataForHoverCard: 0, isCalloutVisible: false, refSelected: null, - selectedLegend: '', - activeLegend: '', + selectedLegends: props.legendProps?.selectedLegends || [], + activeLegend: undefined, xCalloutValue: '', yCalloutValue: '', activeXdataPoint: null, @@ -129,6 +140,15 @@ export class VerticalBarChartBase extends React.Component 1) && { isCalloutForStack: true })} legendBars={legendBars} datasetForXAxisDomain={this._xAxisLabels} barwidth={this._barWidth} @@ -200,6 +221,7 @@ export class VerticalBarChartBase extends React.Component { return ( @@ -230,6 +252,10 @@ export class VerticalBarChartBase extends React.Component { - const { selectedLegend, activeXdataPoint } = this.state; - if (selectedLegend !== '') { - if (xAxisPoint === activeXdataPoint && selectedLegend === legend) { + const { activeXdataPoint } = this.state; + if (!this._noLegendHighlighted()) { + if (xAxisPoint === activeXdataPoint && this._legendHighlighted(legend)) { return { visibility: CircleVisbility.show, radius: 8 }; - } else if (selectedLegend === legend) { + } else if (this._legendHighlighted(legend)) { // Don't hide the circle to keep it focusable. For more information, // see https://fuzzbomb.github.io/accessibility-demos/visually-hidden-focus-test.html return { visibility: CircleVisbility.show, radius: 0.3 }; @@ -517,7 +543,11 @@ export class VerticalBarChartBase extends React.Component + {this.props.enableGradient && ( @@ -860,7 +892,7 @@ export class VerticalBarChartBase extends React.Component {this.props.enableGradient && ( @@ -973,7 +1005,7 @@ export class VerticalBarChartBase extends React.Component + {this.props.enableGradient && ( @@ -1037,18 +1069,6 @@ export class VerticalBarChartBase extends React.Component = {}; data.forEach((point: IVerticalBarChartDataPoint, _index: number) => { let color: string = !useSingleColor ? point.color! : this._createColors()(1); @@ -1076,16 +1097,16 @@ export class VerticalBarChartBase extends React.Component { // mapping data to the format Legends component needs const legend: ILegend = { - title: point.legend!, + title: legendTitle, color, - action: () => { - this._onLegendClick(point.legend!); - }, hoverAction: () => { this._handleChartMouseLeave(); - this._onLegendHover(point.legend!); + this._onLegendHover(legendTitle); }, onMouseOutAction: () => { this._onLegendLeave(); @@ -1097,9 +1118,6 @@ export class VerticalBarChartBase extends React.Component { - this._onLegendClick(lineLegendText); - }, hoverAction: () => { this._handleChartMouseLeave(); this._onLegendHover(lineLegendText); @@ -1119,11 +1137,27 @@ export class VerticalBarChartBase extends React.Component ); return legends; }; + private _onLegendSelectionChange( + selectedLegends: string[], + event: React.MouseEvent, + currentLegend?: ILegend, + ): void { + if (this.props.legendProps?.canSelectMultipleLegends) { + this.setState({ selectedLegends }); + } else { + this.setState({ selectedLegends: selectedLegends.slice(-1) }); + } + if (this.props.legendProps?.onChange) { + this.props.legendProps.onChange(selectedLegends, event, currentLegend); + } + } + private _getAxisData = (yAxisData: IAxisData) => { if (yAxisData && yAxisData.yAxisDomainValues.length) { const { yAxisDomainValues: domainValue } = yAxisData; @@ -1138,20 +1172,25 @@ export class VerticalBarChartBase extends React.Component { - return ( - this.state.selectedLegend === legendTitle || - (this.state.selectedLegend === '' && this.state.activeLegend === legendTitle) - ); + private _legendHighlighted = (legendTitle: string | undefined) => { + return this._getHighlightedLegend().includes(legendTitle!); }; /** * This function checks if none of the legends is selected or hovered. */ private _noLegendHighlighted = () => { - return this.state.selectedLegend === '' && this.state.activeLegend === ''; + return this._getHighlightedLegend().length === 0; }; + private _getHighlightedLegend() { + return this.state.selectedLegends.length > 0 + ? this.state.selectedLegends + : this.state.activeLegend + ? [this.state.activeLegend] + : []; + } + private _getAriaLabel = (point: IVerticalBarChartDataPoint): string => { const xValue = point.xAxisCalloutData ? point.xAxisCalloutData @@ -1199,6 +1238,8 @@ export class VerticalBarChartBase extends React.Component 1) { + // Calculate the remaining width after rendering bars at their maximum allowable width + const bandwidth = totalWidth / (this._xAxisLabels.length + (this._xAxisLabels.length - 1) * barGapRate); + const barWidth = getBarWidth(this.props.barWidth, this.props.maxBarWidth, bandwidth); + let reqWidth = (this._xAxisLabels.length + (this._xAxisLabels.length - 1) * barGapRate) * barWidth; + const margin1 = (totalWidth - reqWidth) / 2; + + // Calculate the remaining width after accounting for the space required to render x-axis labels + const step = calculateLongestLabelWidth(this._xAxisLabels) + 20; + reqWidth = (this._xAxisLabels.length - this._xAxisInnerPadding) * step; + const margin2 = (totalWidth - reqWidth) / 2; + + this._domainMargin = MIN_DOMAIN_MARGIN + Math.max(0, Math.min(margin1, margin2)); } } else { - const data = (this.props.data?.map(point => point.x) as number[] | Date[] | undefined) || []; + const uniqueX: Record = {}; + this.props.data?.forEach(point => { + if (point.x instanceof Date) { + uniqueX[point.x.getTime()] = point.x; + } else { + uniqueX[point.x as number] = point.x as number; + } + }); + const data = Object.values(uniqueX) as number[] | Date[]; this._barWidth = getBarWidth( this.props.barWidth, this.props.maxBarWidth, diff --git a/packages/charts/react-charting/src/components/VerticalBarChart/VerticalBarChart.types.ts b/packages/charts/react-charting/src/components/VerticalBarChart/VerticalBarChart.types.ts index 8094c91e73a120..aa62768cb0fb59 100644 --- a/packages/charts/react-charting/src/components/VerticalBarChart/VerticalBarChart.types.ts +++ b/packages/charts/react-charting/src/components/VerticalBarChart/VerticalBarChart.types.ts @@ -117,6 +117,12 @@ export interface IVerticalBarChartProps extends ICartesianChartProps { * The prop used to enable rounded corners for the chart. */ roundCorners?: boolean; + + /** + * Specifies the mode of the chart. + * @default 'default' + */ + mode?: 'default' | 'plotly'; } /** diff --git a/packages/charts/react-charting/src/components/VerticalBarChart/VerticalBarChartRTL.test.tsx b/packages/charts/react-charting/src/components/VerticalBarChart/VerticalBarChartRTL.test.tsx index c677c11883ab44..7a4c6180deeaf8 100644 --- a/packages/charts/react-charting/src/components/VerticalBarChart/VerticalBarChartRTL.test.tsx +++ b/packages/charts/react-charting/src/components/VerticalBarChart/VerticalBarChartRTL.test.tsx @@ -652,6 +652,87 @@ describe('Vertical bar chart - Subcomponent Legends', () => { expect(bars[7]).toHaveStyle('opacity: 0.1'); }, ); + + testWithWait( + 'Should reduce the opacity of the other bars/lines and their legends on mouse over multiple legends', + VerticalBarChart, + { data: pointsWithLine, lineLegendText: 'just line', legendProps: { canSelectMultipleLegends: true } }, + container => { + const bars = getById(container, /_VBC_bar/i); + const line = getById(container, /_VBC_line/i)[0]; + const legends = screen.getAllByText((content, element) => element!.tagName.toLowerCase() === 'button'); + expect(line).toBeDefined(); + expect(bars).toHaveLength(8); + expect(legends).toHaveLength(9); + fireEvent.click(screen.getByText('just line')); + fireEvent.click(screen.getByText('Oranges')); + expect(line.getAttribute('opacity')).toEqual('1'); + expect(screen.getByText('Oranges')).not.toHaveAttribute('opacity'); + expect(screen.getByText('Dogs')).toHaveStyle('opacity: 0.67'); + expect(screen.getByText('Apples')).toHaveStyle('opacity: 0.67'); + expect(screen.getByText('Bananas')).toHaveStyle('opacity: 0.67'); + expect(screen.getByText('Giraffes')).toHaveStyle('opacity: 0.67'); + expect(screen.getByText('Cats')).toHaveStyle('opacity: 0.67'); + expect(screen.getByText('Elephants')).toHaveStyle('opacity: 0.67'); + expect(screen.getByText('Monkeys')).toHaveStyle('opacity: 0.67'); + expect(line).toBeDefined(); + expect(bars[0]).toBeDefined(); + expect(bars[0]).not.toHaveAttribute('opacity'); + expect(bars[1]).toBeDefined(); + expect(bars[1]).toHaveStyle('opacity: 0.1'); + expect(bars[2]).toBeDefined(); + expect(bars[2]).toHaveStyle('opacity: 0.1'); + expect(bars[3]).toBeDefined(); + expect(bars[3]).toHaveStyle('opacity: 0.1'); + expect(bars[4]).toBeDefined(); + expect(bars[4]).toHaveStyle('opacity: 0.1'); + expect(bars[5]).toBeDefined(); + expect(bars[5]).toHaveStyle('opacity: 0.1'); + expect(bars[6]).toBeDefined(); + expect(bars[6]).toHaveStyle('opacity: 0.1'); + expect(bars[7]).toBeDefined(); + expect(bars[7]).toHaveStyle('opacity: 0.1'); + }, + ); + + testWithWait( + 'Should reduce the opacity of the other bars/lines and their legends on mouse over multiple legends', + VerticalBarChart, + { data: pointsWithLine, lineLegendText: 'just line', legendProps: { canSelectMultipleLegends: true } }, + container => { + const bars = getById(container, /_VBC_bar/i); + const line = getById(container, /_VBC_line/i)[0]; + const legends = screen.getAllByText((content, element) => element!.tagName.toLowerCase() === 'button'); + expect(line).toBeDefined(); + expect(bars).toHaveLength(8); + expect(legends).toHaveLength(9); + fireEvent.click(screen.getByText('just line')); + fireEvent.click(screen.getByText('Oranges')); + expect(line.getAttribute('opacity')).toEqual('1'); + expect(screen.getByText('Dogs')).toHaveStyle('opacity: 0.67'); + expect(screen.getByText('Apples')).toHaveStyle('opacity: 0.67'); + expect(screen.getByText('Bananas')).toHaveStyle('opacity: 0.67'); + expect(screen.getByText('Giraffes')).toHaveStyle('opacity: 0.67'); + expect(screen.getByText('Cats')).toHaveStyle('opacity: 0.67'); + expect(screen.getByText('Elephants')).toHaveStyle('opacity: 0.67'); + expect(screen.getByText('Monkeys')).toHaveStyle('opacity: 0.67'); + expect(line).toBeDefined(); + expect(bars[1]).toBeDefined(); + expect(bars[1]).toHaveStyle('opacity: 0.1'); + expect(bars[2]).toBeDefined(); + expect(bars[2]).toHaveStyle('opacity: 0.1'); + expect(bars[3]).toBeDefined(); + expect(bars[3]).toHaveStyle('opacity: 0.1'); + expect(bars[4]).toBeDefined(); + expect(bars[4]).toHaveStyle('opacity: 0.1'); + expect(bars[5]).toBeDefined(); + expect(bars[5]).toHaveStyle('opacity: 0.1'); + expect(bars[6]).toBeDefined(); + expect(bars[6]).toHaveStyle('opacity: 0.1'); + expect(bars[7]).toBeDefined(); + expect(bars[7]).toHaveStyle('opacity: 0.1'); + }, + ); }); describe('Vertical bar chart - Subcomponent callout', () => { diff --git a/packages/charts/react-charting/src/components/VerticalBarChart/__snapshots__/VerticalBarChartRTL.test.tsx.snap b/packages/charts/react-charting/src/components/VerticalBarChart/__snapshots__/VerticalBarChartRTL.test.tsx.snap index 885b42fed8c1dd..676ff7ca71b994 100644 --- a/packages/charts/react-charting/src/components/VerticalBarChart/__snapshots__/VerticalBarChartRTL.test.tsx.snap +++ b/packages/charts/react-charting/src/components/VerticalBarChart/__snapshots__/VerticalBarChartRTL.test.tsx.snap @@ -2505,7 +2505,7 @@ exports[`Vertical bar chart re-rendering Should re-render the vertical bar chart fill="currentColor" y="16" > - 10,000 + 10000 - 25,000 + 25000 @@ -14400,7 +14400,7 @@ exports[`Vertical bar chart rendering Should render the vertical bar chart with aria-label="undefined" aria-posinset="1" aria-selected="false" - aria-setsize="4" + aria-setsize="1" class= { @@ -14455,300 +14455,6 @@ exports[`Vertical bar chart rendering Should render the vertical bar chart with
-
- -
-
- -
-
- -
-
-
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 dddf57a74ccb23..5f2e25f9ac3745 100644 --- a/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChart.base.tsx +++ b/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChart.base.tsx @@ -9,7 +9,14 @@ import { scaleUtc as d3ScaleUtc, scaleTime as d3ScaleTime, } from 'd3-scale'; -import { classNamesFunction, getId, getRTL, warnDeprecations, memoizeFunction } from '@fluentui/react/lib/Utilities'; +import { + classNamesFunction, + getId, + getRTL, + warnDeprecations, + memoizeFunction, + initializeComponentRef, +} from '@fluentui/react/lib/Utilities'; import { IPalette, IProcessedStyleSet } from '@fluentui/react/lib/Styling'; import { DirectionalHint } from '@fluentui/react/lib/Callout'; import { ILegend, Legends } from '../Legends/index'; @@ -52,7 +59,10 @@ import { createStringYAxis, formatDate, getNextGradient, + areArraysEqual, + calculateLongestLabelWidth, } from '../../utilities/index'; +import { IChart } from '../../types/index'; const getClassNames = classNamesFunction(); type NumericAxis = D3Axis; @@ -93,11 +103,12 @@ export interface IVerticalStackedBarChartState extends IBasestate { activeXAxisDataPoint: number | string | Date; callOutAccessibilityData?: IAccessibilityProps; calloutLegend: string; + selectedLegends: string[]; } -export class VerticalStackedBarChartBase extends React.Component< - IVerticalStackedBarChartProps, - IVerticalStackedBarChartState -> { +export class VerticalStackedBarChartBase + extends React.Component + implements IChart +{ public static defaultProps: Partial = { maxBarWidth: 24, useUTC: true, @@ -123,13 +134,17 @@ export class VerticalStackedBarChartBase extends React.Component< private _emptyChartId: string; private _xAxisInnerPadding: number; private _xAxisOuterPadding: number; + private _cartesianChartRef: React.RefObject; public constructor(props: IVerticalStackedBarChartProps) { super(props); + + initializeComponentRef(this); + this.state = { isCalloutVisible: false, - selectedLegend: '', - activeLegend: '', + selectedLegends: props.legendProps?.selectedLegends || [], + activeLegend: undefined, refSelected: null, dataForHoverCard: 0, color: '', @@ -154,9 +169,16 @@ export class VerticalStackedBarChartBase extends React.Component< this._createLegendsForLine = memoizeFunction((data: IVerticalStackedChartProps[]) => this._getLineLegends(data)); this._emptyChartId = getId('_VSBC_empty'); this._domainMargin = MIN_DOMAIN_MARGIN; + this._cartesianChartRef = React.createRef(); } public componentDidUpdate(prevProps: IVerticalStackedBarChartProps): void { + if (!areArraysEqual(prevProps.legendProps?.selectedLegends, this.props.legendProps?.selectedLegends)) { + this.setState({ + selectedLegends: this.props.legendProps?.selectedLegends || [], + }); + } + if ( prevProps.height !== this.props.height || prevProps.width !== this.props.width || @@ -238,6 +260,7 @@ export class VerticalStackedBarChartBase extends React.Component< xAxisInnerPadding: this._xAxisInnerPadding, xAxisOuterPadding: this._xAxisOuterPadding, })} + ref={this._cartesianChartRef} /* eslint-disable react/jsx-no-bind */ children={(props: IChildProps) => { return ( @@ -269,6 +292,10 @@ export class VerticalStackedBarChartBase extends React.Component< ); } + public get chartContainer(): HTMLElement | null { + return this._cartesianChartRef.current?.chartContainer || null; + } + /** * This function tells us what to focus either the whole stack as focusable item. * or each individual item in the stack as focusable item. basically it depends @@ -281,7 +308,7 @@ export class VerticalStackedBarChartBase extends React.Component< const { isCalloutForStack = false } = this.props; let shouldFocusStackOnly: boolean = false; if (_isHavingLines) { - if (this.state.selectedLegend !== '') { + if (this._getHighlightedLegend().length === 1) { shouldFocusStackOnly = false; } else { shouldFocusStackOnly = true; @@ -380,7 +407,7 @@ export class VerticalStackedBarChartBase extends React.Component< const xScaleBandwidthTranslate = this._xAxisType !== XAxisTypes.StringAxis ? 0 : xScale.bandwidth() / 2; Object.keys(lineObject).forEach((item: string, index: number) => { - const shouldHighlight = this._legendHighlighted(item) || this._noLegendHighlighted(); // item is legend name + const shouldHighlight = this._isLegendHighlighted(item) || this._noLegendHighlighted(); // item is legend name for (let i = 1; i < lineObject[item].length; i++) { const x1 = xScale(lineObject[item][i - 1].xItem.xAxisPoint); const useSecondaryYScale = @@ -414,11 +441,12 @@ export class VerticalStackedBarChartBase extends React.Component< x2={x2} y2={y2} opacity={shouldHighlight ? 1 : 0.1} - strokeWidth={3} - strokeLinecap="round" + strokeWidth={lineObject[item][0].lineOptions?.strokeWidth ?? 3} + strokeLinecap={lineObject[item][0].lineOptions?.strokeLinecap ?? 'round'} + strokeDasharray={lineObject[item][0].lineOptions?.strokeDasharray} stroke={lineObject[item][i].color} transform={`translate(${xScaleBandwidthTranslate}, 0)`} - {...(this.state.selectedLegend === item && { + {...(this._isLegendHighlighted(item) && { onMouseOver: this._lineHover.bind(this, lineObject[item][i - 1]), onMouseLeave: this._lineHoverOut, })} @@ -438,11 +466,11 @@ export class VerticalStackedBarChartBase extends React.Component< circlePoint.useSecondaryYScale && secondaryYScale ? secondaryYScale(circlePoint.y) : yScale(circlePoint.y) } onMouseOver={ - this.state.selectedLegend === item + this._isLegendHighlighted(item) ? this._lineHover.bind(this, circlePoint) : this._onStackHover.bind(this, circlePoint.xItem) } - {...(this.state.selectedLegend === item && { + {...(this._isLegendHighlighted(item) && { onMouseLeave: this._lineHoverOut, })} r={this._getCircleVisibilityAndRadius(circlePoint.xItem.xAxisPoint, circlePoint.legend).radius} @@ -454,7 +482,7 @@ export class VerticalStackedBarChartBase extends React.Component< // When no legend is highlighted: Line points are automatically displayed along with the bars // at the same x-axis point in the stack callout. So to prevent an increase in focusable elements // and avoid conveying duplicate info, make these line points non-focusable. - data-is-focusable={this._legendHighlighted(item)} + data-is-focusable={this._isLegendHighlighted(item)} ref={e => (circleRef.refElement = e)} onFocus={this._lineFocus.bind(this, circlePoint, circleRef)} onBlur={this._lineHoverOut} @@ -475,11 +503,11 @@ export class VerticalStackedBarChartBase extends React.Component< xAxisPoint: string | number | Date, legend: string, ): { visibility: CircleVisbility; radius: number } => { - const { selectedLegend, activeXAxisDataPoint } = this.state; - if (selectedLegend !== '') { - if (xAxisPoint === activeXAxisDataPoint && selectedLegend === legend) { + const { activeXAxisDataPoint } = this.state; + if (!this._noLegendHighlighted()) { + if (xAxisPoint === activeXAxisDataPoint && this._isLegendHighlighted(legend)) { return { visibility: CircleVisbility.show, radius: 8 }; - } else if (selectedLegend === legend) { + } else if (this._isLegendHighlighted(legend)) { return { visibility: CircleVisbility.show, radius: 0.3 }; } else { return { visibility: CircleVisbility.hide, radius: 0 }; @@ -497,7 +525,7 @@ export class VerticalStackedBarChartBase extends React.Component< 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); @@ -549,18 +577,6 @@ export class VerticalStackedBarChartBase extends React.Component< : null; }; - private _onLegendClick(legendTitle: string): void { - if (this.state.selectedLegend === legendTitle) { - this.setState({ - selectedLegend: '', - }); - } else { - this.setState({ - selectedLegend: legendTitle, - }); - } - } - private _onLegendHover(legendTitle: string): void { this.setState({ activeLegend: legendTitle, @@ -569,7 +585,7 @@ export class VerticalStackedBarChartBase extends React.Component< private _onLegendLeave(): void { this.setState({ - activeLegend: '', + activeLegend: undefined, }); } @@ -604,9 +620,6 @@ export class VerticalStackedBarChartBase extends React.Component< const legend: ILegend = { title: point.legend, color, - action: () => { - this._onLegendClick(point.legend); - }, hoverAction: allowHoverOnLegend ? () => { this._handleChartMouseLeave(); @@ -626,9 +639,6 @@ export class VerticalStackedBarChartBase extends React.Component< title: point.title, color: point.color, isLineLegendInBarChart: true, - action: () => { - this._onLegendClick(point.title); - }, hoverAction: allowHoverOnLegend ? () => { this._handleChartMouseLeave(); @@ -649,10 +659,34 @@ export class VerticalStackedBarChartBase extends React.Component< focusZonePropsInHoverCard={this.props.focusZonePropsForLegendsInHoverCard} overflowText={this.props.legendsOverflowText} {...this.props.legendProps} + onChange={this._onLegendSelectionChange.bind(this)} /> ); } + private _onLegendSelectionChange( + selectedLegends: string[], + event: React.MouseEvent, + currentLegend?: ILegend, + ): void { + if (this.props.legendProps?.canSelectMultipleLegends) { + this.setState({ selectedLegends }); + } else { + this.setState({ selectedLegends: selectedLegends.slice(-1) }); + } + if (this.props.legendProps?.onChange) { + this.props.legendProps.onChange(selectedLegends, event, currentLegend); + } + } + + private _getHighlightedLegend() { + return this.state.selectedLegends.length > 0 + ? this.state.selectedLegends + : this.state.activeLegend + ? [this.state.activeLegend] + : []; + } + private _onRectHover( xAxisPoint: string, point: IVSChartDataPoint, @@ -680,7 +714,7 @@ export class VerticalStackedBarChartBase extends React.Component< * Show the callout if highlighted bar is focused/hovered * and Hide it if unhighlighted bar is focused/hovered */ - isCalloutVisible: this.state.selectedLegend === '' || this.state.selectedLegend === point.legend, + isCalloutVisible: this._noLegendHighlighted() || this._isLegendHighlighted(point.legend), calloutLegend: point.legend, dataForHoverCard: point.data, color, @@ -734,6 +768,13 @@ export class VerticalStackedBarChartBase extends React.Component< stack: IVerticalStackedChartProps, refSelected: React.MouseEvent | SVGGElement, ): void { + if (!this._noLegendHighlighted()) { + stack = { + ...stack, + chartData: stack.chartData.filter(dataPoint => this._isLegendHighlighted(dataPoint.legend)), + lineData: stack.lineData?.filter(dataPoint => this._isLegendHighlighted(dataPoint.legend)), + }; + } const lineData = stack.lineData; const isLinesPresent: boolean = lineData !== undefined && lineData.length > 0; if (isLinesPresent) { @@ -742,9 +783,10 @@ export class VerticalStackedBarChartBase extends React.Component< item.shouldDrawBorderBottom = true; }); } + this.setState({ refSelected, - isCalloutVisible: true, + isCalloutVisible: stack.chartData.length > 0 || (stack.lineData?.length ?? 0) > 0, YValueHover: isLinesPresent ? [...lineData!.sort((a, b) => (a.data! < b.data! ? 1 : -1)), ...stack.chartData.slice().reverse()] : stack.chartData.slice().reverse(), @@ -870,7 +912,7 @@ export class VerticalStackedBarChartBase extends React.Component< const ref: IRefArrayData = {}; - const shouldHighlight = this._legendHighlighted(point.legend) || this._noLegendHighlighted() ? true : false; + const shouldHighlight = this._isLegendHighlighted(point.legend) || this._noLegendHighlighted() ? true : false; this._classNames = getClassNames(this.props.styles!, { theme: this.props.theme!, shouldHighlight, @@ -977,7 +1019,7 @@ export class VerticalStackedBarChartBase extends React.Component< barLabel = barTotalValue; } else { barsToDisplay.forEach(point => { - if (this._legendHighlighted(point.legend)) { + if (this._isLegendHighlighted(point.legend)) { showLabel = true; barLabel += point.data; } @@ -1103,18 +1145,15 @@ export class VerticalStackedBarChartBase extends React.Component< * 1. selection: if the user clicks on it * 2. hovering: if there is no selected legend and the user hovers over it */ - private _legendHighlighted = (legendTitle: string) => { - return ( - this.state.selectedLegend === legendTitle || - (this.state.selectedLegend === '' && this.state.activeLegend === legendTitle) - ); + private _isLegendHighlighted = (legendTitle: string): boolean => { + return this._getHighlightedLegend().includes(legendTitle); }; /** * This function checks if none of the legends is selected or hovered. */ private _noLegendHighlighted = () => { - return this.state.selectedLegend === '' && this.state.activeLegend === ''; + return this._getHighlightedLegend().length === 0; }; private _getAriaLabel = (singleChartData: IVerticalStackedChartProps, point?: IVSChartDataPoint): string => { @@ -1162,6 +1201,8 @@ export class VerticalStackedBarChartBase extends React.Component< /** Total width available to render the bars */ const totalWidth = containerWidth - (this.margins.left! + MIN_DOMAIN_MARGIN) - (this.margins.right! + MIN_DOMAIN_MARGIN); + /** Rate at which the space between the bars changes wrt the bar width */ + const barGapRate = this._xAxisInnerPadding / (1 - this._xAxisInnerPadding); if (this._xAxisType === XAxisTypes.StringAxis) { if (isScalePaddingDefined(this.props.xAxisOuterPadding, this.props.xAxisPadding)) { @@ -1169,8 +1210,6 @@ export class VerticalStackedBarChartBase extends React.Component< // to adjust the space before the first bar and after the last bar. this._domainMargin = 0; } else if (this.props.barWidth !== 'auto') { - /** Rate at which the space between the bars changes wrt the bar width */ - const barGapRate = this._xAxisInnerPadding / (1 - this._xAxisInnerPadding); // Update the bar width so that when CartesianChart rerenders, // the following calculations don't use the previous bar width. this._barWidth = getBarWidth(this.props.barWidth, this.props.maxBarWidth); @@ -1181,6 +1220,19 @@ export class VerticalStackedBarChartBase extends React.Component< // Center align the chart by setting equal left and right margins for domain this._domainMargin = MIN_DOMAIN_MARGIN + (totalWidth - reqWidth) / 2; } + } else if (this.props.mode === 'plotly' && this._xAxisLabels.length > 1) { + // Calculate the remaining width after rendering bars at their maximum allowable width + const bandwidth = totalWidth / (this._xAxisLabels.length + (this._xAxisLabels.length - 1) * barGapRate); + const barWidth = getBarWidth(this.props.barWidth, this.props.maxBarWidth, bandwidth); + let reqWidth = (this._xAxisLabels.length + (this._xAxisLabels.length - 1) * barGapRate) * barWidth; + const margin1 = (totalWidth - reqWidth) / 2; + + // Calculate the remaining width after accounting for the space required to render x-axis labels + const step = calculateLongestLabelWidth(this._xAxisLabels) + 20; + reqWidth = (this._xAxisLabels.length - this._xAxisInnerPadding) * step; + const margin2 = (totalWidth - reqWidth) / 2; + + this._domainMargin = MIN_DOMAIN_MARGIN + Math.max(0, Math.min(margin1, margin2)); } } else { const data = (this.props.data?.map(point => point.xAxisPoint) as number[] | Date[] | undefined) || []; @@ -1203,7 +1255,7 @@ export class VerticalStackedBarChartBase extends React.Component< 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/components/VerticalStackedBarChart/VerticalStackedBarChart.types.ts b/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChart.types.ts index 5e47df049599cf..5fa46b7dcf6d8d 100644 --- a/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChart.types.ts +++ b/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChart.types.ts @@ -155,6 +155,12 @@ export interface IVerticalStackedBarChartProps extends ICartesianChartProps { * The prop used to enable rounded corners for the chart. */ roundCorners?: boolean; + + /** + * Specifies the mode of the chart. + * @default 'default' + */ + mode?: 'default' | 'plotly'; } /** diff --git a/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChartRTL.test.tsx b/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChartRTL.test.tsx index d3a36f9ac55d97..025dc39d66596c 100644 --- a/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChartRTL.test.tsx +++ b/packages/charts/react-charting/src/components/VerticalStackedBarChart/VerticalStackedBarChartRTL.test.tsx @@ -503,13 +503,30 @@ describe('Vertical stacked bar chart - Subcomponent Legends', () => { { data: simplePointsWithLine, calloutProps: { doNotLayer: true } }, container => { // eslint-disable-next-line - const handleMouseClick = jest.spyOn(VerticalStackedBarChartBase.prototype as any, '_onLegendClick'); + const handleMouseClick = jest.spyOn(VerticalStackedBarChartBase.prototype as any, '_onLegendSelectionChange'); const legends = screen.getAllByText((content, element) => element!.tagName.toLowerCase() === 'button'); fireEvent.click(legends[0]); // Assert expect(handleMouseClick).toHaveBeenCalled(); }, ); + + testWithoutWait( + 'Should select multiple legends on click', + VerticalStackedBarChart, + { data: simplePoints, legendProps: { canSelectMultipleLegends: true }, calloutProps: { doNotLayer: true } }, + container => { + const firstLegend = screen.queryByText('Metadata1')?.closest('button'); + const secondLegend = screen.queryByText('Metadata2')?.closest('button'); + expect(firstLegend).toBeDefined(); + expect(secondLegend).toBeDefined(); + fireEvent.click(firstLegend!); + fireEvent.click(secondLegend!); + //Assert + expect(firstLegend).toHaveAttribute('aria-selected', 'true'); + expect(secondLegend).toHaveAttribute('aria-selected', 'true'); + }, + ); }); describe('Vertical stacked bar chart - Subcomponent callout', () => { diff --git a/packages/charts/react-charting/src/index.ts b/packages/charts/react-charting/src/index.ts index c27c09d1430456..2ae3660ac7f75a 100644 --- a/packages/charts/react-charting/src/index.ts +++ b/packages/charts/react-charting/src/index.ts @@ -97,6 +97,7 @@ export type { IVerticalStackedChartProps, SLink, SNode, + IChart, } from './types/index'; export type { IChartHoverCardProps, @@ -135,7 +136,7 @@ export { DataVizPalette, getColorFromToken, getNextColor } from './utilities/col export { DataVizGradientPalette, getGradientFromToken, getNextGradient } from './utilities/gradients'; export type { IGaugeChartProps, IGaugeChartSegment, IGaugeChartStyleProps, IGaugeChartStyles } from './GaugeChart'; export { GaugeChart, GaugeChartVariant, GaugeValueFormat } from './GaugeChart'; -export type { DeclarativeChartProps, Schema } from './DeclarativeChart'; +export type { DeclarativeChartProps, Schema, IDeclarativeChart, IImageExportOptions } from './DeclarativeChart'; export { DeclarativeChart } from './DeclarativeChart'; import './version'; diff --git a/packages/charts/react-charting/src/types/IDataPoint.ts b/packages/charts/react-charting/src/types/IDataPoint.ts index 7e4127b26f2ee5..5ca0f1393677e1 100644 --- a/packages/charts/react-charting/src/types/IDataPoint.ts +++ b/packages/charts/react-charting/src/types/IDataPoint.ts @@ -650,6 +650,10 @@ export interface ILineDataInVerticalStackedBarChart { * False by default. */ useSecondaryYScale?: boolean; + /** + * options for the line drawn + */ + lineOptions?: ILineChartLineOptions; } /** @@ -814,3 +818,10 @@ export interface ICustomizedCalloutData { x: number | string | Date; values: ICustomizedCalloutDataPoint[]; } + +/** + * {@docCategory Chart} + */ +export interface IChart { + chartContainer: HTMLElement | null; +} diff --git a/packages/charts/react-charting/src/utilities/SVGTooltipText.tsx b/packages/charts/react-charting/src/utilities/SVGTooltipText.tsx index eb625317a5465b..4923c3d2583ce9 100644 --- a/packages/charts/react-charting/src/utilities/SVGTooltipText.tsx +++ b/packages/charts/react-charting/src/utilities/SVGTooltipText.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import { ITooltipHost, ITooltipProps, Tooltip, TooltipDelay } from '@fluentui/react/lib/Tooltip'; import { Async, KeyCodes, getId, portalContainsElement } from '../Utilities'; +import { getRTL, ITheme } from '@fluentui/react'; interface ISVGTooltipTextProps { /** @@ -62,13 +63,30 @@ interface ISVGTooltipTextProps { * and return a boolean value indicating whether the text overflowed */ wrapContent?: (content: string, id: string, maxWidth: number, maxHeight?: number) => boolean; + + /** + * Theme provided by High Order Component + */ + theme?: ITheme; + + /** + * @default false + * Prop to selectively display the tooltip background + */ + showBackground?: boolean; } interface ISVGTooltipTextState { isTooltipVisible: boolean; isOverflowing: boolean; + textX?: number; + textY?: number; + textWidth?: number; + textHeight?: number; } +const PADDING = 4; + /** * Component to render an SVG text element with an optional tooltip. * The tooltip appears on hovering and focusing the element when its content overflows. @@ -104,8 +122,8 @@ export class SVGTooltipText } public render(): React.ReactNode { - const { content, tooltipProps, textProps, shouldReceiveFocus = true } = this.props; - const { isTooltipVisible } = this.state; + const { content, tooltipProps, textProps, shouldReceiveFocus = true, showBackground = false } = this.props; + const { isTooltipVisible, textX, textY, textWidth, textHeight } = this.state; const tooltipRenderProps: ITooltipProps = { content, targetElement: this._getTargetElement(), @@ -121,9 +139,21 @@ export class SVGTooltipText const showTooltip = (!!this.props.isTooltipVisibleProp && this.state.isOverflowing && !!content) || (isTooltipVisible && !!content); - + const backgroundColor = this.props.theme ? this.props.theme.semanticColors.bodyBackground : undefined; + const isRTL = getRTL(); + const rectX = isRTL ? (textX ?? 0) + (textWidth ?? 0) - PADDING : (textX ?? 0) - PADDING; return ( <> + {showBackground && ( + + )} ): void { if (this.props.maxWidth !== prevProps.maxWidth || this.props.maxHeight !== prevProps.maxHeight) { this._wrapContent(); + this._measureText(); } } @@ -168,6 +200,18 @@ export class SVGTooltipText this._hideTooltip(); }; + private _measureText = (): void => { + if (this._tooltipHost.current && typeof this._tooltipHost.current.getBBox === 'function') { + const bbox = this._tooltipHost.current.getBBox(); + this.setState({ + textX: bbox.x, + textY: bbox.y, + textWidth: bbox.width, + textHeight: bbox.height, + }); + } + }; + private _getTargetElement = (): HTMLElement | undefined => { if (!this._tooltipHost.current) { return undefined; @@ -252,7 +296,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/UtilityUnitTests.test.ts b/packages/charts/react-charting/src/utilities/UtilityUnitTests.test.ts index 4f2a6990c36d79..a5d1eb608b84bf 100644 --- a/packages/charts/react-charting/src/utilities/UtilityUnitTests.test.ts +++ b/packages/charts/react-charting/src/utilities/UtilityUnitTests.test.ts @@ -136,6 +136,7 @@ const createXAxisParams = (xAxisParams?: ICreateXAxisParams): utils.IXAxisParams return { xAxisElement, containerHeight: 100, + containerWidth: 100, ...xAxisParams, domainNRangeValues: { dStartValue: 0, @@ -157,9 +158,8 @@ const convertXAxisResultToJson = ( // eslint-disable-next-line @typescript-eslint/no-explicit-any result: { xScale: any; tickValues: string[] }, isStringAxis: boolean = false, - tickCount: number = 6, ): [number, string][] => { - const tickValues = isStringAxis ? result.tickValues : result.xScale.ticks(tickCount); + const tickValues = isStringAxis ? result.tickValues : result.xScale.ticks(result.tickValues.length); return tickValues.map((item: number | Date | string, i: number) => [result.xScale(item), result.tickValues[i]]); }; // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -170,7 +170,7 @@ const matchResult = (result: any) => { describe('createNumericXAxis', () => { it('should render the x-axis labels correctly', () => { const xAxisParams = createXAxisParams(); - utils.createNumericXAxis(xAxisParams, utils.ChartTypes.VerticalBarChart); + utils.createNumericXAxis(xAxisParams, {}, utils.ChartTypes.VerticalBarChart); expect(xAxisParams.xAxisElement).toMatchSnapshot(); }); @@ -179,7 +179,7 @@ describe('createNumericXAxis', () => { domainNRangeValues: { dStartValue: 0.243, dEndValue: 0.433 }, showRoundOffXTickValues: true, }); - const result = utils.createNumericXAxis(xAxisParams, utils.ChartTypes.VerticalBarChart); + const result = utils.createNumericXAxis(xAxisParams, {}, utils.ChartTypes.VerticalBarChart); matchResult(convertXAxisResultToJson(result)); }); @@ -187,21 +187,27 @@ describe('createNumericXAxis', () => { // Tick padding refers to the space between a tick mark and its corresponding tick label. it('should render the x-axis labels correctly for specific tick size and padding values', () => { const xAxisParams = createXAxisParams({ xAxistickSize: 10, tickPadding: 5 }); - utils.createNumericXAxis(xAxisParams, utils.ChartTypes.VerticalBarChart); + utils.createNumericXAxis(xAxisParams, {}, utils.ChartTypes.VerticalBarChart); expect(xAxisParams.xAxisElement).toMatchSnapshot(); }); it('should create the x-axis labels correctly for a specific number of ticks', () => { const xAxisParams = createXAxisParams({ xAxisCount: 3 }); - const result = utils.createNumericXAxis(xAxisParams, utils.ChartTypes.VerticalBarChart); - matchResult(convertXAxisResultToJson(result, false, xAxisParams.xAxisCount)); + const result = utils.createNumericXAxis(xAxisParams, {}, utils.ChartTypes.VerticalBarChart); + matchResult(convertXAxisResultToJson(result, false)); }); it('should render the x-axis labels correctly for horizontal bar chart with axis', () => { const xAxisParams = createXAxisParams(); - utils.createNumericXAxis(xAxisParams, utils.ChartTypes.HorizontalBarChartWithAxis); + utils.createNumericXAxis(xAxisParams, {}, utils.ChartTypes.HorizontalBarChartWithAxis); expect(xAxisParams.xAxisElement).toMatchSnapshot(); }); + + it('should render fewer x-axis labels when hideTickOverlap is true and container width is small', () => { + const xAxisParams = createXAxisParams({ domainNRangeValues: { rEndValue: 50 }, hideTickOverlap: true }); + const result = utils.createNumericXAxis(xAxisParams, {}, utils.ChartTypes.VerticalBarChart); + matchResult(convertXAxisResultToJson(result)); + }); }); conditionalDescribe(isTimezoneSet(Timezone.UTC) && env === 'TEST')('createDateXAxis', () => { @@ -225,7 +231,7 @@ conditionalDescribe(isTimezoneSet(Timezone.UTC) && env === 'TEST')('createDateXA it('should create the x-axis labels correctly for a specific number of ticks', () => { const xAxisParams = createXAxisParams({ domainNRangeValues, xAxisCount: 12 }); const result = utils.createDateXAxis(xAxisParams, {}); - matchResult(convertXAxisResultToJson(result, false, xAxisParams.xAxisCount)); + matchResult(convertXAxisResultToJson(result, false)); }); it('should create the x-axis labels correctly when customDateTimeFormatter is provided', () => { @@ -264,6 +270,15 @@ conditionalDescribe(isTimezoneSet(Timezone.UTC) && env === 'TEST')('createDateXA }); expect(xAxisParams.xAxisElement).toMatchSnapshot(); }); + + it('should render fewer x-axis labels when hideTickOverlap is true and container width is small', () => { + const xAxisParams = createXAxisParams({ + domainNRangeValues: { ...domainNRangeValues, rEndValue: 50 }, + hideTickOverlap: true, + }); + const result = utils.createDateXAxis(xAxisParams, {}); + matchResult(convertXAxisResultToJson(result)); + }); }); describe('createStringXAxis', () => { @@ -296,6 +311,12 @@ describe('createStringXAxis', () => { const result = utils.createStringXAxis(xAxisParams, {}, dataset); matchResult(convertXAxisResultToJson(result, true)); }); + + it('should render fewer x-axis labels when hideTickOverlap is true and container width is small', () => { + const xAxisParams = createXAxisParams({ containerWidth: 50, hideTickOverlap: true }); + const result = utils.createStringXAxis(xAxisParams, {}, dataset); + matchResult(convertXAxisResultToJson(result, true)); + }); }); describe('prepareDatapoints', () => { @@ -335,6 +356,43 @@ describe('prepareDatapoints', () => { }); }); +describe('prepareDatapoints for rounded tick value cases', () => { + it('should return an array with rounded data points when roundedTicks is true and yMinValue is 0', () => { + const result = utils.prepareDatapoints(100, 0, 3, true, true); + matchResult(result); + }); + + it('should return an array with rounded data points when roundedTicks is true and yMinValue is positive', () => { + const result = utils.prepareDatapoints(100, 50, 4, true, true); + matchResult(result); + }); + + it('should return an array with rounded data points when roundedTicks is true and yMinValue is negative', () => { + const result = utils.prepareDatapoints(100, -100, 4, true, true); + matchResult(result); + }); + + it('should return an array with rounded data points when roundedTicks is true and yMaxValue is negative', () => { + const result = utils.prepareDatapoints(-100, -200, 4, true, true); + matchResult(result); + }); + + it('should return an array with rounded data points with non-integral dataset', () => { + const result = utils.prepareDatapoints(12.8, -8.4, 4, false, true); + matchResult(result); + }); + + it('should return an array with rounded data points with large numbers in dataset', () => { + const result = utils.prepareDatapoints(9874663, -8996557, 4, true, true); + matchResult(result); + }); + + it('should return an array with rounded data points with variation in dataset', () => { + const result = utils.prepareDatapoints(589030.78, -234.45, 4, false, true); + matchResult(result); + }); +}); + const createYAxisParams = (yAxisParams?: Partial): utils.IYAxisParams => { const yAxisElement = document.createElementNS('http://www.w3.org/2000/svg', 'g') as SVGSVGElement; @@ -1182,3 +1240,25 @@ describe('getGradientFromToken', () => { expect(result).toEqual(['invalidTokenWithoutDot', 'invalidTokenWithoutDot']); }); }); + +describe('test array equality utility', () => { + it('both arrays are undefined', () => { + expect(utils.areArraysEqual(undefined, undefined) === true); + }); + + it('second array is undefined', () => { + expect(utils.areArraysEqual(['ac', 'bd'], undefined) === true); + }); + + it('first array is undefined', () => { + expect(utils.areArraysEqual(undefined, ['cg', 'df']) === false); + }); + + it('both arrays are unequal', () => { + expect(utils.areArraysEqual(['ae', 'bf'], ['cg', 'dh']) === false); + }); + + it('both arrays are equal', () => { + expect(utils.areArraysEqual(['ab', 'cd', 'ef', 'gh'], ['ab', 'cd', 'ef', 'gh']) === true); + }); +}); diff --git a/packages/charts/react-charting/src/utilities/__snapshots__/UtilityUnitTests.test.ts.snap b/packages/charts/react-charting/src/utilities/__snapshots__/UtilityUnitTests.test.ts.snap index 6fa3d785f4bac6..01ccde1e32e5f4 100644 --- a/packages/charts/react-charting/src/utilities/__snapshots__/UtilityUnitTests.test.ts.snap +++ b/packages/charts/react-charting/src/utilities/__snapshots__/UtilityUnitTests.test.ts.snap @@ -545,6 +545,23 @@ Array [ ] `; +exports[`createNumericXAxis should render fewer x-axis labels when hideTickOverlap is true and container width is small 1`] = ` +Array [ + Array [ + 0, + "0", + ], + Array [ + 25, + "50", + ], + Array [ + 50, + "100", + ], +] +`; + exports[`createNumericXAxis should render the x-axis labels correctly 1`] = ` { + return v <= 0.04045 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4; +}; + +const rgbLrgb = ({ r, g, b }: { r: number; g: number; b: number }): { r: number; g: number; b: number } => { + return { + r: rgbLrgb1(r / 255), + g: rgbLrgb1(g / 255), + b: rgbLrgb1(b / 255), + }; +}; + +const lrgbLuminance = ({ r, g, b }: { r: number; g: number; b: number }): number => { + return 0.2126 * r + 0.7152 * g + 0.0722 * b; +}; + +export const getColorContrast = (c1: string, c2: string): number => { + const l1 = lrgbLuminance(rgbLrgb(d3Rgb(c1))); + const l2 = lrgbLuminance(rgbLrgb(d3Rgb(c2))); + return (Math.max(l1, l2) + 0.05) / (Math.min(l1, l2) + 0.05); +}; diff --git a/packages/charts/react-charting/src/utilities/utilities.ts b/packages/charts/react-charting/src/utilities/utilities.ts index 76105824f4e9c8..10d42324914d15 100644 --- a/packages/charts/react-charting/src/utilities/utilities.ts +++ b/packages/charts/react-charting/src/utilities/utilities.ts @@ -1,10 +1,11 @@ import { axisRight as d3AxisRight, axisBottom as d3AxisBottom, axisLeft as d3AxisLeft, Axis as D3Axis } from 'd3-axis'; -import { max as d3Max, min as d3Min } from 'd3-array'; +import { max as d3Max, min as d3Min, ticks as d3Ticks, nice as d3nice } from 'd3-array'; import { scaleLinear as d3ScaleLinear, scaleBand as d3ScaleBand, scaleUtc as d3ScaleUtc, scaleTime as d3ScaleTime, + NumberValue, } from 'd3-scale'; import { select as d3Select, selectAll as d3SelectAll } from 'd3-selection'; import { format as d3Format } from 'd3-format'; @@ -126,9 +127,11 @@ export interface IXAxisParams { xAxisOuterPadding?: number; margins: IMargins; containerHeight: number; + containerWidth: number; + hideTickOverlap?: boolean; } export interface ITickParams { - tickValues?: Date[] | number[]; + tickValues?: Date[] | number[] | string[]; tickFormat?: string; } @@ -158,35 +161,59 @@ export interface IYAxisParams { * @export * @param {IXAxisParams} xAxisParams */ -export function createNumericXAxis(xAxisParams: IXAxisParams, chartType: ChartTypes, culture?: string) { +export function createNumericXAxis( + xAxisParams: IXAxisParams, + tickParams: ITickParams, + chartType: ChartTypes, + culture?: string, +) { const { domainNRangeValues, showRoundOffXTickValues = false, xAxistickSize = 6, tickPadding = 10, - xAxisCount = 6, + xAxisCount, xAxisElement, + hideTickOverlap, } = xAxisParams; const xAxisScale = d3ScaleLinear() .domain([domainNRangeValues.dStartValue, domainNRangeValues.dEndValue]) .range([domainNRangeValues.rStartValue, domainNRangeValues.rEndValue]); showRoundOffXTickValues && xAxisScale.nice(); + let tickCount = xAxisCount ?? 6; + const tickFormat = (domainValue: NumberValue, _index: number) => { + if (tickParams.tickFormat) { + return d3Format(tickParams.tickFormat)(domainValue); + } + const xAxisValue = typeof domainValue === 'number' ? domainValue : domainValue.valueOf(); + return convertToLocaleString(xAxisValue, culture) as string; + }; + if (hideTickOverlap && typeof xAxisCount === 'undefined') { + const longestLabelWidth = + calculateLongestLabelWidth(xAxisScale.ticks().map(tickFormat), '[class^="xAxis-"] text') + 20; + const [start, end] = xAxisScale.range(); + tickCount = Math.max(1, Math.floor(Math.abs(end - start) / longestLabelWidth)); + } + const xAxis = d3AxisBottom(xAxisScale) .tickSize(xAxistickSize) .tickPadding(tickPadding) - .ticks(xAxisCount) - .tickFormat((domainValue, index) => { - const xAxisValue = typeof domainValue === 'number' ? domainValue : domainValue.valueOf(); - return convertToLocaleString(xAxisValue, culture) as string; - }); + .ticks(tickCount) + .tickFormat(tickFormat); if (chartType === ChartTypes.HorizontalBarChartWithAxis) { xAxis.tickSizeInner(-(xAxisParams.containerHeight - xAxisParams.margins.top!)); } + if (tickParams.tickValues) { + xAxis.tickValues(tickParams.tickValues as number[]); + } + if (xAxisElement) { d3Select(xAxisElement).call(xAxis).selectAll('text').attr('aria-hidden', 'true'); } - const tickValues = xAxisScale.ticks(xAxisCount).map(xAxis.tickFormat()!); + const tickValues = ((tickParams.tickValues as number[] | undefined) ?? xAxisScale.ticks(tickCount)).map( + xAxis.tickFormat()!, + ); return { xScale: xAxisScale, tickValues }; } @@ -244,42 +271,60 @@ export function createDateXAxis( customDateTimeFormatter?: (dateTime: Date) => string, useUTC?: boolean, ) { - const { domainNRangeValues, xAxisElement, tickPadding = 6, xAxistickSize = 6, xAxisCount = 6 } = xAxisParams; + const { + domainNRangeValues, + xAxisElement, + tickPadding = 6, + xAxistickSize = 6, + xAxisCount, + hideTickOverlap, + } = xAxisParams; const xAxisScale = useUTC ? d3ScaleUtc() : d3ScaleTime(); xAxisScale .domain([domainNRangeValues.dStartValue, domainNRangeValues.dEndValue]) .range([domainNRangeValues.rStartValue, domainNRangeValues.rEndValue]); - const xAxis = d3AxisBottom(xAxisScale).tickSize(xAxistickSize).tickPadding(tickPadding).ticks(xAxisCount); - if (customDateTimeFormatter) { - xAxis.tickFormat((domainValue: Date, _index: number) => { + + let tickCount = xAxisCount ?? 6; + const tickFormat = (domainValue: Date, _index: number) => { + if (customDateTimeFormatter) { return customDateTimeFormatter(domainValue); - }); - } else if (culture && options) { - xAxis.tickFormat((domainValue: Date, _index: number) => { + } + if (culture && options) { return domainValue.toLocaleString(culture, options); - }); - } else if (timeFormatLocale) { - const locale: d3TimeLocaleObject = d3TimeFormatLocale(timeFormatLocale!); - - xAxis.tickFormat((domainValue: Date, _index: number) => { + } + if (timeFormatLocale) { + const locale: d3TimeLocaleObject = d3TimeFormatLocale(timeFormatLocale!); return multiFormat(domainValue, locale, useUTC); - }); + } + if (culture === undefined && tickParams.tickFormat) { + if (useUTC) { + return d3UtcFormat(tickParams.tickFormat)(domainValue); + } else { + return d3TimeFormat(tickParams.tickFormat)(domainValue); + } + } + return multiFormat(domainValue, undefined, useUTC); + }; + if (hideTickOverlap && typeof xAxisCount === 'undefined') { + const longestLabelWidth = + calculateLongestLabelWidth(xAxisScale.ticks().map(tickFormat), '[class^="xAxis-"] text') + 40; + const [start, end] = xAxisScale.range(); + tickCount = Math.max(1, Math.floor(Math.abs(end - start) / longestLabelWidth)); } - tickParams.tickValues ? xAxis.tickValues(tickParams.tickValues) : ''; - if (culture === undefined) { - tickParams.tickFormat - ? xAxis.tickFormat(useUTC ? d3UtcFormat(tickParams.tickFormat) : d3TimeFormat(tickParams.tickFormat)) - : ''; - } + const xAxis = d3AxisBottom(xAxisScale) + .tickSize(xAxistickSize) + .tickPadding(tickPadding) + .ticks(tickCount) + .tickFormat(tickFormat); + + tickParams.tickValues ? xAxis.tickValues(tickParams.tickValues as Date[]) : ''; if (xAxisElement) { d3Select(xAxisElement).call(xAxis).selectAll('text').attr('aria-hidden', 'true'); } - const tickValues = (tickParams.tickValues ?? xAxisScale.ticks(xAxisCount)).map((val, idx) => { - const tickFormat = xAxis.tickFormat(); - // val is a Date object. So when the tick format is not set, format val as a string to calculate its width - return tickFormat ? tickFormat(val, idx) : multiFormat(val as Date, undefined, useUTC); - }); + const tickValues = ((tickParams.tickValues as Date[] | undefined) ?? xAxisScale.ticks(tickCount)).map( + xAxis.tickFormat()!, + ); return { xScale: xAxisScale, tickValues }; } @@ -300,33 +345,73 @@ export function createStringXAxis( ) { const { domainNRangeValues, - xAxisCount = 6, xAxistickSize = 6, tickPadding = 10, xAxisPadding = 0.1, xAxisInnerPadding, xAxisOuterPadding, + containerWidth, + hideTickOverlap, } = xAxisParams; const xAxisScale = d3ScaleBand() .domain(dataset!) .range([domainNRangeValues.rStartValue, domainNRangeValues.rEndValue]) .paddingInner(typeof xAxisInnerPadding !== 'undefined' ? xAxisInnerPadding : xAxisPadding) .paddingOuter(typeof xAxisOuterPadding !== 'undefined' ? xAxisOuterPadding : xAxisPadding); - const xAxis = d3AxisBottom(xAxisScale) - .tickSize(xAxistickSize) - .tickPadding(tickPadding) - .ticks(xAxisCount) - .tickFormat((x: string, index: number) => { - return convertToLocaleString(dataset[index], culture) as string; - }); + + let tickValues = (tickParams.tickValues as string[] | undefined) ?? dataset; + if (hideTickOverlap) { + let nonOverlappingTickValues = []; + // Here, we need the width of each individual label to detect overlaps, + // but calculateLongestLabelWidth returns the maximum pixel width from an array of labels. + // So call this function separately for each label, instead of the entire array. + const tickSizes = tickValues.map(value => calculateLongestLabelWidth([value], '[class^="xAxis-"] text')); + // for LTR + let start = 0; + let end = containerWidth; + let sign = 1; + const range = xAxisScale.range(); + if (range[1] - range[0] < 0) { + // for RTL + start = containerWidth; + end = 0; + sign = -1; + } + for (let i = tickValues.length - 1; i >= 0; i--) { + const tickPosition = xAxisScale(tickValues[i])!; + if ( + sign * (tickPosition - (sign * tickSizes[i]) / 2 - start) >= 0 && + sign * (tickPosition + (sign * tickSizes[i]) / 2 - end) <= 0 + ) { + nonOverlappingTickValues.push(tickValues[i]); + end = tickPosition - sign * (tickSizes[i] / 2 + 10); + } + } + nonOverlappingTickValues = nonOverlappingTickValues.reverse(); + tickValues = nonOverlappingTickValues; + } + + const xAxis = d3AxisBottom(xAxisScale).tickSize(xAxistickSize).tickPadding(tickPadding).tickValues(tickValues); if (xAxisParams.xAxisElement) { d3Select(xAxisParams.xAxisElement).call(xAxis).selectAll('text').attr('aria-hidden', 'true'); } - const tickValues = dataset.map(xAxis.tickFormat()!); return { xScale: xAxisScale, tickValues }; } +/** + * This method is used to calculate the rounded tick values for the y-axis + * @param {number} minVal + * @param {number} maxVal + * @param {number} splitInto + * @returns {number[]} + */ +function calculateRoundedTicks(minVal: number, maxVal: number, splitInto: number) { + const finalYmin = minVal >= 0 && minVal === maxVal ? 0 : minVal; + const finalYmax = minVal < 0 && minVal === maxVal ? 0 : maxVal; + const ticksInterval = d3nice(finalYmin, finalYmax, splitInto); + return d3Ticks(ticksInterval[0], ticksInterval[ticksInterval.length - 1], splitInto); +} /** * This method used for creating data points for the y axis. * @export @@ -341,7 +426,11 @@ export function prepareDatapoints( minVal: number, splitInto: number, isIntegralDataset: boolean, + roundedTicks?: boolean, ): number[] { + if (roundedTicks) { + return calculateRoundedTicks(minVal, maxVal, splitInto); + } const val = isIntegralDataset ? Math.ceil((maxVal - minVal) / splitInto) : (maxVal - minVal) / splitInto >= 1 @@ -409,6 +498,7 @@ export function createNumericYAxis( isIntegralDataset: boolean, useSecondaryYScale: boolean = false, supportNegativeData: boolean = false, + roundedTicks: boolean = false, ) { const { yMinMaxValues = { startValue: 0, endValue: 0 }, @@ -434,7 +524,7 @@ export function createNumericYAxis( : yMinMaxValues.startValue < yMinValue ? 0 : yMinValue!; - const domainValues = prepareDatapoints(finalYmax, finalYmin, yAxisTickCount, isIntegralDataset); + const domainValues = prepareDatapoints(finalYmax, finalYmin, yAxisTickCount, isIntegralDataset, roundedTicks); const yAxisScale = d3ScaleLinear() .domain([supportNegativeData ? domainValues[0] : finalYmin, domainValues[domainValues.length - 1]]) .range([containerHeight - margins.bottom!, margins.top! + (eventAnnotationProps! ? eventLabelHeight! : 0)]); @@ -1415,3 +1505,30 @@ export function getSecureProps(props: Record = {}): Record { + return containerStyles.getPropertyValue(group1); + }); +} diff --git a/packages/charts/react-charts-preview/library/CHANGELOG.json b/packages/charts/react-charts-preview/library/CHANGELOG.json index 53f61074c0760d..7675e0d9cd71e1 100644 --- a/packages/charts/react-charts-preview/library/CHANGELOG.json +++ b/packages/charts/react-charts-preview/library/CHANGELOG.json @@ -1,6 +1,324 @@ { "name": "@fluentui/react-charts-preview", "entries": [ + { + "date": "Fri, 21 Feb 2025 14:34:05 GMT", + "tag": "@fluentui/react-charts-preview_v0.2.0", + "version": "0.2.0", + "comments": { + "minor": [ + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-button to v9.4.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-overflow to v9.3.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-popover to v9.10.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-tabster to v9.24.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-tooltip to v9.6.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + } + ] + } + }, + { + "date": "Tue, 18 Feb 2025 11:26:27 GMT", + "tag": "@fluentui/react-charts-preview_v0.1.10", + "version": "0.1.10", + "comments": { + "none": [ + { + "author": "martinhochel@microsoft.com", + "package": "@fluentui/react-charts-preview", + "commit": "5b5091795bd462fe78f1545fd91b21ef6510a45d", + "comment": "chore: add new 'charting' domain tag" + } + ] + } + }, + { + "date": "Fri, 07 Feb 2025 10:42:12 GMT", + "tag": "@fluentui/react-charts-preview_v0.1.10", + "version": "0.1.10", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-button to v9.3.102", + "commit": "b37554b631f4e27e0927b123732f3d57d62660a3" + } + ] + } + }, + { + "date": "Tue, 28 Jan 2025 21:26:35 GMT", + "tag": "@fluentui/react-charts-preview_v0.1.9", + "version": "0.1.9", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-button to v9.3.101", + "commit": "a081a7573fa328d640c2efb0127f2be99a1368f8" + } + ] + } + }, + { + "date": "Mon, 27 Jan 2025 20:27:35 GMT", + "tag": "@fluentui/react-charts-preview_v0.1.8", + "version": "0.1.8", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-overflow to v9.2.8", + "commit": "808cd501d50a317249d3d02f01ea3dd88114b252" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-popover to v9.9.32", + "commit": "808cd501d50a317249d3d02f01ea3dd88114b252" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-tooltip to v9.5.5", + "commit": "808cd501d50a317249d3d02f01ea3dd88114b252" + } + ] + } + }, + { + "date": "Wed, 22 Jan 2025 14:00:21 GMT", + "tag": "@fluentui/react-charts-preview_v0.1.7", + "version": "0.1.7", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-button to v9.3.100", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.50", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-overflow to v9.2.7", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-popover to v9.9.31", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-tabster to v9.23.3", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-tooltip to v9.5.4", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-utilities to v9.18.20", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + } + ] + } + }, + { + "date": "Wed, 08 Jan 2025 18:33:36 GMT", + "tag": "@fluentui/react-charts-preview_v0.1.6", + "version": "0.1.6", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-button to v9.3.99", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.49", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-overflow to v9.2.6", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-popover to v9.9.30", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-tooltip to v9.5.3", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + } + ] + } + }, + { + "date": "Wed, 18 Dec 2024 10:59:37 GMT", + "tag": "@fluentui/react-charts-preview_v0.1.5", + "version": "0.1.5", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-overflow to v9.2.5", + "commit": "54afa8c6ce8f7d200d5241584801899b27baaf1b" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-popover to v9.9.29", + "commit": "54afa8c6ce8f7d200d5241584801899b27baaf1b" + } + ] + } + }, + { + "date": "Mon, 16 Dec 2024 16:26:49 GMT", + "tag": "@fluentui/react-charts-preview_v0.1.4", + "version": "0.1.4", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-button to v9.3.98", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.48", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-overflow to v9.2.4", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-popover to v9.9.28", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-shared-contexts to v9.21.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-tabster to v9.23.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-theme to v9.1.24", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-tooltip to v9.5.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-utilities to v9.18.19", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + } + ] + } + }, + { + "date": "Mon, 09 Dec 2024 17:38:16 GMT", + "tag": "@fluentui/react-charts-preview_v0.1.3", + "version": "0.1.3", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-button to v9.3.97", + "commit": "80f2ce07be06e66b369bd18e4484d8faf6b493c7" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-overflow to v9.2.3", + "commit": "80f2ce07be06e66b369bd18e4484d8faf6b493c7" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-popover to v9.9.27", + "commit": "80f2ce07be06e66b369bd18e4484d8faf6b493c7" + }, + { + "author": "beachball", + "package": "@fluentui/react-charts-preview", + "comment": "Bump @fluentui/react-tooltip to v9.5.1", + "commit": "80f2ce07be06e66b369bd18e4484d8faf6b493c7" + } + ] + } + }, { "date": "Fri, 06 Dec 2024 12:53:38 GMT", "tag": "@fluentui/react-charts-preview_v0.1.2", diff --git a/packages/charts/react-charts-preview/library/CHANGELOG.md b/packages/charts/react-charts-preview/library/CHANGELOG.md index 8a3b5cd6cd7ca1..c12795478641c4 100644 --- a/packages/charts/react-charts-preview/library/CHANGELOG.md +++ b/packages/charts/react-charts-preview/library/CHANGELOG.md @@ -1,9 +1,118 @@ # Change Log - @fluentui/react-charts-preview -This log was last generated on Fri, 06 Dec 2024 12:53:38 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 14:34:05 GMT and should not be manually modified. +## [0.2.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-charts-preview_v0.2.0) + +Fri, 21 Feb 2025 14:34:05 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charts-preview_v0.1.10..@fluentui/react-charts-preview_v0.2.0) + +### Minor changes + +- Bump @fluentui/react-button to v9.4.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) +- Bump @fluentui/react-overflow to v9.3.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) +- Bump @fluentui/react-popover to v9.10.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) +- Bump @fluentui/react-tabster to v9.24.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) +- Bump @fluentui/react-tooltip to v9.6.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) + +## [0.1.10](https://github.com/microsoft/fluentui/tree/@fluentui/react-charts-preview_v0.1.10) + +Fri, 07 Feb 2025 10:42:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charts-preview_v0.1.9..@fluentui/react-charts-preview_v0.1.10) + +### Patches + +- Bump @fluentui/react-button to v9.3.102 ([PR #33797](https://github.com/microsoft/fluentui/pull/33797) by beachball) + +## [0.1.9](https://github.com/microsoft/fluentui/tree/@fluentui/react-charts-preview_v0.1.9) + +Tue, 28 Jan 2025 21:26:35 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charts-preview_v0.1.8..@fluentui/react-charts-preview_v0.1.9) + +### Patches + +- Bump @fluentui/react-button to v9.3.101 ([PR #33736](https://github.com/microsoft/fluentui/pull/33736) by beachball) + +## [0.1.8](https://github.com/microsoft/fluentui/tree/@fluentui/react-charts-preview_v0.1.8) + +Mon, 27 Jan 2025 20:27:35 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charts-preview_v0.1.7..@fluentui/react-charts-preview_v0.1.8) + +### Patches + +- Bump @fluentui/react-overflow to v9.2.8 ([PR #33724](https://github.com/microsoft/fluentui/pull/33724) by beachball) +- Bump @fluentui/react-popover to v9.9.32 ([PR #33724](https://github.com/microsoft/fluentui/pull/33724) by beachball) +- Bump @fluentui/react-tooltip to v9.5.5 ([PR #33724](https://github.com/microsoft/fluentui/pull/33724) by beachball) + +## [0.1.7](https://github.com/microsoft/fluentui/tree/@fluentui/react-charts-preview_v0.1.7) + +Wed, 22 Jan 2025 14:00:21 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charts-preview_v0.1.6..@fluentui/react-charts-preview_v0.1.7) + +### Patches + +- Bump @fluentui/react-button to v9.3.100 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.50 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-overflow to v9.2.7 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-popover to v9.9.31 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-tabster to v9.23.3 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-tooltip to v9.5.4 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-utilities to v9.18.20 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) + +## [0.1.6](https://github.com/microsoft/fluentui/tree/@fluentui/react-charts-preview_v0.1.6) + +Wed, 08 Jan 2025 18:33:36 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charts-preview_v0.1.5..@fluentui/react-charts-preview_v0.1.6) + +### Patches + +- Bump @fluentui/react-button to v9.3.99 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.49 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-overflow to v9.2.6 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-popover to v9.9.30 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-tooltip to v9.5.3 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) + +## [0.1.5](https://github.com/microsoft/fluentui/tree/@fluentui/react-charts-preview_v0.1.5) + +Wed, 18 Dec 2024 10:59:37 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charts-preview_v0.1.4..@fluentui/react-charts-preview_v0.1.5) + +### Patches + +- Bump @fluentui/react-overflow to v9.2.5 ([PR #33483](https://github.com/microsoft/fluentui/pull/33483) by beachball) +- Bump @fluentui/react-popover to v9.9.29 ([PR #33483](https://github.com/microsoft/fluentui/pull/33483) by beachball) + +## [0.1.4](https://github.com/microsoft/fluentui/tree/@fluentui/react-charts-preview_v0.1.4) + +Mon, 16 Dec 2024 16:26:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charts-preview_v0.1.3..@fluentui/react-charts-preview_v0.1.4) + +### Patches + +- Bump @fluentui/react-button to v9.3.98 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.48 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-overflow to v9.2.4 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-popover to v9.9.28 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-shared-contexts to v9.21.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-tabster to v9.23.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-theme to v9.1.24 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-tooltip to v9.5.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-utilities to v9.18.19 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) + +## [0.1.3](https://github.com/microsoft/fluentui/tree/@fluentui/react-charts-preview_v0.1.3) + +Mon, 09 Dec 2024 17:38:16 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-charts-preview_v0.1.2..@fluentui/react-charts-preview_v0.1.3) + +### Patches + +- Bump @fluentui/react-button to v9.3.97 ([PR #33431](https://github.com/microsoft/fluentui/pull/33431) by beachball) +- Bump @fluentui/react-overflow to v9.2.3 ([PR #33431](https://github.com/microsoft/fluentui/pull/33431) by beachball) +- Bump @fluentui/react-popover to v9.9.27 ([PR #33431](https://github.com/microsoft/fluentui/pull/33431) by beachball) +- Bump @fluentui/react-tooltip to v9.5.1 ([PR #33431](https://github.com/microsoft/fluentui/pull/33431) by beachball) + ## [0.1.2](https://github.com/microsoft/fluentui/tree/@fluentui/react-charts-preview_v0.1.2) Fri, 06 Dec 2024 12:53:38 GMT diff --git a/packages/charts/react-charts-preview/library/package.json b/packages/charts/react-charts-preview/library/package.json index 15e67212082bf3..f58e629c86c008 100644 --- a/packages/charts/react-charts-preview/library/package.json +++ b/packages/charts/react-charts-preview/library/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-charts-preview", - "version": "0.1.2", + "version": "0.2.0", "description": "React web chart controls for Microsoft fluentui v9 system.", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -38,15 +38,15 @@ "@fluentui/scripts-tasks": "*" }, "dependencies": { - "@fluentui/react-button": "^9.3.96", - "@fluentui/react-jsx-runtime": "^9.0.47", - "@fluentui/react-overflow": "^9.2.2", - "@fluentui/react-popover": "^9.9.26", - "@fluentui/react-shared-contexts": "^9.21.1", - "@fluentui/react-tabster": "^9.23.1", - "@fluentui/react-theme": "^9.1.23", - "@fluentui/react-tooltip": "^9.5.0", - "@fluentui/react-utilities": "^9.18.18", + "@fluentui/react-button": "^9.4.0", + "@fluentui/react-jsx-runtime": "^9.0.50", + "@fluentui/react-overflow": "^9.3.0", + "@fluentui/react-popover": "^9.10.0", + "@fluentui/react-shared-contexts": "^9.21.2", + "@fluentui/react-tabster": "^9.24.0", + "@fluentui/react-theme": "^9.1.24", + "@fluentui/react-tooltip": "^9.6.0", + "@fluentui/react-utilities": "^9.18.20", "@griffel/react": "^1.5.22", "@swc/helpers": "^0.5.1", "@types/d3-array": "^3.0.0", diff --git a/packages/charts/react-charts-preview/library/project.json b/packages/charts/react-charts-preview/library/project.json index e6396947463a4e..ebfc6ffe4f8074 100644 --- a/packages/charts/react-charts-preview/library/project.json +++ b/packages/charts/react-charts-preview/library/project.json @@ -3,6 +3,6 @@ "$schema": "../../../../node_modules/nx/schemas/project-schema.json", "projectType": "library", "sourceRoot": "packages/charts/react-charts-preview/library/src", - "tags": ["platform:web", "vNext"], + "tags": ["platform:web", "vNext", "charting"], "implicitDependencies": [] } diff --git a/packages/charts/react-charts-preview/stories/project.json b/packages/charts/react-charts-preview/stories/project.json index 52acb2c42b81d4..269944482f12c7 100644 --- a/packages/charts/react-charts-preview/stories/project.json +++ b/packages/charts/react-charts-preview/stories/project.json @@ -3,6 +3,6 @@ "$schema": "../../../../node_modules/nx/schemas/project-schema.json", "projectType": "library", "sourceRoot": "packages/react-charts-preview/stories/src", - "tags": ["vNext", "platform:web", "type:stories"], + "tags": ["vNext", "platform:web", "type:stories", "charting"], "implicitDependencies": [] } 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 909e250cea9cd3..9b2d21d8a738fb 100644 --- a/packages/codemods/CHANGELOG.json +++ b/packages/codemods/CHANGELOG.json @@ -1,6 +1,36 @@ { "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", + "version": "8.4.27", + "comments": { + "patch": [ + { + "author": "olfedias@microsoft.com", + "package": "@fluentui/codemods", + "commit": "dc7bb663e3d93a19b611cf1892556d69c57b1269", + "comment": "chore: remove usage of \"export *\"" + } + ] + } + }, { "date": "Thu, 11 Jul 2024 07:33:36 GMT", "tag": "@fluentui/codemods_v8.4.26", diff --git a/packages/codemods/CHANGELOG.md b/packages/codemods/CHANGELOG.md index 4a1409ea50e398..6548074ea7a59f 100644 --- a/packages/codemods/CHANGELOG.md +++ b/packages/codemods/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/codemods -This log was last generated on Tue, 09 Jul 2024 07:36:39 GMT and should not be manually modified. +This log was last generated on Mon, 23 Dec 2024 07:22:57 GMT and should not be manually modified. +## [8.4.27](https://github.com/microsoft/fluentui/tree/@fluentui/codemods_v8.4.27) + +Mon, 23 Dec 2024 07:22:57 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/codemods_v8.4.26..@fluentui/codemods_v8.4.27) + +### Patches + +- chore: remove usage of "export *" ([PR #33448](https://github.com/microsoft/fluentui/pull/33448) by olfedias@microsoft.com) + ## [8.4.26](https://github.com/microsoft/fluentui/tree/@fluentui/codemods_v8.4.26) Tue, 09 Jul 2024 07:36:39 GMT diff --git a/packages/codemods/package.json b/packages/codemods/package.json index 1db4b8f33dea6d..27f6a4cb2f7ab5 100644 --- a/packages/codemods/package.json +++ b/packages/codemods/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/codemods", - "version": "8.4.26", + "version": "8.4.27", "description": "Tool enabling easy upgrades to new Fluent UI versions", "main": "lib-commonjs/index.js", "typings": "lib-commonjs/index.d.ts", diff --git a/packages/codemods/src/codeMods/tests/mock/compat/mockIndex.ts b/packages/codemods/src/codeMods/tests/mock/compat/mockIndex.ts index 2b56b163693673..69ff37c638f1bf 100644 --- a/packages/codemods/src/codeMods/tests/mock/compat/mockIndex.ts +++ b/packages/codemods/src/codeMods/tests/mock/compat/mockIndex.ts @@ -1,2 +1,2 @@ -export * from './Button'; -export * from './DefaultButton'; +export { Button, OtherButton } from './Button'; +export { DefaultButton } from './DefaultButton'; 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/codemods/src/codeMods/utilities/index.ts b/packages/codemods/src/codeMods/utilities/index.ts index 95a9bb3bbafac1..aaf4eede1810ad 100644 --- a/packages/codemods/src/codeMods/utilities/index.ts +++ b/packages/codemods/src/codeMods/utilities/index.ts @@ -1,4 +1,4 @@ -export * from './jsx'; -export * from './imports'; -export * from './props'; -export * from './transforms'; +export { findJsxTag } from './jsx'; +export { appendOrCreateNamedImport, getImportsByPath, renameImport, repathImport } from './imports'; +export { renameProp } from './props'; +export { boolTransform, enumTransform, numberTransform, stringTransform } from './transforms'; diff --git a/packages/common-styles/package.json b/packages/common-styles/package.json index c80c5e6739edfc..247168e81dbff9 100644 --- a/packages/common-styles/package.json +++ b/packages/common-styles/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/common-styles", - "version": "1.2.63", + "version": "1.2.66", "description": "Common style definitions for Fluent UI React components", "repository": { "type": "git", diff --git a/packages/cra-template/package.json b/packages/cra-template/package.json index 4e72a27e0ea09a..d4e9636fb91238 100644 --- a/packages/cra-template/package.json +++ b/packages/cra-template/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/cra-template", - "version": "8.4.189", + "version": "8.4.201", "description": "Create React App template for Fluent UI React (@fluentui/react)", "repository": { "type": "git", diff --git a/packages/date-time-utilities/CHANGELOG.json b/packages/date-time-utilities/CHANGELOG.json index 30141825b6fbee..8ec9b0aa57d93b 100644 --- a/packages/date-time-utilities/CHANGELOG.json +++ b/packages/date-time-utilities/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/date-time-utilities", "entries": [ + { + "date": "Fri, 21 Feb 2025 07:22:41 GMT", + "tag": "@fluentui/date-time-utilities_v8.6.10", + "version": "8.6.10", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/date-time-utilities", + "comment": "Bump @fluentui/set-version to v8.2.24", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + } + ] + } + }, { "date": "Thu, 11 Jul 2024 07:33:37 GMT", "tag": "@fluentui/date-time-utilities_v8.6.9", diff --git a/packages/date-time-utilities/CHANGELOG.md b/packages/date-time-utilities/CHANGELOG.md index 070de8494ece05..dabd6e1557d641 100644 --- a/packages/date-time-utilities/CHANGELOG.md +++ b/packages/date-time-utilities/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/date-time-utilities -This log was last generated on Mon, 24 Jun 2024 07:33:22 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 07:22:41 GMT and should not be manually modified. +## [8.6.10](https://github.com/microsoft/fluentui/tree/@fluentui/date-time-utilities_v8.6.10) + +Fri, 21 Feb 2025 07:22:41 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/date-time-utilities_v8.6.9..@fluentui/date-time-utilities_v8.6.10) + +### Patches + +- Bump @fluentui/set-version to v8.2.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) + ## [8.6.9](https://github.com/microsoft/fluentui/tree/@fluentui/date-time-utilities_v8.6.9) Mon, 24 Jun 2024 07:33:22 GMT diff --git a/packages/date-time-utilities/package.json b/packages/date-time-utilities/package.json index 1a0eb4de56dd1e..704a924e09a17d 100644 --- a/packages/date-time-utilities/package.json +++ b/packages/date-time-utilities/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/date-time-utilities", - "version": "8.6.9", + "version": "8.6.10", "description": "Date-time utilities", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -29,7 +29,7 @@ "@fluentui/scripts-tasks": "*" }, "dependencies": { - "@fluentui/set-version": "^8.2.23", + "@fluentui/set-version": "^8.2.24", "tslib": "^2.1.0" }, "exports": { diff --git a/packages/dom-utilities/CHANGELOG.json b/packages/dom-utilities/CHANGELOG.json index 82d4d8584760f6..3b242b4e965f16 100644 --- a/packages/dom-utilities/CHANGELOG.json +++ b/packages/dom-utilities/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/dom-utilities", "entries": [ + { + "date": "Fri, 21 Feb 2025 07:22:41 GMT", + "tag": "@fluentui/dom-utilities_v2.3.10", + "version": "2.3.10", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/dom-utilities", + "comment": "Bump @fluentui/set-version to v8.2.24", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + } + ] + } + }, { "date": "Fri, 11 Oct 2024 16:51:53 GMT", "tag": "@fluentui/dom-utilities_v2.3.9", diff --git a/packages/dom-utilities/CHANGELOG.md b/packages/dom-utilities/CHANGELOG.md index aeafb045c68aa6..8a97a46b11c5e5 100644 --- a/packages/dom-utilities/CHANGELOG.md +++ b/packages/dom-utilities/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/dom-utilities -This log was last generated on Fri, 11 Oct 2024 16:51:53 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 07:22:41 GMT and should not be manually modified. +## [2.3.10](https://github.com/microsoft/fluentui/tree/@fluentui/dom-utilities_v2.3.10) + +Fri, 21 Feb 2025 07:22:41 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/dom-utilities_v2.3.9..@fluentui/dom-utilities_v2.3.10) + +### Patches + +- Bump @fluentui/set-version to v8.2.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) + ## [2.3.9](https://github.com/microsoft/fluentui/tree/@fluentui/dom-utilities_v2.3.9) Fri, 11 Oct 2024 16:51:53 GMT diff --git a/packages/dom-utilities/package.json b/packages/dom-utilities/package.json index e4725fafcf0a8c..f09cc1663e7bba 100644 --- a/packages/dom-utilities/package.json +++ b/packages/dom-utilities/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/dom-utilities", - "version": "2.3.9", + "version": "2.3.10", "description": "DOM utilities for use within Fluent web components", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -29,7 +29,7 @@ "@fluentui/scripts-tasks": "*" }, "dependencies": { - "@fluentui/set-version": "^8.2.23", + "@fluentui/set-version": "^8.2.24", "tslib": "^2.1.0" }, "exports": { 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/base.js b/packages/eslint-plugin/src/configs/base.js index 2423f8a7b8b882..cab360135da702 100644 --- a/packages/eslint-plugin/src/configs/base.js +++ b/packages/eslint-plugin/src/configs/base.js @@ -19,10 +19,9 @@ module.exports = { }, overrides: [ { - files: '**/src/index.{ts,tsx,js}', + files: '**/src/**/*.{ts,tsx,js}', rules: { - // TODO: propagate to `error` once all packages barrel files have been fixed - '@rnx-kit/no-export-all': ['warn', { expand: 'all' }], + '@rnx-kit/no-export-all': ['error', { expand: 'all' }], }, }, ], 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 b6a5fda7b34a2c..e2437ae96629a1 100644 --- a/packages/fluent2-theme/CHANGELOG.json +++ b/packages/fluent2-theme/CHANGELOG.json @@ -1,6 +1,192 @@ { "name": "@fluentui/fluent2-theme", "entries": [ + { + "date": "Fri, 21 Feb 2025 07:22:41 GMT", + "tag": "@fluentui/fluent2-theme_v8.107.128", + "version": "8.107.128", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/fluent2-theme", + "comment": "Bump @fluentui/react to v8.122.11", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/fluent2-theme", + "comment": "Bump @fluentui/set-version to v8.2.24", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + } + ] + } + }, + { + "date": "Wed, 19 Feb 2025 07:21:16 GMT", + "tag": "@fluentui/fluent2-theme_v8.107.127", + "version": "8.107.127", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/fluent2-theme", + "comment": "Bump @fluentui/react to v8.122.10", + "commit": "8264ce0435583ae69c051f109388005be3c0de2b" + } + ] + } + }, + { + "date": "Wed, 29 Jan 2025 07:21:15 GMT", + "tag": "@fluentui/fluent2-theme_v8.107.126", + "version": "8.107.126", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/fluent2-theme", + "comment": "Bump @fluentui/react to v8.122.9", + "commit": "111bf937b3793db68e32a90774b04f3bf61f4be5" + } + ] + } + }, + { + "date": "Wed, 22 Jan 2025 07:21:49 GMT", + "tag": "@fluentui/fluent2-theme_v8.107.125", + "version": "8.107.125", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/fluent2-theme", + "comment": "Bump @fluentui/react to v8.122.8", + "commit": "012298d98651800023aac24c591831e9bc51bea2" + } + ] + } + }, + { + "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", + "version": "8.107.123", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/fluent2-theme", + "comment": "Bump @fluentui/react to v8.122.6", + "commit": "bf60a56cb23b3af90bcb62462c2423468eb9fa3c" + } + ] + } + }, + { + "date": "Wed, 08 Jan 2025 07:21:37 GMT", + "tag": "@fluentui/fluent2-theme_v8.107.122", + "version": "8.107.122", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/fluent2-theme", + "comment": "Bump @fluentui/react to v8.122.5", + "commit": "8f763922d713d9ccd35e65db07206c10b170fafd" + } + ] + } + }, + { + "date": "Fri, 03 Jan 2025 07:21:32 GMT", + "tag": "@fluentui/fluent2-theme_v8.107.121", + "version": "8.107.121", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/fluent2-theme", + "comment": "Bump @fluentui/react to v8.122.4", + "commit": "7bb97f178d73a470dc438a2b19d165d9d0bd4b51" + } + ] + } + }, + { + "date": "Mon, 30 Dec 2024 07:21:29 GMT", + "tag": "@fluentui/fluent2-theme_v8.107.120", + "version": "8.107.120", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/fluent2-theme", + "comment": "Bump @fluentui/react to v8.122.3", + "commit": "681a95a732fe385a70b8d4537dc489acbcd1c21e" + } + ] + } + }, + { + "date": "Mon, 23 Dec 2024 07:22:58 GMT", + "tag": "@fluentui/fluent2-theme_v8.107.119", + "version": "8.107.119", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/fluent2-theme", + "comment": "Bump @fluentui/react to v8.122.2", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + } + ] + } + }, + { + "date": "Fri, 13 Dec 2024 07:23:12 GMT", + "tag": "@fluentui/fluent2-theme_v8.107.118", + "version": "8.107.118", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/fluent2-theme", + "comment": "Bump @fluentui/react to v8.122.1", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7" + } + ] + } + }, + { + "date": "Thu, 12 Dec 2024 07:22:33 GMT", + "tag": "@fluentui/fluent2-theme_v8.107.117", + "version": "8.107.117", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/fluent2-theme", + "comment": "Bump @fluentui/react to v8.122.0", + "commit": "53dd771e70338065810404663cd6219d1b54c1e2" + } + ] + } + }, { "date": "Fri, 22 Nov 2024 07:21:18 GMT", "tag": "@fluentui/fluent2-theme_v8.107.116", diff --git a/packages/fluent2-theme/CHANGELOG.md b/packages/fluent2-theme/CHANGELOG.md index 21168ef63f2106..66c4c6dea9d64d 100644 --- a/packages/fluent2-theme/CHANGELOG.md +++ b/packages/fluent2-theme/CHANGELOG.md @@ -1,9 +1,118 @@ # Change Log - @fluentui/fluent2-theme -This log was last generated on Fri, 22 Nov 2024 07:21:18 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 07:22:41 GMT and should not be manually modified. +## [8.107.128](https://github.com/microsoft/fluentui/tree/@fluentui/fluent2-theme_v8.107.128) + +Fri, 21 Feb 2025 07:22:41 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/fluent2-theme_v8.107.127..@fluentui/fluent2-theme_v8.107.128) + +### Patches + +- Bump @fluentui/react to v8.122.11 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/set-version to v8.2.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) + +## [8.107.127](https://github.com/microsoft/fluentui/tree/@fluentui/fluent2-theme_v8.107.127) + +Wed, 19 Feb 2025 07:21:16 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/fluent2-theme_v8.107.126..@fluentui/fluent2-theme_v8.107.127) + +### Patches + +- Bump @fluentui/react to v8.122.10 ([PR #33867](https://github.com/microsoft/fluentui/pull/33867) by beachball) + +## [8.107.126](https://github.com/microsoft/fluentui/tree/@fluentui/fluent2-theme_v8.107.126) + +Wed, 29 Jan 2025 07:21:15 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/fluent2-theme_v8.107.125..@fluentui/fluent2-theme_v8.107.126) + +### Patches + +- Bump @fluentui/react to v8.122.9 ([PR #33713](https://github.com/microsoft/fluentui/pull/33713) by beachball) + +## [8.107.125](https://github.com/microsoft/fluentui/tree/@fluentui/fluent2-theme_v8.107.125) + +Wed, 22 Jan 2025 07:21:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/fluent2-theme_v8.107.124..@fluentui/fluent2-theme_v8.107.125) + +### Patches + +- Bump @fluentui/react to v8.122.8 ([PR #33685](https://github.com/microsoft/fluentui/pull/33685) by beachball) + +## [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 +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/fluent2-theme_v8.107.122..@fluentui/fluent2-theme_v8.107.123) + +### Patches + +- Bump @fluentui/react to v8.122.6 ([PR #33148](https://github.com/microsoft/fluentui/pull/33148) by beachball) + +## [8.107.122](https://github.com/microsoft/fluentui/tree/@fluentui/fluent2-theme_v8.107.122) + +Wed, 08 Jan 2025 07:21:37 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/fluent2-theme_v8.107.121..@fluentui/fluent2-theme_v8.107.122) + +### Patches + +- Bump @fluentui/react to v8.122.5 ([PR #33578](https://github.com/microsoft/fluentui/pull/33578) by beachball) + +## [8.107.121](https://github.com/microsoft/fluentui/tree/@fluentui/fluent2-theme_v8.107.121) + +Fri, 03 Jan 2025 07:21:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/fluent2-theme_v8.107.120..@fluentui/fluent2-theme_v8.107.121) + +### Patches + +- Bump @fluentui/react to v8.122.4 ([PR #33529](https://github.com/microsoft/fluentui/pull/33529) by beachball) + +## [8.107.120](https://github.com/microsoft/fluentui/tree/@fluentui/fluent2-theme_v8.107.120) + +Mon, 30 Dec 2024 07:21:29 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/fluent2-theme_v8.107.119..@fluentui/fluent2-theme_v8.107.120) + +### Patches + +- Bump @fluentui/react to v8.122.3 ([PR #33520](https://github.com/microsoft/fluentui/pull/33520) by beachball) + +## [8.107.119](https://github.com/microsoft/fluentui/tree/@fluentui/fluent2-theme_v8.107.119) + +Mon, 23 Dec 2024 07:22:58 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/fluent2-theme_v8.107.118..@fluentui/fluent2-theme_v8.107.119) + +### Patches + +- Bump @fluentui/react to v8.122.2 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) + +## [8.107.118](https://github.com/microsoft/fluentui/tree/@fluentui/fluent2-theme_v8.107.118) + +Fri, 13 Dec 2024 07:23:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/fluent2-theme_v8.107.117..@fluentui/fluent2-theme_v8.107.118) + +### Patches + +- Bump @fluentui/react to v8.122.1 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) + +## [8.107.117](https://github.com/microsoft/fluentui/tree/@fluentui/fluent2-theme_v8.107.117) + +Thu, 12 Dec 2024 07:22:33 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/fluent2-theme_v8.107.116..@fluentui/fluent2-theme_v8.107.117) + +### Patches + +- Bump @fluentui/react to v8.122.0 ([PR #33243](https://github.com/microsoft/fluentui/pull/33243) by beachball) + ## [8.107.116](https://github.com/microsoft/fluentui/tree/@fluentui/fluent2-theme_v8.107.116) Fri, 22 Nov 2024 07:21:18 GMT diff --git a/packages/fluent2-theme/package.json b/packages/fluent2-theme/package.json index 6009ac41a3d9fc..6ffeb7de73471b 100644 --- a/packages/fluent2-theme/package.json +++ b/packages/fluent2-theme/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/fluent2-theme", - "version": "8.107.116", + "version": "8.107.128", "description": "A Fluent2 theme for Fluent UI React 8.x", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -27,8 +27,8 @@ "@fluentui/scripts-webpack": "*" }, "dependencies": { - "@fluentui/react": "^8.121.13", - "@fluentui/set-version": "^8.2.23", + "@fluentui/react": "^8.122.11", + "@fluentui/set-version": "^8.2.24", "tslib": "^2.1.0" } } diff --git a/packages/fluentui/projects-test/assets/cra/src/index.tsx b/packages/fluentui/projects-test/assets/cra/src/index.tsx new file mode 100644 index 00000000000000..b0ddfeee00e36d --- /dev/null +++ b/packages/fluentui/projects-test/assets/cra/src/index.tsx @@ -0,0 +1,7 @@ +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import App from './App'; + +const root = document.getElementById('root') as HTMLElement; + +ReactDOM.render(, root); diff --git a/packages/fluentui/projects-test/src/createReactApp.ts b/packages/fluentui/projects-test/src/createReactApp.ts index d8b81ba6e11ac3..f926fe4b802f0a 100644 --- a/packages/fluentui/projects-test/src/createReactApp.ts +++ b/packages/fluentui/projects-test/src/createReactApp.ts @@ -37,6 +37,11 @@ export async function createReactApp() { await addResolutionPathsForProjectPackages(testAppPathRoot); await shEcho(`yarn add ${packedPackages['@fluentui/react-northstar']}`, testAppPathRoot); + + // Enforce React 17 + const dependencies = ['@types/react@17', '@types/react-dom@17', 'react@17', 'react-dom@17'].join(' '); + await shEcho(`yarn add ${dependencies}`, tempPaths.testApp); + logger(`✔️ Fluent UI packages were added to dependencies`); logger("STEP 3. Reference Fluent UI components in test project's App.tsx"); diff --git a/packages/fluentui/react-northstar/jest.config.js b/packages/fluentui/react-northstar/jest.config.js index 5cdf12e0e8ac32..d873ab12d72319 100644 --- a/packages/fluentui/react-northstar/jest.config.js +++ b/packages/fluentui/react-northstar/jest.config.js @@ -10,6 +10,9 @@ const config = commonConfig({ // Legacy aliases, they should not be used in new tests ...getAliases(), }, + // Keeps Jest from using too much memory as GC gets invokes more often, makes tests slower + // https://stackoverflow.com/a/75857711 + workerIdleMemoryLimit: '1024MB', }); config.setupFilesAfterEnv = [...config.setupFilesAfterEnv, './jest-setup.js']; diff --git a/packages/font-icons-mdl2/CHANGELOG.json b/packages/font-icons-mdl2/CHANGELOG.json index 41025c700dde47..677890254604f8 100644 --- a/packages/font-icons-mdl2/CHANGELOG.json +++ b/packages/font-icons-mdl2/CHANGELOG.json @@ -1,6 +1,78 @@ { "name": "@fluentui/font-icons-mdl2", "entries": [ + { + "date": "Fri, 21 Feb 2025 07:22:41 GMT", + "tag": "@fluentui/font-icons-mdl2_v8.5.58", + "version": "8.5.58", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/font-icons-mdl2", + "comment": "Bump @fluentui/set-version to v8.2.24", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/font-icons-mdl2", + "comment": "Bump @fluentui/style-utilities to v8.11.7", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/font-icons-mdl2", + "comment": "Bump @fluentui/utilities to v8.15.20", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + } + ] + } + }, + { + "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", + "version": "8.5.57", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/font-icons-mdl2", + "comment": "Bump @fluentui/style-utilities to v8.11.6", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + } + ] + } + }, + { + "date": "Fri, 13 Dec 2024 07:23:12 GMT", + "tag": "@fluentui/font-icons-mdl2_v8.5.56", + "version": "8.5.56", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/font-icons-mdl2", + "comment": "Bump @fluentui/style-utilities to v8.11.5", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7" + } + ] + } + }, { "date": "Fri, 01 Nov 2024 07:23:21 GMT", "tag": "@fluentui/font-icons-mdl2_v8.5.55", diff --git a/packages/font-icons-mdl2/CHANGELOG.md b/packages/font-icons-mdl2/CHANGELOG.md index bbcbe6fb89a441..c2a9e5da21a0fd 100644 --- a/packages/font-icons-mdl2/CHANGELOG.md +++ b/packages/font-icons-mdl2/CHANGELOG.md @@ -1,9 +1,38 @@ # Change Log - @fluentui/font-icons-mdl2 -This log was last generated on Fri, 01 Nov 2024 07:23:21 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 07:22:41 GMT and should not be manually modified. +## [8.5.58](https://github.com/microsoft/fluentui/tree/@fluentui/font-icons-mdl2_v8.5.58) + +Fri, 21 Feb 2025 07:22:41 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/font-icons-mdl2_v8.5.57..@fluentui/font-icons-mdl2_v8.5.58) + +### Patches + +- Bump @fluentui/set-version to v8.2.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/style-utilities to v8.11.7 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/utilities to v8.15.20 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) + +## [8.5.57](https://github.com/microsoft/fluentui/tree/@fluentui/font-icons-mdl2_v8.5.57) + +Mon, 23 Dec 2024 07:22:58 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/font-icons-mdl2_v8.5.56..@fluentui/font-icons-mdl2_v8.5.57) + +### Patches + +- Bump @fluentui/style-utilities to v8.11.6 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) + +## [8.5.56](https://github.com/microsoft/fluentui/tree/@fluentui/font-icons-mdl2_v8.5.56) + +Fri, 13 Dec 2024 07:23:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/font-icons-mdl2_v8.5.55..@fluentui/font-icons-mdl2_v8.5.56) + +### Patches + +- Bump @fluentui/style-utilities to v8.11.5 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) + ## [8.5.55](https://github.com/microsoft/fluentui/tree/@fluentui/font-icons-mdl2_v8.5.55) Fri, 01 Nov 2024 07:23:21 GMT diff --git a/packages/font-icons-mdl2/package.json b/packages/font-icons-mdl2/package.json index 4bdd4c8e1dc89f..8370e83482aef9 100644 --- a/packages/font-icons-mdl2/package.json +++ b/packages/font-icons-mdl2/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/font-icons-mdl2", - "version": "8.5.55", + "version": "8.5.58", "description": "Fluent UI React icon set.", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -27,9 +27,9 @@ "@fluentui/scripts-tasks": "*" }, "dependencies": { - "@fluentui/set-version": "^8.2.23", - "@fluentui/style-utilities": "^8.11.4", - "@fluentui/utilities": "^8.15.19", + "@fluentui/set-version": "^8.2.24", + "@fluentui/style-utilities": "^8.11.7", + "@fluentui/utilities": "^8.15.20", "tslib": "^2.1.0" }, "exports": { 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 8fc320f4ce1ed5..686771b876cd89 100644 --- a/packages/foundation-legacy/CHANGELOG.json +++ b/packages/foundation-legacy/CHANGELOG.json @@ -1,6 +1,84 @@ { "name": "@fluentui/foundation-legacy", "entries": [ + { + "date": "Fri, 21 Feb 2025 07:22:41 GMT", + "tag": "@fluentui/foundation-legacy_v8.4.24", + "version": "8.4.24", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/foundation-legacy", + "comment": "Bump @fluentui/merge-styles to v8.6.14", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/foundation-legacy", + "comment": "Bump @fluentui/set-version to v8.2.24", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/foundation-legacy", + "comment": "Bump @fluentui/style-utilities to v8.11.7", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/foundation-legacy", + "comment": "Bump @fluentui/utilities to v8.15.20", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + } + ] + } + }, + { + "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", + "version": "8.4.23", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/foundation-legacy", + "comment": "Bump @fluentui/style-utilities to v8.11.6", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + } + ] + } + }, + { + "date": "Fri, 13 Dec 2024 07:23:12 GMT", + "tag": "@fluentui/foundation-legacy_v8.4.22", + "version": "8.4.22", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/foundation-legacy", + "comment": "Bump @fluentui/style-utilities to v8.11.5", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7" + } + ] + } + }, { "date": "Fri, 01 Nov 2024 07:23:21 GMT", "tag": "@fluentui/foundation-legacy_v8.4.21", diff --git a/packages/foundation-legacy/CHANGELOG.md b/packages/foundation-legacy/CHANGELOG.md index f1170378699446..9a740a82f9dd75 100644 --- a/packages/foundation-legacy/CHANGELOG.md +++ b/packages/foundation-legacy/CHANGELOG.md @@ -1,9 +1,39 @@ # Change Log - @fluentui/foundation-legacy -This log was last generated on Fri, 01 Nov 2024 07:23:21 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 07:22:41 GMT and should not be manually modified. +## [8.4.24](https://github.com/microsoft/fluentui/tree/@fluentui/foundation-legacy_v8.4.24) + +Fri, 21 Feb 2025 07:22:41 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/foundation-legacy_v8.4.23..@fluentui/foundation-legacy_v8.4.24) + +### Patches + +- Bump @fluentui/merge-styles to v8.6.14 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/set-version to v8.2.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/style-utilities to v8.11.7 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/utilities to v8.15.20 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) + +## [8.4.23](https://github.com/microsoft/fluentui/tree/@fluentui/foundation-legacy_v8.4.23) + +Mon, 23 Dec 2024 07:22:58 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/foundation-legacy_v8.4.22..@fluentui/foundation-legacy_v8.4.23) + +### Patches + +- Bump @fluentui/style-utilities to v8.11.6 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) + +## [8.4.22](https://github.com/microsoft/fluentui/tree/@fluentui/foundation-legacy_v8.4.22) + +Fri, 13 Dec 2024 07:23:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/foundation-legacy_v8.4.21..@fluentui/foundation-legacy_v8.4.22) + +### Patches + +- Bump @fluentui/style-utilities to v8.11.5 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) + ## [8.4.21](https://github.com/microsoft/fluentui/tree/@fluentui/foundation-legacy_v8.4.21) Fri, 01 Nov 2024 07:23:21 GMT diff --git a/packages/foundation-legacy/package.json b/packages/foundation-legacy/package.json index 8162850fb65515..5bb4eba06b391c 100644 --- a/packages/foundation-legacy/package.json +++ b/packages/foundation-legacy/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/foundation-legacy", - "version": "8.4.21", + "version": "8.4.24", "description": "Legacy utilities for building Fluent UI React components.", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -33,10 +33,10 @@ "@fluentui/scripts-webpack": "*" }, "dependencies": { - "@fluentui/merge-styles": "^8.6.13", - "@fluentui/set-version": "^8.2.23", - "@fluentui/style-utilities": "^8.11.4", - "@fluentui/utilities": "^8.15.19", + "@fluentui/merge-styles": "^8.6.14", + "@fluentui/set-version": "^8.2.24", + "@fluentui/style-utilities": "^8.11.7", + "@fluentui/utilities": "^8.15.20", "tslib": "^2.1.0" }, "peerDependencies": { 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/jest-serializer-merge-styles/CHANGELOG.json b/packages/jest-serializer-merge-styles/CHANGELOG.json index 616f739983968a..559e51bc3d2e41 100644 --- a/packages/jest-serializer-merge-styles/CHANGELOG.json +++ b/packages/jest-serializer-merge-styles/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/jest-serializer-merge-styles", "entries": [ + { + "date": "Fri, 21 Feb 2025 07:22:41 GMT", + "tag": "@fluentui/jest-serializer-merge-styles_v8.0.47", + "version": "8.0.47", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/jest-serializer-merge-styles", + "comment": "Bump @fluentui/merge-styles to v8.6.14", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + } + ] + } + }, { "date": "Thu, 08 Aug 2024 07:24:18 GMT", "tag": "@fluentui/jest-serializer-merge-styles_v8.0.46", diff --git a/packages/jest-serializer-merge-styles/CHANGELOG.md b/packages/jest-serializer-merge-styles/CHANGELOG.md index 5263cc563cc534..0a114ef69e8f30 100644 --- a/packages/jest-serializer-merge-styles/CHANGELOG.md +++ b/packages/jest-serializer-merge-styles/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/jest-serializer-merge-styles -This log was last generated on Thu, 08 Aug 2024 07:24:18 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 07:22:41 GMT and should not be manually modified. +## [8.0.47](https://github.com/microsoft/fluentui/tree/@fluentui/jest-serializer-merge-styles_v8.0.47) + +Fri, 21 Feb 2025 07:22:41 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/jest-serializer-merge-styles_v8.0.46..@fluentui/jest-serializer-merge-styles_v8.0.47) + +### Patches + +- Bump @fluentui/merge-styles to v8.6.14 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) + ## [8.0.46](https://github.com/microsoft/fluentui/tree/@fluentui/jest-serializer-merge-styles_v8.0.46) Thu, 08 Aug 2024 07:24:18 GMT diff --git a/packages/jest-serializer-merge-styles/package.json b/packages/jest-serializer-merge-styles/package.json index 5ff662db05d7ff..3edf64d7bbaf62 100644 --- a/packages/jest-serializer-merge-styles/package.json +++ b/packages/jest-serializer-merge-styles/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/jest-serializer-merge-styles", - "version": "8.0.46", + "version": "8.0.47", "description": "Jest serializer for merge-styles.", "main": "lib-commonjs/index.js", "typings": "lib-commonjs/index.d.ts", @@ -24,6 +24,6 @@ "@fluentui/scripts-tasks": "*" }, "dependencies": { - "@fluentui/merge-styles": "^8.6.13" + "@fluentui/merge-styles": "^8.6.14" } } 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..2701352f8e37ce 100644 --- a/packages/merge-styles/CHANGELOG.json +++ b/packages/merge-styles/CHANGELOG.json @@ -1,6 +1,36 @@ { "name": "@fluentui/merge-styles", "entries": [ + { + "date": "Fri, 21 Feb 2025 07:22:41 GMT", + "tag": "@fluentui/merge-styles_v8.6.14", + "version": "8.6.14", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/merge-styles", + "comment": "Bump @fluentui/set-version to v8.2.24", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + } + ] + } + }, + { + "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/CHANGELOG.md b/packages/merge-styles/CHANGELOG.md index 3515e8b0f327dc..d90cb9626948c9 100644 --- a/packages/merge-styles/CHANGELOG.md +++ b/packages/merge-styles/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/merge-styles -This log was last generated on Thu, 08 Aug 2024 07:24:14 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 07:22:41 GMT and should not be manually modified. +## [8.6.14](https://github.com/microsoft/fluentui/tree/@fluentui/merge-styles_v8.6.14) + +Fri, 21 Feb 2025 07:22:41 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/merge-styles_v8.6.13..@fluentui/merge-styles_v8.6.14) + +### Patches + +- Bump @fluentui/set-version to v8.2.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) + ## [8.6.13](https://github.com/microsoft/fluentui/tree/@fluentui/merge-styles_v8.6.13) Thu, 08 Aug 2024 07:24:14 GMT diff --git a/packages/merge-styles/package.json b/packages/merge-styles/package.json index db60f8ca46ba94..a70b43c4e6b03b 100644 --- a/packages/merge-styles/package.json +++ b/packages/merge-styles/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/merge-styles", - "version": "8.6.13", + "version": "8.6.14", "description": "Style loading utilities.", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -30,7 +30,7 @@ "@fluentui/scripts-webpack": "*" }, "dependencies": { - "@fluentui/set-version": "^8.2.23", + "@fluentui/set-version": "^8.2.24", "tslib": "^2.1.0" }, "exports": { 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 bb548270a8d163..92e59346b7bb32 100644 --- a/packages/react-cards/CHANGELOG.json +++ b/packages/react-cards/CHANGELOG.json @@ -1,6 +1,210 @@ { "name": "@fluentui/react-cards", "entries": [ + { + "date": "Fri, 21 Feb 2025 07:22:41 GMT", + "tag": "@fluentui/react-cards_v0.205.200", + "version": "0.205.200", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-cards", + "comment": "Bump @fluentui/react to v8.122.11", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react-cards", + "comment": "Bump @fluentui/foundation-legacy to v8.4.24", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react-cards", + "comment": "Bump @fluentui/set-version to v8.2.24", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + } + ] + } + }, + { + "date": "Wed, 19 Feb 2025 07:21:16 GMT", + "tag": "@fluentui/react-cards_v0.205.199", + "version": "0.205.199", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-cards", + "comment": "Bump @fluentui/react to v8.122.10", + "commit": "8264ce0435583ae69c051f109388005be3c0de2b" + } + ] + } + }, + { + "date": "Wed, 29 Jan 2025 07:21:15 GMT", + "tag": "@fluentui/react-cards_v0.205.198", + "version": "0.205.198", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-cards", + "comment": "Bump @fluentui/react to v8.122.9", + "commit": "111bf937b3793db68e32a90774b04f3bf61f4be5" + } + ] + } + }, + { + "date": "Wed, 22 Jan 2025 07:21:49 GMT", + "tag": "@fluentui/react-cards_v0.205.197", + "version": "0.205.197", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-cards", + "comment": "Bump @fluentui/react to v8.122.8", + "commit": "012298d98651800023aac24c591831e9bc51bea2" + } + ] + } + }, + { + "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", + "version": "0.205.195", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-cards", + "comment": "Bump @fluentui/react to v8.122.6", + "commit": "bf60a56cb23b3af90bcb62462c2423468eb9fa3c" + } + ] + } + }, + { + "date": "Wed, 08 Jan 2025 07:21:37 GMT", + "tag": "@fluentui/react-cards_v0.205.194", + "version": "0.205.194", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-cards", + "comment": "Bump @fluentui/react to v8.122.5", + "commit": "8f763922d713d9ccd35e65db07206c10b170fafd" + } + ] + } + }, + { + "date": "Fri, 03 Jan 2025 07:21:32 GMT", + "tag": "@fluentui/react-cards_v0.205.193", + "version": "0.205.193", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-cards", + "comment": "Bump @fluentui/react to v8.122.4", + "commit": "7bb97f178d73a470dc438a2b19d165d9d0bd4b51" + } + ] + } + }, + { + "date": "Mon, 30 Dec 2024 07:21:29 GMT", + "tag": "@fluentui/react-cards_v0.205.192", + "version": "0.205.192", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-cards", + "comment": "Bump @fluentui/react to v8.122.3", + "commit": "681a95a732fe385a70b8d4537dc489acbcd1c21e" + } + ] + } + }, + { + "date": "Mon, 23 Dec 2024 07:22:58 GMT", + "tag": "@fluentui/react-cards_v0.205.191", + "version": "0.205.191", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-cards", + "comment": "Bump @fluentui/react to v8.122.2", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + }, + { + "author": "beachball", + "package": "@fluentui/react-cards", + "comment": "Bump @fluentui/foundation-legacy to v8.4.23", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + } + ] + } + }, + { + "date": "Fri, 13 Dec 2024 07:23:12 GMT", + "tag": "@fluentui/react-cards_v0.205.190", + "version": "0.205.190", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-cards", + "comment": "Bump @fluentui/react to v8.122.1", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7" + }, + { + "author": "beachball", + "package": "@fluentui/react-cards", + "comment": "Bump @fluentui/foundation-legacy to v8.4.22", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7" + } + ] + } + }, + { + "date": "Thu, 12 Dec 2024 07:22:33 GMT", + "tag": "@fluentui/react-cards_v0.205.189", + "version": "0.205.189", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-cards", + "comment": "Bump @fluentui/react to v8.122.0", + "commit": "53dd771e70338065810404663cd6219d1b54c1e2" + } + ] + } + }, { "date": "Fri, 22 Nov 2024 07:21:18 GMT", "tag": "@fluentui/react-cards_v0.205.188", diff --git a/packages/react-cards/CHANGELOG.md b/packages/react-cards/CHANGELOG.md index 6d16c496290699..71b48bc71c8800 100644 --- a/packages/react-cards/CHANGELOG.md +++ b/packages/react-cards/CHANGELOG.md @@ -1,9 +1,121 @@ # Change Log - @fluentui/react-cards -This log was last generated on Fri, 22 Nov 2024 07:21:18 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 07:22:41 GMT and should not be manually modified. +## [0.205.200](https://github.com/microsoft/fluentui/tree/@fluentui/react-cards_v0.205.200) + +Fri, 21 Feb 2025 07:22:41 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-cards_v0.205.199..@fluentui/react-cards_v0.205.200) + +### Patches + +- Bump @fluentui/react to v8.122.11 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/foundation-legacy to v8.4.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/set-version to v8.2.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) + +## [0.205.199](https://github.com/microsoft/fluentui/tree/@fluentui/react-cards_v0.205.199) + +Wed, 19 Feb 2025 07:21:16 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-cards_v0.205.198..@fluentui/react-cards_v0.205.199) + +### Patches + +- Bump @fluentui/react to v8.122.10 ([PR #33867](https://github.com/microsoft/fluentui/pull/33867) by beachball) + +## [0.205.198](https://github.com/microsoft/fluentui/tree/@fluentui/react-cards_v0.205.198) + +Wed, 29 Jan 2025 07:21:15 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-cards_v0.205.197..@fluentui/react-cards_v0.205.198) + +### Patches + +- Bump @fluentui/react to v8.122.9 ([PR #33713](https://github.com/microsoft/fluentui/pull/33713) by beachball) + +## [0.205.197](https://github.com/microsoft/fluentui/tree/@fluentui/react-cards_v0.205.197) + +Wed, 22 Jan 2025 07:21:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-cards_v0.205.196..@fluentui/react-cards_v0.205.197) + +### Patches + +- Bump @fluentui/react to v8.122.8 ([PR #33685](https://github.com/microsoft/fluentui/pull/33685) by beachball) + +## [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 +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-cards_v0.205.194..@fluentui/react-cards_v0.205.195) + +### Patches + +- Bump @fluentui/react to v8.122.6 ([PR #33148](https://github.com/microsoft/fluentui/pull/33148) by beachball) + +## [0.205.194](https://github.com/microsoft/fluentui/tree/@fluentui/react-cards_v0.205.194) + +Wed, 08 Jan 2025 07:21:37 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-cards_v0.205.193..@fluentui/react-cards_v0.205.194) + +### Patches + +- Bump @fluentui/react to v8.122.5 ([PR #33578](https://github.com/microsoft/fluentui/pull/33578) by beachball) + +## [0.205.193](https://github.com/microsoft/fluentui/tree/@fluentui/react-cards_v0.205.193) + +Fri, 03 Jan 2025 07:21:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-cards_v0.205.192..@fluentui/react-cards_v0.205.193) + +### Patches + +- Bump @fluentui/react to v8.122.4 ([PR #33529](https://github.com/microsoft/fluentui/pull/33529) by beachball) + +## [0.205.192](https://github.com/microsoft/fluentui/tree/@fluentui/react-cards_v0.205.192) + +Mon, 30 Dec 2024 07:21:29 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-cards_v0.205.191..@fluentui/react-cards_v0.205.192) + +### Patches + +- Bump @fluentui/react to v8.122.3 ([PR #33520](https://github.com/microsoft/fluentui/pull/33520) by beachball) + +## [0.205.191](https://github.com/microsoft/fluentui/tree/@fluentui/react-cards_v0.205.191) + +Mon, 23 Dec 2024 07:22:58 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-cards_v0.205.190..@fluentui/react-cards_v0.205.191) + +### Patches + +- Bump @fluentui/react to v8.122.2 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) +- Bump @fluentui/foundation-legacy to v8.4.23 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) + +## [0.205.190](https://github.com/microsoft/fluentui/tree/@fluentui/react-cards_v0.205.190) + +Fri, 13 Dec 2024 07:23:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-cards_v0.205.189..@fluentui/react-cards_v0.205.190) + +### Patches + +- Bump @fluentui/react to v8.122.1 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) +- Bump @fluentui/foundation-legacy to v8.4.22 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) + +## [0.205.189](https://github.com/microsoft/fluentui/tree/@fluentui/react-cards_v0.205.189) + +Thu, 12 Dec 2024 07:22:33 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-cards_v0.205.188..@fluentui/react-cards_v0.205.189) + +### Patches + +- Bump @fluentui/react to v8.122.0 ([PR #33243](https://github.com/microsoft/fluentui/pull/33243) by beachball) + ## [0.205.188](https://github.com/microsoft/fluentui/tree/@fluentui/react-cards_v0.205.188) Fri, 22 Nov 2024 07:21:18 GMT diff --git a/packages/react-cards/package.json b/packages/react-cards/package.json index ea98fefd136453..24b4f14129d9ae 100644 --- a/packages/react-cards/package.json +++ b/packages/react-cards/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-cards", - "version": "0.205.188", + "version": "0.205.200", "description": "Deprecated experimental Card container components for Fluent UI React.", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -33,9 +33,9 @@ "@fluentui/scripts-webpack": "*" }, "dependencies": { - "@fluentui/react": "^8.121.13", - "@fluentui/foundation-legacy": "^8.4.21", - "@fluentui/set-version": "^8.2.23", + "@fluentui/react": "^8.122.11", + "@fluentui/foundation-legacy": "^8.4.24", + "@fluentui/set-version": "^8.2.24", "@microsoft/load-themed-styles": "^1.10.26", "tslib": "^2.1.0" }, diff --git a/packages/react-components/babel-preset-global-context/CHANGELOG.json b/packages/react-components/babel-preset-global-context/CHANGELOG.json index 0717dac3aff7a3..e8a001752075a3 100644 --- a/packages/react-components/babel-preset-global-context/CHANGELOG.json +++ b/packages/react-components/babel-preset-global-context/CHANGELOG.json @@ -1,6 +1,36 @@ { "name": "@fluentui/babel-preset-global-context", "entries": [ + { + "date": "Wed, 22 Jan 2025 14:00:21 GMT", + "tag": "@fluentui/babel-preset-global-context_v9.0.0-beta.79", + "version": "9.0.0-beta.79", + "comments": { + "prerelease": [ + { + "author": "beachball", + "package": "@fluentui/babel-preset-global-context", + "comment": "Bump @fluentui/global-context to v9.0.0-beta.79", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + } + ] + } + }, + { + "date": "Mon, 16 Dec 2024 16:26:49 GMT", + "tag": "@fluentui/babel-preset-global-context_v9.0.0-beta.78", + "version": "9.0.0-beta.78", + "comments": { + "prerelease": [ + { + "author": "beachball", + "package": "@fluentui/babel-preset-global-context", + "comment": "Bump @fluentui/global-context to v9.0.0-beta.78", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + } + ] + } + }, { "date": "Fri, 06 Dec 2024 12:53:46 GMT", "tag": "@fluentui/babel-preset-global-context_v9.0.0-beta.77", diff --git a/packages/react-components/babel-preset-global-context/CHANGELOG.md b/packages/react-components/babel-preset-global-context/CHANGELOG.md index 4055cb3817a0de..d8a7774770321c 100644 --- a/packages/react-components/babel-preset-global-context/CHANGELOG.md +++ b/packages/react-components/babel-preset-global-context/CHANGELOG.md @@ -1,9 +1,27 @@ # Change Log - @fluentui/babel-preset-global-context -This log was last generated on Fri, 06 Dec 2024 12:53:46 GMT and should not be manually modified. +This log was last generated on Wed, 22 Jan 2025 14:00:21 GMT and should not be manually modified. +## [9.0.0-beta.79](https://github.com/microsoft/fluentui/tree/@fluentui/babel-preset-global-context_v9.0.0-beta.79) + +Wed, 22 Jan 2025 14:00:21 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/babel-preset-global-context_v9.0.0-beta.78..@fluentui/babel-preset-global-context_v9.0.0-beta.79) + +### Changes + +- Bump @fluentui/global-context to v9.0.0-beta.79 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) + +## [9.0.0-beta.78](https://github.com/microsoft/fluentui/tree/@fluentui/babel-preset-global-context_v9.0.0-beta.78) + +Mon, 16 Dec 2024 16:26:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/babel-preset-global-context_v9.0.0-beta.77..@fluentui/babel-preset-global-context_v9.0.0-beta.78) + +### Changes + +- Bump @fluentui/global-context to v9.0.0-beta.78 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) + ## [9.0.0-beta.77](https://github.com/microsoft/fluentui/tree/@fluentui/babel-preset-global-context_v9.0.0-beta.77) Fri, 06 Dec 2024 12:53:46 GMT diff --git a/packages/react-components/babel-preset-global-context/package.json b/packages/react-components/babel-preset-global-context/package.json index a7ad978b37c452..561d0fcb493c63 100644 --- a/packages/react-components/babel-preset-global-context/package.json +++ b/packages/react-components/babel-preset-global-context/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/babel-preset-global-context", - "version": "9.0.0-beta.77", + "version": "9.0.0-beta.79", "description": "Babel preset that transforms createContext calls to use global context shims", "main": "lib-commonjs/index.js", "typings": "./dist/index.d.ts", @@ -25,7 +25,7 @@ "find-up": "^5.0.0" }, "peerDependencies": { - "@fluentui/global-context": "9.0.0-beta.77" + "@fluentui/global-context": "9.0.0-beta.79" }, "beachball": { "disallowedChangeTypes": [ diff --git a/packages/react-components/eslint-plugin-react-components/.eslintrc.json b/packages/react-components/eslint-plugin-react-components/.eslintrc.json index 63b4e8d8a8963a..700ea69cb4542d 100644 --- a/packages/react-components/eslint-plugin-react-components/.eslintrc.json +++ b/packages/react-components/eslint-plugin-react-components/.eslintrc.json @@ -1,5 +1,13 @@ { "extends": ["plugin:@fluentui/eslint-plugin/node", "plugin:eslint-plugin/recommended"], "plugins": ["eslint-plugin"], - "root": true + "root": true, + "overrides": [ + { + "files": ["src/rules/*.ts"], + "rules": { + "@typescript-eslint/naming-convention": "off" + } + } + ] } diff --git a/packages/react-components/eslint-plugin-react-components/CHANGELOG.json b/packages/react-components/eslint-plugin-react-components/CHANGELOG.json index fbf6513e4e7dbd..c3080ab03dec51 100644 --- a/packages/react-components/eslint-plugin-react-components/CHANGELOG.json +++ b/packages/react-components/eslint-plugin-react-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/eslint-plugin-react-components", "entries": [ + { + "date": "Wed, 08 Jan 2025 18:33:32 GMT", + "tag": "@fluentui/eslint-plugin-react-components_v0.1.1", + "version": "0.1.1", + "comments": { + "patch": [ + { + "author": "dmytrokirpa@microsoft.com", + "package": "@fluentui/eslint-plugin-react-components", + "commit": "384df0ccb4a5324da6daee8f18712ef5a81fa05a", + "comment": "feat: add prefer-fluentui-v9 rule" + } + ] + } + }, { "date": "Fri, 06 Dec 2024 12:53:38 GMT", "tag": "@fluentui/eslint-plugin-react-components_v0.1.0", diff --git a/packages/react-components/eslint-plugin-react-components/CHANGELOG.md b/packages/react-components/eslint-plugin-react-components/CHANGELOG.md index 32ebceabc4cfa7..0501f8787c383f 100644 --- a/packages/react-components/eslint-plugin-react-components/CHANGELOG.md +++ b/packages/react-components/eslint-plugin-react-components/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/eslint-plugin-react-components -This log was last generated on Fri, 06 Dec 2024 12:53:38 GMT and should not be manually modified. +This log was last generated on Wed, 08 Jan 2025 18:33:32 GMT and should not be manually modified. +## [0.1.1](https://github.com/microsoft/fluentui/tree/@fluentui/eslint-plugin-react-components_v0.1.1) + +Wed, 08 Jan 2025 18:33:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/eslint-plugin-react-components_v0.1.0..@fluentui/eslint-plugin-react-components_v0.1.1) + +### Patches + +- feat: add prefer-fluentui-v9 rule ([PR #33449](https://github.com/microsoft/fluentui/pull/33449) by dmytrokirpa@microsoft.com) + ## [0.1.0](https://github.com/microsoft/fluentui/tree/@fluentui/eslint-plugin-react-components_v0.1.0) Fri, 06 Dec 2024 12:53:38 GMT diff --git a/packages/react-components/eslint-plugin-react-components/README.md b/packages/react-components/eslint-plugin-react-components/README.md index 5da83b63a80507..0b22544de65533 100644 --- a/packages/react-components/eslint-plugin-react-components/README.md +++ b/packages/react-components/eslint-plugin-react-components/README.md @@ -40,21 +40,42 @@ module.exports = { }; ``` -1. Or configure individual rules manually: +2. Or configure individual rules manually: ```js module.exports = { plugins: ['@fluentui/react-components'], rules: { - '@fluentui/react-components/rule-name-1': 'error', - '@fluentui/react-components/rule-name-2': 'warn', + '@fluentui/react-components/prefer-fluentui-v9': 'warn', }, }; ``` ## Available Rules -TBD +### prefer-fluentui-v9 + +This rule ensures the use of Fluent UI v9 counterparts for Fluent UI v8 components. + +#### Examples + +**✅ Do** + +```js +// Import and use components that have been already migrated to Fluent UI v9 +import { Button } from '@fluentui/react-components'; + +const Component = () => ; +``` + +**❌ Don't** + +```js +// Avoid importing and using Fluent UI V8 components that have already been migrated to Fluent UI V9. +import { DefaultButton } from '@fluentui/react'; + +const Component = () => ...; +``` ## License diff --git a/packages/react-components/eslint-plugin-react-components/etc/eslint-plugin-react-components.api.md b/packages/react-components/eslint-plugin-react-components/etc/eslint-plugin-react-components.api.md index ebe584c246463f..d4416ee6720ef5 100644 --- a/packages/react-components/eslint-plugin-react-components/etc/eslint-plugin-react-components.api.md +++ b/packages/react-components/eslint-plugin-react-components/etc/eslint-plugin-react-components.api.md @@ -4,8 +4,11 @@ ```ts +import { RuleListener } from '@typescript-eslint/utils/dist/ts-eslint'; +import { RuleModule } from '@typescript-eslint/utils/dist/ts-eslint'; + // @public (undocumented) -const plugin: { +export const plugin: { meta: { name: string; version: string; @@ -16,9 +19,10 @@ const plugin: { rules: {}; }; }; - rules: {}; + rules: { + "prefer-fluentui-v9": RuleModule<"replaceFluent8With9" | "replaceIconWithJsx" | "replaceStackWithFlex" | "replaceFocusZoneWithTabster", {}[], unknown, RuleListener>; + }; }; -export default plugin; // (No @packageDocumentation comment for this package) diff --git a/packages/react-components/eslint-plugin-react-components/package.json b/packages/react-components/eslint-plugin-react-components/package.json index a7bfca2ce415e6..b67ca20a4c7985 100644 --- a/packages/react-components/eslint-plugin-react-components/package.json +++ b/packages/react-components/eslint-plugin-react-components/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/eslint-plugin-react-components", - "version": "0.1.0", + "version": "0.1.1", "description": "ESLint plugin and custom rules for Fluent UI components v9", "main": "./lib-commonjs/index.js", "module": "./lib/index.js", diff --git a/packages/react-components/eslint-plugin-react-components/src/index.ts b/packages/react-components/eslint-plugin-react-components/src/index.ts index 821e8d8738ab9e..e3ed57c99b71fd 100644 --- a/packages/react-components/eslint-plugin-react-components/src/index.ts +++ b/packages/react-components/eslint-plugin-react-components/src/index.ts @@ -1,7 +1,8 @@ import { name, version } from '../package.json'; +import { RULE_NAME as preferFluentUIV9Name, rule as preferFluentUIV9 } from './rules/prefer-fluentui-v9'; const allRules = { - // add all rules here + [preferFluentUIV9Name]: preferFluentUIV9, }; const configs = { @@ -14,7 +15,7 @@ const configs = { }; // Plugin definition -const plugin = { +export const plugin = { meta: { name, version, @@ -33,4 +34,4 @@ Object.assign(configs, { }, }); -export default plugin; +module.exports = plugin; diff --git a/packages/react-components/eslint-plugin-react-components/src/rules/prefer-fluentui-v9.spec.ts b/packages/react-components/eslint-plugin-react-components/src/rules/prefer-fluentui-v9.spec.ts new file mode 100644 index 00000000000000..22f79c07d8055a --- /dev/null +++ b/packages/react-components/eslint-plugin-react-components/src/rules/prefer-fluentui-v9.spec.ts @@ -0,0 +1,40 @@ +import { RuleTester } from '@typescript-eslint/rule-tester'; +import { RULE_NAME, rule } from './prefer-fluentui-v9'; + +const ruleTester = new RuleTester(); + +ruleTester.run(RULE_NAME, rule, { + valid: [ + { + code: `import type { IDropdownOption } from '@fluentui/react';`, + }, + { + code: `import type { ITheme } from '@fluentui/react';`, + }, + { + code: `import { ThemeProvider } from '@fluentui/react';`, + }, + { + code: `import { Button } from '@fluentui/react-components';`, + }, + ], + invalid: [ + { + code: `import { Dropdown, Icon } from '@fluentui/react';`, + errors: [{ messageId: 'replaceFluent8With9' }, { messageId: 'replaceIconWithJsx' }], + }, + { + code: `import { Stack } from '@fluentui/react';`, + errors: [{ messageId: 'replaceStackWithFlex' }], + }, + { + code: `import { DatePicker } from '@fluentui/react';`, + errors: [ + { + messageId: 'replaceFluent8With9', + data: { fluent8: 'DatePicker', fluent9: 'DatePicker', package: '@fluentui/react-datepicker-compat' }, + }, + ], + }, + ], +}); diff --git a/packages/react-components/eslint-plugin-react-components/src/rules/prefer-fluentui-v9.ts b/packages/react-components/eslint-plugin-react-components/src/rules/prefer-fluentui-v9.ts new file mode 100644 index 00000000000000..bf43866a6e90dd --- /dev/null +++ b/packages/react-components/eslint-plugin-react-components/src/rules/prefer-fluentui-v9.ts @@ -0,0 +1,148 @@ +import { AST_NODE_TYPES } from '@typescript-eslint/utils'; + +import { createRule } from './utils/create-rule'; + +export const RULE_NAME = 'prefer-fluentui-v9'; + +type Options = Array<{}>; + +type MessageIds = 'replaceFluent8With9' | 'replaceIconWithJsx' | 'replaceStackWithFlex' | 'replaceFocusZoneWithTabster'; + +export const rule = createRule({ + name: RULE_NAME, + meta: { + type: 'problem', + docs: { + description: 'This rule ensures the use of Fluent UI v9 counterparts for Fluent UI v8 components.', + }, + schema: [], + messages: { + replaceFluent8With9: `Avoid importing {{ fluent8 }} from '@fluentui/react', as this package has started migration to Fluent UI 9. Import {{ fluent9 }} from '{{ package }}' instead.`, + replaceIconWithJsx: `Avoid using Icon from '@fluentui/react', as this package has already migrated to Fluent UI 9. Use a JSX SVG icon from '@fluentui/react-icons' instead.`, + replaceStackWithFlex: `Avoid using Stack from '@fluentui/react', as this package has already migrated to Fluent UI 9. Use native CSS flexbox instead. More details are available at https://react.fluentui.dev/?path=/docs/concepts-migration-from-v8-components-flex-stack--docs`, + replaceFocusZoneWithTabster: `Avoid using {{ fluent8 }} from '@fluentui/react', as this package has already migrated to Fluent UI 9. Use the equivalent [Tabster](https://tabster.io/) hook instead.`, + }, + }, + defaultOptions: [], + create(context) { + return { + ImportDeclaration(node) { + if (node.source.value !== '@fluentui/react') { + return; + } + + for (const specifier of node.specifiers) { + if ( + specifier.type === AST_NODE_TYPES.ImportSpecifier && + specifier.imported.type === AST_NODE_TYPES.Identifier + ) { + const name = specifier.imported.name; + + switch (name) { + case 'Icon': + context.report({ node, messageId: 'replaceIconWithJsx' }); + break; + case 'Stack': + context.report({ node, messageId: 'replaceStackWithFlex' }); + break; + case 'FocusTrapZone': + case 'FocusZone': + context.report({ node, messageId: 'replaceFocusZoneWithTabster', data: { fluent8: name } }); + break; + default: + if (isMigration(name)) { + const migration = MIGRATIONS[name]; + + context.report({ + node, + messageId: 'replaceFluent8With9', + data: { + fluent8: name, + fluent9: migration.import, + package: migration.package, + }, + }); + } + } + } + } + }, + }; + }, +}); + +/** + * Migrations from Fluent 8 components to Fluent 9 components. + * @see https://react.fluentui.dev/?path=/docs/concepts-migration-from-v8-component-mapping--docs + */ +const MIGRATIONS = { + makeStyles: { import: 'makeStyles', package: '@fluentui/react-components' }, + ActionButton: { import: 'Button', package: '@fluentui/react-components' }, + Announced: { import: 'useAnnounce', package: '@fluentui/react-components' }, + Breadcrumb: { import: 'Breadcrumb', package: '@fluentui/react-components' }, + Button: { import: 'Button', package: '@fluentui/react-components' }, + Callout: { import: 'Popover', package: '@fluentui/react-components' }, + Calendar: { import: 'Calendar', package: '@fluentui/react-calendar-compat' }, + CommandBar: { import: 'Toolbar', package: '@fluentui/react-components' }, + CommandBarButton: { import: 'Toolbar', package: '@fluentui/react-components' }, + CommandButton: { import: 'MenuButton', package: '@fluentui/react-components' }, + CompoundButton: { import: 'CompoundButton', package: '@fluentui/react-components' }, + Checkbox: { import: 'Checkbox', package: '@fluentui/react-components' }, + ChoiceGroup: { import: 'RadioGroup', package: '@fluentui/react-components' }, + Coachmark: { import: 'TeachingPopover', package: '@fluentui/react-components' }, + ComboBox: { import: 'Combobox', package: '@fluentui/react-components' }, + ContextualMenu: { import: 'Menu', package: '@fluentui/react-components' }, + DefaultButton: { import: 'Button', package: '@fluentui/react-components' }, + DatePicker: { import: 'DatePicker', package: '@fluentui/react-datepicker-compat' }, + DetailsList: { import: 'DataGrid', package: '@fluentui/react-components' }, + Dialog: { import: 'Dialog', package: '@fluentui/react-components' }, + DocumentCard: { import: 'Card', package: '@fluentui/react-components' }, + Dropdown: { import: 'Dropdown', package: '@fluentui/react-components' }, + Fabric: { import: 'FluentProvider', package: '@fluentui/react-components' }, + Facepile: { import: 'AvatarGroup', package: '@fluentui/react-components' }, + FocusTrapZone: { import: 'Tabster', package: '@fluentui/react-components' }, + FocusZone: { import: 'Tabster', package: '@fluentui/react-components' }, + GroupedList: { import: 'Tree', package: '@fluentui/react-components' }, + HoverCard: { import: 'Popover', package: '@fluentui/react-components' }, // Not a direct equivalent; but could be used with custom behavior. + IconButton: { import: 'Button', package: '@fluentui/react-components' }, + Image: { import: 'Image', package: '@fluentui/react-components' }, + Keytips: { import: 'Keytips', package: '@fluentui-contrib/react-keytips' }, + Label: { import: 'Label', package: '@fluentui/react-components' }, + Layer: { import: 'Portal', package: '@fluentui/react-components' }, + Link: { import: 'Link', package: '@fluentui/react-components' }, + MessageBar: { import: 'MessageBar', package: '@fluentui/react-components' }, + Modal: { import: 'Dialog', package: '@fluentui/react-components' }, + OverflowSet: { import: 'Overflow', package: '@fluentui/react-components' }, + Overlay: { import: 'Portal', package: '@fluentui/react-components' }, + Panel: { import: 'Drawer', package: '@fluentui/react-components' }, + PeoplePicker: { import: 'TagPicker', package: '@fluentui/react-components' }, + Persona: { import: 'Persona', package: '@fluentui/react-components' }, + Pivot: { import: 'TabList', package: '@fluentui/react-components' }, + PivotItem: { import: 'Tab', package: '@fluentui/react-components' }, + ProgressIndicator: { import: 'ProgressBar', package: '@fluentui/react-components' }, + Rating: { import: 'Rating', package: '@fluentui/react-components' }, + SearchBox: { import: 'SearchBox', package: '@fluentui/react-components' }, + Separator: { import: 'Divider', package: '@fluentui/react-components' }, + Shimmer: { import: 'Skeleton', package: '@fluentui/react-components' }, + Slider: { import: 'Slider', package: '@fluentui/react-components' }, + SplitButton: { import: 'SplitButton', package: '@fluentui/react-components' }, + SpinButton: { import: 'SpinButton', package: '@fluentui/react-components' }, + Spinner: { import: 'Spinner', package: '@fluentui/react-components' }, + Stack: { import: 'StackShim', package: '@fluentui/react-components' }, + SwatchColorPicker: { import: 'SwatchPicker', package: '@fluentui/react-components' }, + TagPicker: { import: 'TagPicker', package: '@fluentui/react-components' }, + TeachingBubble: { import: 'TeachingPopover', package: '@fluentui/react-components' }, + Text: { import: 'Text', package: '@fluentui/react-components' }, + TextField: { import: 'Input', package: '@fluentui/react-components' }, + TimePicker: { import: 'TimePicker', package: '@fluentui/react-timepicker-compat' }, + ToggleButton: { import: 'ToggleButton', package: '@fluentui/react-components' }, + Toggle: { import: 'Switch', package: '@fluentui/react-components' }, + Tooltip: { import: 'Tooltip', package: '@fluentui/react-components' }, +}; + +/** + * Checks if a component name is in the MIGRATIONS list. + * @param name - The name of the component. + * @returns True if the component is in the MIGRATIONS list, false otherwise. + */ +const isMigration = (name: string): name is keyof typeof MIGRATIONS => name in MIGRATIONS; diff --git a/packages/react-components/eslint-plugin-react-components/src/rules/utils/create-rule.ts b/packages/react-components/eslint-plugin-react-components/src/rules/utils/create-rule.ts new file mode 100644 index 00000000000000..0365797e179f62 --- /dev/null +++ b/packages/react-components/eslint-plugin-react-components/src/rules/utils/create-rule.ts @@ -0,0 +1,9 @@ +import { ESLintUtils } from '@typescript-eslint/utils'; + +/** + * Creates an ESLint rule with a pre-configured URL pointing to the rule's documentation. + */ +export const createRule = ESLintUtils.RuleCreator( + name => + `https://github.com/microsoft/fluentui/blob/master/packages/react-components/eslint-plugin-react-components/README.md#${name}`, +); diff --git a/packages/react-components/eslint-plugin-react-components/tsconfig.spec.json b/packages/react-components/eslint-plugin-react-components/tsconfig.spec.json index 469fcba4d7ba75..18aba1c9375371 100644 --- a/packages/react-components/eslint-plugin-react-components/tsconfig.spec.json +++ b/packages/react-components/eslint-plugin-react-components/tsconfig.spec.json @@ -1,7 +1,8 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "module": "CommonJS", + "module": "NodeNext", + "moduleResolution": "NodeNext", "outDir": "dist", "types": ["jest", "node"] }, diff --git a/packages/react-components/global-context/CHANGELOG.json b/packages/react-components/global-context/CHANGELOG.json index 0ee518dd86a666..1f4a5e1fbc23fc 100644 --- a/packages/react-components/global-context/CHANGELOG.json +++ b/packages/react-components/global-context/CHANGELOG.json @@ -1,6 +1,48 @@ { "name": "@fluentui/global-context", "entries": [ + { + "date": "Wed, 22 Jan 2025 14:00:21 GMT", + "tag": "@fluentui/global-context_v9.0.0-beta.79", + "version": "9.0.0-beta.79", + "comments": { + "prerelease": [ + { + "author": "beachball", + "package": "@fluentui/global-context", + "comment": "Bump @fluentui/react-context-selector to v9.1.72", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/global-context", + "comment": "Bump @fluentui/react-utilities to v9.18.20", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + } + ] + } + }, + { + "date": "Mon, 16 Dec 2024 16:26:49 GMT", + "tag": "@fluentui/global-context_v9.0.0-beta.78", + "version": "9.0.0-beta.78", + "comments": { + "prerelease": [ + { + "author": "beachball", + "package": "@fluentui/global-context", + "comment": "Bump @fluentui/react-context-selector to v9.1.71", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/global-context", + "comment": "Bump @fluentui/react-utilities to v9.18.19", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + } + ] + } + }, { "date": "Fri, 06 Dec 2024 12:53:46 GMT", "tag": "@fluentui/global-context_v9.0.0-beta.77", diff --git a/packages/react-components/global-context/CHANGELOG.md b/packages/react-components/global-context/CHANGELOG.md index 1fa6f4b09b6d54..d9fa75d8193239 100644 --- a/packages/react-components/global-context/CHANGELOG.md +++ b/packages/react-components/global-context/CHANGELOG.md @@ -1,9 +1,29 @@ # Change Log - @fluentui/global-context -This log was last generated on Fri, 06 Dec 2024 12:53:46 GMT and should not be manually modified. +This log was last generated on Wed, 22 Jan 2025 14:00:21 GMT and should not be manually modified. +## [9.0.0-beta.79](https://github.com/microsoft/fluentui/tree/@fluentui/global-context_v9.0.0-beta.79) + +Wed, 22 Jan 2025 14:00:21 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/global-context_v9.0.0-beta.78..@fluentui/global-context_v9.0.0-beta.79) + +### Changes + +- Bump @fluentui/react-context-selector to v9.1.72 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-utilities to v9.18.20 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) + +## [9.0.0-beta.78](https://github.com/microsoft/fluentui/tree/@fluentui/global-context_v9.0.0-beta.78) + +Mon, 16 Dec 2024 16:26:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/global-context_v9.0.0-beta.77..@fluentui/global-context_v9.0.0-beta.78) + +### Changes + +- Bump @fluentui/react-context-selector to v9.1.71 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-utilities to v9.18.19 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) + ## [9.0.0-beta.77](https://github.com/microsoft/fluentui/tree/@fluentui/global-context_v9.0.0-beta.77) Fri, 06 Dec 2024 12:53:46 GMT diff --git a/packages/react-components/global-context/package.json b/packages/react-components/global-context/package.json index 028f2ac4395050..de6cb8687f61f5 100644 --- a/packages/react-components/global-context/package.json +++ b/packages/react-components/global-context/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/global-context", - "version": "9.0.0-beta.77", + "version": "9.0.0-beta.79", "description": "Extension of React createContext to be a true singleton on the global scope", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -17,8 +17,8 @@ "@fluentui/scripts-cypress": "*" }, "dependencies": { - "@fluentui/react-context-selector": "^9.1.70", - "@fluentui/react-utilities": "^9.18.18", + "@fluentui/react-context-selector": "^9.1.72", + "@fluentui/react-utilities": "^9.18.20", "@swc/helpers": "^0.5.1" }, "peerDependencies": { diff --git a/packages/react-components/priority-overflow/CHANGELOG.json b/packages/react-components/priority-overflow/CHANGELOG.json index 162027b248c490..4d68d0c4583c86 100644 --- a/packages/react-components/priority-overflow/CHANGELOG.json +++ b/packages/react-components/priority-overflow/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/priority-overflow", "entries": [ + { + "date": "Fri, 21 Feb 2025 14:34:03 GMT", + "tag": "@fluentui/priority-overflow_v9.1.15", + "version": "9.1.15", + "comments": { + "patch": [ + { + "author": "lingfangao@hotmail.com", + "package": "@fluentui/priority-overflow", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3", + "comment": "fix: Add a defensive check when getting overflow item records" + } + ] + } + }, { "date": "Mon, 11 Nov 2024 10:01:03 GMT", "tag": "@fluentui/priority-overflow_v9.1.14", diff --git a/packages/react-components/priority-overflow/CHANGELOG.md b/packages/react-components/priority-overflow/CHANGELOG.md index 70710fcb5463a5..ba2291f943cbb3 100644 --- a/packages/react-components/priority-overflow/CHANGELOG.md +++ b/packages/react-components/priority-overflow/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/priority-overflow -This log was last generated on Mon, 11 Nov 2024 10:01:03 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 14:34:03 GMT and should not be manually modified. +## [9.1.15](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.1.15) + +Fri, 21 Feb 2025 14:34:03 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/priority-overflow_v9.1.14..@fluentui/priority-overflow_v9.1.15) + +### Patches + +- fix: Add a defensive check when getting overflow item records ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by lingfangao@hotmail.com) + ## [9.1.14](https://github.com/microsoft/fluentui/tree/@fluentui/priority-overflow_v9.1.14) Mon, 11 Nov 2024 10:01:03 GMT diff --git a/packages/react-components/priority-overflow/package.json b/packages/react-components/priority-overflow/package.json index d9936b028bb5c1..66efbb3ef60210 100644 --- a/packages/react-components/priority-overflow/package.json +++ b/packages/react-components/priority-overflow/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/priority-overflow", - "version": "9.1.14", + "version": "9.1.15", "description": "Vanilla JS utilities to implement overflow menus", "main": "lib-commonjs/index.js", "module": "lib/index.js", diff --git a/packages/react-components/priority-overflow/src/overflowManager.ts b/packages/react-components/priority-overflow/src/overflowManager.ts index bb29076af5c861..87e043ba64eb90 100644 --- a/packages/react-components/priority-overflow/src/overflowManager.ts +++ b/packages/react-components/priority-overflow/src/overflowManager.ts @@ -54,6 +54,12 @@ export function createOverflowManager(): OverflowManager { const lte = overflowItems[lt]; const rte = overflowItems[rt]; + // TODO this should not happen but there have been reports of one of these items being undefined + // Try to find a consistent repro for this + if (!lte || !rte) { + return lte ? 1 : -1; + } + if (lte.priority !== rte.priority) { return lte.priority > rte.priority ? 1 : -1; } diff --git a/packages/react-components/react-accordion/library/CHANGELOG.json b/packages/react-components/react-accordion/library/CHANGELOG.json index a8947fbd149ba0..ba9e4e8478c250 100644 --- a/packages/react-components/react-accordion/library/CHANGELOG.json +++ b/packages/react-components/react-accordion/library/CHANGELOG.json @@ -1,6 +1,215 @@ { "name": "@fluentui/react-accordion", "entries": [ + { + "date": "Fri, 21 Feb 2025 14:34:05 GMT", + "tag": "@fluentui/react-accordion_v9.6.0", + "version": "9.6.0", + "comments": { + "minor": [ + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-aria to v9.14.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + }, + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-tabster to v9.24.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + } + ] + } + }, + { + "date": "Wed, 22 Jan 2025 14:00:14 GMT", + "tag": "@fluentui/react-accordion_v9.5.14", + "version": "9.5.14", + "comments": { + "none": [ + { + "author": "vgenaev@gmail.com", + "package": "@fluentui/react-accordion", + "commit": "fd420e1e0b66e04c8a423cff3eea6d21d9434d2d", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule" + } + ], + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-aria to v9.13.14", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-context-selector to v9.1.72", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.50", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-motion to v9.6.7", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-motion-components-preview to v0.4.3", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-tabster to v9.23.3", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-utilities to v9.18.20", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + } + ] + } + }, + { + "date": "Wed, 08 Jan 2025 18:33:36 GMT", + "tag": "@fluentui/react-accordion_v9.5.13", + "version": "9.5.13", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-aria to v9.13.13", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + }, + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.49", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + }, + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-motion to v9.6.6", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + }, + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-motion-components-preview to v0.4.2", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + } + ] + } + }, + { + "date": "Mon, 16 Dec 2024 16:26:49 GMT", + "tag": "@fluentui/react-accordion_v9.5.12", + "version": "9.5.12", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-aria to v9.13.12", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-context-selector to v9.1.71", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.48", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-shared-contexts to v9.21.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-motion to v9.6.5", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-motion-components-preview to v0.4.1", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-tabster to v9.23.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-theme to v9.1.24", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-utilities to v9.18.19", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + } + ] + } + }, + { + "date": "Mon, 09 Dec 2024 17:38:07 GMT", + "tag": "@fluentui/react-accordion_v9.5.11", + "version": "9.5.11", + "comments": { + "patch": [ + { + "author": "olfedias@microsoft.com", + "package": "@fluentui/react-accordion", + "commit": "cad13936cd49ba0b34b50bc2f58395605c4e8da4", + "comment": "chore: remove usage of \"export *\"" + }, + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-aria to v9.13.11", + "commit": "80f2ce07be06e66b369bd18e4484d8faf6b493c7" + }, + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-motion to v9.6.4", + "commit": "80f2ce07be06e66b369bd18e4484d8faf6b493c7" + }, + { + "author": "beachball", + "package": "@fluentui/react-accordion", + "comment": "Bump @fluentui/react-motion-components-preview to v0.4.0", + "commit": "80f2ce07be06e66b369bd18e4484d8faf6b493c7" + } + ] + } + }, { "date": "Fri, 06 Dec 2024 12:53:46 GMT", "tag": "@fluentui/react-accordion_v9.5.10", diff --git a/packages/react-components/react-accordion/library/CHANGELOG.md b/packages/react-components/react-accordion/library/CHANGELOG.md index be8cb3436c45d6..e5f4035a8ec484 100644 --- a/packages/react-components/react-accordion/library/CHANGELOG.md +++ b/packages/react-components/react-accordion/library/CHANGELOG.md @@ -1,9 +1,75 @@ # Change Log - @fluentui/react-accordion -This log was last generated on Fri, 06 Dec 2024 12:53:46 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 14:34:05 GMT and should not be manually modified. +## [9.6.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-accordion_v9.6.0) + +Fri, 21 Feb 2025 14:34:05 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-accordion_v9.5.14..@fluentui/react-accordion_v9.6.0) + +### Minor changes + +- Bump @fluentui/react-aria to v9.14.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) +- Bump @fluentui/react-tabster to v9.24.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) + +## [9.5.14](https://github.com/microsoft/fluentui/tree/@fluentui/react-accordion_v9.5.14) + +Wed, 22 Jan 2025 14:00:14 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-accordion_v9.5.13..@fluentui/react-accordion_v9.5.14) + +### Patches + +- Bump @fluentui/react-aria to v9.13.14 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-context-selector to v9.1.72 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.50 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-motion to v9.6.7 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-motion-components-preview to v0.4.3 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-tabster to v9.23.3 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-utilities to v9.18.20 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) + +## [9.5.13](https://github.com/microsoft/fluentui/tree/@fluentui/react-accordion_v9.5.13) + +Wed, 08 Jan 2025 18:33:36 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-accordion_v9.5.12..@fluentui/react-accordion_v9.5.13) + +### Patches + +- Bump @fluentui/react-aria to v9.13.13 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.49 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-motion to v9.6.6 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-motion-components-preview to v0.4.2 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) + +## [9.5.12](https://github.com/microsoft/fluentui/tree/@fluentui/react-accordion_v9.5.12) + +Mon, 16 Dec 2024 16:26:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-accordion_v9.5.11..@fluentui/react-accordion_v9.5.12) + +### Patches + +- Bump @fluentui/react-aria to v9.13.12 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-context-selector to v9.1.71 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.48 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-shared-contexts to v9.21.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-motion to v9.6.5 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-motion-components-preview to v0.4.1 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-tabster to v9.23.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-theme to v9.1.24 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-utilities to v9.18.19 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) + +## [9.5.11](https://github.com/microsoft/fluentui/tree/@fluentui/react-accordion_v9.5.11) + +Mon, 09 Dec 2024 17:38:07 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-accordion_v9.5.10..@fluentui/react-accordion_v9.5.11) + +### Patches + +- chore: remove usage of "export *" ([PR #33384](https://github.com/microsoft/fluentui/pull/33384) by olfedias@microsoft.com) +- Bump @fluentui/react-aria to v9.13.11 ([PR #33431](https://github.com/microsoft/fluentui/pull/33431) by beachball) +- Bump @fluentui/react-motion to v9.6.4 ([PR #33431](https://github.com/microsoft/fluentui/pull/33431) by beachball) +- Bump @fluentui/react-motion-components-preview to v0.4.0 ([PR #33431](https://github.com/microsoft/fluentui/pull/33431) by beachball) + ## [9.5.10](https://github.com/microsoft/fluentui/tree/@fluentui/react-accordion_v9.5.10) Fri, 06 Dec 2024 12:53:46 GMT diff --git a/packages/react-components/react-accordion/library/package.json b/packages/react-components/react-accordion/library/package.json index e374efe5d9f133..b651872678ca8d 100644 --- a/packages/react-components/react-accordion/library/package.json +++ b/packages/react-components/react-accordion/library/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-accordion", - "version": "9.5.10", + "version": "9.6.0", "description": "Fluent UI accordion component", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -18,16 +18,16 @@ "@fluentui/scripts-api-extractor": "*" }, "dependencies": { - "@fluentui/react-aria": "^9.13.10", - "@fluentui/react-context-selector": "^9.1.70", + "@fluentui/react-aria": "^9.14.0", + "@fluentui/react-context-selector": "^9.1.72", "@fluentui/react-icons": "^2.0.245", - "@fluentui/react-jsx-runtime": "^9.0.47", - "@fluentui/react-shared-contexts": "^9.21.1", - "@fluentui/react-motion": "^9.6.3", - "@fluentui/react-motion-components-preview": "^0.3.2", - "@fluentui/react-tabster": "^9.23.1", - "@fluentui/react-theme": "^9.1.23", - "@fluentui/react-utilities": "^9.18.18", + "@fluentui/react-jsx-runtime": "^9.0.50", + "@fluentui/react-shared-contexts": "^9.21.2", + "@fluentui/react-motion": "^9.6.7", + "@fluentui/react-motion-components-preview": "^0.4.3", + "@fluentui/react-tabster": "^9.24.0", + "@fluentui/react-theme": "^9.1.24", + "@fluentui/react-utilities": "^9.18.20", "@griffel/react": "^1.5.22", "@swc/helpers": "^0.5.1" }, diff --git a/packages/react-components/react-accordion/library/src/Accordion.ts b/packages/react-components/react-accordion/library/src/Accordion.ts index 064a71a9bbf3d0..dcaa059bf3ecef 100644 --- a/packages/react-components/react-accordion/library/src/Accordion.ts +++ b/packages/react-components/react-accordion/library/src/Accordion.ts @@ -1 +1,18 @@ -export * from './components/Accordion/index'; +export type { + AccordionContextValues, + AccordionIndex, + AccordionProps, + AccordionSlots, + AccordionState, + AccordionToggleData, + AccordionToggleEvent, + AccordionToggleEventHandler, +} from './components/Accordion/index'; +export { + Accordion, + accordionClassNames, + renderAccordion_unstable, + useAccordionContextValues_unstable, + useAccordionStyles_unstable, + useAccordion_unstable, +} from './components/Accordion/index'; diff --git a/packages/react-components/react-accordion/library/src/AccordionHeader.ts b/packages/react-components/react-accordion/library/src/AccordionHeader.ts index b2101dc7246b60..0a0b58c53a1f49 100644 --- a/packages/react-components/react-accordion/library/src/AccordionHeader.ts +++ b/packages/react-components/react-accordion/library/src/AccordionHeader.ts @@ -1 +1,16 @@ -export * from './components/AccordionHeader/index'; +export type { + AccordionHeaderContextValues, + AccordionHeaderExpandIconPosition, + AccordionHeaderProps, + AccordionHeaderSize, + AccordionHeaderSlots, + AccordionHeaderState, +} from './components/AccordionHeader/index'; +export { + AccordionHeader, + accordionHeaderClassNames, + renderAccordionHeader_unstable, + useAccordionHeaderContextValues_unstable, + useAccordionHeaderStyles_unstable, + useAccordionHeader_unstable, +} from './components/AccordionHeader/index'; diff --git a/packages/react-components/react-accordion/library/src/AccordionItem.ts b/packages/react-components/react-accordion/library/src/AccordionItem.ts index 0c45f76f75a956..b6ad934eec1863 100644 --- a/packages/react-components/react-accordion/library/src/AccordionItem.ts +++ b/packages/react-components/react-accordion/library/src/AccordionItem.ts @@ -1 +1,15 @@ -export * from './components/AccordionItem/index'; +export type { + AccordionItemContextValues, + AccordionItemProps, + AccordionItemSlots, + AccordionItemState, + AccordionItemValue, +} from './components/AccordionItem/index'; +export { + AccordionItem, + accordionItemClassNames, + renderAccordionItem_unstable, + useAccordionItemContextValues_unstable, + useAccordionItemStyles_unstable, + useAccordionItem_unstable, +} from './components/AccordionItem/index'; diff --git a/packages/react-components/react-accordion/library/src/AccordionPanel.ts b/packages/react-components/react-accordion/library/src/AccordionPanel.ts index 3be2eec2f50100..dd103aa269f9a7 100644 --- a/packages/react-components/react-accordion/library/src/AccordionPanel.ts +++ b/packages/react-components/react-accordion/library/src/AccordionPanel.ts @@ -1 +1,8 @@ -export * from './components/AccordionPanel/index'; +export type { AccordionPanelProps, AccordionPanelSlots, AccordionPanelState } from './components/AccordionPanel/index'; +export { + AccordionPanel, + accordionPanelClassNames, + renderAccordionPanel_unstable, + useAccordionPanelStyles_unstable, + useAccordionPanel_unstable, +} from './components/AccordionPanel/index'; diff --git a/packages/react-components/react-accordion/library/src/components/Accordion/index.ts b/packages/react-components/react-accordion/library/src/components/Accordion/index.ts index c4669810c07b41..38c4840369fee7 100644 --- a/packages/react-components/react-accordion/library/src/components/Accordion/index.ts +++ b/packages/react-components/react-accordion/library/src/components/Accordion/index.ts @@ -1,6 +1,15 @@ -export * from './Accordion'; -export * from './Accordion.types'; -export * from './renderAccordion'; -export * from './useAccordion'; -export * from './useAccordionStyles.styles'; -export * from './useAccordionContextValues'; +export { Accordion } from './Accordion'; +export type { + AccordionContextValues, + AccordionIndex, + AccordionProps, + AccordionSlots, + AccordionState, + AccordionToggleData, + AccordionToggleEvent, + AccordionToggleEventHandler, +} from './Accordion.types'; +export { renderAccordion_unstable } from './renderAccordion'; +export { useAccordion_unstable } from './useAccordion'; +export { accordionClassNames, useAccordionStyles_unstable } from './useAccordionStyles.styles'; +export { useAccordionContextValues_unstable } from './useAccordionContextValues'; 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 2f4b04a3a08bc3..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({ @@ -53,7 +53,7 @@ export const useAccordion_unstable = ( root: slot.always( getIntrinsicElementProps('div', { ...props, - // eslint-disable-next-line deprecation/deprecation + ...(navigation ? arrowNavigationProps : undefined), // FIXME: // `ref` is wrongly assigned to be `HTMLElement` instead of `HTMLDivElement` diff --git a/packages/react-components/react-accordion/library/src/components/AccordionHeader/index.ts b/packages/react-components/react-accordion/library/src/components/AccordionHeader/index.ts index ce32bacc27b603..1f25c7dbe108c3 100644 --- a/packages/react-components/react-accordion/library/src/components/AccordionHeader/index.ts +++ b/packages/react-components/react-accordion/library/src/components/AccordionHeader/index.ts @@ -1,6 +1,13 @@ -export * from './AccordionHeader'; -export * from './AccordionHeader.types'; -export * from './renderAccordionHeader'; -export * from './useAccordionHeader'; -export * from './useAccordionHeaderContextValues'; -export * from './useAccordionHeaderStyles.styles'; +export { AccordionHeader } from './AccordionHeader'; +export type { + AccordionHeaderContextValues, + AccordionHeaderExpandIconPosition, + AccordionHeaderProps, + AccordionHeaderSize, + AccordionHeaderSlots, + AccordionHeaderState, +} from './AccordionHeader.types'; +export { renderAccordionHeader_unstable } from './renderAccordionHeader'; +export { useAccordionHeader_unstable } from './useAccordionHeader'; +export { useAccordionHeaderContextValues_unstable } from './useAccordionHeaderContextValues'; +export { accordionHeaderClassNames, useAccordionHeaderStyles_unstable } from './useAccordionHeaderStyles.styles'; diff --git a/packages/react-components/react-accordion/library/src/components/AccordionItem/index.ts b/packages/react-components/react-accordion/library/src/components/AccordionItem/index.ts index 3e8670fc4e40a7..fc51003a06306f 100644 --- a/packages/react-components/react-accordion/library/src/components/AccordionItem/index.ts +++ b/packages/react-components/react-accordion/library/src/components/AccordionItem/index.ts @@ -1,6 +1,12 @@ -export * from './AccordionItem'; -export * from './AccordionItem.types'; -export * from './renderAccordionItem'; -export * from './useAccordionItem'; -export * from './useAccordionItemContextValues'; -export * from './useAccordionItemStyles.styles'; +export { AccordionItem } from './AccordionItem'; +export type { + AccordionItemContextValues, + AccordionItemProps, + AccordionItemSlots, + AccordionItemState, + AccordionItemValue, +} from './AccordionItem.types'; +export { renderAccordionItem_unstable } from './renderAccordionItem'; +export { useAccordionItem_unstable } from './useAccordionItem'; +export { useAccordionItemContextValues_unstable } from './useAccordionItemContextValues'; +export { accordionItemClassNames, useAccordionItemStyles_unstable } from './useAccordionItemStyles.styles'; 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-accordion/library/src/components/AccordionPanel/index.ts b/packages/react-components/react-accordion/library/src/components/AccordionPanel/index.ts index bef7ad6cf7234a..0b1ceb7121f3ff 100644 --- a/packages/react-components/react-accordion/library/src/components/AccordionPanel/index.ts +++ b/packages/react-components/react-accordion/library/src/components/AccordionPanel/index.ts @@ -1,5 +1,5 @@ -export * from './AccordionPanel'; -export * from './AccordionPanel.types'; -export * from './renderAccordionPanel'; -export * from './useAccordionPanel'; -export * from './useAccordionPanelStyles.styles'; +export { AccordionPanel } from './AccordionPanel'; +export type { AccordionPanelProps, AccordionPanelSlots, AccordionPanelState } from './AccordionPanel.types'; +export { renderAccordionPanel_unstable } from './renderAccordionPanel'; +export { useAccordionPanel_unstable } from './useAccordionPanel'; +export { accordionPanelClassNames, useAccordionPanelStyles_unstable } from './useAccordionPanelStyles.styles'; diff --git a/packages/react-components/react-aria/library/CHANGELOG.json b/packages/react-components/react-aria/library/CHANGELOG.json index 9ffaee2555d431..13ed1c8109890c 100644 --- a/packages/react-components/react-aria/library/CHANGELOG.json +++ b/packages/react-components/react-aria/library/CHANGELOG.json @@ -1,6 +1,127 @@ { "name": "@fluentui/react-aria", "entries": [ + { + "date": "Fri, 21 Feb 2025 14:34:03 GMT", + "tag": "@fluentui/react-aria_v9.14.0", + "version": "9.14.0", + "comments": { + "patch": [ + { + "author": "sarah.higley@microsoft.com", + "package": "@fluentui/react-aria", + "commit": "f42a127ac74016eff8c6c48f7eea020e266dffe1", + "comment": "fix: useAnnounce live regions do not get aria-hidden from tabster" + } + ], + "minor": [ + { + "author": "beachball", + "package": "@fluentui/react-aria", + "comment": "Bump @fluentui/react-tabster to v9.24.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + } + ] + } + }, + { + "date": "Wed, 22 Jan 2025 14:00:14 GMT", + "tag": "@fluentui/react-aria_v9.13.14", + "version": "9.13.14", + "comments": { + "none": [ + { + "author": "vgenaev@gmail.com", + "package": "@fluentui/react-aria", + "commit": "fd420e1e0b66e04c8a423cff3eea6d21d9434d2d", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule" + } + ], + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-aria", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.50", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-aria", + "comment": "Bump @fluentui/react-tabster to v9.23.3", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-aria", + "comment": "Bump @fluentui/react-utilities to v9.18.20", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + } + ] + } + }, + { + "date": "Wed, 08 Jan 2025 18:33:36 GMT", + "tag": "@fluentui/react-aria_v9.13.13", + "version": "9.13.13", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-aria", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.49", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + } + ] + } + }, + { + "date": "Mon, 16 Dec 2024 16:26:49 GMT", + "tag": "@fluentui/react-aria_v9.13.12", + "version": "9.13.12", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-aria", + "comment": "Bump @fluentui/react-shared-contexts to v9.21.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-aria", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.48", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-aria", + "comment": "Bump @fluentui/react-tabster to v9.23.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-aria", + "comment": "Bump @fluentui/react-utilities to v9.18.19", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + } + ] + } + }, + { + "date": "Mon, 09 Dec 2024 17:38:08 GMT", + "tag": "@fluentui/react-aria_v9.13.11", + "version": "9.13.11", + "comments": { + "patch": [ + { + "author": "olfedias@microsoft.com", + "package": "@fluentui/react-aria", + "commit": "cad13936cd49ba0b34b50bc2f58395605c4e8da4", + "comment": "chore: remove usage of \"export *\"" + } + ] + } + }, { "date": "Fri, 06 Dec 2024 12:53:46 GMT", "tag": "@fluentui/react-aria_v9.13.10", diff --git a/packages/react-components/react-aria/library/CHANGELOG.md b/packages/react-components/react-aria/library/CHANGELOG.md index 9b932478ca7dee..74a1031ed6d9c3 100644 --- a/packages/react-components/react-aria/library/CHANGELOG.md +++ b/packages/react-components/react-aria/library/CHANGELOG.md @@ -1,9 +1,63 @@ # Change Log - @fluentui/react-aria -This log was last generated on Fri, 06 Dec 2024 12:53:46 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 14:34:03 GMT and should not be manually modified. +## [9.14.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-aria_v9.14.0) + +Fri, 21 Feb 2025 14:34:03 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-aria_v9.13.14..@fluentui/react-aria_v9.14.0) + +### Minor changes + +- Bump @fluentui/react-tabster to v9.24.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) + +### Patches + +- fix: useAnnounce live regions do not get aria-hidden from tabster ([PR #33855](https://github.com/microsoft/fluentui/pull/33855) by sarah.higley@microsoft.com) + +## [9.13.14](https://github.com/microsoft/fluentui/tree/@fluentui/react-aria_v9.13.14) + +Wed, 22 Jan 2025 14:00:14 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-aria_v9.13.13..@fluentui/react-aria_v9.13.14) + +### Patches + +- Bump @fluentui/react-jsx-runtime to v9.0.50 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-tabster to v9.23.3 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-utilities to v9.18.20 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) + +## [9.13.13](https://github.com/microsoft/fluentui/tree/@fluentui/react-aria_v9.13.13) + +Wed, 08 Jan 2025 18:33:36 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-aria_v9.13.12..@fluentui/react-aria_v9.13.13) + +### Patches + +- Bump @fluentui/react-jsx-runtime to v9.0.49 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) + +## [9.13.12](https://github.com/microsoft/fluentui/tree/@fluentui/react-aria_v9.13.12) + +Mon, 16 Dec 2024 16:26:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-aria_v9.13.11..@fluentui/react-aria_v9.13.12) + +### Patches + +- Bump @fluentui/react-shared-contexts to v9.21.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.48 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-tabster to v9.23.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-utilities to v9.18.19 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) + +## [9.13.11](https://github.com/microsoft/fluentui/tree/@fluentui/react-aria_v9.13.11) + +Mon, 09 Dec 2024 17:38:08 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-aria_v9.13.10..@fluentui/react-aria_v9.13.11) + +### Patches + +- chore: remove usage of "export *" ([PR #33384](https://github.com/microsoft/fluentui/pull/33384) by olfedias@microsoft.com) + ## [9.13.10](https://github.com/microsoft/fluentui/tree/@fluentui/react-aria_v9.13.10) Fri, 06 Dec 2024 12:53:46 GMT diff --git a/packages/react-components/react-aria/library/package.json b/packages/react-components/react-aria/library/package.json index 262d294c929699..bdb724a47643a4 100644 --- a/packages/react-components/react-aria/library/package.json +++ b/packages/react-components/react-aria/library/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-aria", - "version": "9.13.10", + "version": "9.14.0", "description": "React helper to ensure ARIA", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -19,10 +19,10 @@ }, "dependencies": { "@fluentui/keyboard-keys": "^9.0.8", - "@fluentui/react-shared-contexts": "^9.21.1", - "@fluentui/react-jsx-runtime": "^9.0.47", - "@fluentui/react-tabster": "^9.23.1", - "@fluentui/react-utilities": "^9.18.18", + "@fluentui/react-shared-contexts": "^9.21.2", + "@fluentui/react-jsx-runtime": "^9.0.50", + "@fluentui/react-tabster": "^9.24.0", + "@fluentui/react-utilities": "^9.18.20", "@swc/helpers": "^0.5.1" }, "peerDependencies": { diff --git a/packages/react-components/react-aria/library/src/AriaLiveAnnouncer/useDomAnnounce.ts b/packages/react-components/react-aria/library/src/AriaLiveAnnouncer/useDomAnnounce.ts index ec80055ea41fff..339d56c0b557d5 100644 --- a/packages/react-components/react-aria/library/src/AriaLiveAnnouncer/useDomAnnounce.ts +++ b/packages/react-components/react-aria/library/src/AriaLiveAnnouncer/useDomAnnounce.ts @@ -1,6 +1,7 @@ import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts'; import type { AnnounceOptions } from '@fluentui/react-shared-contexts'; import { createPriorityQueue, useTimeout } from '@fluentui/react-utilities'; +import { useDangerousNeverHidden_unstable as useDangerousNeverHidden } from '@fluentui/react-tabster'; import * as React from 'react'; import type { AriaLiveAnnounceFn, AriaLiveMessage } from './AriaLiveAnnouncer.types'; @@ -24,6 +25,7 @@ export const useDomAnnounce_unstable = (): AriaLiveAnnounceFn => { const timeoutRef = React.useRef(undefined); const [setAnnounceTimeout, clearAnnounceTimeout] = useTimeout(); + const tabsterNeverHiddenAttributes = useDangerousNeverHidden(); const elementRef = React.useRef(null); @@ -136,6 +138,10 @@ export const useDomAnnounce_unstable = (): AriaLiveAnnounceFn => { const element = targetDocument.createElement('div'); element.setAttribute('aria-live', 'assertive'); + Object.entries(tabsterNeverHiddenAttributes).forEach(([key, value]) => { + element.setAttribute(key, value); + }); + Object.assign(element.style, VISUALLY_HIDDEN_STYLES); targetDocument.body.append(element); @@ -147,7 +153,7 @@ export const useDomAnnounce_unstable = (): AriaLiveAnnounceFn => { clearAnnounceTimeout(); timeoutRef.current = undefined; }; - }, [clearAnnounceTimeout, targetDocument]); + }, [clearAnnounceTimeout, tabsterNeverHiddenAttributes, targetDocument]); return announce; }; diff --git a/packages/react-components/react-aria/library/src/activedescendant/index.ts b/packages/react-components/react-aria/library/src/activedescendant/index.ts index 11a98c7f525236..05927bef3cba6b 100644 --- a/packages/react-components/react-aria/library/src/activedescendant/index.ts +++ b/packages/react-components/react-aria/library/src/activedescendant/index.ts @@ -1,4 +1,16 @@ -export * from './ActiveDescendantContext'; -export * from './useActiveDescendant'; -export * from './constants'; -export * from './types'; +export type { ActiveDescendantContextValue } from './ActiveDescendantContext'; +export { + ActiveDescendantContextProvider, + useActiveDescendantContext, + useHasParentActiveDescendantContext, +} from './ActiveDescendantContext'; +export type { ActiveDescendantChangeEvent } from './useActiveDescendant'; +export { createActiveDescendantChangeEvent, useActiveDescendant } from './useActiveDescendant'; +export { ACTIVEDESCENDANT_ATTRIBUTE, ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE } from './constants'; +export type { + ActiveDescendantImperativeRef, + ActiveDescendantOptions, + FindOptions, + IteratorOptions, + UseActiveDescendantReturn, +} from './types'; 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 caa15e61d0ed13..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,3 +1,12 @@ -export * from './useARIAButtonProps'; -export * from './useARIAButtonShorthand'; -export * from './types'; +export { useARIAButtonProps } from './useARIAButtonProps'; +// eslint-disable-next-line @typescript-eslint/no-deprecated +export { useARIAButtonShorthand } from './useARIAButtonShorthand'; +export type { + ARIAButtonAlteredProps, + ARIAButtonElement, + ARIAButtonElementIntersection, + ARIAButtonProps, + ARIAButtonResultProps, + ARIAButtonSlotProps, + ARIAButtonType, +} from './types'; 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/CHANGELOG.json b/packages/react-components/react-avatar/library/CHANGELOG.json index 4aae1eda726ea1..20462975718c63 100644 --- a/packages/react-components/react-avatar/library/CHANGELOG.json +++ b/packages/react-components/react-avatar/library/CHANGELOG.json @@ -1,6 +1,257 @@ { "name": "@fluentui/react-avatar", "entries": [ + { + "date": "Fri, 21 Feb 2025 14:34:05 GMT", + "tag": "@fluentui/react-avatar_v9.7.0", + "version": "9.7.0", + "comments": { + "minor": [ + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-popover to v9.10.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-tabster to v9.24.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-tooltip to v9.6.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + } + ] + } + }, + { + "date": "Mon, 27 Jan 2025 20:27:35 GMT", + "tag": "@fluentui/react-avatar_v9.6.50", + "version": "9.6.50", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-popover to v9.9.32", + "commit": "808cd501d50a317249d3d02f01ea3dd88114b252" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-tooltip to v9.5.5", + "commit": "808cd501d50a317249d3d02f01ea3dd88114b252" + } + ] + } + }, + { + "date": "Wed, 22 Jan 2025 14:00:14 GMT", + "tag": "@fluentui/react-avatar_v9.6.49", + "version": "9.6.49", + "comments": { + "none": [ + { + "author": "vgenaev@gmail.com", + "package": "@fluentui/react-avatar", + "commit": "fd420e1e0b66e04c8a423cff3eea6d21d9434d2d", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule" + } + ], + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-badge to v9.2.50", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-context-selector to v9.1.72", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-popover to v9.9.31", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-tabster to v9.23.3", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-tooltip to v9.5.4", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-utilities to v9.18.20", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.50", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + } + ] + } + }, + { + "date": "Wed, 08 Jan 2025 18:33:36 GMT", + "tag": "@fluentui/react-avatar_v9.6.48", + "version": "9.6.48", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-badge to v9.2.49", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-popover to v9.9.30", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-tooltip to v9.5.3", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.49", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + } + ] + } + }, + { + "date": "Wed, 18 Dec 2024 10:59:37 GMT", + "tag": "@fluentui/react-avatar_v9.6.47", + "version": "9.6.47", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-popover to v9.9.29", + "commit": "54afa8c6ce8f7d200d5241584801899b27baaf1b" + } + ] + } + }, + { + "date": "Mon, 16 Dec 2024 16:26:49 GMT", + "tag": "@fluentui/react-avatar_v9.6.46", + "version": "9.6.46", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-badge to v9.2.48", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-context-selector to v9.1.71", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-popover to v9.9.28", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-shared-contexts to v9.21.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-tabster to v9.23.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-theme to v9.1.24", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-tooltip to v9.5.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-utilities to v9.18.19", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.48", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + } + ] + } + }, + { + "date": "Mon, 09 Dec 2024 17:38:08 GMT", + "tag": "@fluentui/react-avatar_v9.6.45", + "version": "9.6.45", + "comments": { + "patch": [ + { + "author": "olfedias@microsoft.com", + "package": "@fluentui/react-avatar", + "commit": "cad13936cd49ba0b34b50bc2f58395605c4e8da4", + "comment": "chore: remove usage of \"export *\"" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-badge to v9.2.47", + "commit": "80f2ce07be06e66b369bd18e4484d8faf6b493c7" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-popover to v9.9.27", + "commit": "80f2ce07be06e66b369bd18e4484d8faf6b493c7" + }, + { + "author": "beachball", + "package": "@fluentui/react-avatar", + "comment": "Bump @fluentui/react-tooltip to v9.5.1", + "commit": "80f2ce07be06e66b369bd18e4484d8faf6b493c7" + } + ] + } + }, { "date": "Fri, 06 Dec 2024 12:53:46 GMT", "tag": "@fluentui/react-avatar_v9.6.44", diff --git a/packages/react-components/react-avatar/library/CHANGELOG.md b/packages/react-components/react-avatar/library/CHANGELOG.md index 93ee8635a4c854..4e01aaa1de6a64 100644 --- a/packages/react-components/react-avatar/library/CHANGELOG.md +++ b/packages/react-components/react-avatar/library/CHANGELOG.md @@ -1,9 +1,95 @@ # Change Log - @fluentui/react-avatar -This log was last generated on Fri, 06 Dec 2024 12:53:46 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 14:34:05 GMT and should not be manually modified. +## [9.7.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-avatar_v9.7.0) + +Fri, 21 Feb 2025 14:34:05 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-avatar_v9.6.50..@fluentui/react-avatar_v9.7.0) + +### Minor changes + +- Bump @fluentui/react-popover to v9.10.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) +- Bump @fluentui/react-tabster to v9.24.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) +- Bump @fluentui/react-tooltip to v9.6.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) + +## [9.6.50](https://github.com/microsoft/fluentui/tree/@fluentui/react-avatar_v9.6.50) + +Mon, 27 Jan 2025 20:27:35 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-avatar_v9.6.49..@fluentui/react-avatar_v9.6.50) + +### Patches + +- Bump @fluentui/react-popover to v9.9.32 ([PR #33724](https://github.com/microsoft/fluentui/pull/33724) by beachball) +- Bump @fluentui/react-tooltip to v9.5.5 ([PR #33724](https://github.com/microsoft/fluentui/pull/33724) by beachball) + +## [9.6.49](https://github.com/microsoft/fluentui/tree/@fluentui/react-avatar_v9.6.49) + +Wed, 22 Jan 2025 14:00:14 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-avatar_v9.6.48..@fluentui/react-avatar_v9.6.49) + +### Patches + +- Bump @fluentui/react-badge to v9.2.50 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-context-selector to v9.1.72 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-popover to v9.9.31 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-tabster to v9.23.3 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-tooltip to v9.5.4 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-utilities to v9.18.20 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.50 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) + +## [9.6.48](https://github.com/microsoft/fluentui/tree/@fluentui/react-avatar_v9.6.48) + +Wed, 08 Jan 2025 18:33:36 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-avatar_v9.6.47..@fluentui/react-avatar_v9.6.48) + +### Patches + +- Bump @fluentui/react-badge to v9.2.49 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-popover to v9.9.30 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-tooltip to v9.5.3 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.49 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) + +## [9.6.47](https://github.com/microsoft/fluentui/tree/@fluentui/react-avatar_v9.6.47) + +Wed, 18 Dec 2024 10:59:37 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-avatar_v9.6.46..@fluentui/react-avatar_v9.6.47) + +### Patches + +- Bump @fluentui/react-popover to v9.9.29 ([PR #33483](https://github.com/microsoft/fluentui/pull/33483) by beachball) + +## [9.6.46](https://github.com/microsoft/fluentui/tree/@fluentui/react-avatar_v9.6.46) + +Mon, 16 Dec 2024 16:26:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-avatar_v9.6.45..@fluentui/react-avatar_v9.6.46) + +### Patches + +- Bump @fluentui/react-badge to v9.2.48 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-context-selector to v9.1.71 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-popover to v9.9.28 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-shared-contexts to v9.21.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-tabster to v9.23.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-theme to v9.1.24 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-tooltip to v9.5.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-utilities to v9.18.19 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.48 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) + +## [9.6.45](https://github.com/microsoft/fluentui/tree/@fluentui/react-avatar_v9.6.45) + +Mon, 09 Dec 2024 17:38:08 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-avatar_v9.6.44..@fluentui/react-avatar_v9.6.45) + +### Patches + +- chore: remove usage of "export *" ([PR #33384](https://github.com/microsoft/fluentui/pull/33384) by olfedias@microsoft.com) +- Bump @fluentui/react-badge to v9.2.47 ([PR #33431](https://github.com/microsoft/fluentui/pull/33431) by beachball) +- Bump @fluentui/react-popover to v9.9.27 ([PR #33431](https://github.com/microsoft/fluentui/pull/33431) by beachball) +- Bump @fluentui/react-tooltip to v9.5.1 ([PR #33431](https://github.com/microsoft/fluentui/pull/33431) by beachball) + ## [9.6.44](https://github.com/microsoft/fluentui/tree/@fluentui/react-avatar_v9.6.44) Fri, 06 Dec 2024 12:53:46 GMT diff --git a/packages/react-components/react-avatar/library/package.json b/packages/react-components/react-avatar/library/package.json index 2fa01277b89f11..1cfa24838ef1ef 100644 --- a/packages/react-components/react-avatar/library/package.json +++ b/packages/react-components/react-avatar/library/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-avatar", - "version": "9.6.44", + "version": "9.7.0", "description": "React components for building Microsoft web experiences.", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -21,16 +21,16 @@ "@fluentui/scripts-cypress": "*" }, "dependencies": { - "@fluentui/react-badge": "^9.2.46", - "@fluentui/react-context-selector": "^9.1.70", + "@fluentui/react-badge": "^9.2.50", + "@fluentui/react-context-selector": "^9.1.72", "@fluentui/react-icons": "^2.0.245", - "@fluentui/react-popover": "^9.9.26", - "@fluentui/react-shared-contexts": "^9.21.1", - "@fluentui/react-tabster": "^9.23.1", - "@fluentui/react-theme": "^9.1.23", - "@fluentui/react-tooltip": "^9.5.0", - "@fluentui/react-utilities": "^9.18.18", - "@fluentui/react-jsx-runtime": "^9.0.47", + "@fluentui/react-popover": "^9.10.0", + "@fluentui/react-shared-contexts": "^9.21.2", + "@fluentui/react-tabster": "^9.24.0", + "@fluentui/react-theme": "^9.1.24", + "@fluentui/react-tooltip": "^9.6.0", + "@fluentui/react-utilities": "^9.18.20", + "@fluentui/react-jsx-runtime": "^9.0.50", "@griffel/react": "^1.5.22", "@swc/helpers": "^0.5.1" }, diff --git a/packages/react-components/react-avatar/library/src/Avatar.ts b/packages/react-components/react-avatar/library/src/Avatar.ts index 50a1407299e271..642b24efddd5c4 100644 --- a/packages/react-components/react-avatar/library/src/Avatar.ts +++ b/packages/react-components/react-avatar/library/src/Avatar.ts @@ -1 +1,19 @@ -export * from './components/Avatar/index'; +export type { + AvatarNamedColor, + AvatarProps, + AvatarShape, + AvatarSize, + // eslint-disable-next-line @typescript-eslint/no-deprecated + AvatarSizes, + AvatarSlots, + AvatarState, +} from './components/Avatar/index'; +export { + Avatar, + DEFAULT_STRINGS, + avatarClassNames, + renderAvatar_unstable, + useAvatarStyles_unstable, + useAvatar_unstable, + useSizeStyles, +} from './components/Avatar/index'; diff --git a/packages/react-components/react-avatar/library/src/AvatarGroup.ts b/packages/react-components/react-avatar/library/src/AvatarGroup.ts index e2ea7db4f56d0b..52f4a9ea750d2f 100644 --- a/packages/react-components/react-avatar/library/src/AvatarGroup.ts +++ b/packages/react-components/react-avatar/library/src/AvatarGroup.ts @@ -1 +1,16 @@ -export * from './components/AvatarGroup/index'; +export type { + AvatarGroupContextValue, + AvatarGroupContextValues, + AvatarGroupProps, + AvatarGroupSlots, + AvatarGroupState, +} from './components/AvatarGroup/index'; +export { + AvatarGroup, + avatarGroupClassNames, + defaultAvatarGroupSize, + renderAvatarGroup_unstable, + useAvatarGroupContextValues, + useAvatarGroupStyles_unstable, + useAvatarGroup_unstable, +} from './components/AvatarGroup/index'; diff --git a/packages/react-components/react-avatar/library/src/AvatarGroupItem.ts b/packages/react-components/react-avatar/library/src/AvatarGroupItem.ts index b24ee70b148b46..cf2efa16c65de4 100644 --- a/packages/react-components/react-avatar/library/src/AvatarGroupItem.ts +++ b/packages/react-components/react-avatar/library/src/AvatarGroupItem.ts @@ -1 +1,13 @@ -export * from './components/AvatarGroupItem/index'; +export type { + AvatarGroupItemProps, + AvatarGroupItemSlots, + AvatarGroupItemState, +} from './components/AvatarGroupItem/index'; +export { + AvatarGroupItem, + avatarGroupItemClassNames, + renderAvatarGroupItem_unstable, + useAvatarGroupItemStyles_unstable, + useAvatarGroupItem_unstable, + useGroupChildClassName, +} from './components/AvatarGroupItem/index'; diff --git a/packages/react-components/react-avatar/library/src/AvatarGroupPopover.ts b/packages/react-components/react-avatar/library/src/AvatarGroupPopover.ts index f18e898df58dfe..73d5fc34c7e16b 100644 --- a/packages/react-components/react-avatar/library/src/AvatarGroupPopover.ts +++ b/packages/react-components/react-avatar/library/src/AvatarGroupPopover.ts @@ -1 +1,13 @@ -export * from './components/AvatarGroupPopover/index'; +export type { + AvatarGroupPopoverProps, + AvatarGroupPopoverSlots, + AvatarGroupPopoverState, +} from './components/AvatarGroupPopover/index'; +export { + AvatarGroupPopover, + avatarGroupPopoverClassNames, + renderAvatarGroupPopover_unstable, + useAvatarGroupPopoverContextValues_unstable, + useAvatarGroupPopoverStyles_unstable, + useAvatarGroupPopover_unstable, +} from './components/AvatarGroupPopover/index'; 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 d10c3d89de1d57..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 @@ -1,5 +1,14 @@ -export * from './Avatar.types'; -export * from './Avatar'; -export * from './renderAvatar'; -export * from './useAvatar'; -export * from './useAvatarStyles.styles'; +export type { + AvatarNamedColor, + AvatarProps, + AvatarShape, + AvatarSize, + // eslint-disable-next-line @typescript-eslint/no-deprecated + AvatarSizes, + AvatarSlots, + AvatarState, +} from './Avatar.types'; +export { Avatar } from './Avatar'; +export { renderAvatar_unstable } from './renderAvatar'; +export { DEFAULT_STRINGS, useAvatar_unstable } from './useAvatar'; +export { avatarClassNames, useAvatarStyles_unstable, useSizeStyles } from './useAvatarStyles.styles'; diff --git a/packages/react-components/react-avatar/library/src/components/AvatarGroup/index.ts b/packages/react-components/react-avatar/library/src/components/AvatarGroup/index.ts index 95618fcc1b7d34..55907a525fff6a 100644 --- a/packages/react-components/react-avatar/library/src/components/AvatarGroup/index.ts +++ b/packages/react-components/react-avatar/library/src/components/AvatarGroup/index.ts @@ -1,6 +1,12 @@ -export * from './AvatarGroup'; -export * from './AvatarGroup.types'; -export * from './renderAvatarGroup'; -export * from './useAvatarGroup'; -export * from './useAvatarGroupStyles.styles'; -export * from './useAvatarGroupContextValues'; +export { AvatarGroup } from './AvatarGroup'; +export type { + AvatarGroupContextValue, + AvatarGroupContextValues, + AvatarGroupProps, + AvatarGroupSlots, + AvatarGroupState, +} from './AvatarGroup.types'; +export { renderAvatarGroup_unstable } from './renderAvatarGroup'; +export { defaultAvatarGroupSize, useAvatarGroup_unstable } from './useAvatarGroup'; +export { avatarGroupClassNames, useAvatarGroupStyles_unstable } from './useAvatarGroupStyles.styles'; +export { useAvatarGroupContextValues } from './useAvatarGroupContextValues'; diff --git a/packages/react-components/react-avatar/library/src/components/AvatarGroupItem/index.ts b/packages/react-components/react-avatar/library/src/components/AvatarGroupItem/index.ts index 9e10c244cc7acd..8554c20f3ec73e 100644 --- a/packages/react-components/react-avatar/library/src/components/AvatarGroupItem/index.ts +++ b/packages/react-components/react-avatar/library/src/components/AvatarGroupItem/index.ts @@ -1,5 +1,9 @@ -export * from './AvatarGroupItem'; -export * from './AvatarGroupItem.types'; -export * from './renderAvatarGroupItem'; -export * from './useAvatarGroupItem'; -export * from './useAvatarGroupItemStyles.styles'; +export { AvatarGroupItem } from './AvatarGroupItem'; +export type { AvatarGroupItemProps, AvatarGroupItemSlots, AvatarGroupItemState } from './AvatarGroupItem.types'; +export { renderAvatarGroupItem_unstable } from './renderAvatarGroupItem'; +export { useAvatarGroupItem_unstable } from './useAvatarGroupItem'; +export { + avatarGroupItemClassNames, + useAvatarGroupItemStyles_unstable, + useGroupChildClassName, +} from './useAvatarGroupItemStyles.styles'; diff --git a/packages/react-components/react-avatar/library/src/components/AvatarGroupPopover/index.ts b/packages/react-components/react-avatar/library/src/components/AvatarGroupPopover/index.ts index c115ccbc9f53ec..5960dba8fee19b 100644 --- a/packages/react-components/react-avatar/library/src/components/AvatarGroupPopover/index.ts +++ b/packages/react-components/react-avatar/library/src/components/AvatarGroupPopover/index.ts @@ -1,6 +1,13 @@ -export * from './AvatarGroupPopover'; -export * from './AvatarGroupPopover.types'; -export * from './renderAvatarGroupPopover'; -export * from './useAvatarGroupPopover'; -export * from './useAvatarGroupPopoverStyles.styles'; -export * from './useAvatarGroupPopoverContextValues'; +export { AvatarGroupPopover } from './AvatarGroupPopover'; +export type { + AvatarGroupPopoverProps, + AvatarGroupPopoverSlots, + AvatarGroupPopoverState, +} from './AvatarGroupPopover.types'; +export { renderAvatarGroupPopover_unstable } from './renderAvatarGroupPopover'; +export { useAvatarGroupPopover_unstable } from './useAvatarGroupPopover'; +export { + avatarGroupPopoverClassNames, + useAvatarGroupPopoverStyles_unstable, +} from './useAvatarGroupPopoverStyles.styles'; +export { useAvatarGroupPopoverContextValues_unstable } from './useAvatarGroupPopoverContextValues'; diff --git a/packages/react-components/react-avatar/library/src/contexts/index.ts b/packages/react-components/react-avatar/library/src/contexts/index.ts index 9a81f44d0634db..7b00b912b51f37 100644 --- a/packages/react-components/react-avatar/library/src/contexts/index.ts +++ b/packages/react-components/react-avatar/library/src/contexts/index.ts @@ -1,2 +1,3 @@ -export * from './AvatarGroupContext'; -export * from './AvatarContext'; +export { AvatarGroupContext, AvatarGroupProvider, useAvatarGroupContext_unstable } from './AvatarGroupContext'; +export type { AvatarContextValue } from './AvatarContext'; +export { AvatarContextProvider, useAvatarContext } from './AvatarContext'; 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-avatar/stories/src/AvatarGroup/index.stories.tsx b/packages/react-components/react-avatar/stories/src/AvatarGroup/index.stories.tsx index a36558a029e075..5060a6819261f6 100644 --- a/packages/react-components/react-avatar/stories/src/AvatarGroup/index.stories.tsx +++ b/packages/react-components/react-avatar/stories/src/AvatarGroup/index.stories.tsx @@ -1,4 +1,4 @@ -import { AvatarGroup } from '@fluentui/react-components'; +import { AvatarGroup, AvatarGroupItem, Avatar, AvatarGroupPopover } from '@fluentui/react-components'; import bestPracticesMd from './AvatarGroupBestPractices.md'; import descriptionMd from './AvatarGroupDescription.md'; @@ -14,6 +14,11 @@ export { Tooltip } from './AvatarGroupTooltip.stories'; export default { title: 'Components/AvatarGroup', component: AvatarGroup, + subcomponents: { + AvatarGroupItem, + Avatar, + AvatarGroupPopover, + }, parameters: { docs: { description: { diff --git a/packages/react-components/react-badge/library/CHANGELOG.json b/packages/react-components/react-badge/library/CHANGELOG.json index 6b5ef36214d189..efac2d70c8eec3 100644 --- a/packages/react-components/react-badge/library/CHANGELOG.json +++ b/packages/react-components/react-badge/library/CHANGELOG.json @@ -1,6 +1,90 @@ { "name": "@fluentui/react-badge", "entries": [ + { + "date": "Wed, 22 Jan 2025 14:00:21 GMT", + "tag": "@fluentui/react-badge_v9.2.50", + "version": "9.2.50", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-badge", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.50", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-badge", + "comment": "Bump @fluentui/react-utilities to v9.18.20", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + } + ] + } + }, + { + "date": "Wed, 08 Jan 2025 18:33:36 GMT", + "tag": "@fluentui/react-badge_v9.2.49", + "version": "9.2.49", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-badge", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.49", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + } + ] + } + }, + { + "date": "Mon, 16 Dec 2024 16:26:49 GMT", + "tag": "@fluentui/react-badge_v9.2.48", + "version": "9.2.48", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-badge", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.48", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-badge", + "comment": "Bump @fluentui/react-shared-contexts to v9.21.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-badge", + "comment": "Bump @fluentui/react-theme to v9.1.24", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-badge", + "comment": "Bump @fluentui/react-utilities to v9.18.19", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + } + ] + } + }, + { + "date": "Mon, 09 Dec 2024 17:38:08 GMT", + "tag": "@fluentui/react-badge_v9.2.47", + "version": "9.2.47", + "comments": { + "patch": [ + { + "author": "olfedias@microsoft.com", + "package": "@fluentui/react-badge", + "commit": "cad13936cd49ba0b34b50bc2f58395605c4e8da4", + "comment": "chore: remove usage of \"export *\"" + } + ] + } + }, { "date": "Fri, 06 Dec 2024 12:53:46 GMT", "tag": "@fluentui/react-badge_v9.2.46", diff --git a/packages/react-components/react-badge/library/CHANGELOG.md b/packages/react-components/react-badge/library/CHANGELOG.md index a59459fe8baea2..33347dfe86ee72 100644 --- a/packages/react-components/react-badge/library/CHANGELOG.md +++ b/packages/react-components/react-badge/library/CHANGELOG.md @@ -1,9 +1,49 @@ # Change Log - @fluentui/react-badge -This log was last generated on Fri, 06 Dec 2024 12:53:46 GMT and should not be manually modified. +This log was last generated on Wed, 22 Jan 2025 14:00:21 GMT and should not be manually modified. +## [9.2.50](https://github.com/microsoft/fluentui/tree/@fluentui/react-badge_v9.2.50) + +Wed, 22 Jan 2025 14:00:21 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-badge_v9.2.49..@fluentui/react-badge_v9.2.50) + +### Patches + +- Bump @fluentui/react-jsx-runtime to v9.0.50 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-utilities to v9.18.20 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) + +## [9.2.49](https://github.com/microsoft/fluentui/tree/@fluentui/react-badge_v9.2.49) + +Wed, 08 Jan 2025 18:33:36 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-badge_v9.2.48..@fluentui/react-badge_v9.2.49) + +### Patches + +- Bump @fluentui/react-jsx-runtime to v9.0.49 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) + +## [9.2.48](https://github.com/microsoft/fluentui/tree/@fluentui/react-badge_v9.2.48) + +Mon, 16 Dec 2024 16:26:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-badge_v9.2.47..@fluentui/react-badge_v9.2.48) + +### Patches + +- Bump @fluentui/react-jsx-runtime to v9.0.48 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-shared-contexts to v9.21.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-theme to v9.1.24 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-utilities to v9.18.19 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) + +## [9.2.47](https://github.com/microsoft/fluentui/tree/@fluentui/react-badge_v9.2.47) + +Mon, 09 Dec 2024 17:38:08 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-badge_v9.2.46..@fluentui/react-badge_v9.2.47) + +### Patches + +- chore: remove usage of "export *" ([PR #33384](https://github.com/microsoft/fluentui/pull/33384) by olfedias@microsoft.com) + ## [9.2.46](https://github.com/microsoft/fluentui/tree/@fluentui/react-badge_v9.2.46) Fri, 06 Dec 2024 12:53:46 GMT diff --git a/packages/react-components/react-badge/library/package.json b/packages/react-components/react-badge/library/package.json index 630537cf1d647f..870712d4dac4f7 100644 --- a/packages/react-components/react-badge/library/package.json +++ b/packages/react-components/react-badge/library/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-badge", - "version": "9.2.46", + "version": "9.2.50", "description": "React components for building web experiences", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -19,10 +19,10 @@ }, "dependencies": { "@fluentui/react-icons": "^2.0.245", - "@fluentui/react-jsx-runtime": "^9.0.47", - "@fluentui/react-shared-contexts": "^9.21.1", - "@fluentui/react-theme": "^9.1.23", - "@fluentui/react-utilities": "^9.18.18", + "@fluentui/react-jsx-runtime": "^9.0.50", + "@fluentui/react-shared-contexts": "^9.21.2", + "@fluentui/react-theme": "^9.1.24", + "@fluentui/react-utilities": "^9.18.20", "@griffel/react": "^1.5.22", "@swc/helpers": "^0.5.1" }, diff --git a/packages/react-components/react-badge/library/src/Badge.ts b/packages/react-components/react-badge/library/src/Badge.ts index 2735febca45d3d..56de48b1a2b87e 100644 --- a/packages/react-components/react-badge/library/src/Badge.ts +++ b/packages/react-components/react-badge/library/src/Badge.ts @@ -1 +1,8 @@ -export * from './components/Badge/index'; +export type { BadgeProps, BadgeSlots, BadgeState } from './components/Badge/index'; +export { + Badge, + badgeClassNames, + renderBadge_unstable, + useBadgeStyles_unstable, + useBadge_unstable, +} from './components/Badge/index'; diff --git a/packages/react-components/react-badge/library/src/CounterBadge.ts b/packages/react-components/react-badge/library/src/CounterBadge.ts index 4486f92bbb5859..7fad9f1447d63c 100644 --- a/packages/react-components/react-badge/library/src/CounterBadge.ts +++ b/packages/react-components/react-badge/library/src/CounterBadge.ts @@ -1 +1,7 @@ -export * from './components/CounterBadge/index'; +export type { CounterBadgeProps, CounterBadgeState } from './components/CounterBadge/index'; +export { + CounterBadge, + counterBadgeClassNames, + useCounterBadgeStyles_unstable, + useCounterBadge_unstable, +} from './components/CounterBadge/index'; diff --git a/packages/react-components/react-badge/library/src/PresenceBadge.ts b/packages/react-components/react-badge/library/src/PresenceBadge.ts index c67b3091e9f2df..84d192cfde4958 100644 --- a/packages/react-components/react-badge/library/src/PresenceBadge.ts +++ b/packages/react-components/react-badge/library/src/PresenceBadge.ts @@ -1 +1,18 @@ -export * from './components/PresenceBadge/index'; +export type { PresenceBadgeProps, PresenceBadgeState, PresenceBadgeStatus } from './components/PresenceBadge/index'; +export { + PresenceBadge, + presenceAvailableFilled, + presenceAvailableRegular, + presenceAwayFilled, + presenceAwayRegular, + presenceBadgeClassNames, + presenceBlockedRegular, + presenceBusyFilled, + presenceDndFilled, + presenceDndRegular, + presenceOfflineRegular, + presenceOofRegular, + presenceUnknownRegular, + usePresenceBadgeStyles_unstable, + usePresenceBadge_unstable, +} from './components/PresenceBadge/index'; diff --git a/packages/react-components/react-badge/library/src/components/Badge/index.ts b/packages/react-components/react-badge/library/src/components/Badge/index.ts index b74a9cefb773fb..94552cb73b051f 100644 --- a/packages/react-components/react-badge/library/src/components/Badge/index.ts +++ b/packages/react-components/react-badge/library/src/components/Badge/index.ts @@ -1,6 +1,6 @@ -export * from './Badge'; +export { Badge } from './Badge'; // Explicit exports to omit BadgeCommons export type { BadgeProps, BadgeSlots, BadgeState } from './Badge.types'; -export * from './renderBadge'; -export * from './useBadge'; -export * from './useBadgeStyles.styles'; +export { renderBadge_unstable } from './renderBadge'; +export { useBadge_unstable } from './useBadge'; +export { badgeClassNames, useBadgeStyles_unstable } from './useBadgeStyles.styles'; diff --git a/packages/react-components/react-badge/library/src/components/CounterBadge/index.ts b/packages/react-components/react-badge/library/src/components/CounterBadge/index.ts index 2534ccd5622dda..2c149ed8d8fbd7 100644 --- a/packages/react-components/react-badge/library/src/components/CounterBadge/index.ts +++ b/packages/react-components/react-badge/library/src/components/CounterBadge/index.ts @@ -1,4 +1,4 @@ -export * from './CounterBadge'; -export * from './CounterBadge.types'; -export * from './useCounterBadge'; -export * from './useCounterBadgeStyles.styles'; +export { CounterBadge } from './CounterBadge'; +export type { CounterBadgeProps, CounterBadgeState } from './CounterBadge.types'; +export { useCounterBadge_unstable } from './useCounterBadge'; +export { counterBadgeClassNames, useCounterBadgeStyles_unstable } from './useCounterBadgeStyles.styles'; diff --git a/packages/react-components/react-badge/library/src/components/PresenceBadge/index.ts b/packages/react-components/react-badge/library/src/components/PresenceBadge/index.ts index 495291e5a2ebd4..ca264ac9288d3c 100644 --- a/packages/react-components/react-badge/library/src/components/PresenceBadge/index.ts +++ b/packages/react-components/react-badge/library/src/components/PresenceBadge/index.ts @@ -1,5 +1,17 @@ -export * from './PresenceBadge'; -export * from './PresenceBadge.types'; -export * from './usePresenceBadge'; -export * from './usePresenceBadgeStyles.styles'; -export * from './presenceIcons'; +export { PresenceBadge } from './PresenceBadge'; +export type { PresenceBadgeProps, PresenceBadgeState, PresenceBadgeStatus } from './PresenceBadge.types'; +export { usePresenceBadge_unstable } from './usePresenceBadge'; +export { presenceBadgeClassNames, usePresenceBadgeStyles_unstable } from './usePresenceBadgeStyles.styles'; +export { + presenceAvailableFilled, + presenceAvailableRegular, + presenceAwayFilled, + presenceAwayRegular, + presenceBlockedRegular, + presenceBusyFilled, + presenceDndFilled, + presenceDndRegular, + presenceOfflineRegular, + presenceOofRegular, + presenceUnknownRegular, +} from './presenceIcons'; diff --git a/packages/react-components/react-breadcrumb/library/CHANGELOG.json b/packages/react-components/react-breadcrumb/library/CHANGELOG.json index 5da28e7b112745..46f8d18c99b103 100644 --- a/packages/react-components/react-breadcrumb/library/CHANGELOG.json +++ b/packages/react-components/react-breadcrumb/library/CHANGELOG.json @@ -1,6 +1,237 @@ { "name": "@fluentui/react-breadcrumb", "entries": [ + { + "date": "Fri, 21 Feb 2025 14:34:05 GMT", + "tag": "@fluentui/react-breadcrumb_v9.1.0", + "version": "9.1.0", + "comments": { + "minor": [ + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-aria to v9.14.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + }, + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-button to v9.4.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + }, + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-link to v9.4.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + }, + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-tabster to v9.24.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + } + ] + } + }, + { + "date": "Fri, 07 Feb 2025 10:42:12 GMT", + "tag": "@fluentui/react-breadcrumb_v9.0.52", + "version": "9.0.52", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-button to v9.3.102", + "commit": "b37554b631f4e27e0927b123732f3d57d62660a3" + } + ] + } + }, + { + "date": "Tue, 28 Jan 2025 21:26:35 GMT", + "tag": "@fluentui/react-breadcrumb_v9.0.51", + "version": "9.0.51", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-button to v9.3.101", + "commit": "a081a7573fa328d640c2efb0127f2be99a1368f8" + } + ] + } + }, + { + "date": "Wed, 22 Jan 2025 14:00:21 GMT", + "tag": "@fluentui/react-breadcrumb_v9.0.49", + "version": "9.0.49", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-aria to v9.13.14", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-button to v9.3.100", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-link to v9.3.7", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-tabster to v9.23.3", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-utilities to v9.18.20", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.50", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + } + ] + } + }, + { + "date": "Wed, 08 Jan 2025 18:33:36 GMT", + "tag": "@fluentui/react-breadcrumb_v9.0.48", + "version": "9.0.48", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-aria to v9.13.13", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + }, + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-button to v9.3.99", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + }, + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-link to v9.3.6", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + }, + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.49", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + } + ] + } + }, + { + "date": "Mon, 16 Dec 2024 16:26:49 GMT", + "tag": "@fluentui/react-breadcrumb_v9.0.46", + "version": "9.0.46", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-aria to v9.13.12", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-button to v9.3.98", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-link to v9.3.5", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-shared-contexts to v9.21.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-tabster to v9.23.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-theme to v9.1.24", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-utilities to v9.18.19", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.48", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + } + ] + } + }, + { + "date": "Mon, 09 Dec 2024 17:38:09 GMT", + "tag": "@fluentui/react-breadcrumb_v9.0.45", + "version": "9.0.45", + "comments": { + "patch": [ + { + "author": "olfedias@microsoft.com", + "package": "@fluentui/react-breadcrumb", + "commit": "cad13936cd49ba0b34b50bc2f58395605c4e8da4", + "comment": "chore: remove usage of \"export *\"" + }, + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-aria to v9.13.11", + "commit": "80f2ce07be06e66b369bd18e4484d8faf6b493c7" + }, + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-button to v9.3.97", + "commit": "80f2ce07be06e66b369bd18e4484d8faf6b493c7" + }, + { + "author": "beachball", + "package": "@fluentui/react-breadcrumb", + "comment": "Bump @fluentui/react-link to v9.3.4", + "commit": "80f2ce07be06e66b369bd18e4484d8faf6b493c7" + } + ] + } + }, { "date": "Fri, 06 Dec 2024 12:53:38 GMT", "tag": "@fluentui/react-breadcrumb_v9.0.44", diff --git a/packages/react-components/react-breadcrumb/library/CHANGELOG.md b/packages/react-components/react-breadcrumb/library/CHANGELOG.md index a1bcc5c4f3a2d2..2703b995d1eb2a 100644 --- a/packages/react-components/react-breadcrumb/library/CHANGELOG.md +++ b/packages/react-components/react-breadcrumb/library/CHANGELOG.md @@ -1,9 +1,93 @@ # Change Log - @fluentui/react-breadcrumb -This log was last generated on Fri, 06 Dec 2024 12:53:38 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 14:34:05 GMT and should not be manually modified. +## [9.1.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-breadcrumb_v9.1.0) + +Fri, 21 Feb 2025 14:34:05 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-breadcrumb_v9.0.52..@fluentui/react-breadcrumb_v9.1.0) + +### Minor changes + +- Bump @fluentui/react-aria to v9.14.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) +- Bump @fluentui/react-button to v9.4.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) +- Bump @fluentui/react-link to v9.4.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) +- Bump @fluentui/react-tabster to v9.24.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) + +## [9.0.52](https://github.com/microsoft/fluentui/tree/@fluentui/react-breadcrumb_v9.0.52) + +Fri, 07 Feb 2025 10:42:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-breadcrumb_v9.0.51..@fluentui/react-breadcrumb_v9.0.52) + +### Patches + +- Bump @fluentui/react-button to v9.3.102 ([PR #33797](https://github.com/microsoft/fluentui/pull/33797) by beachball) + +## [9.0.51](https://github.com/microsoft/fluentui/tree/@fluentui/react-breadcrumb_v9.0.51) + +Tue, 28 Jan 2025 21:26:35 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-breadcrumb_v9.0.49..@fluentui/react-breadcrumb_v9.0.51) + +### Patches + +- Bump @fluentui/react-button to v9.3.101 ([PR #33736](https://github.com/microsoft/fluentui/pull/33736) by beachball) + +## [9.0.49](https://github.com/microsoft/fluentui/tree/@fluentui/react-breadcrumb_v9.0.49) + +Wed, 22 Jan 2025 14:00:21 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-breadcrumb_v9.0.48..@fluentui/react-breadcrumb_v9.0.49) + +### Patches + +- Bump @fluentui/react-aria to v9.13.14 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-button to v9.3.100 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-link to v9.3.7 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-tabster to v9.23.3 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-utilities to v9.18.20 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.50 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) + +## [9.0.48](https://github.com/microsoft/fluentui/tree/@fluentui/react-breadcrumb_v9.0.48) + +Wed, 08 Jan 2025 18:33:36 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-breadcrumb_v9.0.46..@fluentui/react-breadcrumb_v9.0.48) + +### Patches + +- Bump @fluentui/react-aria to v9.13.13 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-button to v9.3.99 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-link to v9.3.6 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.49 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) + +## [9.0.46](https://github.com/microsoft/fluentui/tree/@fluentui/react-breadcrumb_v9.0.46) + +Mon, 16 Dec 2024 16:26:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-breadcrumb_v9.0.45..@fluentui/react-breadcrumb_v9.0.46) + +### Patches + +- Bump @fluentui/react-aria to v9.13.12 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-button to v9.3.98 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-link to v9.3.5 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-shared-contexts to v9.21.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-tabster to v9.23.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-theme to v9.1.24 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-utilities to v9.18.19 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.48 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) + +## [9.0.45](https://github.com/microsoft/fluentui/tree/@fluentui/react-breadcrumb_v9.0.45) + +Mon, 09 Dec 2024 17:38:09 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-breadcrumb_v9.0.44..@fluentui/react-breadcrumb_v9.0.45) + +### Patches + +- chore: remove usage of "export *" ([PR #33384](https://github.com/microsoft/fluentui/pull/33384) by olfedias@microsoft.com) +- Bump @fluentui/react-aria to v9.13.11 ([PR #33431](https://github.com/microsoft/fluentui/pull/33431) by beachball) +- Bump @fluentui/react-button to v9.3.97 ([PR #33431](https://github.com/microsoft/fluentui/pull/33431) by beachball) +- Bump @fluentui/react-link to v9.3.4 ([PR #33431](https://github.com/microsoft/fluentui/pull/33431) by beachball) + ## [9.0.44](https://github.com/microsoft/fluentui/tree/@fluentui/react-breadcrumb_v9.0.44) Fri, 06 Dec 2024 12:53:38 GMT diff --git a/packages/react-components/react-breadcrumb/library/package.json b/packages/react-components/react-breadcrumb/library/package.json index 490beac953382a..c9d69b9b8446b2 100644 --- a/packages/react-components/react-breadcrumb/library/package.json +++ b/packages/react-components/react-breadcrumb/library/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-breadcrumb", - "version": "9.0.44", + "version": "9.1.0", "description": "Breadcrumb component for Fluent UI React.", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -22,15 +22,15 @@ "@fluentui/scripts-cypress": "*" }, "dependencies": { - "@fluentui/react-aria": "^9.13.10", - "@fluentui/react-button": "^9.3.96", + "@fluentui/react-aria": "^9.14.0", + "@fluentui/react-button": "^9.4.0", "@fluentui/react-icons": "^2.0.245", - "@fluentui/react-link": "^9.3.3", - "@fluentui/react-shared-contexts": "^9.21.1", - "@fluentui/react-tabster": "^9.23.1", - "@fluentui/react-theme": "^9.1.23", - "@fluentui/react-utilities": "^9.18.18", - "@fluentui/react-jsx-runtime": "^9.0.47", + "@fluentui/react-link": "^9.4.0", + "@fluentui/react-shared-contexts": "^9.21.2", + "@fluentui/react-tabster": "^9.24.0", + "@fluentui/react-theme": "^9.1.24", + "@fluentui/react-utilities": "^9.18.20", + "@fluentui/react-jsx-runtime": "^9.0.50", "@griffel/react": "^1.5.22", "@swc/helpers": "^0.5.1" }, diff --git a/packages/react-components/react-breadcrumb/library/src/Breadcrumb.ts b/packages/react-components/react-breadcrumb/library/src/Breadcrumb.ts index 64b84fda7c7917..2feb00f9ed21b8 100644 --- a/packages/react-components/react-breadcrumb/library/src/Breadcrumb.ts +++ b/packages/react-components/react-breadcrumb/library/src/Breadcrumb.ts @@ -1 +1,16 @@ -export * from './components/Breadcrumb/index'; +export type { + BreadcrumbContextValues, + BreadcrumbProps, + BreadcrumbSlots, + BreadcrumbState, +} from './components/Breadcrumb/index'; +export { + Breadcrumb, + BreadcrumbProvider, + breadcrumbClassNames, + breadcrumbDefaultValue, + renderBreadcrumb_unstable, + useBreadcrumbContext_unstable, + useBreadcrumbStyles_unstable, + useBreadcrumb_unstable, +} from './components/Breadcrumb/index'; diff --git a/packages/react-components/react-breadcrumb/library/src/BreadcrumbButton.ts b/packages/react-components/react-breadcrumb/library/src/BreadcrumbButton.ts index 3cf12c11c45937..f525aba4b13c8e 100644 --- a/packages/react-components/react-breadcrumb/library/src/BreadcrumbButton.ts +++ b/packages/react-components/react-breadcrumb/library/src/BreadcrumbButton.ts @@ -1 +1,12 @@ -export * from './components/BreadcrumbButton/index'; +export type { + BreadcrumbButtonProps, + BreadcrumbButtonSlots, + BreadcrumbButtonState, +} from './components/BreadcrumbButton/index'; +export { + BreadcrumbButton, + breadcrumbButtonClassNames, + renderBreadcrumbButton_unstable, + useBreadcrumbButtonStyles_unstable, + useBreadcrumbButton_unstable, +} from './components/BreadcrumbButton/index'; diff --git a/packages/react-components/react-breadcrumb/library/src/BreadcrumbDivider.ts b/packages/react-components/react-breadcrumb/library/src/BreadcrumbDivider.ts index b38620b9c532e3..c0c7374debdbbc 100644 --- a/packages/react-components/react-breadcrumb/library/src/BreadcrumbDivider.ts +++ b/packages/react-components/react-breadcrumb/library/src/BreadcrumbDivider.ts @@ -1 +1,12 @@ -export * from './components/BreadcrumbDivider/index'; +export type { + BreadcrumbDividerProps, + BreadcrumbDividerSlots, + BreadcrumbDividerState, +} from './components/BreadcrumbDivider/index'; +export { + BreadcrumbDivider, + breadcrumbDividerClassNames, + renderBreadcrumbDivider_unstable, + useBreadcrumbDividerStyles_unstable, + useBreadcrumbDivider_unstable, +} from './components/BreadcrumbDivider/index'; diff --git a/packages/react-components/react-breadcrumb/library/src/BreadcrumbItem.ts b/packages/react-components/react-breadcrumb/library/src/BreadcrumbItem.ts index 7f84c993cca3cb..42a2163236606b 100644 --- a/packages/react-components/react-breadcrumb/library/src/BreadcrumbItem.ts +++ b/packages/react-components/react-breadcrumb/library/src/BreadcrumbItem.ts @@ -1 +1,8 @@ -export * from './components/BreadcrumbItem/index'; +export type { BreadcrumbItemProps, BreadcrumbItemSlots, BreadcrumbItemState } from './components/BreadcrumbItem/index'; +export { + BreadcrumbItem, + breadcrumbItemClassNames, + renderBreadcrumbItem_unstable, + useBreadcrumbItemStyles_unstable, + useBreadcrumbItem_unstable, +} from './components/BreadcrumbItem/index'; diff --git a/packages/react-components/react-breadcrumb/library/src/components/Breadcrumb/index.ts b/packages/react-components/react-breadcrumb/library/src/components/Breadcrumb/index.ts index 0db3ad8b2dcd21..8da2c7b8036135 100644 --- a/packages/react-components/react-breadcrumb/library/src/components/Breadcrumb/index.ts +++ b/packages/react-components/react-breadcrumb/library/src/components/Breadcrumb/index.ts @@ -1,6 +1,6 @@ -export * from './Breadcrumb'; -export * from './Breadcrumb.types'; -export * from './BreadcrumbContext'; -export * from './renderBreadcrumb'; -export * from './useBreadcrumb'; -export * from './useBreadcrumbStyles.styles'; +export { Breadcrumb } from './Breadcrumb'; +export type { BreadcrumbContextValues, BreadcrumbProps, BreadcrumbSlots, BreadcrumbState } from './Breadcrumb.types'; +export { BreadcrumbProvider, breadcrumbDefaultValue, useBreadcrumbContext_unstable } from './BreadcrumbContext'; +export { renderBreadcrumb_unstable } from './renderBreadcrumb'; +export { useBreadcrumb_unstable } from './useBreadcrumb'; +export { breadcrumbClassNames, useBreadcrumbStyles_unstable } from './useBreadcrumbStyles.styles'; diff --git a/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbButton/index.ts b/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbButton/index.ts index d972283c4ee090..817c2ee01cc28a 100644 --- a/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbButton/index.ts +++ b/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbButton/index.ts @@ -1,5 +1,5 @@ -export * from './BreadcrumbButton'; -export * from './BreadcrumbButton.types'; -export * from './renderBreadcrumbButton'; -export * from './useBreadcrumbButton'; -export * from './useBreadcrumbButtonStyles.styles'; +export { BreadcrumbButton } from './BreadcrumbButton'; +export type { BreadcrumbButtonProps, BreadcrumbButtonSlots, BreadcrumbButtonState } from './BreadcrumbButton.types'; +export { renderBreadcrumbButton_unstable } from './renderBreadcrumbButton'; +export { useBreadcrumbButton_unstable } from './useBreadcrumbButton'; +export { breadcrumbButtonClassNames, useBreadcrumbButtonStyles_unstable } from './useBreadcrumbButtonStyles.styles'; diff --git a/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbDivider/index.ts b/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbDivider/index.ts index e984ecbb9aeb89..87a01d0cb8e96d 100644 --- a/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbDivider/index.ts +++ b/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbDivider/index.ts @@ -1,5 +1,5 @@ -export * from './BreadcrumbDivider'; -export * from './BreadcrumbDivider.types'; -export * from './renderBreadcrumbDivider'; -export * from './useBreadcrumbDivider'; -export * from './useBreadcrumbDividerStyles.styles'; +export { BreadcrumbDivider } from './BreadcrumbDivider'; +export type { BreadcrumbDividerProps, BreadcrumbDividerSlots, BreadcrumbDividerState } from './BreadcrumbDivider.types'; +export { renderBreadcrumbDivider_unstable } from './renderBreadcrumbDivider'; +export { useBreadcrumbDivider_unstable } from './useBreadcrumbDivider'; +export { breadcrumbDividerClassNames, useBreadcrumbDividerStyles_unstable } from './useBreadcrumbDividerStyles.styles'; diff --git a/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbItem/index.ts b/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbItem/index.ts index c5bfc978fdde03..bd92e54aee7ba5 100644 --- a/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbItem/index.ts +++ b/packages/react-components/react-breadcrumb/library/src/components/BreadcrumbItem/index.ts @@ -1,5 +1,5 @@ -export * from './BreadcrumbItem'; -export * from './BreadcrumbItem.types'; -export * from './renderBreadcrumbItem'; -export * from './useBreadcrumbItem'; -export * from './useBreadcrumbItemStyles.styles'; +export { BreadcrumbItem } from './BreadcrumbItem'; +export type { BreadcrumbItemProps, BreadcrumbItemSlots, BreadcrumbItemState } from './BreadcrumbItem.types'; +export { renderBreadcrumbItem_unstable } from './renderBreadcrumbItem'; +export { useBreadcrumbItem_unstable } from './useBreadcrumbItem'; +export { breadcrumbItemClassNames, useBreadcrumbItemStyles_unstable } from './useBreadcrumbItemStyles.styles'; diff --git a/packages/react-components/react-button/library/CHANGELOG.json b/packages/react-components/react-button/library/CHANGELOG.json index 0299abfe30011e..88087672659ea4 100644 --- a/packages/react-components/react-button/library/CHANGELOG.json +++ b/packages/react-components/react-button/library/CHANGELOG.json @@ -1,6 +1,177 @@ { "name": "@fluentui/react-button", "entries": [ + { + "date": "Fri, 21 Feb 2025 14:34:05 GMT", + "tag": "@fluentui/react-button_v9.4.0", + "version": "9.4.0", + "comments": { + "minor": [ + { + "author": "beachball", + "package": "@fluentui/react-button", + "comment": "Bump @fluentui/react-aria to v9.14.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + }, + { + "author": "beachball", + "package": "@fluentui/react-button", + "comment": "Bump @fluentui/react-tabster to v9.24.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + } + ] + } + }, + { + "date": "Fri, 07 Feb 2025 10:42:11 GMT", + "tag": "@fluentui/react-button_v9.3.102", + "version": "9.3.102", + "comments": { + "patch": [ + { + "author": "sarah.higley@microsoft.com", + "package": "@fluentui/react-button", + "commit": "da62e83423063b6ab3ed62e62bcb965f37cf5700", + "comment": "fix: Button sets correct disabledFocusable icon color" + } + ] + } + }, + { + "date": "Tue, 28 Jan 2025 21:26:33 GMT", + "tag": "@fluentui/react-button_v9.3.101", + "version": "9.3.101", + "comments": { + "patch": [ + { + "author": "vgenaev@gmail.com", + "package": "@fluentui/react-button", + "commit": "61d6bbe9279d1184ee455c2fa5b1c8b05bfd6f6b", + "comment": "fix: make SplitButton divider transparent for subtle and transparent variants" + } + ] + } + }, + { + "date": "Wed, 22 Jan 2025 14:00:21 GMT", + "tag": "@fluentui/react-button_v9.3.100", + "version": "9.3.100", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-button", + "comment": "Bump @fluentui/react-aria to v9.13.14", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-button", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.50", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-button", + "comment": "Bump @fluentui/react-tabster to v9.23.3", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-button", + "comment": "Bump @fluentui/react-utilities to v9.18.20", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + } + ] + } + }, + { + "date": "Wed, 08 Jan 2025 18:33:36 GMT", + "tag": "@fluentui/react-button_v9.3.99", + "version": "9.3.99", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-button", + "comment": "Bump @fluentui/react-aria to v9.13.13", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + }, + { + "author": "beachball", + "package": "@fluentui/react-button", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.49", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + } + ] + } + }, + { + "date": "Mon, 16 Dec 2024 16:26:47 GMT", + "tag": "@fluentui/react-button_v9.3.98", + "version": "9.3.98", + "comments": { + "patch": [ + { + "author": "olfedias@microsoft.com", + "package": "@fluentui/react-button", + "commit": "f15afa79910b9998044dddcce63e9583e4f8b905", + "comment": "chore: remove usage of \"export *\"" + }, + { + "author": "beachball", + "package": "@fluentui/react-button", + "comment": "Bump @fluentui/react-aria to v9.13.12", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-button", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.48", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-button", + "comment": "Bump @fluentui/react-shared-contexts to v9.21.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-button", + "comment": "Bump @fluentui/react-tabster to v9.23.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-button", + "comment": "Bump @fluentui/react-theme to v9.1.24", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-button", + "comment": "Bump @fluentui/react-utilities to v9.18.19", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + } + ] + } + }, + { + "date": "Mon, 09 Dec 2024 17:38:16 GMT", + "tag": "@fluentui/react-button_v9.3.97", + "version": "9.3.97", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-button", + "comment": "Bump @fluentui/react-aria to v9.13.11", + "commit": "80f2ce07be06e66b369bd18e4484d8faf6b493c7" + } + ] + } + }, { "date": "Fri, 06 Dec 2024 12:53:46 GMT", "tag": "@fluentui/react-button_v9.3.96", diff --git a/packages/react-components/react-button/library/CHANGELOG.md b/packages/react-components/react-button/library/CHANGELOG.md index 74fafe359e276f..e6483b062b8d4c 100644 --- a/packages/react-components/react-button/library/CHANGELOG.md +++ b/packages/react-components/react-button/library/CHANGELOG.md @@ -1,9 +1,83 @@ # Change Log - @fluentui/react-button -This log was last generated on Fri, 06 Dec 2024 12:53:46 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 14:34:05 GMT and should not be manually modified. +## [9.4.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-button_v9.4.0) + +Fri, 21 Feb 2025 14:34:05 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-button_v9.3.102..@fluentui/react-button_v9.4.0) + +### Minor changes + +- Bump @fluentui/react-aria to v9.14.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) +- Bump @fluentui/react-tabster to v9.24.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) + +## [9.3.102](https://github.com/microsoft/fluentui/tree/@fluentui/react-button_v9.3.102) + +Fri, 07 Feb 2025 10:42:11 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-button_v9.3.101..@fluentui/react-button_v9.3.102) + +### Patches + +- fix: Button sets correct disabledFocusable icon color ([PR #33756](https://github.com/microsoft/fluentui/pull/33756) by sarah.higley@microsoft.com) + +## [9.3.101](https://github.com/microsoft/fluentui/tree/@fluentui/react-button_v9.3.101) + +Tue, 28 Jan 2025 21:26:33 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-button_v9.3.100..@fluentui/react-button_v9.3.101) + +### Patches + +- fix: make SplitButton divider transparent for subtle and transparent variants ([PR #33726](https://github.com/microsoft/fluentui/pull/33726) by vgenaev@gmail.com) + +## [9.3.100](https://github.com/microsoft/fluentui/tree/@fluentui/react-button_v9.3.100) + +Wed, 22 Jan 2025 14:00:21 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-button_v9.3.99..@fluentui/react-button_v9.3.100) + +### Patches + +- Bump @fluentui/react-aria to v9.13.14 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.50 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-tabster to v9.23.3 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-utilities to v9.18.20 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) + +## [9.3.99](https://github.com/microsoft/fluentui/tree/@fluentui/react-button_v9.3.99) + +Wed, 08 Jan 2025 18:33:36 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-button_v9.3.98..@fluentui/react-button_v9.3.99) + +### Patches + +- Bump @fluentui/react-aria to v9.13.13 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.49 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) + +## [9.3.98](https://github.com/microsoft/fluentui/tree/@fluentui/react-button_v9.3.98) + +Mon, 16 Dec 2024 16:26:47 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-button_v9.3.97..@fluentui/react-button_v9.3.98) + +### Patches + +- chore: remove usage of "export *" ([PR #33457](https://github.com/microsoft/fluentui/pull/33457) by olfedias@microsoft.com) +- Bump @fluentui/react-aria to v9.13.12 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.48 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-shared-contexts to v9.21.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-tabster to v9.23.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-theme to v9.1.24 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-utilities to v9.18.19 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) + +## [9.3.97](https://github.com/microsoft/fluentui/tree/@fluentui/react-button_v9.3.97) + +Mon, 09 Dec 2024 17:38:16 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-button_v9.3.96..@fluentui/react-button_v9.3.97) + +### Patches + +- Bump @fluentui/react-aria to v9.13.11 ([PR #33431](https://github.com/microsoft/fluentui/pull/33431) by beachball) + ## [9.3.96](https://github.com/microsoft/fluentui/tree/@fluentui/react-button_v9.3.96) Fri, 06 Dec 2024 12:53:46 GMT diff --git a/packages/react-components/react-button/library/package.json b/packages/react-components/react-button/library/package.json index 3146f701d5ed25..b7b6f9c075749e 100644 --- a/packages/react-components/react-button/library/package.json +++ b/packages/react-components/react-button/library/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-button", - "version": "9.3.96", + "version": "9.4.0", "description": "Fluent UI React Button component.", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -20,13 +20,13 @@ }, "dependencies": { "@fluentui/keyboard-keys": "^9.0.8", - "@fluentui/react-aria": "^9.13.10", + "@fluentui/react-aria": "^9.14.0", "@fluentui/react-icons": "^2.0.245", - "@fluentui/react-jsx-runtime": "^9.0.47", - "@fluentui/react-shared-contexts": "^9.21.1", - "@fluentui/react-tabster": "^9.23.1", - "@fluentui/react-theme": "^9.1.23", - "@fluentui/react-utilities": "^9.18.18", + "@fluentui/react-jsx-runtime": "^9.0.50", + "@fluentui/react-shared-contexts": "^9.21.2", + "@fluentui/react-tabster": "^9.24.0", + "@fluentui/react-theme": "^9.1.24", + "@fluentui/react-utilities": "^9.18.20", "@griffel/react": "^1.5.22", "@swc/helpers": "^0.5.1" }, diff --git a/packages/react-components/react-button/library/src/Button.tsx b/packages/react-components/react-button/library/src/Button.tsx index a26b1440791325..ce711cd84c1d25 100644 --- a/packages/react-components/react-button/library/src/Button.tsx +++ b/packages/react-components/react-button/library/src/Button.tsx @@ -1 +1,8 @@ -export * from './components/Button/index'; +export type { ButtonProps, ButtonSlots, ButtonState } from './components/Button/index'; +export { + Button, + buttonClassNames, + renderButton_unstable, + useButtonStyles_unstable, + useButton_unstable, +} from './components/Button/index'; diff --git a/packages/react-components/react-button/library/src/CompoundButton.ts b/packages/react-components/react-button/library/src/CompoundButton.ts index efb920c2c458c2..bcaaab10d42d2a 100644 --- a/packages/react-components/react-button/library/src/CompoundButton.ts +++ b/packages/react-components/react-button/library/src/CompoundButton.ts @@ -1 +1,8 @@ -export * from './components/CompoundButton/index'; +export type { CompoundButtonProps, CompoundButtonSlots, CompoundButtonState } from './components/CompoundButton/index'; +export { + CompoundButton, + compoundButtonClassNames, + renderCompoundButton_unstable, + useCompoundButtonStyles_unstable, + useCompoundButton_unstable, +} from './components/CompoundButton/index'; diff --git a/packages/react-components/react-button/library/src/MenuButton.ts b/packages/react-components/react-button/library/src/MenuButton.ts index 97b690d11ee4dd..785ec93d696673 100644 --- a/packages/react-components/react-button/library/src/MenuButton.ts +++ b/packages/react-components/react-button/library/src/MenuButton.ts @@ -1 +1,8 @@ -export * from './components/MenuButton/index'; +export type { MenuButtonProps, MenuButtonSlots, MenuButtonState } from './components/MenuButton/index'; +export { + MenuButton, + menuButtonClassNames, + renderMenuButton_unstable, + useMenuButtonStyles_unstable, + useMenuButton_unstable, +} from './components/MenuButton/index'; diff --git a/packages/react-components/react-button/library/src/SplitButton.ts b/packages/react-components/react-button/library/src/SplitButton.ts index 6a45500d356140..4b3dc83adc8d5b 100644 --- a/packages/react-components/react-button/library/src/SplitButton.ts +++ b/packages/react-components/react-button/library/src/SplitButton.ts @@ -1 +1,8 @@ -export * from './components/SplitButton/index'; +export type { SplitButtonProps, SplitButtonSlots, SplitButtonState } from './components/SplitButton/index'; +export { + SplitButton, + renderSplitButton_unstable, + splitButtonClassNames, + useSplitButtonStyles_unstable, + useSplitButton_unstable, +} from './components/SplitButton/index'; diff --git a/packages/react-components/react-button/library/src/ToggleButton.ts b/packages/react-components/react-button/library/src/ToggleButton.ts index 5d5920d8598f08..21846587fad4ee 100644 --- a/packages/react-components/react-button/library/src/ToggleButton.ts +++ b/packages/react-components/react-button/library/src/ToggleButton.ts @@ -1 +1,8 @@ -export * from './components/ToggleButton/index'; +export type { ToggleButtonProps, ToggleButtonState } from './components/ToggleButton/index'; +export { + ToggleButton, + renderToggleButton_unstable, + toggleButtonClassNames, + useToggleButtonStyles_unstable, + useToggleButton_unstable, +} from './components/ToggleButton/index'; diff --git a/packages/react-components/react-button/library/src/components/Button/index.ts b/packages/react-components/react-button/library/src/components/Button/index.ts index 13abd561ef142f..0c8139e9838f2d 100644 --- a/packages/react-components/react-button/library/src/components/Button/index.ts +++ b/packages/react-components/react-button/library/src/components/Button/index.ts @@ -1,6 +1,6 @@ -export * from './Button'; +export { Button } from './Button'; // Explicit exports to omit ButtonCommons export type { ButtonProps, ButtonSlots, ButtonState } from './Button.types'; -export * from './renderButton'; -export * from './useButton'; +export { renderButton_unstable } from './renderButton'; +export { useButton_unstable } from './useButton'; export { buttonClassNames, useButtonStyles_unstable } from './useButtonStyles.styles'; diff --git a/packages/react-components/react-button/library/src/components/Button/useButtonStyles.styles.ts b/packages/react-components/react-button/library/src/components/Button/useButtonStyles.styles.ts index 7c609920f10605..e2ed9b065e57f9 100644 --- a/packages/react-components/react-button/library/src/components/Button/useButtonStyles.styles.ts +++ b/packages/react-components/react-button/library/src/components/Button/useButtonStyles.styles.ts @@ -373,6 +373,10 @@ const useRootDisabledStyles = makeStyles({ ...shorthands.borderColor('GrayText'), color: 'GrayText', + [`& .${buttonClassNames.icon}`]: { + color: 'GrayText', + }, + ':focus': { ...shorthands.borderColor('GrayText'), }, @@ -381,12 +385,20 @@ const useRootDisabledStyles = makeStyles({ backgroundColor: 'ButtonFace', ...shorthands.borderColor('GrayText'), color: 'GrayText', + + [`& .${buttonClassNames.icon}`]: { + color: 'GrayText', + }, }, ':hover:active': { backgroundColor: 'ButtonFace', ...shorthands.borderColor('GrayText'), color: 'GrayText', + + [`& .${buttonClassNames.icon}`]: { + color: 'GrayText', + }, }, }, }, diff --git a/packages/react-components/react-button/library/src/components/CompoundButton/index.ts b/packages/react-components/react-button/library/src/components/CompoundButton/index.ts index e5682a639bc944..388384ad7be0cf 100644 --- a/packages/react-components/react-button/library/src/components/CompoundButton/index.ts +++ b/packages/react-components/react-button/library/src/components/CompoundButton/index.ts @@ -1,5 +1,5 @@ -export * from './CompoundButton'; -export * from './CompoundButton.types'; -export * from './renderCompoundButton'; -export * from './useCompoundButton'; +export { CompoundButton } from './CompoundButton'; +export type { CompoundButtonProps, CompoundButtonSlots, CompoundButtonState } from './CompoundButton.types'; +export { renderCompoundButton_unstable } from './renderCompoundButton'; +export { useCompoundButton_unstable } from './useCompoundButton'; export { compoundButtonClassNames, useCompoundButtonStyles_unstable } from './useCompoundButtonStyles.styles'; diff --git a/packages/react-components/react-button/library/src/components/MenuButton/index.ts b/packages/react-components/react-button/library/src/components/MenuButton/index.ts index 3c101cb75fb087..f81604be3c3ab8 100644 --- a/packages/react-components/react-button/library/src/components/MenuButton/index.ts +++ b/packages/react-components/react-button/library/src/components/MenuButton/index.ts @@ -1,5 +1,5 @@ -export * from './MenuButton.types'; -export * from './MenuButton'; -export * from './renderMenuButton'; -export * from './useMenuButton'; +export type { MenuButtonProps, MenuButtonSlots, MenuButtonState } from './MenuButton.types'; +export { MenuButton } from './MenuButton'; +export { renderMenuButton_unstable } from './renderMenuButton'; +export { useMenuButton_unstable } from './useMenuButton'; export { menuButtonClassNames, useMenuButtonStyles_unstable } from './useMenuButtonStyles.styles'; diff --git a/packages/react-components/react-button/library/src/components/SplitButton/index.ts b/packages/react-components/react-button/library/src/components/SplitButton/index.ts index e2093e966b8822..ba8bc5714108e2 100644 --- a/packages/react-components/react-button/library/src/components/SplitButton/index.ts +++ b/packages/react-components/react-button/library/src/components/SplitButton/index.ts @@ -1,5 +1,5 @@ -export * from './SplitButton'; -export * from './SplitButton.types'; -export * from './renderSplitButton'; -export * from './useSplitButton'; +export { SplitButton } from './SplitButton'; +export type { SplitButtonProps, SplitButtonSlots, SplitButtonState } from './SplitButton.types'; +export { renderSplitButton_unstable } from './renderSplitButton'; +export { useSplitButton_unstable } from './useSplitButton'; export { splitButtonClassNames, useSplitButtonStyles_unstable } from './useSplitButtonStyles.styles'; diff --git a/packages/react-components/react-button/library/src/components/SplitButton/useSplitButtonStyles.styles.ts b/packages/react-components/react-button/library/src/components/SplitButton/useSplitButtonStyles.styles.ts index f3ebfaf3efa880..f5b9d126160cc8 100644 --- a/packages/react-components/react-button/library/src/components/SplitButton/useSplitButtonStyles.styles.ts +++ b/packages/react-components/react-button/library/src/components/SplitButton/useSplitButtonStyles.styles.ts @@ -92,35 +92,35 @@ const useRootStyles = makeStyles({ }, subtle: { [`& .${splitButtonClassNames.primaryActionButton}`]: { - borderRightColor: tokens.colorNeutralStroke1, + borderRightColor: tokens.colorTransparentBackground, }, ':hover': { [`& .${splitButtonClassNames.primaryActionButton}`]: { - borderRightColor: tokens.colorNeutralStroke1Hover, + borderRightColor: tokens.colorTransparentBackgroundHover, }, }, ':hover:active': { [`& .${splitButtonClassNames.primaryActionButton}`]: { - borderRightColor: tokens.colorNeutralStroke1Pressed, + borderRightColor: tokens.colorTransparentBackgroundPressed, }, }, }, transparent: { [`& .${splitButtonClassNames.primaryActionButton}`]: { - borderRightColor: tokens.colorNeutralStroke1, + borderRightColor: tokens.colorTransparentBackground, }, ':hover': { [`& .${splitButtonClassNames.primaryActionButton}`]: { - borderRightColor: tokens.colorNeutralStroke1Hover, + borderRightColor: tokens.colorTransparentBackgroundHover, }, }, ':hover:active': { [`& .${splitButtonClassNames.primaryActionButton}`]: { - borderRightColor: tokens.colorNeutralStroke1Pressed, + borderRightColor: tokens.colorTransparentBackgroundPressed, }, }, }, diff --git a/packages/react-components/react-button/library/src/components/ToggleButton/index.ts b/packages/react-components/react-button/library/src/components/ToggleButton/index.ts index e2c9e651ddf016..66dfe4c99b5ce9 100644 --- a/packages/react-components/react-button/library/src/components/ToggleButton/index.ts +++ b/packages/react-components/react-button/library/src/components/ToggleButton/index.ts @@ -1,5 +1,5 @@ -export * from './ToggleButton'; -export * from './ToggleButton.types'; -export * from './renderToggleButton'; -export * from './useToggleButton'; +export { ToggleButton } from './ToggleButton'; +export type { ToggleButtonProps, ToggleButtonState } from './ToggleButton.types'; +export { renderToggleButton_unstable } from './renderToggleButton'; +export { useToggleButton_unstable } from './useToggleButton'; export { toggleButtonClassNames, useToggleButtonStyles_unstable } from './useToggleButtonStyles.styles'; diff --git a/packages/react-components/react-button/library/src/contexts/index.ts b/packages/react-components/react-button/library/src/contexts/index.ts index e0b0457ba97a21..d5dba33ecff56f 100644 --- a/packages/react-components/react-button/library/src/contexts/index.ts +++ b/packages/react-components/react-button/library/src/contexts/index.ts @@ -1 +1,2 @@ -export * from './ButtonContext'; +export type { ButtonContextValue } from './ButtonContext'; +export { ButtonContextProvider, useButtonContext } from './ButtonContext'; diff --git a/packages/react-components/react-button/library/src/utils/index.ts b/packages/react-components/react-button/library/src/utils/index.ts index 686f2bfac76a0d..3a7d2e11abe1e0 100644 --- a/packages/react-components/react-button/library/src/utils/index.ts +++ b/packages/react-components/react-button/library/src/utils/index.ts @@ -1 +1 @@ -export * from './useToggleState'; +export { useToggleState } from './useToggleState'; diff --git a/packages/react-components/react-calendar-compat/library/CHANGELOG.json b/packages/react-components/react-calendar-compat/library/CHANGELOG.json index 545c63a03f91d8..3137a6fb934248 100644 --- a/packages/react-components/react-calendar-compat/library/CHANGELOG.json +++ b/packages/react-components/react-calendar-compat/library/CHANGELOG.json @@ -1,6 +1,117 @@ { "name": "@fluentui/react-calendar-compat", "entries": [ + { + "date": "Fri, 21 Feb 2025 14:34:05 GMT", + "tag": "@fluentui/react-calendar-compat_v0.2.0", + "version": "0.2.0", + "comments": { + "minor": [ + { + "author": "beachball", + "package": "@fluentui/react-calendar-compat", + "comment": "Bump @fluentui/react-tabster to v9.24.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + } + ] + } + }, + { + "date": "Wed, 22 Jan 2025 14:00:21 GMT", + "tag": "@fluentui/react-calendar-compat_v0.1.26", + "version": "0.1.26", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-calendar-compat", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.50", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-calendar-compat", + "comment": "Bump @fluentui/react-tabster to v9.23.3", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-calendar-compat", + "comment": "Bump @fluentui/react-utilities to v9.18.20", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + } + ] + } + }, + { + "date": "Wed, 08 Jan 2025 18:33:36 GMT", + "tag": "@fluentui/react-calendar-compat_v0.1.25", + "version": "0.1.25", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-calendar-compat", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.49", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + } + ] + } + }, + { + "date": "Mon, 16 Dec 2024 16:26:49 GMT", + "tag": "@fluentui/react-calendar-compat_v0.1.24", + "version": "0.1.24", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-calendar-compat", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.48", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-calendar-compat", + "comment": "Bump @fluentui/react-shared-contexts to v9.21.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-calendar-compat", + "comment": "Bump @fluentui/react-tabster to v9.23.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-calendar-compat", + "comment": "Bump @fluentui/react-theme to v9.1.24", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-calendar-compat", + "comment": "Bump @fluentui/react-utilities to v9.18.19", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + } + ] + } + }, + { + "date": "Mon, 09 Dec 2024 17:38:09 GMT", + "tag": "@fluentui/react-calendar-compat_v0.1.23", + "version": "0.1.23", + "comments": { + "patch": [ + { + "author": "olfedias@microsoft.com", + "package": "@fluentui/react-calendar-compat", + "commit": "cad13936cd49ba0b34b50bc2f58395605c4e8da4", + "comment": "chore: remove usage of \"export *\"" + } + ] + } + }, { "date": "Fri, 06 Dec 2024 12:53:46 GMT", "tag": "@fluentui/react-calendar-compat_v0.1.22", diff --git a/packages/react-components/react-calendar-compat/library/CHANGELOG.md b/packages/react-components/react-calendar-compat/library/CHANGELOG.md index a6a6e1df6e9bfd..79d0db36a29187 100644 --- a/packages/react-components/react-calendar-compat/library/CHANGELOG.md +++ b/packages/react-components/react-calendar-compat/library/CHANGELOG.md @@ -1,9 +1,60 @@ # Change Log - @fluentui/react-calendar-compat -This log was last generated on Fri, 06 Dec 2024 12:53:46 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 14:34:05 GMT and should not be manually modified. +## [0.2.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-calendar-compat_v0.2.0) + +Fri, 21 Feb 2025 14:34:05 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-calendar-compat_v0.1.26..@fluentui/react-calendar-compat_v0.2.0) + +### Minor changes + +- Bump @fluentui/react-tabster to v9.24.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) + +## [0.1.26](https://github.com/microsoft/fluentui/tree/@fluentui/react-calendar-compat_v0.1.26) + +Wed, 22 Jan 2025 14:00:21 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-calendar-compat_v0.1.25..@fluentui/react-calendar-compat_v0.1.26) + +### Patches + +- Bump @fluentui/react-jsx-runtime to v9.0.50 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-tabster to v9.23.3 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-utilities to v9.18.20 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) + +## [0.1.25](https://github.com/microsoft/fluentui/tree/@fluentui/react-calendar-compat_v0.1.25) + +Wed, 08 Jan 2025 18:33:36 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-calendar-compat_v0.1.24..@fluentui/react-calendar-compat_v0.1.25) + +### Patches + +- Bump @fluentui/react-jsx-runtime to v9.0.49 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) + +## [0.1.24](https://github.com/microsoft/fluentui/tree/@fluentui/react-calendar-compat_v0.1.24) + +Mon, 16 Dec 2024 16:26:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-calendar-compat_v0.1.23..@fluentui/react-calendar-compat_v0.1.24) + +### Patches + +- Bump @fluentui/react-jsx-runtime to v9.0.48 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-shared-contexts to v9.21.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-tabster to v9.23.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-theme to v9.1.24 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-utilities to v9.18.19 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) + +## [0.1.23](https://github.com/microsoft/fluentui/tree/@fluentui/react-calendar-compat_v0.1.23) + +Mon, 09 Dec 2024 17:38:09 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-calendar-compat_v0.1.22..@fluentui/react-calendar-compat_v0.1.23) + +### Patches + +- chore: remove usage of "export *" ([PR #33384](https://github.com/microsoft/fluentui/pull/33384) by olfedias@microsoft.com) + ## [0.1.22](https://github.com/microsoft/fluentui/tree/@fluentui/react-calendar-compat_v0.1.22) Fri, 06 Dec 2024 12:53:46 GMT diff --git a/packages/react-components/react-calendar-compat/library/package.json b/packages/react-components/react-calendar-compat/library/package.json index ca78af9317a701..b03eab7561814e 100644 --- a/packages/react-components/react-calendar-compat/library/package.json +++ b/packages/react-components/react-calendar-compat/library/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-calendar-compat", - "version": "0.1.22", + "version": "0.2.0", "description": "Calendar compat component for Fluent UI v9", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -20,11 +20,11 @@ "dependencies": { "@fluentui/keyboard-keys": "^9.0.8", "@fluentui/react-icons": "^2.0.245", - "@fluentui/react-jsx-runtime": "^9.0.47", - "@fluentui/react-shared-contexts": "^9.21.1", - "@fluentui/react-tabster": "^9.23.1", - "@fluentui/react-theme": "^9.1.23", - "@fluentui/react-utilities": "^9.18.18", + "@fluentui/react-jsx-runtime": "^9.0.50", + "@fluentui/react-shared-contexts": "^9.21.2", + "@fluentui/react-tabster": "^9.24.0", + "@fluentui/react-theme": "^9.1.24", + "@fluentui/react-utilities": "^9.18.20", "@griffel/react": "^1.5.22", "@swc/helpers": "^0.5.1" }, diff --git a/packages/react-components/react-calendar-compat/library/src/Calendar.ts b/packages/react-components/react-calendar-compat/library/src/Calendar.ts index 44c674c047ffe5..aeea7db3d4228e 100644 --- a/packages/react-components/react-calendar-compat/library/src/Calendar.ts +++ b/packages/react-components/react-calendar-compat/library/src/Calendar.ts @@ -1 +1,8 @@ -export * from './components/Calendar/index'; +export type { CalendarProps, CalendarStyleProps, CalendarStyles, ICalendar } from './components/Calendar/index'; +export { + AnimationDirection, + Calendar, + calendarClassNames, + defaultCalendarStrings, + useCalendarStyles_unstable, +} from './components/Calendar/index'; diff --git a/packages/react-components/react-calendar-compat/library/src/CalendarDay.ts b/packages/react-components/react-calendar-compat/library/src/CalendarDay.ts index 59f69692a93c58..2d301d6c61ae8d 100644 --- a/packages/react-components/react-calendar-compat/library/src/CalendarDay.ts +++ b/packages/react-components/react-calendar-compat/library/src/CalendarDay.ts @@ -1 +1,7 @@ -export * from './components/CalendarDay/index'; +export type { + CalendarDayProps, + CalendarDayStyleProps, + CalendarDayStyles, + ICalendarDay, +} from './components/CalendarDay/index'; +export { CalendarDay, calendarDayClassNames, useCalendarDayStyles_unstable } from './components/CalendarDay/index'; diff --git a/packages/react-components/react-calendar-compat/library/src/CalendarDayGrid.ts b/packages/react-components/react-calendar-compat/library/src/CalendarDayGrid.ts index 2beebf459bc992..2acc0434cc7758 100644 --- a/packages/react-components/react-calendar-compat/library/src/CalendarDayGrid.ts +++ b/packages/react-components/react-calendar-compat/library/src/CalendarDayGrid.ts @@ -1 +1,14 @@ -export * from './components/CalendarDayGrid/index'; +export type { + CalendarDayGridProps, + CalendarDayGridStyleProps, + CalendarDayGridStyles, + DayInfo, + ICalendarDayGrid, + WeekCorners, +} from './components/CalendarDayGrid/index'; +export { + CalendarDayGrid, + calendarDayGridClassNames, + extraCalendarDayGridClassNames, + useCalendarDayGridStyles_unstable, +} from './components/CalendarDayGrid/index'; diff --git a/packages/react-components/react-calendar-compat/library/src/CalendarMonth.ts b/packages/react-components/react-calendar-compat/library/src/CalendarMonth.ts index 9f28941cc82d04..1670537c183eba 100644 --- a/packages/react-components/react-calendar-compat/library/src/CalendarMonth.ts +++ b/packages/react-components/react-calendar-compat/library/src/CalendarMonth.ts @@ -1 +1,7 @@ -export * from './components/CalendarMonth/index'; +export type { + CalendarMonthProps, + CalendarMonthStyleProps, + CalendarMonthStyles, + ICalendarMonth, +} from './components/CalendarMonth/index'; +export { CalendarMonth, useCalendarMonthStyles_unstable } from './components/CalendarMonth/index'; diff --git a/packages/react-components/react-calendar-compat/library/src/CalendarPicker.ts b/packages/react-components/react-calendar-compat/library/src/CalendarPicker.ts index cb4cb2f81147ce..d45d097ec842f0 100644 --- a/packages/react-components/react-calendar-compat/library/src/CalendarPicker.ts +++ b/packages/react-components/react-calendar-compat/library/src/CalendarPicker.ts @@ -1 +1,2 @@ -export * from './components/CalendarPicker/index'; +export type { CalendarPickerStyleProps, CalendarPickerStyles } from './components/CalendarPicker/index'; +export { calendarPickerClassNames, useCalendarPickerStyles_unstable } from './components/CalendarPicker/index'; diff --git a/packages/react-components/react-calendar-compat/library/src/CalendarYear.ts b/packages/react-components/react-calendar-compat/library/src/CalendarYear.ts index 4f0d02bcc054a7..8d451e13af05f4 100644 --- a/packages/react-components/react-calendar-compat/library/src/CalendarYear.ts +++ b/packages/react-components/react-calendar-compat/library/src/CalendarYear.ts @@ -1 +1,11 @@ -export * from './components/CalendarYear/index'; +export type { + CalendarYearHeaderProps, + CalendarYearProps, + CalendarYearRange, + CalendarYearRangeToString, + CalendarYearStrings, + CalendarYearStyleProps, + CalendarYearStyles, + ICalendarYear, +} from './components/CalendarYear/index'; +export { CalendarYear, useCalendarYearStyles_unstable } from './components/CalendarYear/index'; diff --git a/packages/react-components/react-calendar-compat/library/src/components/Calendar/index.ts b/packages/react-components/react-calendar-compat/library/src/components/Calendar/index.ts index e03daab6f730fb..f6f51dd4870e06 100644 --- a/packages/react-components/react-calendar-compat/library/src/components/Calendar/index.ts +++ b/packages/react-components/react-calendar-compat/library/src/components/Calendar/index.ts @@ -1,4 +1,5 @@ -export * from './Calendar'; -export * from './Calendar.types'; -export * from './useCalendarStyles.styles'; +export { Calendar } from './Calendar'; +export type { CalendarProps, CalendarStyleProps, CalendarStyles, ICalendar } from './Calendar.types'; +export { AnimationDirection } from './Calendar.types'; +export { calendarClassNames, useCalendarStyles_unstable } from './useCalendarStyles.styles'; export { defaultCalendarStrings } from './defaults'; diff --git a/packages/react-components/react-calendar-compat/library/src/components/CalendarDay/index.ts b/packages/react-components/react-calendar-compat/library/src/components/CalendarDay/index.ts index e7be79824e0009..00f0da3ac6ccb9 100644 --- a/packages/react-components/react-calendar-compat/library/src/components/CalendarDay/index.ts +++ b/packages/react-components/react-calendar-compat/library/src/components/CalendarDay/index.ts @@ -1,3 +1,3 @@ -export * from './CalendarDay'; -export * from './CalendarDay.types'; -export * from './useCalendarDayStyles.styles'; +export { CalendarDay } from './CalendarDay'; +export type { CalendarDayProps, CalendarDayStyleProps, CalendarDayStyles, ICalendarDay } from './CalendarDay.types'; +export { calendarDayClassNames, useCalendarDayStyles_unstable } from './useCalendarDayStyles.styles'; diff --git a/packages/react-components/react-calendar-compat/library/src/components/CalendarDayGrid/index.ts b/packages/react-components/react-calendar-compat/library/src/components/CalendarDayGrid/index.ts index 5b26ba8bc2f066..dccf6f02696068 100644 --- a/packages/react-components/react-calendar-compat/library/src/components/CalendarDayGrid/index.ts +++ b/packages/react-components/react-calendar-compat/library/src/components/CalendarDayGrid/index.ts @@ -1,5 +1,14 @@ -export * from './CalendarDayGrid'; -export * from './CalendarDayGrid.types'; -export * from './useCalendarDayGridStyles.styles'; -export { calendarDayGridClassNames, extraCalendarDayGridClassNames } from './useCalendarDayGridStyles.styles'; +export type { DayInfo } from './CalendarDayGrid'; +export { CalendarDayGrid } from './CalendarDayGrid'; +export type { + CalendarDayGridProps, + CalendarDayGridStyleProps, + CalendarDayGridStyles, + ICalendarDayGrid, +} from './CalendarDayGrid.types'; +export { + calendarDayGridClassNames, + extraCalendarDayGridClassNames, + useCalendarDayGridStyles_unstable, +} from './useCalendarDayGridStyles.styles'; export type { WeekCorners } from './useWeekCornerStyles.styles'; diff --git a/packages/react-components/react-calendar-compat/library/src/components/CalendarMonth/index.ts b/packages/react-components/react-calendar-compat/library/src/components/CalendarMonth/index.ts index 7c2981069ff8d0..e75c98f1a62734 100644 --- a/packages/react-components/react-calendar-compat/library/src/components/CalendarMonth/index.ts +++ b/packages/react-components/react-calendar-compat/library/src/components/CalendarMonth/index.ts @@ -1,3 +1,8 @@ -export * from './CalendarMonth'; -export * from './CalendarMonth.types'; -export * from './useCalendarMonthStyles.styles'; +export { CalendarMonth } from './CalendarMonth'; +export type { + CalendarMonthProps, + CalendarMonthStyleProps, + CalendarMonthStyles, + ICalendarMonth, +} from './CalendarMonth.types'; +export { useCalendarMonthStyles_unstable } from './useCalendarMonthStyles.styles'; diff --git a/packages/react-components/react-calendar-compat/library/src/components/CalendarPicker/index.ts b/packages/react-components/react-calendar-compat/library/src/components/CalendarPicker/index.ts index 45fa614ab928d6..57d2598940a49c 100644 --- a/packages/react-components/react-calendar-compat/library/src/components/CalendarPicker/index.ts +++ b/packages/react-components/react-calendar-compat/library/src/components/CalendarPicker/index.ts @@ -1,2 +1,2 @@ -export * from './CalendarPicker.types'; -export * from './useCalendarPickerStyles.styles'; +export type { CalendarPickerStyleProps, CalendarPickerStyles } from './CalendarPicker.types'; +export { calendarPickerClassNames, useCalendarPickerStyles_unstable } from './useCalendarPickerStyles.styles'; diff --git a/packages/react-components/react-calendar-compat/library/src/components/CalendarYear/index.ts b/packages/react-components/react-calendar-compat/library/src/components/CalendarYear/index.ts index d03d1a5c9d2fe0..93d3e425a5dba1 100644 --- a/packages/react-components/react-calendar-compat/library/src/components/CalendarYear/index.ts +++ b/packages/react-components/react-calendar-compat/library/src/components/CalendarYear/index.ts @@ -1,3 +1,12 @@ -export * from './CalendarYear'; -export * from './CalendarYear.types'; -export * from './useCalendarYearStyles.styles'; +export { CalendarYear } from './CalendarYear'; +export type { + CalendarYearHeaderProps, + CalendarYearProps, + CalendarYearRange, + CalendarYearRangeToString, + CalendarYearStrings, + CalendarYearStyleProps, + CalendarYearStyles, + ICalendarYear, +} from './CalendarYear.types'; +export { useCalendarYearStyles_unstable } from './useCalendarYearStyles.styles'; diff --git a/packages/react-components/react-calendar-compat/library/src/utils/dateFormatting/index.ts b/packages/react-components/react-calendar-compat/library/src/utils/dateFormatting/index.ts index 76cf3f30a0f1c6..31f6511db1e044 100644 --- a/packages/react-components/react-calendar-compat/library/src/utils/dateFormatting/index.ts +++ b/packages/react-components/react-calendar-compat/library/src/utils/dateFormatting/index.ts @@ -1,2 +1,11 @@ -export * from './dateFormatting.defaults'; -export * from './dateFormatting.types'; +export { + DEFAULT_CALENDAR_STRINGS, + DEFAULT_DATE_FORMATTING, + DEFAULT_DATE_GRID_STRINGS, + formatDay, + formatMonth, + formatMonthDayYear, + formatMonthYear, + formatYear, +} from './dateFormatting.defaults'; +export type { CalendarStrings, DateFormatting, DateGridStrings } from './dateFormatting.types'; diff --git a/packages/react-components/react-calendar-compat/library/src/utils/dateGrid/index.ts b/packages/react-components/react-calendar-compat/library/src/utils/dateGrid/index.ts index 015f680c01e9c3..2af528f7078a6c 100644 --- a/packages/react-components/react-calendar-compat/library/src/utils/dateGrid/index.ts +++ b/packages/react-components/react-calendar-compat/library/src/utils/dateGrid/index.ts @@ -1,5 +1,5 @@ -export * from './dateGrid.types'; -export * from './findAvailableDate'; -export * from './getBoundedDateRange'; -export * from './getDayGrid'; -export * from './isRestrictedDate'; +export type { AvailableDateOptions, Day, DayGridOptions, RestrictedDatesOptions } from './dateGrid.types'; +export { findAvailableDate } from './findAvailableDate'; +export { getBoundedDateRange } from './getBoundedDateRange'; +export { getDayGrid } from './getDayGrid'; +export { isRestrictedDate } from './isRestrictedDate'; diff --git a/packages/react-components/react-calendar-compat/library/src/utils/dateMath/index.ts b/packages/react-components/react-calendar-compat/library/src/utils/dateMath/index.ts index 162dde38c42c49..f2afb200544834 100644 --- a/packages/react-components/react-calendar-compat/library/src/utils/dateMath/index.ts +++ b/packages/react-components/react-calendar-compat/library/src/utils/dateMath/index.ts @@ -1 +1,20 @@ -export * from './dateMath'; +export { + addDays, + addMonths, + addWeeks, + addYears, + compareDatePart, + compareDates, + getDatePartHashValue, + getDateRangeArray, + getEndDateOfWeek, + getMonthEnd, + getMonthStart, + getStartDateOfWeek, + getWeekNumber, + getWeekNumbersInMonth, + getYearEnd, + getYearStart, + isInDateRangeArray, + setMonth, +} from './dateMath'; diff --git a/packages/react-components/react-calendar-compat/library/src/utils/index.ts b/packages/react-components/react-calendar-compat/library/src/utils/index.ts index cb8c73d5cadcb6..2cdf76e5e0414c 100644 --- a/packages/react-components/react-calendar-compat/library/src/utils/index.ts +++ b/packages/react-components/react-calendar-compat/library/src/utils/index.ts @@ -1,6 +1,52 @@ -export * from './animations'; -export * from './constants'; -export * from './dateFormatting'; -export * from './dateGrid'; -export * from './dateMath'; -export * from './focus'; +export { + DURATION_1, + DURATION_2, + DURATION_3, + DURATION_4, + EASING_FUNCTION_1, + EASING_FUNCTION_2, + FADE_IN, + FADE_OUT, + SLIDE_DOWN_IN20, + SLIDE_DOWN_OUT20, + SLIDE_LEFT_IN20, + SLIDE_RIGHT_IN20, + SLIDE_UP_IN20, + SLIDE_UP_OUT20, + TRANSITION_ROW_DISAPPEARANCE, +} from './animations'; +export { DAYS_IN_WEEK, DateRangeType, DayOfWeek, FirstWeekOfYear, MonthOfYear, TimeConstants } from './constants'; +export type { CalendarStrings, DateFormatting, DateGridStrings } from './dateFormatting'; +export { + DEFAULT_CALENDAR_STRINGS, + DEFAULT_DATE_FORMATTING, + DEFAULT_DATE_GRID_STRINGS, + formatDay, + formatMonth, + formatMonthDayYear, + formatMonthYear, + formatYear, +} from './dateFormatting'; +export type { AvailableDateOptions, Day, DayGridOptions, RestrictedDatesOptions } from './dateGrid'; +export { findAvailableDate, getBoundedDateRange, getDayGrid, isRestrictedDate } from './dateGrid'; +export { + addDays, + addMonths, + addWeeks, + addYears, + compareDatePart, + compareDates, + getDatePartHashValue, + getDateRangeArray, + getEndDateOfWeek, + getMonthEnd, + getMonthStart, + getStartDateOfWeek, + getWeekNumber, + getWeekNumbersInMonth, + getYearEnd, + getYearStart, + isInDateRangeArray, + setMonth, +} from './dateMath'; +export { focusAsync } from './focus'; diff --git a/packages/react-components/react-card/library/CHANGELOG.json b/packages/react-components/react-card/library/CHANGELOG.json index e6fff5458538d7..d2ee824539b47f 100644 --- a/packages/react-components/react-card/library/CHANGELOG.json +++ b/packages/react-components/react-card/library/CHANGELOG.json @@ -1,6 +1,135 @@ { "name": "@fluentui/react-card", "entries": [ + { + "date": "Fri, 21 Feb 2025 14:34:05 GMT", + "tag": "@fluentui/react-card_v9.1.0", + "version": "9.1.0", + "comments": { + "minor": [ + { + "author": "beachball", + "package": "@fluentui/react-card", + "comment": "Bump @fluentui/react-tabster to v9.24.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + } + ] + } + }, + { + "date": "Wed, 22 Jan 2025 14:00:21 GMT", + "tag": "@fluentui/react-card_v9.0.102", + "version": "9.0.102", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-card", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.50", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-card", + "comment": "Bump @fluentui/react-tabster to v9.23.3", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-card", + "comment": "Bump @fluentui/react-text to v9.4.32", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-card", + "comment": "Bump @fluentui/react-utilities to v9.18.20", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + } + ] + } + }, + { + "date": "Wed, 08 Jan 2025 18:33:36 GMT", + "tag": "@fluentui/react-card_v9.0.101", + "version": "9.0.101", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-card", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.49", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + }, + { + "author": "beachball", + "package": "@fluentui/react-card", + "comment": "Bump @fluentui/react-text to v9.4.31", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + } + ] + } + }, + { + "date": "Mon, 16 Dec 2024 16:26:49 GMT", + "tag": "@fluentui/react-card_v9.0.100", + "version": "9.0.100", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-card", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.48", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-card", + "comment": "Bump @fluentui/react-tabster to v9.23.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-card", + "comment": "Bump @fluentui/react-text to v9.4.30", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-card", + "comment": "Bump @fluentui/react-theme to v9.1.24", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-card", + "comment": "Bump @fluentui/react-utilities to v9.18.19", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + } + ] + } + }, + { + "date": "Mon, 09 Dec 2024 17:38:09 GMT", + "tag": "@fluentui/react-card_v9.0.99", + "version": "9.0.99", + "comments": { + "patch": [ + { + "author": "olfedias@microsoft.com", + "package": "@fluentui/react-card", + "commit": "cad13936cd49ba0b34b50bc2f58395605c4e8da4", + "comment": "chore: remove usage of \"export *\"" + }, + { + "author": "beachball", + "package": "@fluentui/react-card", + "comment": "Bump @fluentui/react-text to v9.4.29", + "commit": "80f2ce07be06e66b369bd18e4484d8faf6b493c7" + } + ] + } + }, { "date": "Fri, 06 Dec 2024 12:53:46 GMT", "tag": "@fluentui/react-card_v9.0.98", diff --git a/packages/react-components/react-card/library/CHANGELOG.md b/packages/react-components/react-card/library/CHANGELOG.md index 95f2391b76f105..5d70e52ec05eaf 100644 --- a/packages/react-components/react-card/library/CHANGELOG.md +++ b/packages/react-components/react-card/library/CHANGELOG.md @@ -1,9 +1,63 @@ # Change Log - @fluentui/react-card -This log was last generated on Fri, 06 Dec 2024 12:53:46 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 14:34:05 GMT and should not be manually modified. +## [9.1.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-card_v9.1.0) + +Fri, 21 Feb 2025 14:34:05 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-card_v9.0.102..@fluentui/react-card_v9.1.0) + +### Minor changes + +- Bump @fluentui/react-tabster to v9.24.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) + +## [9.0.102](https://github.com/microsoft/fluentui/tree/@fluentui/react-card_v9.0.102) + +Wed, 22 Jan 2025 14:00:21 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-card_v9.0.101..@fluentui/react-card_v9.0.102) + +### Patches + +- Bump @fluentui/react-jsx-runtime to v9.0.50 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-tabster to v9.23.3 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-text to v9.4.32 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-utilities to v9.18.20 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) + +## [9.0.101](https://github.com/microsoft/fluentui/tree/@fluentui/react-card_v9.0.101) + +Wed, 08 Jan 2025 18:33:36 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-card_v9.0.100..@fluentui/react-card_v9.0.101) + +### Patches + +- Bump @fluentui/react-jsx-runtime to v9.0.49 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-text to v9.4.31 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) + +## [9.0.100](https://github.com/microsoft/fluentui/tree/@fluentui/react-card_v9.0.100) + +Mon, 16 Dec 2024 16:26:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-card_v9.0.99..@fluentui/react-card_v9.0.100) + +### Patches + +- Bump @fluentui/react-jsx-runtime to v9.0.48 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-tabster to v9.23.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-text to v9.4.30 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-theme to v9.1.24 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-utilities to v9.18.19 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) + +## [9.0.99](https://github.com/microsoft/fluentui/tree/@fluentui/react-card_v9.0.99) + +Mon, 09 Dec 2024 17:38:09 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-card_v9.0.98..@fluentui/react-card_v9.0.99) + +### Patches + +- chore: remove usage of "export *" ([PR #33384](https://github.com/microsoft/fluentui/pull/33384) by olfedias@microsoft.com) +- Bump @fluentui/react-text to v9.4.29 ([PR #33431](https://github.com/microsoft/fluentui/pull/33431) by beachball) + ## [9.0.98](https://github.com/microsoft/fluentui/tree/@fluentui/react-card_v9.0.98) Fri, 06 Dec 2024 12:53:46 GMT diff --git a/packages/react-components/react-card/library/package.json b/packages/react-components/react-card/library/package.json index 499b140f116d56..ca622f87428eeb 100644 --- a/packages/react-components/react-card/library/package.json +++ b/packages/react-components/react-card/library/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-card", - "version": "9.0.98", + "version": "9.1.0", "private": false, "description": "Card container components for Fluent UI React.", "main": "lib-commonjs/index.js", @@ -23,11 +23,11 @@ }, "dependencies": { "@fluentui/keyboard-keys": "^9.0.8", - "@fluentui/react-jsx-runtime": "^9.0.47", - "@fluentui/react-tabster": "^9.23.1", - "@fluentui/react-text": "^9.4.28", - "@fluentui/react-theme": "^9.1.23", - "@fluentui/react-utilities": "^9.18.18", + "@fluentui/react-jsx-runtime": "^9.0.50", + "@fluentui/react-tabster": "^9.24.0", + "@fluentui/react-text": "^9.4.32", + "@fluentui/react-theme": "^9.1.24", + "@fluentui/react-utilities": "^9.18.20", "@griffel/react": "^1.5.22", "@swc/helpers": "^0.5.1" }, diff --git a/packages/react-components/react-card/library/src/Card.ts b/packages/react-components/react-card/library/src/Card.ts index 734059d20a2e1f..bb11582e735f2f 100644 --- a/packages/react-components/react-card/library/src/Card.ts +++ b/packages/react-components/react-card/library/src/Card.ts @@ -1 +1,19 @@ -export * from './components/Card/index'; +export type { + CardContextValue, + CardOnSelectData, + CardOnSelectionChangeEvent, + CardProps, + CardSlots, + CardState, +} from './components/Card/index'; +export { + Card, + CardProvider, + cardCSSVars, + cardClassNames, + cardContextDefaultValue, + renderCard_unstable, + useCardContext_unstable, + useCardStyles_unstable, + useCard_unstable, +} from './components/Card/index'; diff --git a/packages/react-components/react-card/library/src/CardFooter.ts b/packages/react-components/react-card/library/src/CardFooter.ts index 9b3c2765cea0de..207a0901d98884 100644 --- a/packages/react-components/react-card/library/src/CardFooter.ts +++ b/packages/react-components/react-card/library/src/CardFooter.ts @@ -1 +1,8 @@ -export * from './components/CardFooter/index'; +export type { CardFooterProps, CardFooterSlots, CardFooterState } from './components/CardFooter/index'; +export { + CardFooter, + cardFooterClassNames, + renderCardFooter_unstable, + useCardFooterStyles_unstable, + useCardFooter_unstable, +} from './components/CardFooter/index'; diff --git a/packages/react-components/react-card/library/src/CardHeader.ts b/packages/react-components/react-card/library/src/CardHeader.ts index 4b46089d4c3af5..6586d529594397 100644 --- a/packages/react-components/react-card/library/src/CardHeader.ts +++ b/packages/react-components/react-card/library/src/CardHeader.ts @@ -1 +1,9 @@ -export * from './components/CardHeader/index'; +export type { CardHeaderProps, CardHeaderSlots, CardHeaderState } from './components/CardHeader/index'; +export { + CardHeader, + cardHeaderCSSVars, + cardHeaderClassNames, + renderCardHeader_unstable, + useCardHeaderStyles_unstable, + useCardHeader_unstable, +} from './components/CardHeader/index'; diff --git a/packages/react-components/react-card/library/src/CardPreview.ts b/packages/react-components/react-card/library/src/CardPreview.ts index 0d68cbfee5c08a..1c3b2c8c177410 100644 --- a/packages/react-components/react-card/library/src/CardPreview.ts +++ b/packages/react-components/react-card/library/src/CardPreview.ts @@ -1 +1,8 @@ -export * from './components/CardPreview/index'; +export type { CardPreviewProps, CardPreviewSlots, CardPreviewState } from './components/CardPreview/index'; +export { + CardPreview, + cardPreviewClassNames, + renderCardPreview_unstable, + useCardPreviewStyles_unstable, + useCardPreview_unstable, +} from './components/CardPreview/index'; diff --git a/packages/react-components/react-card/library/src/components/Card/index.ts b/packages/react-components/react-card/library/src/components/Card/index.ts index c1f77d8ed79487..a475265471a5f1 100644 --- a/packages/react-components/react-card/library/src/components/Card/index.ts +++ b/packages/react-components/react-card/library/src/components/Card/index.ts @@ -1,6 +1,13 @@ -export * from './Card'; -export * from './Card.types'; -export * from './CardContext'; -export * from './renderCard'; -export * from './useCard'; -export * from './useCardStyles.styles'; +export { Card } from './Card'; +export type { + CardContextValue, + CardOnSelectData, + CardOnSelectionChangeEvent, + CardProps, + CardSlots, + CardState, +} from './Card.types'; +export { CardProvider, cardContextDefaultValue, useCardContext_unstable } from './CardContext'; +export { renderCard_unstable } from './renderCard'; +export { useCard_unstable } from './useCard'; +export { cardCSSVars, cardClassNames, useCardStyles_unstable } from './useCardStyles.styles'; diff --git a/packages/react-components/react-card/library/src/components/CardFooter/index.ts b/packages/react-components/react-card/library/src/components/CardFooter/index.ts index c95072f03c4c93..b3034dc567b3ef 100644 --- a/packages/react-components/react-card/library/src/components/CardFooter/index.ts +++ b/packages/react-components/react-card/library/src/components/CardFooter/index.ts @@ -1,5 +1,5 @@ -export * from './CardFooter'; -export * from './CardFooter.types'; -export * from './renderCardFooter'; -export * from './useCardFooter'; -export * from './useCardFooterStyles.styles'; +export { CardFooter } from './CardFooter'; +export type { CardFooterProps, CardFooterSlots, CardFooterState } from './CardFooter.types'; +export { renderCardFooter_unstable } from './renderCardFooter'; +export { useCardFooter_unstable } from './useCardFooter'; +export { cardFooterClassNames, useCardFooterStyles_unstable } from './useCardFooterStyles.styles'; diff --git a/packages/react-components/react-card/library/src/components/CardHeader/index.ts b/packages/react-components/react-card/library/src/components/CardHeader/index.ts index 6f516cdf246ba4..d2204310d4e7ff 100644 --- a/packages/react-components/react-card/library/src/components/CardHeader/index.ts +++ b/packages/react-components/react-card/library/src/components/CardHeader/index.ts @@ -1,5 +1,5 @@ -export * from './CardHeader'; -export * from './CardHeader.types'; -export * from './renderCardHeader'; -export * from './useCardHeader'; -export * from './useCardHeaderStyles.styles'; +export { CardHeader } from './CardHeader'; +export type { CardHeaderProps, CardHeaderSlots, CardHeaderState } from './CardHeader.types'; +export { renderCardHeader_unstable } from './renderCardHeader'; +export { useCardHeader_unstable } from './useCardHeader'; +export { cardHeaderCSSVars, cardHeaderClassNames, useCardHeaderStyles_unstable } from './useCardHeaderStyles.styles'; diff --git a/packages/react-components/react-card/library/src/components/CardPreview/index.ts b/packages/react-components/react-card/library/src/components/CardPreview/index.ts index 5b3c4eedc68b2c..74770de2731e4a 100644 --- a/packages/react-components/react-card/library/src/components/CardPreview/index.ts +++ b/packages/react-components/react-card/library/src/components/CardPreview/index.ts @@ -1,5 +1,5 @@ -export * from './CardPreview'; -export * from './CardPreview.types'; -export * from './renderCardPreview'; -export * from './useCardPreview'; -export * from './useCardPreviewStyles.styles'; +export { CardPreview } from './CardPreview'; +export type { CardPreviewProps, CardPreviewSlots, CardPreviewState } from './CardPreview.types'; +export { renderCardPreview_unstable } from './renderCardPreview'; +export { useCardPreview_unstable } from './useCardPreview'; +export { cardPreviewClassNames, useCardPreviewStyles_unstable } from './useCardPreviewStyles.styles'; diff --git a/packages/react-components/react-card/stories/src/CardFooter/CardFooterDefault.stories.tsx b/packages/react-components/react-card/stories/src/CardFooter/CardFooterDefault.stories.tsx index bc1f2167d38ec4..84359a729fb5e7 100644 --- a/packages/react-components/react-card/stories/src/CardFooter/CardFooterDefault.stories.tsx +++ b/packages/react-components/react-card/stories/src/CardFooter/CardFooterDefault.stories.tsx @@ -15,7 +15,7 @@ export const Default = () => { return ( } />} + action={ diff --git a/packages/react-components/react-carousel/library/CHANGELOG.json b/packages/react-components/react-carousel/library/CHANGELOG.json index 0e995e0fb23f55..cecd06943d4fc8 100644 --- a/packages/react-components/react-carousel/library/CHANGELOG.json +++ b/packages/react-components/react-carousel/library/CHANGELOG.json @@ -1,6 +1,270 @@ { "name": "@fluentui/react-carousel", "entries": [ + { + "date": "Fri, 21 Feb 2025 14:34:03 GMT", + "tag": "@fluentui/react-carousel_v9.6.0", + "version": "9.6.0", + "comments": { + "minor": [ + { + "author": "mifraser@microsoft.com", + "package": "@fluentui/react-carousel", + "commit": "3441c65501ce8a65495db7646f0e4b2af5066b83", + "comment": "feat: Implement props to control animation duration and autoplay interval" + }, + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-aria to v9.14.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + }, + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-button to v9.4.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + }, + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-tooltip to v9.6.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + }, + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-tabster to v9.24.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + } + ] + } + }, + { + "date": "Tue, 18 Feb 2025 11:26:27 GMT", + "tag": "@fluentui/react-carousel_v9.5.0", + "version": "9.5.0", + "comments": { + "minor": [ + { + "author": "mifraser@microsoft.com", + "package": "@fluentui/react-carousel", + "commit": "58c34624254f34c19d41033d92d968b1be02d258", + "comment": "feat: Add tooltip wrappers for icon buttons in nav container" + } + ] + } + }, + { + "date": "Fri, 07 Feb 2025 10:42:12 GMT", + "tag": "@fluentui/react-carousel_v9.4.7", + "version": "9.4.7", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-button to v9.3.102", + "commit": "b37554b631f4e27e0927b123732f3d57d62660a3" + } + ] + } + }, + { + "date": "Tue, 28 Jan 2025 21:26:34 GMT", + "tag": "@fluentui/react-carousel_v9.4.6", + "version": "9.4.6", + "comments": { + "patch": [ + { + "author": "mifraser@microsoft.com", + "package": "@fluentui/react-carousel", + "commit": "1ae2f93564a5a3ae95d056a38818c9330f5a9737", + "comment": "fix: Ensure carousel handles indexing when window size is larger then combined card size" + }, + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-button to v9.3.101", + "commit": "a081a7573fa328d640c2efb0127f2be99a1368f8" + } + ] + } + }, + { + "date": "Wed, 22 Jan 2025 14:00:21 GMT", + "tag": "@fluentui/react-carousel_v9.4.5", + "version": "9.4.5", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-aria to v9.13.14", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-button to v9.3.100", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-context-selector to v9.1.72", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.50", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-tabster to v9.23.3", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-utilities to v9.18.20", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + } + ] + } + }, + { + "date": "Wed, 08 Jan 2025 18:33:36 GMT", + "tag": "@fluentui/react-carousel_v9.4.4", + "version": "9.4.4", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-aria to v9.13.13", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + }, + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-button to v9.3.99", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + }, + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.49", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + } + ] + } + }, + { + "date": "Mon, 16 Dec 2024 16:26:47 GMT", + "tag": "@fluentui/react-carousel_v9.4.3", + "version": "9.4.3", + "comments": { + "patch": [ + { + "author": "mifraser@microsoft.com", + "package": "@fluentui/react-carousel", + "commit": "1175ab27b7c787e61469f2747203a5904f769b19", + "comment": "fix: Set totalSlides on CarouselNav to controlled state" + }, + { + "author": "olfedias@microsoft.com", + "package": "@fluentui/react-carousel", + "commit": "f15afa79910b9998044dddcce63e9583e4f8b905", + "comment": "chore: remove usage of \"export *\"" + }, + { + "author": "mifraser@microsoft.com", + "package": "@fluentui/react-carousel", + "commit": "c142edc1617943b7745f66398893a04c90be16e9", + "comment": "fix: Set tabster default on carousel initialization" + }, + { + "author": "mifraser@microsoft.com", + "package": "@fluentui/react-carousel", + "commit": "592b73f62e471a2e4668a0949583790a5ef17ef8", + "comment": "fix: Ensure a viable background color for nav items in high contrast windows" + }, + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-aria to v9.13.12", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-button to v9.3.98", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-context-selector to v9.1.71", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.48", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-shared-contexts to v9.21.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-tabster to v9.23.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-theme to v9.1.24", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-utilities to v9.18.19", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + } + ] + } + }, + { + "date": "Mon, 09 Dec 2024 17:38:16 GMT", + "tag": "@fluentui/react-carousel_v9.4.2", + "version": "9.4.2", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-aria to v9.13.11", + "commit": "80f2ce07be06e66b369bd18e4484d8faf6b493c7" + }, + { + "author": "beachball", + "package": "@fluentui/react-carousel", + "comment": "Bump @fluentui/react-button to v9.3.97", + "commit": "80f2ce07be06e66b369bd18e4484d8faf6b493c7" + } + ] + } + }, { "date": "Fri, 06 Dec 2024 12:53:46 GMT", "tag": "@fluentui/react-carousel_v9.4.1", diff --git a/packages/react-components/react-carousel/library/CHANGELOG.md b/packages/react-components/react-carousel/library/CHANGELOG.md index 29bb5f5c53da6b..e10aa283dc3ecf 100644 --- a/packages/react-components/react-carousel/library/CHANGELOG.md +++ b/packages/react-components/react-carousel/library/CHANGELOG.md @@ -1,9 +1,105 @@ # Change Log - @fluentui/react-carousel -This log was last generated on Fri, 06 Dec 2024 12:53:46 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 14:34:03 GMT and should not be manually modified. +## [9.6.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-carousel_v9.6.0) + +Fri, 21 Feb 2025 14:34:03 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-carousel_v9.5.0..@fluentui/react-carousel_v9.6.0) + +### Minor changes + +- feat: Implement props to control animation duration and autoplay interval ([PR #33820](https://github.com/microsoft/fluentui/pull/33820) by mifraser@microsoft.com) +- Bump @fluentui/react-aria to v9.14.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) +- Bump @fluentui/react-button to v9.4.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) +- Bump @fluentui/react-tooltip to v9.6.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) +- Bump @fluentui/react-tabster to v9.24.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) + +## [9.5.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-carousel_v9.5.0) + +Tue, 18 Feb 2025 11:26:27 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-carousel_v9.4.7..@fluentui/react-carousel_v9.5.0) + +### Minor changes + +- feat: Add tooltip wrappers for icon buttons in nav container ([PR #33821](https://github.com/microsoft/fluentui/pull/33821) by mifraser@microsoft.com) + +## [9.4.7](https://github.com/microsoft/fluentui/tree/@fluentui/react-carousel_v9.4.7) + +Fri, 07 Feb 2025 10:42:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-carousel_v9.4.6..@fluentui/react-carousel_v9.4.7) + +### Patches + +- Bump @fluentui/react-button to v9.3.102 ([PR #33797](https://github.com/microsoft/fluentui/pull/33797) by beachball) + +## [9.4.6](https://github.com/microsoft/fluentui/tree/@fluentui/react-carousel_v9.4.6) + +Tue, 28 Jan 2025 21:26:34 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-carousel_v9.4.5..@fluentui/react-carousel_v9.4.6) + +### Patches + +- fix: Ensure carousel handles indexing when window size is larger then combined card size ([PR #33732](https://github.com/microsoft/fluentui/pull/33732) by mifraser@microsoft.com) +- Bump @fluentui/react-button to v9.3.101 ([PR #33736](https://github.com/microsoft/fluentui/pull/33736) by beachball) + +## [9.4.5](https://github.com/microsoft/fluentui/tree/@fluentui/react-carousel_v9.4.5) + +Wed, 22 Jan 2025 14:00:21 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-carousel_v9.4.4..@fluentui/react-carousel_v9.4.5) + +### Patches + +- Bump @fluentui/react-aria to v9.13.14 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-button to v9.3.100 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-context-selector to v9.1.72 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.50 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-tabster to v9.23.3 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-utilities to v9.18.20 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) + +## [9.4.4](https://github.com/microsoft/fluentui/tree/@fluentui/react-carousel_v9.4.4) + +Wed, 08 Jan 2025 18:33:36 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-carousel_v9.4.3..@fluentui/react-carousel_v9.4.4) + +### Patches + +- Bump @fluentui/react-aria to v9.13.13 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-button to v9.3.99 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.49 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) + +## [9.4.3](https://github.com/microsoft/fluentui/tree/@fluentui/react-carousel_v9.4.3) + +Mon, 16 Dec 2024 16:26:47 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-carousel_v9.4.2..@fluentui/react-carousel_v9.4.3) + +### Patches + +- fix: Set totalSlides on CarouselNav to controlled state ([PR #33453](https://github.com/microsoft/fluentui/pull/33453) by mifraser@microsoft.com) +- chore: remove usage of "export *" ([PR #33457](https://github.com/microsoft/fluentui/pull/33457) by olfedias@microsoft.com) +- fix: Set tabster default on carousel initialization ([PR #33401](https://github.com/microsoft/fluentui/pull/33401) by mifraser@microsoft.com) +- fix: Ensure a viable background color for nav items in high contrast windows ([PR #33411](https://github.com/microsoft/fluentui/pull/33411) by mifraser@microsoft.com) +- Bump @fluentui/react-aria to v9.13.12 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-button to v9.3.98 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-context-selector to v9.1.71 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.48 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-shared-contexts to v9.21.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-tabster to v9.23.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-theme to v9.1.24 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-utilities to v9.18.19 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) + +## [9.4.2](https://github.com/microsoft/fluentui/tree/@fluentui/react-carousel_v9.4.2) + +Mon, 09 Dec 2024 17:38:16 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-carousel_v9.4.1..@fluentui/react-carousel_v9.4.2) + +### Patches + +- Bump @fluentui/react-aria to v9.13.11 ([PR #33431](https://github.com/microsoft/fluentui/pull/33431) by beachball) +- Bump @fluentui/react-button to v9.3.97 ([PR #33431](https://github.com/microsoft/fluentui/pull/33431) by beachball) + ## [9.4.1](https://github.com/microsoft/fluentui/tree/@fluentui/react-carousel_v9.4.1) Fri, 06 Dec 2024 12:53:46 GMT diff --git a/packages/react-components/react-carousel/library/etc/react-carousel.api.md b/packages/react-components/react-carousel/library/etc/react-carousel.api.md index 5ca840719cc5b7..85fbeeb8e93b61 100644 --- a/packages/react-components/react-carousel/library/etc/react-carousel.api.md +++ b/packages/react-components/react-carousel/library/etc/react-carousel.api.md @@ -25,6 +25,7 @@ import type { Slot } from '@fluentui/react-utilities'; import type { SlotClassNames } from '@fluentui/react-utilities'; import { ToggleButtonProps } from '@fluentui/react-button'; import { ToggleButtonState } from '@fluentui/react-button'; +import { TooltipProps } from '@fluentui/react-tooltip'; // @public export const Carousel: ForwardRefComponent; @@ -159,8 +160,11 @@ export type CarouselNavContainerProps = ComponentProps; next?: Slot; + nextTooltip?: Slot; prev?: Slot; + prevTooltip?: Slot; autoplay?: Slot; + autoplayTooltip?: Slot; }; // @public @@ -215,6 +219,7 @@ export type CarouselProps = ComponentProps & { whitespace?: boolean; motion?: CarouselMotion; announcement?: CarouselAnnouncerFunction; + autoplayInterval?: number; }; // @public (undocumented) diff --git a/packages/react-components/react-carousel/library/package.json b/packages/react-components/react-carousel/library/package.json index a9985ecda5e90c..2fb54081c39d91 100644 --- a/packages/react-components/react-carousel/library/package.json +++ b/packages/react-components/react-carousel/library/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-carousel", - "version": "9.4.1", + "version": "9.6.0", "description": "A composable carousel component that enables pagination with minimal rerenders", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -25,15 +25,16 @@ "@fluentui/scripts-cypress": "*" }, "dependencies": { - "@fluentui/react-aria": "^9.13.10", - "@fluentui/react-button": "^9.3.96", - "@fluentui/react-context-selector": "^9.1.70", + "@fluentui/react-aria": "^9.14.0", + "@fluentui/react-button": "^9.4.0", + "@fluentui/react-context-selector": "^9.1.72", "@fluentui/react-icons": "^2.0.245", - "@fluentui/react-jsx-runtime": "^9.0.47", - "@fluentui/react-shared-contexts": "^9.21.1", - "@fluentui/react-tabster": "^9.23.1", - "@fluentui/react-theme": "^9.1.23", - "@fluentui/react-utilities": "^9.18.18", + "@fluentui/react-tooltip": "^9.6.0", + "@fluentui/react-jsx-runtime": "^9.0.50", + "@fluentui/react-shared-contexts": "^9.21.2", + "@fluentui/react-tabster": "^9.24.0", + "@fluentui/react-theme": "^9.1.24", + "@fluentui/react-utilities": "^9.18.20", "@griffel/react": "^1.5.22", "@swc/helpers": "^0.5.1", "embla-carousel": "^8.5.1", diff --git a/packages/react-components/react-carousel/library/src/Carousel.ts b/packages/react-components/react-carousel/library/src/Carousel.ts index 8c21999da170eb..f1005db6a3980a 100644 --- a/packages/react-components/react-carousel/library/src/Carousel.ts +++ b/packages/react-components/react-carousel/library/src/Carousel.ts @@ -1 +1,17 @@ -export * from './components/Carousel/index'; +export type { + CarouselAnnouncerFunction, + CarouselMotion, + CarouselProps, + CarouselSlots, + CarouselState, + CarouselUpdateData, + CarouselVisibilityChangeEvent, + CarouselVisibilityEventDetail, +} from './components/Carousel/index'; +export { + Carousel, + carouselClassNames, + renderCarousel_unstable, + useCarouselStyles_unstable, + useCarousel_unstable, +} from './components/Carousel/index'; diff --git a/packages/react-components/react-carousel/library/src/CarouselAutoplayButton.ts b/packages/react-components/react-carousel/library/src/CarouselAutoplayButton.ts index f2328c210d8d06..fa0fa0ba458a12 100644 --- a/packages/react-components/react-carousel/library/src/CarouselAutoplayButton.ts +++ b/packages/react-components/react-carousel/library/src/CarouselAutoplayButton.ts @@ -1 +1,14 @@ -export * from './components/CarouselAutoplayButton/index'; +export type { + CarouselAutoplayAriaLabelFunction, + CarouselAutoplayButtonProps, + CarouselAutoplayButtonSlots, + CarouselAutoplayButtonState, + CarouselAutoplayChangeData, +} from './components/CarouselAutoplayButton/index'; +export { + CarouselAutoplayButton, + carouselAutoplayButtonClassNames, + renderCarouselAutoplayButton_unstable, + useCarouselAutoplayButtonStyles_unstable, + useCarouselAutoplayButton_unstable, +} from './components/CarouselAutoplayButton/index'; diff --git a/packages/react-components/react-carousel/library/src/CarouselButton.ts b/packages/react-components/react-carousel/library/src/CarouselButton.ts index 06bb699e6e42a3..c29b89aadc3e84 100644 --- a/packages/react-components/react-carousel/library/src/CarouselButton.ts +++ b/packages/react-components/react-carousel/library/src/CarouselButton.ts @@ -1 +1,8 @@ -export * from './components/CarouselButton/index'; +export type { CarouselButtonProps, CarouselButtonSlots, CarouselButtonState } from './components/CarouselButton/index'; +export { + CarouselButton, + carouselButtonClassNames, + renderCarouselButton_unstable, + useCarouselButtonStyles_unstable, + useCarouselButton_unstable, +} from './components/CarouselButton/index'; diff --git a/packages/react-components/react-carousel/library/src/CarouselCard.ts b/packages/react-components/react-carousel/library/src/CarouselCard.ts index 1536d47e44f24e..2c9c8530b243ce 100644 --- a/packages/react-components/react-carousel/library/src/CarouselCard.ts +++ b/packages/react-components/react-carousel/library/src/CarouselCard.ts @@ -1 +1,8 @@ -export * from './components/CarouselCard/index'; +export type { CarouselCardProps, CarouselCardSlots, CarouselCardState } from './components/CarouselCard/index'; +export { + CarouselCard, + carouselCardClassNames, + renderCarouselCard_unstable, + useCarouselCardStyles_unstable, + useCarouselCard_unstable, +} from './components/CarouselCard/index'; diff --git a/packages/react-components/react-carousel/library/src/CarouselContext.ts b/packages/react-components/react-carousel/library/src/CarouselContext.ts index 29056ad29a3685..36555684377f73 100644 --- a/packages/react-components/react-carousel/library/src/CarouselContext.ts +++ b/packages/react-components/react-carousel/library/src/CarouselContext.ts @@ -1,2 +1,10 @@ -export * from './components/CarouselContext'; -export * from './components/CarouselContext.types'; +export { + CarouselProvider, + carouselContextDefaultValue, + useCarouselContext_unstable, +} from './components/CarouselContext'; +export type { + CarouselContextValue, + CarouselContextValues, + CarouselIndexChangeData, +} from './components/CarouselContext.types'; diff --git a/packages/react-components/react-carousel/library/src/CarouselNav.ts b/packages/react-components/react-carousel/library/src/CarouselNav.ts index 03838ee1812187..d3cbd1c0c90d99 100644 --- a/packages/react-components/react-carousel/library/src/CarouselNav.ts +++ b/packages/react-components/react-carousel/library/src/CarouselNav.ts @@ -1 +1,14 @@ -export * from './components/CarouselNav/index'; +export type { + CarouselNavContextValue, + CarouselNavProps, + CarouselNavSlots, + CarouselNavState, + NavButtonRenderFunction, +} from './components/CarouselNav/index'; +export { + CarouselNav, + carouselNavClassNames, + renderCarouselNav_unstable, + useCarouselNavStyles_unstable, + useCarouselNav_unstable, +} from './components/CarouselNav/index'; diff --git a/packages/react-components/react-carousel/library/src/CarouselNavButton.ts b/packages/react-components/react-carousel/library/src/CarouselNavButton.ts index 898216ae73abc3..21a8fa1c905b79 100644 --- a/packages/react-components/react-carousel/library/src/CarouselNavButton.ts +++ b/packages/react-components/react-carousel/library/src/CarouselNavButton.ts @@ -1 +1,12 @@ -export * from './components/CarouselNavButton/index'; +export type { + CarouselNavButtonProps, + CarouselNavButtonSlots, + CarouselNavButtonState, +} from './components/CarouselNavButton/index'; +export { + CarouselNavButton, + carouselNavButtonClassNames, + renderCarouselNavButton_unstable, + useCarouselNavButtonStyles_unstable, + useCarouselNavButton_unstable, +} from './components/CarouselNavButton/index'; diff --git a/packages/react-components/react-carousel/library/src/CarouselNavContainer.ts b/packages/react-components/react-carousel/library/src/CarouselNavContainer.ts index df1c37cf0f5e32..760338c73194bf 100644 --- a/packages/react-components/react-carousel/library/src/CarouselNavContainer.ts +++ b/packages/react-components/react-carousel/library/src/CarouselNavContainer.ts @@ -1 +1,12 @@ -export * from './components/CarouselNavContainer/index'; +export type { + CarouselNavContainerProps, + CarouselNavContainerSlots, + CarouselNavContainerState, +} from './components/CarouselNavContainer/index'; +export { + CarouselNavContainer, + carouselNavContainerClassNames, + renderCarouselNavContainer_unstable, + useCarouselNavContainerStyles_unstable, + useCarouselNavContainer_unstable, +} from './components/CarouselNavContainer/index'; diff --git a/packages/react-components/react-carousel/library/src/CarouselNavImageButton.ts b/packages/react-components/react-carousel/library/src/CarouselNavImageButton.ts index 942a6fbe8e7408..046b480f961d1f 100644 --- a/packages/react-components/react-carousel/library/src/CarouselNavImageButton.ts +++ b/packages/react-components/react-carousel/library/src/CarouselNavImageButton.ts @@ -1 +1,12 @@ -export * from './components/CarouselNavImageButton/index'; +export type { + CarouselNavImageButtonProps, + CarouselNavImageButtonSlots, + CarouselNavImageButtonState, +} from './components/CarouselNavImageButton/index'; +export { + CarouselNavImageButton, + carouselNavImageButtonClassNames, + renderCarouselNavImageButton_unstable, + useCarouselNavImageButtonStyles_unstable, + useCarouselNavImageButton_unstable, +} from './components/CarouselNavImageButton/index'; diff --git a/packages/react-components/react-carousel/library/src/CarouselSlider.ts b/packages/react-components/react-carousel/library/src/CarouselSlider.ts index 3c09290f52c217..829d0c0fd07cf8 100644 --- a/packages/react-components/react-carousel/library/src/CarouselSlider.ts +++ b/packages/react-components/react-carousel/library/src/CarouselSlider.ts @@ -1 +1,13 @@ -export * from './components/CarouselSlider/index'; +export type { + CarouselSliderContextValue, + CarouselSliderProps, + CarouselSliderSlots, + CarouselSliderState, +} from './components/CarouselSlider/index'; +export { + CarouselSlider, + carouselSliderClassNames, + renderCarouselSlider_unstable, + useCarouselSliderStyles_unstable, + useCarouselSlider_unstable, +} from './components/CarouselSlider/index'; diff --git a/packages/react-components/react-carousel/library/src/CarouselViewport.ts b/packages/react-components/react-carousel/library/src/CarouselViewport.ts index 2ac88670f56ce9..4ff5fda10fd240 100644 --- a/packages/react-components/react-carousel/library/src/CarouselViewport.ts +++ b/packages/react-components/react-carousel/library/src/CarouselViewport.ts @@ -1 +1,12 @@ -export * from './components/CarouselViewport/index'; +export type { + CarouselViewportProps, + CarouselViewportSlots, + CarouselViewportState, +} from './components/CarouselViewport/index'; +export { + CarouselViewport, + carouselViewportClassNames, + renderCarouselViewport_unstable, + useCarouselViewportStyles_unstable, + useCarouselViewport_unstable, +} from './components/CarouselViewport/index'; diff --git a/packages/react-components/react-carousel/library/src/components/Carousel/Carousel.types.ts b/packages/react-components/react-carousel/library/src/components/Carousel/Carousel.types.ts index 13503bb2f9b95b..cd135e7abed793 100644 --- a/packages/react-components/react-carousel/library/src/components/Carousel/Carousel.types.ts +++ b/packages/react-components/react-carousel/library/src/components/Carousel/Carousel.types.ts @@ -13,7 +13,7 @@ export type CarouselAnnouncerFunction = (index: number, totalSlides: number, sli /** * List of integrated motion types */ -export type CarouselMotion = 'slide' | 'fade'; +export type CarouselMotion = 'slide' | { kind: 'slide'; duration?: number } | 'fade'; /** * Carousel Props @@ -63,8 +63,15 @@ export type CarouselProps = ComponentProps & { whitespace?: boolean; /** - * Sets motion to fade in/out style with minimal movement - * Defaults: false + * Sets motion type as either 'slide' or 'fade' + * Defaults: 'slide' + * + * Users can also pass 'slide' & duration via CarouselMotion object to control carousel speed. + * Drag interactions are not affected because duration is then determined by the drag force. + * + * Note: Duration is not in milliseconds because Carousel uses an + * attraction physics simulation when scrolling instead of easings. + * Only values between 20-60 are recommended, 25 is the default. */ motion?: CarouselMotion; @@ -73,6 +80,14 @@ export type CarouselProps = ComponentProps & { * Defaults to: undefined */ announcement?: CarouselAnnouncerFunction; + + /** + * Choose a delay between autoplay transitions in milliseconds. + * Only active if Autoplay is enabled via CarouselAutoplayButton + * + * Defaults: 4000 + */ + autoplayInterval?: number; }; /** diff --git a/packages/react-components/react-carousel/library/src/components/Carousel/index.ts b/packages/react-components/react-carousel/library/src/components/Carousel/index.ts index a3529a2ecafd2d..56347a4734d57a 100644 --- a/packages/react-components/react-carousel/library/src/components/Carousel/index.ts +++ b/packages/react-components/react-carousel/library/src/components/Carousel/index.ts @@ -1,5 +1,14 @@ -export * from './Carousel'; -export * from './Carousel.types'; -export * from './renderCarousel'; -export * from './useCarousel'; -export * from './useCarouselStyles.styles'; +export { Carousel } from './Carousel'; +export type { + CarouselAnnouncerFunction, + CarouselMotion, + CarouselProps, + CarouselSlots, + CarouselState, + CarouselUpdateData, + CarouselVisibilityChangeEvent, + CarouselVisibilityEventDetail, +} from './Carousel.types'; +export { renderCarousel_unstable } from './renderCarousel'; +export { useCarousel_unstable } from './useCarousel'; +export { carouselClassNames, useCarouselStyles_unstable } from './useCarouselStyles.styles'; diff --git a/packages/react-components/react-carousel/library/src/components/Carousel/useCarousel.ts b/packages/react-components/react-carousel/library/src/components/Carousel/useCarousel.ts index 1f61ea71e13a9e..f82ae482bee371 100644 --- a/packages/react-components/react-carousel/library/src/components/Carousel/useCarousel.ts +++ b/packages/react-components/react-carousel/library/src/components/Carousel/useCarousel.ts @@ -34,6 +34,7 @@ export function useCarousel_unstable(props: CarouselProps, ref: React.Ref { diff --git a/packages/react-components/react-carousel/library/src/components/CarouselAutoplayButton/index.ts b/packages/react-components/react-carousel/library/src/components/CarouselAutoplayButton/index.ts index d1b21630977bcb..173f2e343ff64d 100644 --- a/packages/react-components/react-carousel/library/src/components/CarouselAutoplayButton/index.ts +++ b/packages/react-components/react-carousel/library/src/components/CarouselAutoplayButton/index.ts @@ -1,5 +1,14 @@ -export * from './CarouselAutoplayButton'; -export * from './CarouselAutoplayButton.types'; -export * from './renderCarouselAutoplayButton'; -export * from './useCarouselAutoplayButton'; -export * from './useCarouselAutoplayButtonStyles.styles'; +export { CarouselAutoplayButton } from './CarouselAutoplayButton'; +export type { + CarouselAutoplayAriaLabelFunction, + CarouselAutoplayButtonProps, + CarouselAutoplayButtonSlots, + CarouselAutoplayButtonState, + CarouselAutoplayChangeData, +} from './CarouselAutoplayButton.types'; +export { renderCarouselAutoplayButton_unstable } from './renderCarouselAutoplayButton'; +export { useCarouselAutoplayButton_unstable } from './useCarouselAutoplayButton'; +export { + carouselAutoplayButtonClassNames, + useCarouselAutoplayButtonStyles_unstable, +} from './useCarouselAutoplayButtonStyles.styles'; diff --git a/packages/react-components/react-carousel/library/src/components/CarouselButton/index.ts b/packages/react-components/react-carousel/library/src/components/CarouselButton/index.ts index af0d5e1876830c..8364cf5e019d2b 100644 --- a/packages/react-components/react-carousel/library/src/components/CarouselButton/index.ts +++ b/packages/react-components/react-carousel/library/src/components/CarouselButton/index.ts @@ -1,5 +1,5 @@ -export * from './CarouselButton'; -export * from './CarouselButton.types'; -export * from './renderCarouselButton'; -export * from './useCarouselButton'; -export * from './useCarouselButtonStyles.styles'; +export { CarouselButton } from './CarouselButton'; +export type { CarouselButtonProps, CarouselButtonSlots, CarouselButtonState } from './CarouselButton.types'; +export { renderCarouselButton_unstable } from './renderCarouselButton'; +export { useCarouselButton_unstable } from './useCarouselButton'; +export { carouselButtonClassNames, useCarouselButtonStyles_unstable } from './useCarouselButtonStyles.styles'; diff --git a/packages/react-components/react-carousel/library/src/components/CarouselCard/index.ts b/packages/react-components/react-carousel/library/src/components/CarouselCard/index.ts index 4855951f5aae26..3e5e4fee24221e 100644 --- a/packages/react-components/react-carousel/library/src/components/CarouselCard/index.ts +++ b/packages/react-components/react-carousel/library/src/components/CarouselCard/index.ts @@ -1,5 +1,5 @@ -export * from './CarouselCard'; -export * from './CarouselCard.types'; -export * from './renderCarouselCard'; -export * from './useCarouselCard'; -export * from './useCarouselCardStyles.styles'; +export { CarouselCard } from './CarouselCard'; +export type { CarouselCardProps, CarouselCardSlots, CarouselCardState } from './CarouselCard.types'; +export { renderCarouselCard_unstable } from './renderCarouselCard'; +export { useCarouselCard_unstable } from './useCarouselCard'; +export { carouselCardClassNames, useCarouselCardStyles_unstable } from './useCarouselCardStyles.styles'; diff --git a/packages/react-components/react-carousel/library/src/components/CarouselNav/index.ts b/packages/react-components/react-carousel/library/src/components/CarouselNav/index.ts index eec7488052a3b8..65d30987547c40 100644 --- a/packages/react-components/react-carousel/library/src/components/CarouselNav/index.ts +++ b/packages/react-components/react-carousel/library/src/components/CarouselNav/index.ts @@ -1,5 +1,11 @@ -export * from './CarouselNav'; -export * from './CarouselNav.types'; -export * from './renderCarouselNav'; -export * from './useCarouselNav'; -export * from './useCarouselNavStyles.styles'; +export { CarouselNav } from './CarouselNav'; +export type { + CarouselNavContextValue, + CarouselNavProps, + CarouselNavSlots, + CarouselNavState, + NavButtonRenderFunction, +} from './CarouselNav.types'; +export { renderCarouselNav_unstable } from './renderCarouselNav'; +export { useCarouselNav_unstable } from './useCarouselNav'; +export { carouselNavClassNames, useCarouselNavStyles_unstable } from './useCarouselNavStyles.styles'; diff --git a/packages/react-components/react-carousel/library/src/components/CarouselNav/useCarouselNav.ts b/packages/react-components/react-carousel/library/src/components/CarouselNav/useCarouselNav.ts index e715e5c710376a..4640d53be07551 100644 --- a/packages/react-components/react-carousel/library/src/components/CarouselNav/useCarouselNav.ts +++ b/packages/react-components/react-carousel/library/src/components/CarouselNav/useCarouselNav.ts @@ -4,6 +4,7 @@ import * as React from 'react'; import { useCarouselContext_unstable as useCarouselContext } from '../CarouselContext'; import type { CarouselNavProps, CarouselNavState } from './CarouselNav.types'; +import { useControllableState } from '@fluentui/react-utilities'; /** * Create the state required to render CarouselNav. @@ -25,14 +26,19 @@ export const useCarouselNav_unstable = (props: CarouselNavProps, ref: React.Ref< unstable_hasDefault: true, }); - const [totalSlides, setTotalSlides] = React.useState(props.totalSlides ?? 0); + // Users can choose controlled or uncontrolled, if uncontrolled, the default is initialized by carousel context + const [totalSlides, setTotalSlides] = useControllableState({ + state: props.totalSlides, + initialState: 0, + }); + const subscribeForValues = useCarouselContext(ctx => ctx.subscribeForValues); useIsomorphicLayoutEffect(() => { return subscribeForValues(data => { setTotalSlides(data.navItemsCount); }); - }, [subscribeForValues]); + }, [subscribeForValues, setTotalSlides]); return { totalSlides, diff --git a/packages/react-components/react-carousel/library/src/components/CarouselNavButton/index.ts b/packages/react-components/react-carousel/library/src/components/CarouselNavButton/index.ts index 38e5687358e584..a3a016e7c51d7a 100644 --- a/packages/react-components/react-carousel/library/src/components/CarouselNavButton/index.ts +++ b/packages/react-components/react-carousel/library/src/components/CarouselNavButton/index.ts @@ -1,5 +1,5 @@ -export * from './CarouselNavButton'; -export * from './CarouselNavButton.types'; -export * from './renderCarouselNavButton'; -export * from './useCarouselNavButton'; -export * from './useCarouselNavButtonStyles.styles'; +export { CarouselNavButton } from './CarouselNavButton'; +export type { CarouselNavButtonProps, CarouselNavButtonSlots, CarouselNavButtonState } from './CarouselNavButton.types'; +export { renderCarouselNavButton_unstable } from './renderCarouselNavButton'; +export { useCarouselNavButton_unstable } from './useCarouselNavButton'; +export { carouselNavButtonClassNames, useCarouselNavButtonStyles_unstable } from './useCarouselNavButtonStyles.styles'; diff --git a/packages/react-components/react-carousel/library/src/components/CarouselNavButton/useCarouselNavButton.ts b/packages/react-components/react-carousel/library/src/components/CarouselNavButton/useCarouselNavButton.ts index 6092e1d539dfdf..ca3ba392b7cfdd 100644 --- a/packages/react-components/react-carousel/library/src/components/CarouselNavButton/useCarouselNavButton.ts +++ b/packages/react-components/react-carousel/library/src/components/CarouselNavButton/useCarouselNavButton.ts @@ -70,7 +70,7 @@ export const useCarouselNavButton_unstable = ( useIsomorphicLayoutEffect(() => { return subscribeForValues(data => { - const controlList = data.groupIndexList[index]; + const controlList = data.groupIndexList?.[index] ?? []; const _controlledSlideIds = controlList .map((slideIndex: number) => { return data.slideNodes[slideIndex].id; diff --git a/packages/react-components/react-carousel/library/src/components/CarouselNavButton/useCarouselNavButtonStyles.styles.ts b/packages/react-components/react-carousel/library/src/components/CarouselNavButton/useCarouselNavButtonStyles.styles.ts index 148f484f18775d..aacad8ce413930 100644 --- a/packages/react-components/react-carousel/library/src/components/CarouselNavButton/useCarouselNavButtonStyles.styles.ts +++ b/packages/react-components/react-carousel/library/src/components/CarouselNavButton/useCarouselNavButtonStyles.styles.ts @@ -31,6 +31,12 @@ const useStyles = makeStyles({ width: tokens.spacingHorizontalS, backgroundColor: tokens.colorNeutralForeground1, color: tokens.colorNeutralForeground1, + '@media (forced-colors: active)': { + // Bypass OS high contrast with inverted blend mode (otherwise icon is invisible) + forcedColorAdjust: 'none', + backgroundColor: 'white', + mixBlendMode: 'difference', + }, }, }, rootUnselected: { diff --git a/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/CarouselNavContainer.test.tsx b/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/CarouselNavContainer.test.tsx index a3f4c69ef18b3d..6b64fc26cae73c 100644 --- a/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/CarouselNavContainer.test.tsx +++ b/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/CarouselNavContainer.test.tsx @@ -2,12 +2,28 @@ import * as React from 'react'; import { render } from '@testing-library/react'; import { isConformant } from '../../testing/isConformant'; import { CarouselNavContainer } from './CarouselNavContainer'; +import { carouselNavContainerClassNames } from './useCarouselNavContainerStyles.styles'; describe('CarouselNavContainer', () => { isConformant({ Component: CarouselNavContainer, displayName: 'CarouselNavContainer', requiredProps: { autoplay: '' }, + + testOptions: { + 'has-static-classnames': [ + { + props: {}, + expectedClassNames: { + // Tooltip classNames are not expected as it has no root + root: carouselNavContainerClassNames.root, + next: carouselNavContainerClassNames.next, + prev: carouselNavContainerClassNames.prev, + autoplay: carouselNavContainerClassNames.autoplay, + }, + }, + ], + }, }); // TODO add more tests here, and create visual regression tests in /apps/vr-tests diff --git a/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/CarouselNavContainer.types.ts b/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/CarouselNavContainer.types.ts index 928745b9f3956b..dea6429b3998b6 100644 --- a/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/CarouselNavContainer.types.ts +++ b/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/CarouselNavContainer.types.ts @@ -1,12 +1,16 @@ import type { ComponentProps, ComponentState, Slot } from '@fluentui/react-utilities'; import { CarouselAutoplayButton } from '../CarouselAutoplayButton/CarouselAutoplayButton'; import { CarouselButtonProps } from '../CarouselButton/CarouselButton.types'; +import { TooltipProps } from '@fluentui/react-tooltip'; export type CarouselNavContainerSlots = { root: Slot<'div'>; next?: Slot; + nextTooltip?: Slot; prev?: Slot; + prevTooltip?: Slot; autoplay?: Slot; + autoplayTooltip?: Slot; }; /** diff --git a/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/index.ts b/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/index.ts index eb482ee8accd89..70c01028eb1adc 100644 --- a/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/index.ts +++ b/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/index.ts @@ -1,5 +1,12 @@ -export * from './CarouselNavContainer'; -export * from './CarouselNavContainer.types'; -export * from './renderCarouselNavContainer'; -export * from './useCarouselNavContainer'; -export * from './useCarouselNavContainerStyles.styles'; +export { CarouselNavContainer } from './CarouselNavContainer'; +export type { + CarouselNavContainerProps, + CarouselNavContainerSlots, + CarouselNavContainerState, +} from './CarouselNavContainer.types'; +export { renderCarouselNavContainer_unstable } from './renderCarouselNavContainer'; +export { useCarouselNavContainer_unstable } from './useCarouselNavContainer'; +export { + carouselNavContainerClassNames, + useCarouselNavContainerStyles_unstable, +} from './useCarouselNavContainerStyles.styles'; diff --git a/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/renderCarouselNavContainer.tsx b/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/renderCarouselNavContainer.tsx index 9a7e6c8655ddd1..8fd36b3416faa7 100644 --- a/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/renderCarouselNavContainer.tsx +++ b/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/renderCarouselNavContainer.tsx @@ -12,10 +12,25 @@ export const renderCarouselNavContainer_unstable = (state: CarouselNavContainerS return ( - {state.autoplay && } - {state.prev && } + {!state.autoplayTooltip && state.autoplay && } + {state.autoplayTooltip && state.autoplay && ( + + + + )} + {!state.prevTooltip && state.prev && } + {state.prevTooltip && state.prev && ( + + + + )} {state.root.children} - {state.next && } + {!state.nextTooltip && state.next && } + {state.nextTooltip && state.next && ( + + + + )} ); }; diff --git a/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/useCarouselNavContainer.ts b/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/useCarouselNavContainer.ts index db99b5725426de..1d58f5cb48dc2d 100644 --- a/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/useCarouselNavContainer.ts +++ b/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/useCarouselNavContainer.ts @@ -3,6 +3,7 @@ import { getIntrinsicElementProps, slot } from '@fluentui/react-utilities'; import type { CarouselNavContainerProps, CarouselNavContainerState } from './CarouselNavContainer.types'; import { CarouselAutoplayButton } from '../CarouselAutoplayButton/CarouselAutoplayButton'; import { CarouselButton } from '../CarouselButton/CarouselButton'; +import { Tooltip } from '@fluentui/react-tooltip'; /** * Create the state required to render CarouselNavContainer. @@ -35,8 +36,26 @@ export const useCarouselNavContainer_unstable = ( }); const autoplay: CarouselNavContainerState['autoplay'] = slot.optional(props.autoplay, { - renderByDefault: false, elementType: CarouselAutoplayButton, + renderByDefault: !!props.autoplay || !!props.autoplayTooltip, + }); + + const nextTooltip: CarouselNavContainerState['nextTooltip'] = slot.optional(props.nextTooltip, { + defaultProps: {}, + elementType: Tooltip, + renderByDefault: false, + }); + + const prevTooltip: CarouselNavContainerState['prevTooltip'] = slot.optional(props.prevTooltip, { + defaultProps: {}, + elementType: Tooltip, + renderByDefault: false, + }); + + const autoplayTooltip: CarouselNavContainerState['autoplayTooltip'] = slot.optional(props.autoplayTooltip, { + defaultProps: {}, + elementType: Tooltip, + renderByDefault: false, }); return { @@ -46,6 +65,9 @@ export const useCarouselNavContainer_unstable = ( next: CarouselButton, prev: CarouselButton, autoplay: CarouselAutoplayButton, + nextTooltip: Tooltip, + prevTooltip: Tooltip, + autoplayTooltip: Tooltip, }, root: slot.always( getIntrinsicElementProps('div', { @@ -57,5 +79,8 @@ export const useCarouselNavContainer_unstable = ( next, prev, autoplay, + nextTooltip, + prevTooltip, + autoplayTooltip, }; }; diff --git a/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/useCarouselNavContainerStyles.styles.ts b/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/useCarouselNavContainerStyles.styles.ts index 60d5844cc910cd..82e1f62a727d3e 100644 --- a/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/useCarouselNavContainerStyles.styles.ts +++ b/packages/react-components/react-carousel/library/src/components/CarouselNavContainer/useCarouselNavContainerStyles.styles.ts @@ -8,6 +8,12 @@ export const carouselNavContainerClassNames: SlotClassNames { return subscribeForValues(data => { - const controlList = data.groupIndexList[index]; + const controlList = data.groupIndexList?.[index] ?? []; const _controlledSlideIds = controlList .map((slideIndex: number) => { return data.slideNodes[slideIndex].id; diff --git a/packages/react-components/react-carousel/library/src/components/CarouselSlider/index.ts b/packages/react-components/react-carousel/library/src/components/CarouselSlider/index.ts index 4aee85c70e3d6f..6d56c872cf430d 100644 --- a/packages/react-components/react-carousel/library/src/components/CarouselSlider/index.ts +++ b/packages/react-components/react-carousel/library/src/components/CarouselSlider/index.ts @@ -1,5 +1,10 @@ -export * from './CarouselSlider'; -export * from './CarouselSlider.types'; -export * from './renderCarouselSlider'; -export * from './useCarouselSlider'; -export * from './useCarouselSliderStyles.styles'; +export { CarouselSlider } from './CarouselSlider'; +export type { + CarouselSliderContextValue, + CarouselSliderProps, + CarouselSliderSlots, + CarouselSliderState, +} from './CarouselSlider.types'; +export { renderCarouselSlider_unstable } from './renderCarouselSlider'; +export { useCarouselSlider_unstable } from './useCarouselSlider'; +export { carouselSliderClassNames, useCarouselSliderStyles_unstable } from './useCarouselSliderStyles.styles'; diff --git a/packages/react-components/react-carousel/library/src/components/CarouselViewport/index.ts b/packages/react-components/react-carousel/library/src/components/CarouselViewport/index.ts index e58459eaffcf1c..b394d360ba91f2 100644 --- a/packages/react-components/react-carousel/library/src/components/CarouselViewport/index.ts +++ b/packages/react-components/react-carousel/library/src/components/CarouselViewport/index.ts @@ -1,5 +1,5 @@ -export * from './CarouselViewport'; -export * from './CarouselViewport.types'; -export * from './renderCarouselViewport'; -export * from './useCarouselViewport'; -export * from './useCarouselViewportStyles.styles'; +export { CarouselViewport } from './CarouselViewport'; +export type { CarouselViewportProps, CarouselViewportSlots, CarouselViewportState } from './CarouselViewport.types'; +export { renderCarouselViewport_unstable } from './renderCarouselViewport'; +export { useCarouselViewport_unstable } from './useCarouselViewport'; +export { carouselViewportClassNames, useCarouselViewportStyles_unstable } from './useCarouselViewportStyles.styles'; diff --git a/packages/react-components/react-carousel/library/src/components/useEmblaCarousel.ts b/packages/react-components/react-carousel/library/src/components/useEmblaCarousel.ts index c23796005a4185..aede2ea00c94f2 100644 --- a/packages/react-components/react-carousel/library/src/components/useEmblaCarousel.ts +++ b/packages/react-components/react-carousel/library/src/components/useEmblaCarousel.ts @@ -46,10 +46,12 @@ export function useEmblaCarousel( motion?: CarouselMotion; onDragIndexChange?: EventHandler; onAutoplayIndexChange?: EventHandler; + autoplayInterval?: number; }, ) { const { align, + autoplayInterval, direction, loop, slidesToScroll, @@ -59,6 +61,10 @@ export function useEmblaCarousel( onDragIndexChange, onAutoplayIndexChange, } = options; + + const motionType = typeof motion === 'string' ? motion : motion?.kind ?? 'slide'; + const motionDuration = typeof motion === 'string' ? 25 : motion?.duration ?? 25; + const [activeIndex, setActiveIndex] = useControllableState({ defaultState: options.defaultActiveIndex, state: options.activeIndex, @@ -77,6 +83,7 @@ export function useEmblaCarousel( startIndex: activeIndex, watchDrag, containScroll, + duration: motionDuration, }); const emblaApi = React.useRef(null); @@ -92,6 +99,7 @@ export function useEmblaCarousel( plugins.push( Autoplay({ playOnInit: autoplayRef.current, + delay: autoplayInterval, /* stopOnInteraction: false causes autoplay to restart on interaction end*/ /* we'll handle this logic to ensure autoplay state is respected */ stopOnInteraction: true, @@ -101,7 +109,7 @@ export function useEmblaCarousel( ); // Optionally add Fade plugin - if (motion === 'fade') { + if (motionType === 'fade') { plugins.push(Fade()); } @@ -114,7 +122,7 @@ export function useEmblaCarousel( } return plugins; - }, [motion, onDragEvent, watchDrag]); + }, [motionType, onDragEvent, watchDrag, autoplayInterval]); /* This function enables autoplay to pause/play without affecting underlying state * Useful for pausing on focus etc. without having to reinitialize or set autoplay to off @@ -147,11 +155,23 @@ export function useEmblaCarousel( }; }, []); + const updateIndex = () => { + const newIndex = emblaApi.current?.selectedScrollSnap() ?? 0; + const slides = emblaApi.current?.slideNodes(); + const slideRegistry = emblaApi.current?.internalEngine().slideRegistry; + const actualIndex = slideRegistry?.[newIndex]?.[0] ?? 0; + + // We set the first card in the current group as the default tabster index for focus capture + slides?.forEach((slide, slideIndex) => { + setTabsterDefault(slide, slideIndex === actualIndex); + }); + setActiveIndex(newIndex); + }; + const handleReinit = useEventCallback(() => { const nodes: HTMLElement[] = emblaApi.current?.slideNodes() ?? []; const groupIndexList: number[][] = emblaApi.current?.internalEngine().slideRegistry ?? []; const navItemsCount = groupIndexList.length > 0 ? groupIndexList.length : nodes.length; - const data: CarouselUpdateData = { navItemsCount, activeIndex: emblaApi.current?.selectedScrollSnap() ?? 0, @@ -159,6 +179,7 @@ export function useEmblaCarousel( slideNodes: nodes, }; + updateIndex(); emblaApi.current?.scrollTo(activeIndex, false); for (const listener of listeners.current) { listener(data); @@ -167,15 +188,7 @@ export function useEmblaCarousel( const handleIndexChange: EmblaEventHandler = useEventCallback((_, eventType) => { const newIndex = emblaApi.current?.selectedScrollSnap() ?? 0; - const slides = emblaApi.current?.slideNodes(); - const actualIndex = emblaApi.current?.internalEngine().slideRegistry[newIndex][0] ?? 0; - - // We set the active or first index of group on-screen as the selected tabster index - slides?.forEach((slide, slideIndex) => { - setTabsterDefault(slide, slideIndex === actualIndex); - }); - setActiveIndex(newIndex); - + updateIndex(); if (eventType === 'autoplay:select') { const noopEvent = new Event('autoplay'); onAutoplayIndexChange?.(noopEvent, { event: noopEvent, type: 'autoplay', index: newIndex }); @@ -275,6 +288,7 @@ export function useEmblaCarousel( slidesToScroll, watchDrag, containScroll, + duration: motionDuration, }; emblaApi.current?.reInit( @@ -284,7 +298,7 @@ export function useEmblaCarousel( }, plugins, ); - }, [align, containScroll, direction, getPlugins, loop, slidesToScroll, watchDrag]); + }, [align, containScroll, direction, getPlugins, loop, slidesToScroll, watchDrag, motionDuration]); React.useEffect(() => { // Scroll to controlled values on update diff --git a/packages/react-components/react-carousel/stories/src/Carousel/CarouselControlled.stories.tsx b/packages/react-components/react-carousel/stories/src/Carousel/CarouselControlled.stories.tsx index 26ca5acceb4803..1f5c295e059612 100644 --- a/packages/react-components/react-carousel/stories/src/Carousel/CarouselControlled.stories.tsx +++ b/packages/react-components/react-carousel/stories/src/Carousel/CarouselControlled.stories.tsx @@ -162,7 +162,7 @@ export const Controlled = () => {
- + {JSON.stringify({ activeIndex }, null, 2)} diff --git a/packages/react-components/react-carousel/stories/src/Carousel/CarouselDefault.stories.tsx b/packages/react-components/react-carousel/stories/src/Carousel/CarouselDefault.stories.tsx index 60d13fb018e915..96ae032ac8c1d8 100644 --- a/packages/react-components/react-carousel/stories/src/Carousel/CarouselDefault.stories.tsx +++ b/packages/react-components/react-carousel/stories/src/Carousel/CarouselDefault.stories.tsx @@ -90,11 +90,9 @@ export const Default = () => ( {index => } diff --git a/packages/react-components/react-carousel/stories/src/Carousel/CarouselFirstRunExperience.stories.tsx b/packages/react-components/react-carousel/stories/src/Carousel/CarouselFirstRunExperience.stories.tsx index 3087e6c4f73f31..1150ff244e5ea0 100644 --- a/packages/react-components/react-carousel/stories/src/Carousel/CarouselFirstRunExperience.stories.tsx +++ b/packages/react-components/react-carousel/stories/src/Carousel/CarouselFirstRunExperience.stories.tsx @@ -93,7 +93,7 @@ export const FirstRunExperience = () => { - + +## [9.3.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-checkbox_v9.3.0) + +Fri, 21 Feb 2025 14:34:05 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-checkbox_v9.2.47..@fluentui/react-checkbox_v9.3.0) + +### Minor changes + +- Bump @fluentui/react-field to v9.2.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) +- Bump @fluentui/react-tabster to v9.24.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) + +## [9.2.47](https://github.com/microsoft/fluentui/tree/@fluentui/react-checkbox_v9.2.47) + +Mon, 27 Jan 2025 20:27:35 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-checkbox_v9.2.46..@fluentui/react-checkbox_v9.2.47) + +### Patches + +- Bump @fluentui/react-field to v9.1.86 ([PR #33724](https://github.com/microsoft/fluentui/pull/33724) by beachball) + +## [9.2.46](https://github.com/microsoft/fluentui/tree/@fluentui/react-checkbox_v9.2.46) + +Wed, 22 Jan 2025 14:00:21 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-checkbox_v9.2.45..@fluentui/react-checkbox_v9.2.46) + +### Patches + +- Bump @fluentui/react-field to v9.1.85 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.50 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-label to v9.1.83 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-tabster to v9.23.3 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-utilities to v9.18.20 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) + +## [9.2.45](https://github.com/microsoft/fluentui/tree/@fluentui/react-checkbox_v9.2.45) + +Wed, 08 Jan 2025 18:33:36 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-checkbox_v9.2.44..@fluentui/react-checkbox_v9.2.45) + +### Patches + +- Bump @fluentui/react-field to v9.1.84 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.49 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-label to v9.1.82 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) + +## [9.2.44](https://github.com/microsoft/fluentui/tree/@fluentui/react-checkbox_v9.2.44) + +Mon, 16 Dec 2024 16:26:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-checkbox_v9.2.43..@fluentui/react-checkbox_v9.2.44) + +### Patches + +- Bump @fluentui/react-field to v9.1.83 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.48 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-label to v9.1.81 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-shared-contexts to v9.21.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-tabster to v9.23.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-theme to v9.1.24 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-utilities to v9.18.19 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) + +## [9.2.43](https://github.com/microsoft/fluentui/tree/@fluentui/react-checkbox_v9.2.43) + +Mon, 09 Dec 2024 17:38:09 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-checkbox_v9.2.42..@fluentui/react-checkbox_v9.2.43) + +### Patches + +- chore: remove usage of "export *" ([PR #33384](https://github.com/microsoft/fluentui/pull/33384) by olfedias@microsoft.com) +- Bump @fluentui/react-field to v9.1.82 ([PR #33431](https://github.com/microsoft/fluentui/pull/33431) by beachball) +- Bump @fluentui/react-label to v9.1.80 ([PR #33431](https://github.com/microsoft/fluentui/pull/33431) by beachball) + ## [9.2.42](https://github.com/microsoft/fluentui/tree/@fluentui/react-checkbox_v9.2.42) Fri, 06 Dec 2024 12:53:46 GMT diff --git a/packages/react-components/react-checkbox/library/package.json b/packages/react-components/react-checkbox/library/package.json index 70cc856fa252ad..657875702c1d86 100644 --- a/packages/react-components/react-checkbox/library/package.json +++ b/packages/react-components/react-checkbox/library/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-checkbox", - "version": "9.2.42", + "version": "9.3.0", "description": "Fluent UI checkbox component", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -18,14 +18,14 @@ "@fluentui/scripts-api-extractor": "*" }, "dependencies": { - "@fluentui/react-field": "^9.1.81", + "@fluentui/react-field": "^9.2.0", "@fluentui/react-icons": "^2.0.245", - "@fluentui/react-jsx-runtime": "^9.0.47", - "@fluentui/react-label": "^9.1.79", - "@fluentui/react-shared-contexts": "^9.21.1", - "@fluentui/react-tabster": "^9.23.1", - "@fluentui/react-theme": "^9.1.23", - "@fluentui/react-utilities": "^9.18.18", + "@fluentui/react-jsx-runtime": "^9.0.50", + "@fluentui/react-label": "^9.1.83", + "@fluentui/react-shared-contexts": "^9.21.2", + "@fluentui/react-tabster": "^9.24.0", + "@fluentui/react-theme": "^9.1.24", + "@fluentui/react-utilities": "^9.18.20", "@griffel/react": "^1.5.22", "@swc/helpers": "^0.5.1" }, diff --git a/packages/react-components/react-checkbox/library/src/Checkbox.ts b/packages/react-components/react-checkbox/library/src/Checkbox.ts index 0c5e8af240aff5..3803011300e464 100644 --- a/packages/react-components/react-checkbox/library/src/Checkbox.ts +++ b/packages/react-components/react-checkbox/library/src/Checkbox.ts @@ -1 +1,8 @@ -export * from './components/Checkbox/index'; +export type { CheckboxOnChangeData, CheckboxProps, CheckboxSlots, CheckboxState } from './components/Checkbox/index'; +export { + Checkbox, + checkboxClassNames, + renderCheckbox_unstable, + useCheckboxStyles_unstable, + useCheckbox_unstable, +} from './components/Checkbox/index'; diff --git a/packages/react-components/react-checkbox/library/src/components/Checkbox/index.ts b/packages/react-components/react-checkbox/library/src/components/Checkbox/index.ts index 80df796a399fc1..12672f40b4addd 100644 --- a/packages/react-components/react-checkbox/library/src/components/Checkbox/index.ts +++ b/packages/react-components/react-checkbox/library/src/components/Checkbox/index.ts @@ -1,5 +1,5 @@ -export * from './Checkbox'; -export * from './Checkbox.types'; -export * from './renderCheckbox'; -export * from './useCheckbox'; -export * from './useCheckboxStyles.styles'; +export { Checkbox } from './Checkbox'; +export type { CheckboxOnChangeData, CheckboxProps, CheckboxSlots, CheckboxState } from './Checkbox.types'; +export { renderCheckbox_unstable } from './renderCheckbox'; +export { useCheckbox_unstable } from './useCheckbox'; +export { checkboxClassNames, useCheckboxStyles_unstable } from './useCheckboxStyles.styles'; diff --git a/packages/react-components/react-color-picker-preview/library/CHANGELOG.json b/packages/react-components/react-color-picker-preview/library/CHANGELOG.json index 94756fce504f84..c9b461a6a542b0 100644 --- a/packages/react-components/react-color-picker-preview/library/CHANGELOG.json +++ b/packages/react-components/react-color-picker-preview/library/CHANGELOG.json @@ -1,6 +1,232 @@ { "name": "@fluentui/react-color-picker-preview", "entries": [ + { + "date": "Fri, 21 Feb 2025 14:34:05 GMT", + "tag": "@fluentui/react-color-picker-preview_v0.3.0", + "version": "0.3.0", + "comments": { + "minor": [ + { + "author": "beachball", + "package": "@fluentui/react-color-picker-preview", + "comment": "Bump @fluentui/react-tabster to v9.24.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + } + ] + } + }, + { + "date": "Tue, 18 Feb 2025 11:26:27 GMT", + "tag": "@fluentui/react-color-picker-preview_v0.2.0", + "version": "0.2.0", + "comments": { + "patch": [ + { + "author": "vkozlova@microsoft.com", + "package": "@fluentui/react-color-picker-preview", + "commit": "88132360465097de0c8628861fd4cfb9fac0a124", + "comment": "fix: design changes for ColorPicker" + } + ], + "minor": [ + { + "author": "v.kozlova13@gmail.com", + "package": "@fluentui/react-color-picker-preview", + "commit": "d9f7b1a94a36c1a532ac8f9287fdd04a811739ce", + "comment": "custom color channels" + } + ] + } + }, + { + "date": "Fri, 07 Feb 2025 10:42:11 GMT", + "tag": "@fluentui/react-color-picker-preview_v0.1.6", + "version": "0.1.6", + "comments": { + "patch": [ + { + "author": "v.kozlova13@gmail.com", + "package": "@fluentui/react-color-picker-preview", + "commit": "678529c67e1a18062fa8c810e85cf1b4f46ff513", + "comment": "fix: thumb design for ColorPicker - partner's ask" + } + ] + } + }, + { + "date": "Mon, 27 Jan 2025 20:27:33 GMT", + "tag": "@fluentui/react-color-picker-preview_v0.1.5", + "version": "0.1.5", + "comments": { + "patch": [ + { + "author": "v.kozlova13@gmail.com", + "package": "@fluentui/react-color-picker-preview", + "commit": "d8e6230e7e0b504a9651d10b15860ccaf0a87824", + "comment": "fix: default state for ColorSliders" + } + ] + } + }, + { + "date": "Wed, 22 Jan 2025 14:00:14 GMT", + "tag": "@fluentui/react-color-picker-preview_v0.1.4", + "version": "0.1.4", + "comments": { + "none": [ + { + "author": "vgenaev@gmail.com", + "package": "@fluentui/react-color-picker-preview", + "commit": "fd420e1e0b66e04c8a423cff3eea6d21d9434d2d", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule" + }, + { + "author": "martinhochel@microsoft.com", + "package": "@fluentui/react-color-picker-preview", + "commit": "2f88d062a57e6dc44ecd65df2ab067652ae4c7ce", + "comment": "fix: make api.md up to date" + } + ], + "patch": [ + { + "author": "makotom@microsoft.com", + "package": "@fluentui/react-color-picker-preview", + "commit": "e7a954abbbe42a13ba302f28710a908cd34b72b9", + "comment": "chore: Moving @ctrl/tinycolor dependency to be a caret dependency in production packages." + }, + { + "author": "vkozlova@microsoft.com", + "package": "@fluentui/react-color-picker-preview", + "commit": "9ed5fce8dda03bb85d583a23478ed298e51d305d", + "comment": "fix: focus jumps to inputY instead of next element" + }, + { + "author": "v.kozlova13@gmail.com", + "package": "@fluentui/react-color-picker-preview", + "commit": "f1a15496cf7c7121f4d163e2394d5647fbe9eb96", + "comment": "feat: Added `transparent` option to the AlphaSlider" + }, + { + "author": "beachball", + "package": "@fluentui/react-color-picker-preview", + "comment": "Bump @fluentui/react-context-selector to v9.1.72", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-color-picker-preview", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.50", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-color-picker-preview", + "comment": "Bump @fluentui/react-tabster to v9.23.3", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-color-picker-preview", + "comment": "Bump @fluentui/react-utilities to v9.18.20", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + } + ] + } + }, + { + "date": "Wed, 08 Jan 2025 18:33:32 GMT", + "tag": "@fluentui/react-color-picker-preview_v0.1.3", + "version": "0.1.3", + "comments": { + "patch": [ + { + "author": "vkozlova@microsoft.com", + "package": "@fluentui/react-color-picker-preview", + "commit": "c53044a18a262e2defa3f27bf09950ec724a8997", + "comment": "fix: contrast border of thumb" + }, + { + "author": "vkozlova@microsoft.com", + "package": "@fluentui/react-color-picker-preview", + "commit": "b52d6ba234a24ce1d05c636cfc41b0098b15cfb9", + "comment": "feat: added aria-attributes to the ColorPicker" + }, + { + "author": "beachball", + "package": "@fluentui/react-color-picker-preview", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.49", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + } + ] + } + }, + { + "date": "Mon, 16 Dec 2024 16:26:48 GMT", + "tag": "@fluentui/react-color-picker-preview_v0.1.2", + "version": "0.1.2", + "comments": { + "patch": [ + { + "author": "vkozlova@microsoft.com", + "package": "@fluentui/react-color-picker-preview", + "commit": "b9a11c54c2b7bd6d003ef1952b59f63647143451", + "comment": "fix(react-color-picker): active axis for ColorPicker" + }, + { + "author": "beachball", + "package": "@fluentui/react-color-picker-preview", + "comment": "Bump @fluentui/react-context-selector to v9.1.71", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-color-picker-preview", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.48", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-color-picker-preview", + "comment": "Bump @fluentui/react-shared-contexts to v9.21.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-color-picker-preview", + "comment": "Bump @fluentui/react-tabster to v9.23.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-color-picker-preview", + "comment": "Bump @fluentui/react-theme to v9.1.24", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-color-picker-preview", + "comment": "Bump @fluentui/react-utilities to v9.18.19", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + } + ] + } + }, + { + "date": "Mon, 09 Dec 2024 17:38:10 GMT", + "tag": "@fluentui/react-color-picker-preview_v0.1.1", + "version": "0.1.1", + "comments": { + "patch": [ + { + "author": "olfedias@microsoft.com", + "package": "@fluentui/react-color-picker-preview", + "commit": "cad13936cd49ba0b34b50bc2f58395605c4e8da4", + "comment": "chore: remove usage of \"export *\"" + } + ] + } + }, { "date": "Fri, 06 Dec 2024 12:53:39 GMT", "tag": "@fluentui/react-color-picker-preview_v0.1.0", diff --git a/packages/react-components/react-color-picker-preview/library/CHANGELOG.md b/packages/react-components/react-color-picker-preview/library/CHANGELOG.md index 249308f17113fb..60ab284db25c13 100644 --- a/packages/react-components/react-color-picker-preview/library/CHANGELOG.md +++ b/packages/react-components/react-color-picker-preview/library/CHANGELOG.md @@ -1,9 +1,99 @@ # Change Log - @fluentui/react-color-picker-preview -This log was last generated on Fri, 06 Dec 2024 12:53:39 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 14:34:05 GMT and should not be manually modified. +## [0.3.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-color-picker-preview_v0.3.0) + +Fri, 21 Feb 2025 14:34:05 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-color-picker-preview_v0.2.0..@fluentui/react-color-picker-preview_v0.3.0) + +### Minor changes + +- Bump @fluentui/react-tabster to v9.24.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) + +## [0.2.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-color-picker-preview_v0.2.0) + +Tue, 18 Feb 2025 11:26:27 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-color-picker-preview_v0.1.6..@fluentui/react-color-picker-preview_v0.2.0) + +### Minor changes + +- custom color channels ([PR #33763](https://github.com/microsoft/fluentui/pull/33763) by v.kozlova13@gmail.com) + +### Patches + +- fix: design changes for ColorPicker ([PR #33785](https://github.com/microsoft/fluentui/pull/33785) by vkozlova@microsoft.com) + +## [0.1.6](https://github.com/microsoft/fluentui/tree/@fluentui/react-color-picker-preview_v0.1.6) + +Fri, 07 Feb 2025 10:42:11 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-color-picker-preview_v0.1.5..@fluentui/react-color-picker-preview_v0.1.6) + +### Patches + +- fix: thumb design for ColorPicker - partner's ask ([PR #33743](https://github.com/microsoft/fluentui/pull/33743) by v.kozlova13@gmail.com) + +## [0.1.5](https://github.com/microsoft/fluentui/tree/@fluentui/react-color-picker-preview_v0.1.5) + +Mon, 27 Jan 2025 20:27:33 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-color-picker-preview_v0.1.4..@fluentui/react-color-picker-preview_v0.1.5) + +### Patches + +- fix: default state for ColorSliders ([PR #33715](https://github.com/microsoft/fluentui/pull/33715) by v.kozlova13@gmail.com) + +## [0.1.4](https://github.com/microsoft/fluentui/tree/@fluentui/react-color-picker-preview_v0.1.4) + +Wed, 22 Jan 2025 14:00:14 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-color-picker-preview_v0.1.3..@fluentui/react-color-picker-preview_v0.1.4) + +### Patches + +- chore: Moving @ctrl/tinycolor dependency to be a caret dependency in production packages. ([PR #33611](https://github.com/microsoft/fluentui/pull/33611) by makotom@microsoft.com) +- fix: focus jumps to inputY instead of next element ([PR #33620](https://github.com/microsoft/fluentui/pull/33620) by vkozlova@microsoft.com) +- feat: Added `transparent` option to the AlphaSlider ([PR #33572](https://github.com/microsoft/fluentui/pull/33572) by v.kozlova13@gmail.com) +- Bump @fluentui/react-context-selector to v9.1.72 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.50 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-tabster to v9.23.3 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-utilities to v9.18.20 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) + +## [0.1.3](https://github.com/microsoft/fluentui/tree/@fluentui/react-color-picker-preview_v0.1.3) + +Wed, 08 Jan 2025 18:33:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-color-picker-preview_v0.1.2..@fluentui/react-color-picker-preview_v0.1.3) + +### Patches + +- fix: contrast border of thumb ([PR #33526](https://github.com/microsoft/fluentui/pull/33526) by vkozlova@microsoft.com) +- feat: added aria-attributes to the ColorPicker ([PR #33543](https://github.com/microsoft/fluentui/pull/33543) by vkozlova@microsoft.com) +- Bump @fluentui/react-jsx-runtime to v9.0.49 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) + +## [0.1.2](https://github.com/microsoft/fluentui/tree/@fluentui/react-color-picker-preview_v0.1.2) + +Mon, 16 Dec 2024 16:26:48 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-color-picker-preview_v0.1.1..@fluentui/react-color-picker-preview_v0.1.2) + +### Patches + +- fix(react-color-picker): active axis for ColorPicker ([PR #33415](https://github.com/microsoft/fluentui/pull/33415) by vkozlova@microsoft.com) +- Bump @fluentui/react-context-selector to v9.1.71 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.48 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-shared-contexts to v9.21.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-tabster to v9.23.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-theme to v9.1.24 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-utilities to v9.18.19 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) + +## [0.1.1](https://github.com/microsoft/fluentui/tree/@fluentui/react-color-picker-preview_v0.1.1) + +Mon, 09 Dec 2024 17:38:10 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-color-picker-preview_v0.1.0..@fluentui/react-color-picker-preview_v0.1.1) + +### Patches + +- chore: remove usage of "export *" ([PR #33384](https://github.com/microsoft/fluentui/pull/33384) by olfedias@microsoft.com) + ## [0.1.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-color-picker-preview_v0.1.0) Fri, 06 Dec 2024 12:53:39 GMT diff --git a/packages/react-components/react-color-picker-preview/library/bundle-size/ColorArea.fixture.js b/packages/react-components/react-color-picker-preview/library/bundle-size/ColorArea.fixture.js new file mode 100644 index 00000000000000..8a829cb2bf0380 --- /dev/null +++ b/packages/react-components/react-color-picker-preview/library/bundle-size/ColorArea.fixture.js @@ -0,0 +1,7 @@ +import { ColorArea } from '@fluentui/react-color-picker-preview'; + +console.log(ColorArea); + +export default { + name: 'ColorArea', +}; diff --git a/packages/react-components/react-color-picker-preview/library/bundle-size/ColorPicker.fixture.js b/packages/react-components/react-color-picker-preview/library/bundle-size/ColorPicker.fixture.js new file mode 100644 index 00000000000000..7a0b7f9a01cf7b --- /dev/null +++ b/packages/react-components/react-color-picker-preview/library/bundle-size/ColorPicker.fixture.js @@ -0,0 +1,7 @@ +import { ColorPicker } from '@fluentui/react-color-picker-preview'; + +console.log(ColorPicker); + +export default { + name: 'ColorPicker', +}; diff --git a/packages/react-components/react-color-picker-preview/library/bundle-size/ColorSlider.fixture.js b/packages/react-components/react-color-picker-preview/library/bundle-size/ColorSlider.fixture.js new file mode 100644 index 00000000000000..ce8fbc6a055694 --- /dev/null +++ b/packages/react-components/react-color-picker-preview/library/bundle-size/ColorSlider.fixture.js @@ -0,0 +1,7 @@ +import { ColorSlider } from '@fluentui/react-color-picker-preview'; + +console.log(ColorSlider); + +export default { + name: 'ColorSlider', +}; 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 5c78ccfa5aa480..d5a3860b9eceff 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 = Omit & { + transparency?: boolean; +}; // @public (undocumented) export type AlphaSliderSlots = ColorSliderSlots; @@ -35,7 +37,7 @@ export const ColorArea: ForwardRefComponent; export const colorAreaClassNames: SlotClassNames; // @public -export type ColorAreaProps = Omit>, 'color' | 'onChange'> & { +export type ColorAreaProps = Omit>, 'color' | 'onChange'> & Pick & { color?: HsvColor; defaultColor?: HsvColor; onChange?: EventHandler; @@ -50,7 +52,7 @@ export type ColorAreaSlots = { }; // @public -export type ColorAreaState = ComponentState> & Pick; +export type ColorAreaState = ComponentState> & Pick; // @public export const ColorPicker: ForwardRefComponent; @@ -60,8 +62,9 @@ export const colorPickerClassNames: SlotClassNames; // @public export type ColorPickerProps = Omit>, 'color'> & { - color: HsvColor; + color?: HsvColor; onColorChange?: EventHandler; + shape?: 'rounded' | 'square'; }; // @public (undocumented) @@ -79,8 +82,8 @@ export const ColorSlider: ForwardRefComponent; export const colorSliderClassNames: SlotClassNames; // @public -export type ColorSliderProps = Omit, 'input'>, 'defaultValue' | 'onChange' | 'value' | 'color'> & { - channel?: string; +export type ColorSliderProps = Omit, 'input'>, 'defaultValue' | 'onChange' | 'value' | 'color'> & Pick & { + channel?: ColorChannel; onChange?: EventHandler; vertical?: boolean; color?: HsvColor; @@ -96,7 +99,7 @@ export type ColorSliderSlots = { }; // @public -export type ColorSliderState = ComponentState & Pick; +export type ColorSliderState = ComponentState & Pick; // @public export const renderAlphaSlider_unstable: (state: AlphaSliderState) => JSX.Element; diff --git a/packages/react-components/react-color-picker-preview/library/package.json b/packages/react-components/react-color-picker-preview/library/package.json index 94ce9b9afc7ada..c04974deaa789d 100644 --- a/packages/react-components/react-color-picker-preview/library/package.json +++ b/packages/react-components/react-color-picker-preview/library/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-color-picker-preview", - "version": "0.1.0", + "version": "0.3.0", "description": "ColorPicker component for Fluent UI React.", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -24,13 +24,13 @@ "@fluentui/scripts-api-extractor": "*" }, "dependencies": { - "@ctrl/tinycolor": "3.3.4", - "@fluentui/react-context-selector": "^9.1.70", - "@fluentui/react-jsx-runtime": "^9.0.47", - "@fluentui/react-shared-contexts": "^9.21.1", - "@fluentui/react-tabster": "^9.23.1", - "@fluentui/react-theme": "^9.1.23", - "@fluentui/react-utilities": "^9.18.18", + "@ctrl/tinycolor": "^3.3.4", + "@fluentui/react-context-selector": "^9.1.72", + "@fluentui/react-jsx-runtime": "^9.0.50", + "@fluentui/react-shared-contexts": "^9.21.2", + "@fluentui/react-tabster": "^9.24.0", + "@fluentui/react-theme": "^9.1.24", + "@fluentui/react-utilities": "^9.18.20", "@griffel/react": "^1.5.22", "@swc/helpers": "^0.5.1" }, diff --git a/packages/react-components/react-color-picker-preview/library/src/AlphaSlider.ts b/packages/react-components/react-color-picker-preview/library/src/AlphaSlider.ts index 0727e3cae3bfb5..42d1552ee9bb72 100644 --- a/packages/react-components/react-color-picker-preview/library/src/AlphaSlider.ts +++ b/packages/react-components/react-color-picker-preview/library/src/AlphaSlider.ts @@ -1 +1,9 @@ -export * from './components/AlphaSlider/index'; +export type { AlphaSliderProps, AlphaSliderSlots, AlphaSliderState } from './components/AlphaSlider/index'; +export { + AlphaSlider, + alphaSliderCSSVars, + alphaSliderClassNames, + renderAlphaSlider_unstable, + useAlphaSliderStyles_unstable, + useAlphaSlider_unstable, +} from './components/AlphaSlider/index'; diff --git a/packages/react-components/react-color-picker-preview/library/src/ColorArea.ts b/packages/react-components/react-color-picker-preview/library/src/ColorArea.ts index de190e310268d9..ee9f5325048967 100644 --- a/packages/react-components/react-color-picker-preview/library/src/ColorArea.ts +++ b/packages/react-components/react-color-picker-preview/library/src/ColorArea.ts @@ -1 +1,14 @@ -export * from './components/ColorArea/index'; +export type { + ColorAreaOnColorChangeData, + ColorAreaProps, + ColorAreaSlots, + ColorAreaState, +} from './components/ColorArea/index'; +export { + ColorArea, + colorAreaCSSVars, + colorAreaClassNames, + renderColorArea_unstable, + useColorAreaStyles_unstable, + useColorArea_unstable, +} from './components/ColorArea/index'; diff --git a/packages/react-components/react-color-picker-preview/library/src/ColorPicker.ts b/packages/react-components/react-color-picker-preview/library/src/ColorPicker.ts index 83b2c1098f247b..16e6329cf3ca2e 100644 --- a/packages/react-components/react-color-picker-preview/library/src/ColorPicker.ts +++ b/packages/react-components/react-color-picker-preview/library/src/ColorPicker.ts @@ -1 +1,13 @@ -export * from './components/ColorPicker/index'; +export type { + ColorPickerOnChangeData, + ColorPickerProps, + ColorPickerSlots, + ColorPickerState, +} from './components/ColorPicker/index'; +export { + ColorPicker, + colorPickerClassNames, + renderColorPicker_unstable, + useColorPickerStyles_unstable, + useColorPicker_unstable, +} from './components/ColorPicker/index'; diff --git a/packages/react-components/react-color-picker-preview/library/src/ColorSlider.ts b/packages/react-components/react-color-picker-preview/library/src/ColorSlider.ts index e22ac276d3ee4c..eee7bc5a3cb775 100644 --- a/packages/react-components/react-color-picker-preview/library/src/ColorSlider.ts +++ b/packages/react-components/react-color-picker-preview/library/src/ColorSlider.ts @@ -1 +1,14 @@ -export * from './components/ColorSlider/index'; +export type { + ColorSliderProps, + ColorSliderSlots, + ColorSliderState, + SliderOnChangeData, +} from './components/ColorSlider/index'; +export { + ColorSlider, + colorSliderCSSVars, + colorSliderClassNames, + renderColorSlider_unstable, + useColorSliderStyles_unstable, + useColorSlider_unstable, +} from './components/ColorSlider/index'; diff --git a/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/AlphaSlider.cy.tsx b/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/AlphaSlider.cy.tsx new file mode 100644 index 00000000000000..50dbbd82223578 --- /dev/null +++ b/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/AlphaSlider.cy.tsx @@ -0,0 +1,192 @@ +import * as React from 'react'; +import { mount } from '@cypress/react'; +import { FluentProvider } from '@fluentui/react-provider'; +import { webLightTheme } from '@fluentui/react-theme'; +import { AlphaSlider } from './AlphaSlider'; +import type { AlphaSliderProps } from './AlphaSlider.types'; +import { calculateTransparencyValue } from './alphaSliderUtils'; +import { INITIAL_COLOR_HSV } from '../../utils/constants'; + +const mountFluent = (element: JSX.Element) => { + mount({element}); +}; + +const AlphaSliderExample = (props: AlphaSliderProps) => { + const { transparency = false } = props; + const [color, setColor] = React.useState(props.color ?? INITIAL_COLOR_HSV); + return ( + setColor(data.color)} + id="alpha-slider" + aria-label="Alpha" + aria-valuetext={`${calculateTransparencyValue(transparency, color.a ?? 1)}%`} + transparency={transparency} + /> + ); +}; + +describe('AlphaSlider', () => { + describe('keyboard navigation', () => { + it('has correct focus behavior', () => { + mountFluent( + <> +

+ Before +

+ +

+ After +

+ , + ); + cy.get('#before').focus(); + cy.realPress('Tab'); + cy.get('#alpha-slider').should('have.focus'); + cy.realPress('Tab'); + cy.get('#alpha-slider').should('not.have.focus'); + cy.get('#after').should('have.focus'); + }); + + describe('alpha channel', () => { + it('selected correctly', () => { + mountFluent(); + cy.get('.fui-AlphaSlider__input').focus(); + + // decrements the value two times + cy.realPress('ArrowLeft'); + cy.realPress('ArrowLeft'); + assertSliderValue('48'); + + // increments the value + cy.realPress('ArrowRight'); + assertSliderValue('49'); + + // increments the value with arrowUp + cy.realPress('ArrowUp'); + assertSliderValue('50'); + + // decrements the value with arrowDown + cy.realPress('ArrowDown'); + assertSliderValue('49'); + }); + + it('selected on left edge correctly', () => { + mountFluent(); + cy.get('.fui-AlphaSlider__input').focus(); + + // decrements the value two times + cy.realPress('ArrowLeft'); + cy.realPress('ArrowLeft'); + assertSliderValue('0'); + + // decrements the value on left edge + cy.realPress('ArrowLeft'); + assertSliderValue('0'); + + // increments the value + cy.realPress('ArrowRight'); + assertSliderValue('1'); + }); + + it('selected on right edge correctly', () => { + mountFluent(); + cy.get('.fui-AlphaSlider__input').focus(); + + // increments the value + cy.realPress('ArrowRight'); + assertSliderValue('99'); + + // increments the value + cy.realPress('ArrowRight'); + assertSliderValue('100'); + + // increments the value on right edge + cy.realPress('ArrowRight'); + assertSliderValue('100'); + + // decrements the value + cy.realPress('ArrowLeft'); + assertSliderValue('99'); + }); + }); + }); + + describe('transparency', () => { + it('selected correctly', () => { + mountFluent(); + cy.get('.fui-AlphaSlider__input').focus(); + + // decrements the value two times + cy.realPress('ArrowLeft'); + cy.realPress('ArrowLeft'); + assertSliderValue('28'); + + // increments the value + cy.realPress('ArrowRight'); + assertSliderValue('29'); + + // increments the value with arrowUp + cy.realPress('ArrowUp'); + assertSliderValue('30'); + + // decrements the value with arrowDown + cy.realPress('ArrowDown'); + assertSliderValue('29'); + }); + + it('selected on left edge correctly', () => { + mountFluent(); + cy.get('.fui-AlphaSlider__input').focus(); + + // decrements the value two times + cy.realPress('ArrowLeft'); + cy.realPress('ArrowLeft'); + assertSliderValue('0'); + + // decrements the value on left edge + cy.realPress('ArrowLeft'); + assertSliderValue('0'); + + // increments the value + cy.realPress('ArrowRight'); + assertSliderValue('1'); + }); + + it('selected on right edge correctly', () => { + mountFluent(); + cy.get('.fui-AlphaSlider__input').focus(); + + // increments the value + cy.realPress('ArrowRight'); + assertSliderValue('99'); + + // increments the value + cy.realPress('ArrowRight'); + assertSliderValue('100'); + + // increments the value on right edge + cy.realPress('ArrowRight'); + assertSliderValue('100'); + + // decrements the value + cy.realPress('ArrowLeft'); + assertSliderValue('99'); + }); + }); + + describe('mouse navigation', () => { + it('has correct a11y attributes', () => { + mountFluent(); + cy.get('#alpha-slider').should('have.attr', 'aria-label', 'Alpha'); + assertSliderValue('100'); + cy.get('#alpha-slider').realClick(); + assertSliderValue('50'); + }); + }); +}); + +function assertSliderValue(value: string) { + cy.get('#alpha-slider').should('have.attr', 'aria-valuetext', `${value}%`); + cy.get('#alpha-slider').should('have.attr', 'value', value); +} diff --git a/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/AlphaSlider.test.tsx b/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/AlphaSlider.test.tsx index 861317039b11bf..d3162035df0be1 100644 --- a/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/AlphaSlider.test.tsx +++ b/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/AlphaSlider.test.tsx @@ -30,7 +30,7 @@ describe('AlphaSlider', () => {
& { + /** + * 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/index.ts b/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/index.ts index 28a9cce68baaea..5e402c922c3506 100644 --- a/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/index.ts +++ b/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/index.ts @@ -1,5 +1,9 @@ -export * from './AlphaSlider'; -export * from './AlphaSlider.types'; -export * from './renderAlphaSlider'; -export * from './useAlphaSlider'; -export * from './useAlphaSliderStyles.styles'; +export { AlphaSlider } from './AlphaSlider'; +export type { AlphaSliderProps, AlphaSliderSlots, AlphaSliderState } from './AlphaSlider.types'; +export { renderAlphaSlider_unstable } from './renderAlphaSlider'; +export { useAlphaSlider_unstable } from './useAlphaSlider'; +export { + alphaSliderCSSVars, + alphaSliderClassNames, + useAlphaSliderStyles_unstable, +} from './useAlphaSliderStyles.styles'; 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..ac577e8233b5b4 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 @@ -7,7 +7,8 @@ import type { AlphaSliderState, AlphaSliderProps } from './AlphaSlider.types'; 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'; +import { createHsvColor } from '../../utils/createHsvColor'; export const useAlphaSliderState_unstable = (state: AlphaSliderState, props: AlphaSliderProps) => { 'use no memo'; @@ -15,32 +16,35 @@ 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 newColor: HsvColor = { ...hsvColor, a: newValue / 100 }; + const newValue = adjustToTransparency(Number(event.target.value), transparency); + const newColor = createHsvColor({ ...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.thumbColorVar]: `hsla(${hslColor.h} ${hslColor.s * 100}%, ${hslColor.l * 100}%, ${hslColor.a})`, [alphaSliderCSSVars.railColorVar]: `hsl(${hslColor.h} ${hslColor.s * 100}%, ${hslColor.l * 100}%)`, }; diff --git a/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/useAlphaSliderStyles.styles.ts b/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/useAlphaSliderStyles.styles.ts index 76c978ab06253e..958af2a6533d54 100644 --- a/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/useAlphaSliderStyles.styles.ts +++ b/packages/react-components/react-color-picker-preview/library/src/components/AlphaSlider/useAlphaSliderStyles.styles.ts @@ -42,8 +42,11 @@ const useStyles = makeStyles({ */ const useThumbStyles = makeStyles({ thumb: { - backgroundColor: `var(${alphaSliderCSSVars.thumbColorVar})`, + backgroundColor: tokens.colorNeutralBackground1, [`${thumbPositionVar}`]: `clamp(var(${innerThumbRadiusVar}), var(${alphaSliderCSSVars.sliderProgressVar}), calc(100% - var(${innerThumbRadiusVar})))`, + '::before': { + backgroundColor: `var(${alphaSliderCSSVars.thumbColorVar})`, + }, }, horizontal: { transform: 'translateX(-50%)', diff --git a/packages/react-components/react-color-picker-preview/library/src/components/ColorArea/ColorArea.cy.tsx b/packages/react-components/react-color-picker-preview/library/src/components/ColorArea/ColorArea.cy.tsx index 7af7991004db3f..2a9b49c4902bf3 100644 --- a/packages/react-components/react-color-picker-preview/library/src/components/ColorArea/ColorArea.cy.tsx +++ b/packages/react-components/react-color-picker-preview/library/src/components/ColorArea/ColorArea.cy.tsx @@ -24,7 +24,7 @@ describe('ColorArea', () => { describe('keyboard navigation', () => { it('color should be changed correctly', () => { mountFluent(); - cy.realPress('Tab'); + cy.get('.fui-ColorArea__inputX').focus(); cy.realPress('ArrowDown'); cy.get('#color').should('have.text', '#7d3e64'); cy.realPress('ArrowDown'); @@ -45,7 +45,7 @@ describe('ColorArea', () => { }); it('color selected on right edge correctly', () => { mountFluent(); - cy.realPress('Tab'); + cy.get('.fui-ColorArea__inputX').focus(); cy.realPress('ArrowRight'); cy.get('#color').should('have.text', '#071a01'); cy.realPress('ArrowRight'); @@ -55,7 +55,7 @@ describe('ColorArea', () => { }); it('color selected on bottom edge correctly', () => { mountFluent(); - cy.realPress('Tab'); + cy.get('.fui-ColorArea__inputX').focus(); cy.realPress('ArrowDown'); cy.get('#color').should('have.text', '#010500'); cy.realPress('ArrowDown'); @@ -65,7 +65,7 @@ describe('ColorArea', () => { }); it('color selected on left edge correctly', () => { mountFluent(); - cy.realPress('Tab'); + cy.get('.fui-ColorArea__inputX').focus(); cy.realPress('ArrowLeft'); cy.get('#color').should('have.text', '#717370'); cy.realPress('ArrowLeft'); @@ -75,7 +75,7 @@ describe('ColorArea', () => { }); it('color selected on top edge correctly', () => { mountFluent(); - cy.realPress('Tab'); + cy.get('.fui-ColorArea__inputX').focus(); cy.realPress('ArrowUp'); cy.get('#color').should('have.text', '#3afa00'); cy.realPress('ArrowUp'); @@ -85,7 +85,7 @@ describe('ColorArea', () => { }); it('hue stays the same after achiving bottom edge', () => { mountFluent(); - cy.realPress('Tab'); + cy.get('.fui-ColorArea__inputX').focus(); cy.realPress('ArrowDown'); cy.realPress('ArrowDown'); cy.realPress('ArrowDown'); diff --git a/packages/react-components/react-color-picker-preview/library/src/components/ColorArea/ColorArea.test.tsx b/packages/react-components/react-color-picker-preview/library/src/components/ColorArea/ColorArea.test.tsx index 6030fffb24e8c4..520b7993fe1e34 100644 --- a/packages/react-components/react-color-picker-preview/library/src/components/ColorArea/ColorArea.test.tsx +++ b/packages/react-components/react-color-picker-preview/library/src/components/ColorArea/ColorArea.test.tsx @@ -15,7 +15,7 @@ describe('ColorArea', () => {
{ diff --git a/packages/react-components/react-color-picker-preview/library/src/components/ColorArea/index.ts b/packages/react-components/react-color-picker-preview/library/src/components/ColorArea/index.ts index 1ac6ab4dd40a27..eafdc6bbffe238 100644 --- a/packages/react-components/react-color-picker-preview/library/src/components/ColorArea/index.ts +++ b/packages/react-components/react-color-picker-preview/library/src/components/ColorArea/index.ts @@ -1,5 +1,5 @@ -export * from './ColorArea'; -export * from './ColorArea.types'; -export * from './renderColorArea'; -export * from './useColorArea'; -export * from './useColorAreaStyles.styles'; +export { ColorArea } from './ColorArea'; +export type { ColorAreaOnColorChangeData, ColorAreaProps, ColorAreaSlots, ColorAreaState } from './ColorArea.types'; +export { renderColorArea_unstable } from './renderColorArea'; +export { useColorArea_unstable } from './useColorArea'; +export { colorAreaCSSVars, colorAreaClassNames, useColorAreaStyles_unstable } from './useColorAreaStyles.styles'; 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 2a957cebcc4aab..88115d24a9e54a 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 @@ -1,4 +1,5 @@ import * as React from 'react'; +import { tinycolor } from '@ctrl/tinycolor'; import { useId, slot, useMergedRefs, mergeCallbacks, getIntrinsicElementProps } from '@fluentui/react-utilities'; import type { ColorAreaProps, ColorAreaState } from './ColorArea.types'; import type { HsvColor } from '../../types/color'; @@ -48,7 +49,7 @@ export const useColorArea_unstable = (props: ColorAreaProps, ref: React.Ref('x'); + const [activeAxis, setActiveAxis] = React.useState<'x' | 'y' | null>(null); const requestColorChange = useEventCallback((event: MouseEvent) => { if (!rootRef.current) { @@ -153,7 +154,7 @@ export const useColorArea_unstable = (props: ColorAreaProps, ref: React.Ref { - // Focus the active axis input only when the active axis changes - - if (activeAxis === 'x' && targetDocument?.activeElement !== xRef.current) { - xRef.current?.focus(); - } - - if (activeAxis === 'y' && targetDocument?.activeElement !== yRef.current) { - yRef.current?.focus(); - } - }, [activeAxis, targetDocument?.activeElement]); - return state; }; diff --git a/packages/react-components/react-color-picker-preview/library/src/components/ColorArea/useColorAreaStyles.styles.ts b/packages/react-components/react-color-picker-preview/library/src/components/ColorArea/useColorAreaStyles.styles.ts index eab9c3185b8ac1..256e12d4467b21 100644 --- a/packages/react-components/react-color-picker-preview/library/src/components/ColorArea/useColorAreaStyles.styles.ts +++ b/packages/react-components/react-color-picker-preview/library/src/components/ColorArea/useColorAreaStyles.styles.ts @@ -37,8 +37,9 @@ const useRootStyles = makeResetStyles({ alignItems: 'start', justifyItems: 'start', [thumbSizeVar]: '20px', - minWidth: '200px', - minHeight: '200px', + minWidth: '300px', + minHeight: '300px', + boxSizing: 'border-box', [innerThumbRadiusVar]: '6px', }); @@ -54,7 +55,8 @@ const useThumbStyles = makeStyles({ outlineStyle: 'none', forcedColorAdjust: 'none', borderRadius: tokens.borderRadiusCircular, - boxShadow: `0 0 0 calc(var(${thumbSizeVar}) * .2) ${tokens.colorNeutralBackground1} inset`, + border: `${tokens.strokeWidthThin} solid ${tokens.colorNeutralForeground4}`, + boxShadow: tokens.shadow4, backgroundColor: `var(${colorAreaCSSVars.thumbColorVar})`, transform: 'translate(-50%, 50%)', [`${thumbPositionXVar}`]: `clamp(var(${innerThumbRadiusVar}), var(${colorAreaCSSVars.areaXProgressVar}), calc(100% - var(${innerThumbRadiusVar})))`, @@ -67,7 +69,7 @@ const useThumbStyles = makeStyles({ borderRadius: tokens.borderRadiusCircular, boxSizing: 'border-box', content: "''", - border: `calc(var(${thumbSizeVar}) * .05) solid ${tokens.colorNeutralStroke1}`, + border: `${tokens.strokeWidthThick} solid ${tokens.colorNeutralBackground1}`, }, }, focusIndicator: createFocusOutlineStyle({ diff --git a/packages/react-components/react-color-picker-preview/library/src/components/ColorPicker/ColorPicker.types.ts b/packages/react-components/react-color-picker-preview/library/src/components/ColorPicker/ColorPicker.types.ts index 1e76870ecd77ed..5c47504a7feca2 100644 --- a/packages/react-components/react-color-picker-preview/library/src/components/ColorPicker/ColorPicker.types.ts +++ b/packages/react-components/react-color-picker-preview/library/src/components/ColorPicker/ColorPicker.types.ts @@ -18,7 +18,7 @@ export type ColorPickerProps = Omit>, ' /** * Selected color. */ - color: HsvColor; + color?: HsvColor; /** * Callback for when the user changes the color. diff --git a/packages/react-components/react-color-picker-preview/library/src/components/ColorPicker/index.ts b/packages/react-components/react-color-picker-preview/library/src/components/ColorPicker/index.ts index 33e318436b9eec..f85f52b20eca38 100644 --- a/packages/react-components/react-color-picker-preview/library/src/components/ColorPicker/index.ts +++ b/packages/react-components/react-color-picker-preview/library/src/components/ColorPicker/index.ts @@ -1,5 +1,10 @@ -export * from './ColorPicker'; -export * from './ColorPicker.types'; -export * from './renderColorPicker'; -export * from './useColorPicker'; -export * from './useColorPickerStyles.styles'; +export { ColorPicker } from './ColorPicker'; +export type { + ColorPickerOnChangeData, + ColorPickerProps, + ColorPickerSlots, + ColorPickerState, +} from './ColorPicker.types'; +export { renderColorPicker_unstable } from './renderColorPicker'; +export { useColorPicker_unstable } from './useColorPicker'; +export { colorPickerClassNames, useColorPickerStyles_unstable } from './useColorPickerStyles.styles'; diff --git a/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/ColorSlider.cy.tsx b/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/ColorSlider.cy.tsx new file mode 100644 index 00000000000000..1a5a7903817b27 --- /dev/null +++ b/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/ColorSlider.cy.tsx @@ -0,0 +1,125 @@ +import * as React from 'react'; +import { mount } from '@cypress/react'; +import { FluentProvider } from '@fluentui/react-provider'; +import { webLightTheme } from '@fluentui/react-theme'; +import { ColorSlider } from './ColorSlider'; +import type { ColorSliderProps } from './ColorSlider.types'; +import { INITIAL_COLOR_HSV } from '../../utils/constants'; + +const mountFluent = (element: JSX.Element) => { + mount({element}); +}; + +const ColorSliderExample = (props: ColorSliderProps) => { + const [color, setColor] = React.useState(props.color ?? INITIAL_COLOR_HSV); + return ( + setColor(data.color)} + id="color-slider" + aria-label="Hue" + aria-valuetext={`${color.h}°`} + /> + ); +}; + +describe('ColorSlider', () => { + describe('keyboard navigation', () => { + it('has correct focus behavior', () => { + mountFluent( + <> +

+ Before +

+ +

+ After +

+ , + ); + cy.get('#before').focus(); + cy.realPress('Tab'); + cy.get('#color-slider').should('have.focus'); + cy.realPress('Tab'); + cy.get('#color-slider').should('not.have.focus'); + cy.get('#after').should('have.focus'); + }); + + it('hue channel selected correctly', () => { + mountFluent(); + cy.get('.fui-ColorSlider__input').focus(); + + // decrements the value two times + cy.realPress('ArrowLeft'); + cy.realPress('ArrowLeft'); + assertSliderValue('104'); + + // increments the value + cy.realPress('ArrowRight'); + assertSliderValue('105'); + + // increments the value with arrowUp + cy.realPress('ArrowUp'); + assertSliderValue('106'); + + // decrements the value with arrowDown + cy.realPress('ArrowDown'); + assertSliderValue('105'); + }); + + it('hue channel selected on left edge correctly', () => { + mountFluent(); + cy.get('.fui-ColorSlider__input').focus(); + + // decrements the value two times + cy.realPress('ArrowLeft'); + cy.realPress('ArrowLeft'); + assertSliderValue('0'); + + // decrements the value on left edge + cy.realPress('ArrowLeft'); + assertSliderValue('0'); + + // increments the value + cy.realPress('ArrowRight'); + assertSliderValue('1'); + }); + + it('hue channel selected on right edge correctly', () => { + mountFluent(); + cy.get('.fui-ColorSlider__input').focus(); + + // increments the value + cy.realPress('ArrowRight'); + assertSliderValue('359'); + + // increments the value + cy.realPress('ArrowRight'); + assertSliderValue('360'); + + // increments the value on right edge + cy.realPress('ArrowRight'); + assertSliderValue('360'); + + // decrements the value + cy.realPress('ArrowLeft'); + assertSliderValue('359'); + }); + }); + + describe('mouse navigation', () => { + it('has correct a11y attributes', () => { + mountFluent(); + cy.get('#color-slider').should('have.attr', 'aria-label', 'Hue'); + assertSliderValue('324'); + + cy.get('#color-slider').realClick(); + assertSliderValue('180'); + }); + }); +}); + +function assertSliderValue(value: string) { + cy.get('#color-slider').should('have.attr', 'aria-valuetext', `${value}°`); + cy.get('#color-slider').should('have.attr', 'value', value); +} diff --git a/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/ColorSlider.test.tsx b/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/ColorSlider.test.tsx index 1c8ef38586b7f0..f30b3fac0155f1 100644 --- a/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/ColorSlider.test.tsx +++ b/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/ColorSlider.test.tsx @@ -16,13 +16,16 @@ describe('ColorSlider', () => {
diff --git a/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/ColorSlider.types.ts b/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/ColorSlider.types.ts index ca7417aa765d3b..71386680bdf9ac 100644 --- a/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/ColorSlider.types.ts +++ b/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/ColorSlider.types.ts @@ -14,6 +14,8 @@ export type ColorSliderSlots = { input: NonNullable>; }; +export type ColorChannel = 'hue' | 'saturation' | 'value'; + /** * ColorSlider Props */ @@ -22,7 +24,11 @@ export type ColorSliderProps = Omit< 'defaultValue' | 'onChange' | 'value' | 'color' > & Pick & { - channel?: string; + /** + * Color channel of the Slider. + * @default `hue` + */ + channel?: ColorChannel; /** * Triggers a callback when the value has been changed. This will be called on every individual step. @@ -36,7 +42,7 @@ export type ColorSliderProps = Omit< vertical?: boolean; /** - * Color of the COlorPicker + * Color of the ColorPicker */ color?: HsvColor; @@ -49,4 +55,5 @@ export type ColorSliderProps = Omit< /** * State used in rendering ColorSlider */ -export type ColorSliderState = ComponentState & Pick; +export type ColorSliderState = ComponentState & + Pick; diff --git a/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/index.ts b/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/index.ts index a756d845d48c83..822748e81e342b 100644 --- a/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/index.ts +++ b/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/index.ts @@ -1,5 +1,9 @@ -export * from './ColorSlider'; -export * from './ColorSlider.types'; -export * from './renderColorSlider'; -export * from './useColorSlider'; -export * from './useColorSliderStyles.styles'; +export { ColorSlider } from './ColorSlider'; +export type { ColorSliderProps, ColorSliderSlots, ColorSliderState, SliderOnChangeData } from './ColorSlider.types'; +export { renderColorSlider_unstable } from './renderColorSlider'; +export { useColorSlider_unstable } from './useColorSlider'; +export { + colorSliderCSSVars, + colorSliderClassNames, + useColorSliderStyles_unstable, +} from './useColorSliderStyles.styles'; diff --git a/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/useColorSlider.ts b/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/useColorSlider.ts index 2cb225eae94d25..9fe9e7ae20f760 100644 --- a/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/useColorSlider.ts +++ b/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/useColorSlider.ts @@ -1,9 +1,9 @@ import * as React from 'react'; +import { tinycolor } from '@ctrl/tinycolor'; import { getPartitionedNativeProps, useId, slot, - clamp, useControllableState, useEventCallback, } from '@fluentui/react-utilities'; @@ -11,8 +11,12 @@ import { colorSliderCSSVars } from './useColorSliderStyles.styles'; import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts'; import type { ColorSliderProps, ColorSliderState } from './ColorSlider.types'; import { useColorPickerContextValue_unstable } from '../../contexts/colorPicker'; -import { MIN, HUE_MAX as MAX } from '../../utils/constants'; +import { MIN, HUE_MAX, MAX as COLOR_MAX } from '../../utils/constants'; import { getPercent } from '../../utils/getPercent'; +import { createHsvColor } from '../../utils/createHsvColor'; +import { clampValue, type ChannelActions, adjustChannel } from '../../utils/adjustChannel'; +import { HsvColor } from '../../types/color'; +import { INITIAL_COLOR_HSV } from '../../utils/constants'; /** * Create the state required to render ColorSlider. @@ -41,6 +45,7 @@ export const useColorSlider_unstable = ( const { color, + channel = 'hue', onChange = onChangeFromContext, shape = shapeFromContext, vertical, @@ -52,34 +57,61 @@ export const useColorSlider_unstable = ( } = props; const hsvColor = color || colorFromContext; + const hslColor = tinycolor(hsvColor).toHsl(); - const [currentValue, setCurrentValue] = useControllableState({ - defaultState: props.defaultColor?.h, - state: hsvColor?.h, - initialState: 0, + const [currentColor, setCurrentColor] = useControllableState({ + defaultState: props.defaultColor, + state: hsvColor, + initialState: INITIAL_COLOR_HSV, }); - const clampedValue = clamp(currentValue, MIN, MAX); + + const MAX = channel === 'hue' ? HUE_MAX : COLOR_MAX; + + const valueChannelActions: ChannelActions = { + hue: clampValue(currentColor.h), + saturation: clampValue(currentColor.s * 100), + value: clampValue(currentColor.v * 100), + }; + + const clampedValue = adjustChannel(channel, valueChannelActions); const valuePercent = getPercent(clampedValue, MIN, MAX); const inputOnChange = input?.onChange; const _onChange: React.ChangeEventHandler = useEventCallback(event => { const newValue = Number(event.target.value); - const newColor = { ...hsvColor, h: newValue }; - setCurrentValue(newValue); + const colorActions: ChannelActions<() => HsvColor> = { + hue: () => createHsvColor({ ...hsvColor, h: newValue }), + saturation: () => createHsvColor({ ...hsvColor, s: newValue / 100 }), + value: () => createHsvColor({ ...hsvColor, v: newValue / 100 }), + }; + const newColor = adjustChannel(channel, colorActions)(); + + setCurrentColor(newColor); + inputOnChange?.(event); - onChange?.(event, { type: 'change', event, color: newColor }); + onChange?.(event, { + type: 'change', + event, + color: newColor, + }); }); const rootVariables = { [colorSliderCSSVars.sliderDirectionVar]: vertical ? '180deg' : dir === 'ltr' ? '-90deg' : '90deg', [colorSliderCSSVars.sliderProgressVar]: `${valuePercent}%`, - [colorSliderCSSVars.thumbColorVar]: `hsl(${clampedValue}, 100%, 50%)`, + [colorSliderCSSVars.thumbColorVar]: + channel === 'hue' ? `hsl(${clampedValue}, 100%, 50%)` : tinycolor(hsvColor).toRgbString(), + [colorSliderCSSVars.railColorVar]: + channel === 'hue' + ? `hsl(${hslColor.h} ${hslColor.s * 100}%, ${hslColor.l * 100}%)` + : `hsl(${hslColor.h} 100%, 50%)`, }; const state: ColorSliderState = { shape, vertical, + channel, components: { input: 'input', rail: 'div', @@ -87,7 +119,10 @@ export const useColorSlider_unstable = ( thumb: 'div', }, root: slot.always(root, { - defaultProps: nativeProps.root, + defaultProps: { + role: 'group', + ...nativeProps.root, + }, elementType: 'div', }), input: slot.always(input, { @@ -96,6 +131,8 @@ export const useColorSlider_unstable = ( ref, min: MIN, max: MAX, + tabIndex: 0, + ['aria-orientation']: vertical ? 'vertical' : 'horizontal', ...nativeProps.primary, type: 'range', }, diff --git a/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/useColorSliderStyles.styles.ts b/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/useColorSliderStyles.styles.ts index 0ac60b28613d11..c1cb4cd0ccbc5a 100644 --- a/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/useColorSliderStyles.styles.ts +++ b/packages/react-components/react-color-picker-preview/library/src/components/ColorSlider/useColorSliderStyles.styles.ts @@ -14,6 +14,7 @@ export const colorSliderCSSVars = { sliderDirectionVar: `--fui-Slider--direction`, sliderProgressVar: `--fui-Slider--progress`, thumbColorVar: `--fui-Slider__thumb--color`, + railColorVar: `--fui-Slider__rail--color`, }; // Internal CSS variables @@ -24,17 +25,13 @@ const thumbPositionVar = `--fui-Slider__thumb--position`; const hueBackground = `linear-gradient(${[ `var(${colorSliderCSSVars.sliderDirectionVar})`, - 'red 0', - '#f09 10%', - '#cd00ff 20%', - '#3200ff 30%', - '#06f 40%', - '#00fffd 50%', - '#0f6 60%', - '#35ff00 70%', - '#cdff00 80%', - '#f90 90%', - 'red 100%', + 'red', + 'fuchsia', + 'blue', + 'aqua', + 'lime', + 'yellow', + 'red', ].join(',')})`; /** @@ -66,9 +63,18 @@ const useStyles = makeStyles({ gridTemplateRows: `1fr 100% 1fr`, gridTemplateColumns: `1fr var(${thumbSizeVar}) 1fr`, }, +}); + +const useChannelStyles = makeStyles({ hue: { backgroundImage: hueBackground, }, + saturation: { + backgroundImage: `linear-gradient(to right, #808080, var(${colorSliderCSSVars.railColorVar}))`, + }, + value: { + backgroundImage: `linear-gradient(to right, #000, var(${colorSliderCSSVars.railColorVar}))`, + }, }); /** @@ -129,19 +135,17 @@ const useThumbStyles = makeStyles({ outlineStyle: 'none', forcedColorAdjust: 'none', borderRadius: tokens.borderRadiusCircular, - boxShadow: `0 0 0 calc(var(${thumbSizeVar}) * .2) ${tokens.colorNeutralBackground1} inset`, + border: `${tokens.strokeWidthThin} solid ${tokens.colorNeutralForeground4}`, + boxShadow: tokens.shadow4, backgroundColor: `var(${colorSliderCSSVars.thumbColorVar})`, [`${thumbPositionVar}`]: `clamp(var(${innerThumbRadiusVar}), var(${colorSliderCSSVars.sliderProgressVar}), calc(100% - var(${innerThumbRadiusVar})))`, '::before': { position: 'absolute', - top: '0px', - left: '0px', - bottom: '0px', - right: '0px', + inset: '0px', borderRadius: tokens.borderRadiusCircular, boxSizing: 'border-box', content: "''", - border: `calc(var(${thumbSizeVar}) * .05) solid ${tokens.colorNeutralStroke1}`, + border: `${tokens.strokeWidthThick} solid ${tokens.colorNeutralBackground1}`, }, }, horizontal: { @@ -206,6 +210,7 @@ export const useColorSliderStyles_unstable = (state: ColorSliderState): ColorSli const thumbStyles = useThumbStyles(); const inputStyles = useInputStyles(); const shapeStyles = useShapeStyles(); + const channelStyles = useChannelStyles(); const isVertical = state.vertical; state.root.className = mergeClasses( @@ -218,7 +223,7 @@ export const useColorSliderStyles_unstable = (state: ColorSliderState): ColorSli state.rail.className = mergeClasses( colorSliderClassNames.rail, railStyles.rail, - styles.hue, + channelStyles[state.channel || 'hue'], shapeStyles[state.shape || 'rounded'], isVertical ? railStyles.vertical : railStyles.horizontal, state.rail.className, diff --git a/packages/react-components/react-color-picker-preview/library/src/contexts/colorPicker.ts b/packages/react-components/react-color-picker-preview/library/src/contexts/colorPicker.ts index 9175ff7c75693d..a64a140e21c845 100644 --- a/packages/react-components/react-color-picker-preview/library/src/contexts/colorPicker.ts +++ b/packages/react-components/react-color-picker-preview/library/src/contexts/colorPicker.ts @@ -3,13 +3,11 @@ import { createContext, useContextSelector } from '@fluentui/react-context-selec import type { ContextSelector, Context } from '@fluentui/react-context-selector'; import type { ColorPickerState, ColorPickerProps } from '../components/ColorPicker/ColorPicker.types'; import type { HsvColor } from '../types/color'; -import { INITIAL_COLOR_HSV } from '../utils/constants'; /** * The context through which individual color controls communicate with the picker. */ -export type ColorPickerContextValue = Pick & { - color: HsvColor; +export type ColorPickerContextValue = Pick & { /** * @internal * Callback used by Sliders to request a change on it's selected value @@ -35,7 +33,7 @@ export const colorPickerContextDefaultValue: ColorPickerContextValue = { requestChange: () => { /*noop*/ }, - color: { ...INITIAL_COLOR_HSV }, + color: undefined, shape: 'rounded', }; diff --git a/packages/react-components/react-color-picker-preview/library/src/utils/adjustChannel.test.ts b/packages/react-components/react-color-picker-preview/library/src/utils/adjustChannel.test.ts new file mode 100644 index 00000000000000..6cfdd93c7b35db --- /dev/null +++ b/packages/react-components/react-color-picker-preview/library/src/utils/adjustChannel.test.ts @@ -0,0 +1,40 @@ +import { clampValue, adjustChannel, ChannelActions } from './adjustChannel'; +import { MIN, HUE_MAX, MAX as COLOR_MAX } from './constants'; + +describe('clampValue', () => { + it('should clamp value within the hue range', () => { + expect(clampValue(-10, 'hue')).toBe(MIN); + expect(clampValue(370, 'hue')).toBe(HUE_MAX); + expect(clampValue(180, 'hue')).toBe(180); + }); + + it('should clamp value within the saturation/value range', () => { + expect(clampValue(-10, 'saturation')).toBe(MIN); + expect(clampValue(110, 'saturation')).toBe(COLOR_MAX); + expect(clampValue(50, 'saturation')).toBe(50); + + expect(clampValue(-10, 'value')).toBe(MIN); + expect(clampValue(110, 'value')).toBe(COLOR_MAX); + expect(clampValue(50, 'value')).toBe(50); + }); + + it('should default to hue if no channel is provided', () => { + expect(clampValue(-10)).toBe(MIN); + expect(clampValue(370)).toBe(HUE_MAX); + expect(clampValue(180)).toBe(180); + }); +}); + +describe('adjustChannel', () => { + const actions: ChannelActions = { + hue: 'hueAction', + saturation: 'saturationAction', + value: 'valueAction', + }; + + it('should return the correct action for the given channel', () => { + expect(adjustChannel('hue', actions)).toBe('hueAction'); + expect(adjustChannel('saturation', actions)).toBe('saturationAction'); + expect(adjustChannel('value', actions)).toBe('valueAction'); + }); +}); diff --git a/packages/react-components/react-color-picker-preview/library/src/utils/adjustChannel.ts b/packages/react-components/react-color-picker-preview/library/src/utils/adjustChannel.ts new file mode 100644 index 00000000000000..b6c2ba815c85ba --- /dev/null +++ b/packages/react-components/react-color-picker-preview/library/src/utils/adjustChannel.ts @@ -0,0 +1,33 @@ +import type { ColorChannel } from '../components/ColorSlider/ColorSlider.types'; +import { MIN, HUE_MAX, MAX as COLOR_MAX } from './constants'; +import { clamp } from '@fluentui/react-utilities'; + +/** + * Clamps a given value to the valid range for a specified color channel. + * + * @param value - The numeric value to be clamped. + * @param channel - The color channel to use for clamping. Defaults to 'hue'. + * @returns The clamped value within the range defined by the color channel. + */ +export function clampValue(value: number, channel: ColorChannel = 'hue') { + const MAX = channel === 'hue' ? HUE_MAX : COLOR_MAX; + return clamp(value, MIN, MAX); +} + +export type ChannelActions = { + hue: T; + saturation: T; + value: T; +}; + +/** + * Adjusts the specified color channel using the provided actions. + * + * @template T - The type of the result returned by the actions. + * @param {ColorChannel} channel - The color channel to adjust. + * @param {ChannelActions} actions - An object containing actions for each color channel. + * @returns {T} - The result of the action corresponding to the specified channel, or the hue action if the channel is not found. + */ +export function adjustChannel(channel: ColorChannel, actions: ChannelActions): T { + return actions[channel] || actions.hue; +} diff --git a/packages/react-components/react-color-picker-preview/library/src/utils/createHsvColor.test.ts b/packages/react-components/react-color-picker-preview/library/src/utils/createHsvColor.test.ts new file mode 100644 index 00000000000000..60e352b86212b4 --- /dev/null +++ b/packages/react-components/react-color-picker-preview/library/src/utils/createHsvColor.test.ts @@ -0,0 +1,34 @@ +import { createHsvColor } from './createHsvColor'; +import { HsvColor } from '../types/color'; + +describe('createHsvColor', () => { + it('should create an HSV color with default values', () => { + const color: HsvColor = createHsvColor({}); + expect(color).toEqual({ h: 0, s: 0, v: 0, a: 1 }); + }); + + it('should create an HSV color with specified hue', () => { + const color: HsvColor = createHsvColor({ h: 120 }); + expect(color).toEqual({ h: 120, s: 0, v: 0, a: 1 }); + }); + + it('should create an HSV color with specified saturation', () => { + const color: HsvColor = createHsvColor({ s: 50 }); + expect(color).toEqual({ h: 0, s: 50, v: 0, a: 1 }); + }); + + it('should create an HSV color with specified value', () => { + const color: HsvColor = createHsvColor({ v: 75 }); + expect(color).toEqual({ h: 0, s: 0, v: 75, a: 1 }); + }); + + it('should create an HSV color with specified alpha', () => { + const color: HsvColor = createHsvColor({ a: 0.5 }); + expect(color).toEqual({ h: 0, s: 0, v: 0, a: 0.5 }); + }); + + it('should create an HSV color with all specified components', () => { + const color: HsvColor = createHsvColor({ h: 180, s: 100, v: 100, a: 0.8 }); + expect(color).toEqual({ h: 180, s: 100, v: 100, a: 0.8 }); + }); +}); diff --git a/packages/react-components/react-color-picker-preview/library/src/utils/createHsvColor.ts b/packages/react-components/react-color-picker-preview/library/src/utils/createHsvColor.ts new file mode 100644 index 00000000000000..6b775d26407be7 --- /dev/null +++ b/packages/react-components/react-color-picker-preview/library/src/utils/createHsvColor.ts @@ -0,0 +1,15 @@ +import { HsvColor } from '../types/color'; + +/** + * Creates an HSV color object with optional hue, saturation, value, and alpha components. + * + * @param {Partial} param0 - An object containing optional HSV color components: + * - `h` (number): The hue component, default is 0. + * - `s` (number): The saturation component, default is 0. + * - `v` (number): The value component, default is 0. + * - `a` (number): The alpha component, default is 1. + * @returns {HsvColor} The resulting HSV color object. + */ +export function createHsvColor({ h = 0, s = 0, v = 0, a = 1 }: Partial): HsvColor { + return { h, s, v, a }; +} diff --git a/packages/react-components/react-color-picker-preview/library/src/utils/getCoordinates.test.ts b/packages/react-components/react-color-picker-preview/library/src/utils/getCoordinates.test.ts new file mode 100644 index 00000000000000..698638176c2541 --- /dev/null +++ b/packages/react-components/react-color-picker-preview/library/src/utils/getCoordinates.test.ts @@ -0,0 +1,39 @@ +import { getCoordinates, roundTwoDecimal } from './getCoordinates'; + +describe('getCoordinates', () => { + const mockElement = { + getBoundingClientRect: jest.fn(() => ({ + left: 0, + top: 0, + width: 100, + height: 100, + })), + } as unknown as HTMLElement; + + it('should calculate normalized coordinates within bounds', () => { + const event = { clientX: 50, clientY: 50 } as MouseEvent; + const result = getCoordinates(mockElement, event); + expect(result).toEqual({ x: 0.5, y: 0.5 }); + }); + + it('should clamp coordinates to 0 if they are negative', () => { + const event = { clientX: -10, clientY: -10 } as MouseEvent; + const result = getCoordinates(mockElement, event); + expect(result).toEqual({ x: 0, y: 1 }); + }); + + it('should clamp coordinates to 1 if they exceed the element bounds', () => { + const event = { clientX: 110, clientY: 110 } as MouseEvent; + const result = getCoordinates(mockElement, event); + expect(result).toEqual({ x: 1, y: 0 }); + }); +}); + +describe('roundTwoDecimal', () => { + it('should round numbers to two decimal places', () => { + expect(roundTwoDecimal(1.234)).toBe(1.23); + expect(roundTwoDecimal(1.235)).toBe(1.24); + expect(roundTwoDecimal(1.2)).toBe(1.2); + expect(roundTwoDecimal(1)).toBe(1); + }); +}); diff --git a/packages/react-components/react-color-picker-preview/library/src/utils/getCoordinates.ts b/packages/react-components/react-color-picker-preview/library/src/utils/getCoordinates.ts index 00849b4fed85a0..57a1949b9ad8f1 100644 --- a/packages/react-components/react-color-picker-preview/library/src/utils/getCoordinates.ts +++ b/packages/react-components/react-color-picker-preview/library/src/utils/getCoordinates.ts @@ -1,5 +1,12 @@ import { clamp } from '@fluentui/react-utilities'; +/** + * Calculates the normalized coordinates of a mouse event relative to a given HTML element. + * + * @param element - The HTML element to calculate the coordinates relative to. + * @param event - The mouse event containing the clientX and clientY properties. + * @returns An object containing the normalized x and y coordinates, clamped between 0 and 1. + */ export function getCoordinates(element: HTMLElement, event: MouseEvent) { const rect = element.getBoundingClientRect(); @@ -12,6 +19,12 @@ export function getCoordinates(element: HTMLElement, event: MouseEvent) { }; } +/** + * Rounds a given number to two decimal places. + * + * @param num - The number to be rounded. + * @returns The number rounded to two decimal places. + */ export function roundTwoDecimal(num: number) { return Math.round(num * 100) / 100; } diff --git a/packages/react-components/react-color-picker-preview/library/src/utils/getPercent.test.ts b/packages/react-components/react-color-picker-preview/library/src/utils/getPercent.test.ts new file mode 100644 index 00000000000000..b7e48493ab2795 --- /dev/null +++ b/packages/react-components/react-color-picker-preview/library/src/utils/getPercent.test.ts @@ -0,0 +1,39 @@ +import { getPercent } from './getPercent'; + +describe('getPercent', () => { + it('should return 0 if min is equal to max', () => { + expect(getPercent(50, 100, 100)).toBe(0); + }); + + it('should return 0 if value is equal to min', () => { + expect(getPercent(0, 0, 100)).toBe(0); + }); + + it('should return 100 if value is equal to max', () => { + expect(getPercent(100, 0, 100)).toBe(100); + }); + + it('should return 50 if value is halfway between min and max', () => { + expect(getPercent(50, 0, 100)).toBe(50); + }); + + it('should return correct percentage for positive range', () => { + expect(getPercent(75, 50, 100)).toBe(50); + }); + + it('should return correct percentage for negative range', () => { + expect(getPercent(-25, -50, 0)).toBe(50); + }); + + it('should return correct percentage for mixed range', () => { + expect(getPercent(25, 0, 50)).toBe(50); + }); + + it('should return correct percentage for value outside range', () => { + expect(getPercent(150, 0, 100)).toBe(150); + }); + + it('should return correct percentage for value below range', () => { + expect(getPercent(-50, 0, 100)).toBe(-50); + }); +}); diff --git a/packages/react-components/react-color-picker-preview/library/src/utils/getPercent.ts b/packages/react-components/react-color-picker-preview/library/src/utils/getPercent.ts index dcc4c2fce25796..1fdadf40b9a755 100644 --- a/packages/react-components/react-color-picker-preview/library/src/utils/getPercent.ts +++ b/packages/react-components/react-color-picker-preview/library/src/utils/getPercent.ts @@ -1,3 +1,12 @@ +/** + * Calculates the percentage of a value within a given range. + * + * @param value - The value to be converted to a percentage. + * @param min - The minimum value of the range. + * @param max - The maximum value of the range. + * @returns The percentage representation of the value within the range [min, max]. + * Returns 0 if `min` is equal to `max`. + */ export const getPercent = (value: number, min: number, max: number) => { return max === min ? 0 : ((value - min) / (max - min)) * 100; }; diff --git a/packages/react-components/react-color-picker-preview/stories/package.json b/packages/react-components/react-color-picker-preview/stories/package.json index 9659abb1243b41..43f559899ccdb3 100644 --- a/packages/react-components/react-color-picker-preview/stories/package.json +++ b/packages/react-components/react-color-picker-preview/stories/package.json @@ -3,7 +3,6 @@ "version": "0.0.0", "private": true, "devDependencies": { - "@ctrl/tinycolor": "3.3.4", "@fluentui/react-components": "*", "@fluentui/react-color-picker-preview": "*", "@fluentui/react-storybook-addon": "*", diff --git a/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/AlphaSliderDefault.stories.tsx b/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/AlphaSliderDefault.stories.tsx index 6bf15aca3f4dd8..7fffabdc8bec2a 100644 --- a/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/AlphaSliderDefault.stories.tsx +++ b/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/AlphaSliderDefault.stories.tsx @@ -15,29 +15,67 @@ const useStyles = makeStyles({ height: '50px', borderRadius: '4px', border: '1px solid #ccc', + '@media (forced-colors: active)': { + forcedColorAdjust: 'none', + }, }, }); +const COLOR = { h: 96, s: 1, v: 0.9, a: 1 }; -const COLOR = tinycolor('#5be600').toHsv(); - -export const AlphaSliderExample = (props: Partial) => { +export const AlphaSliderDefault = (props: Partial) => { const styles = useStyles(); const [color, setColor] = React.useState(COLOR); - const onSliderChange: AlphaSliderProps['onChange'] = (_, data) => setColor({ ...data.color, a: data.color.a ?? 1 }); + 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 (
- - + +
+

Transparency

+ + +
+
); }; -AlphaSliderExample.parameters = { +AlphaSliderDefault.parameters = { docs: { description: { story: 'The `AlphaSlider` allows users to change the alpha channel of a color value.', 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 new file mode 100644 index 00000000000000..d7dd897d649c9d --- /dev/null +++ b/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorAndSwatchPicker.stories.tsx @@ -0,0 +1,139 @@ +import * as React from 'react'; +import { tinycolor } from '@ctrl/tinycolor'; +import { makeStyles, Button, SwatchPicker, EmptySwatch, ColorSwatch, Label, tokens } from '@fluentui/react-components'; +import { + ColorPicker, + ColorSlider, + AlphaSlider, + ColorPickerProps, + ColorArea, +} from '@fluentui/react-color-picker-preview'; +import type { SwatchPickerOnSelectEventHandler } from '@fluentui/react-components'; + +const useStyles = makeStyles({ + example: { + width: '300px', + display: 'flex', + flexDirection: 'column', + gap: '10px', + }, + previewColor: { + width: '50px', + height: '50px', + borderRadius: tokens.borderRadiusMedium, + border: `1px solid ${tokens.colorNeutralStroke1}`, + margin: `${tokens.spacingVerticalMNudge} 0`, + '@media (forced-colors: active)': { + forcedColorAdjust: 'none', + }, + }, + button: { + marginRight: tokens.spacingHorizontalS, + }, + input: { + display: 'block', + margin: `${tokens.spacingVerticalSNudge} 0`, + }, + row: { + display: 'flex', + gap: '10px', + justifyContent: 'space-between', + }, + sliders: { + display: 'flex', + flexDirection: 'column', + width: '80%', + }, +}); + +const ITEMS_LIMIT = 8; +const DEFAULT_SELECTED_VALUE = '2be700'; + +const DEFAULT_COLOR_HSV = { h: 109, s: 1, v: 0.9, a: 1 }; +const DEFAULT_SELECTED_COLOR = tinycolor(DEFAULT_COLOR_HSV).toHex(); + +export const ColorAndSwatchPicker = () => { + const styles = useStyles(); + const [color, setColor] = React.useState(DEFAULT_COLOR_HSV); + const [selectedValue, setSelectedValue] = React.useState(DEFAULT_SELECTED_VALUE); + const [selectedColor, setSelectedColor] = React.useState(DEFAULT_SELECTED_COLOR); + + const colorFocusTargetRef = React.useRef(null); + const [colorFocusTarget, setColorFocusTarget] = React.useState(null); + + const [items, setItems] = React.useState>([]); + const emptyItems = new Array(ITEMS_LIMIT - items.length).fill(null); + + const handleChange: ColorPickerProps['onColorChange'] = (_, data) => { + setColor({ ...data.color, a: data.color.a ?? 1 }); + }; + + const handleSelect: SwatchPickerOnSelectEventHandler = (_, data) => { + setSelectedValue(data.selectedValue); + setSelectedColor(data.selectedSwatch); + }; + + const handleAddColor = () => { + const newColor = tinycolor(color).toRgbString(); + const newValue = `custom-${newColor} [${items.length - ITEMS_LIMIT}]`; + + setItems([...items, { color: newColor, value: newValue, 'aria-label': newColor }]); + setColorFocusTarget(newValue); + }; + + const resetColors = () => { + setItems([]); + setColorFocusTarget(null); + setSelectedValue(DEFAULT_SELECTED_VALUE); + setSelectedColor(DEFAULT_SELECTED_COLOR); + setColor(DEFAULT_COLOR_HSV); + }; + + React.useEffect(() => { + if (colorFocusTarget) { + colorFocusTargetRef.current?.focus(); + } + }, [colorFocusTarget]); + + return ( +
+ + +
+
+ + +
+
+
+ + + {items.map(item => ( + + ))} + {emptyItems.map((_, index) => ( + + ))} + + +
+ + +
+ ); +}; 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 af090835944133..eefd3d419ad592 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 @@ -15,28 +15,48 @@ const useStyles = makeStyles({ height: '50px', borderRadius: '4px', border: `1px solid ${tokens.colorNeutralStroke1}`, + '@media (forced-colors: active)': { + forcedColorAdjust: 'none', + }, }, }); -const DEFAULT_COLOR_HSV = tinycolor('#804066').toHsv(); +const DEFAULT_COLOR_HSV = { h: 324, s: 0.5, v: 0.5, a: 1 }; -export const ColorAreaExample = () => { +export const ColorAreaDefault = () => { const styles = useStyles(); const [color, setColor] = React.useState(DEFAULT_COLOR_HSV); - const onChange: ColorAreaProps['onChange'] = (_, data) => setColor({ ...data.color, a: data.color.a ?? 1 }); + const [namedColor, setNamedColor] = React.useState(''); + + const onChange: ColorAreaProps['onChange'] = (_, data) => { + setColor({ ...data.color, a: data.color.a ?? 1 }); + const _namedColor = tinycolor(`hsl(${data.color.h},100%,50%)`).toName(); + if (_namedColor) { + setNamedColor(_namedColor); + } + }; const resetSlider = () => setColor(DEFAULT_COLOR_HSV); + const ariaAttributes = { + 'aria-roledescription': '2D slider', + 'aria-valuetext': `Saturation ${color.s * 100}, Brightness: ${color.v * 100}, ${namedColor}`, + }; return (
- +
); }; -ColorAreaExample.parameters = { +ColorAreaDefault.parameters = { docs: { description: { story: 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 4ba93f4bbf9392..ecd56a5520fbe9 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 @@ -1,12 +1,22 @@ import * as React from 'react'; import { tinycolor } from '@ctrl/tinycolor'; -import { makeStyles, useId, Input, type InputProps, Label } from '@fluentui/react-components'; import { - ColorPicker, - ColorSlider, + Input, + type InputProps, + Label, + makeStyles, + SpinButton, + type SpinButtonChangeEvent, + type SpinButtonOnChangeData, + type SpinButtonProps, + useId, +} from '@fluentui/react-components'; +import { AlphaSlider, - ColorPickerProps, ColorArea, + ColorPicker, + ColorPickerProps, + ColorSlider, } from '@fluentui/react-color-picker-preview'; const useStyles = makeStyles({ @@ -21,6 +31,9 @@ const useStyles = makeStyles({ height: '50px', borderRadius: '4px', border: '1px solid #ccc', + '@media (forced-colors: active)': { + forcedColorAdjust: 'none', + }, }, inputFields: { display: 'flex', @@ -36,32 +49,84 @@ const useStyles = makeStyles({ input: { width: '80px', }, + spinButton: { + minWidth: '60px', + }, }); const HEX_COLOR_REGEX = /^#?([0-9A-Fa-f]{0,6})$/; -const DEFAULT_COLOR_HSV = tinycolor('#2be700').toHsv(); +const NUMBER_REGEX = /^\d+$/; +const DEFAULT_COLOR_HSV = { h: 109, s: 1, v: 0.9, a: 1 }; + +type RgbKey = 'r' | 'g' | 'b'; export const Default = () => { const hexId = useId('hex-input'); + const alphaId = useId('alpha-input'); const styles = useStyles(); const [color, setColor] = React.useState(DEFAULT_COLOR_HSV); const [hex, setHex] = React.useState(tinycolor(color).toHexString()); + const [rgb, setRgb] = React.useState(tinycolor(color).toRgb()); + const [alpha, setAlpha] = React.useState(color.a); + const [namedColor, setNamedColor] = React.useState(''); const handleChange: ColorPickerProps['onColorChange'] = (_, data) => { setColor({ ...data.color, a: data.color.a ?? 1 }); setHex(tinycolor(data.color).toHexString()); + setRgb(tinycolor(data.color).toRgb()); + setAlpha(data.color.a ?? 1); + const _namedColor = tinycolor(`hsl(${data.color.h},100%,50%)`).toName(); + if (_namedColor) { + setNamedColor(_namedColor); + } + }; + + const onRgbChange: InputRgbFieldProps['onChange'] = (_, data) => { + const newColor = tinycolor({ ...rgb, [data.name]: data.value }); + if (newColor.isValid) { + setColor(newColor.toHsv()); + setHex(newColor.toHex()); + setRgb(newColor.toRgb()); + } + }; + + const onAlphaChange: SpinButtonProps['onChange'] = React.useCallback( + (_ev, data) => { + const value = data.value ?? parseFloat(data.displayValue ?? ''); + + if (Number.isNaN(value) || value < 0 || value > 1) { + return; + } + + const newColor = tinycolor({ ...color, a: value }); + + if (newColor.isValid) { + setColor(newColor.toHsv()); + setHex(newColor.toHex()); + setRgb(newColor.toRgb()); + setAlpha(newColor.a); + } + }, + [setAlpha, setRgb, setHex, setColor, color], + ); + + const colorAriaAttributes = { + 'aria-roledescription': '2D slider', + 'aria-valuetext': `Saturation ${color.s * 100}, Brightness: ${color.v * 100}, ${namedColor}`, }; return (
- - - + + +
-
{ const newColor = tinycolor(value); if (newColor.isValid) { setColor(newColor.toHsv()); + setRgb(newColor.toRgb()); } setHex(oldValue => (HEX_COLOR_REGEX.test(value) ? value : oldValue)); }} /> + + + +
+
); }; @@ -99,6 +170,69 @@ const InputHexField = ({ ); }; +interface InputRgbFieldProps { + value: number; + label: string; + name: RgbKey; + onChange?: (event: SpinButtonChangeEvent, data: SpinButtonOnChangeData & { name: string }) => void; +} + +const InputRgbField = ({ value, onChange, label, name }: InputRgbFieldProps) => { + const id = useId(`${label.toLowerCase()}-input`); + const styles = useStyles(); + + const handleChange = React.useCallback( + (event: SpinButtonChangeEvent, data: SpinButtonOnChangeData) => { + const val = data.value ?? parseFloat(data.displayValue ?? ''); + + if (val === null || Number.isNaN(val) || !NUMBER_REGEX.test(val.toString())) { + return; + } + + if (onChange) { + onChange(event, { ...data, value: val, name }); + } + }, + [name, onChange], + ); + + return ( +
+ + +
+ ); +}; + +const InputAlphaField = ({ + label = 'Alpha', + value, + onChange, + id, +}: { + value: number; + label?: string; + onChange?: SpinButtonProps['onChange']; + id: string; +}) => { + const styles = useStyles(); + + return ( +
+ + +
+ ); +}; + const handleOnBlur = (e: React.FocusEvent) => { const value = tinycolor(e.target.value); if (!value.isValid) { 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 new file mode 100644 index 00000000000000..54c783638ba87e --- /dev/null +++ b/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorPickerPopup.stories.tsx @@ -0,0 +1,93 @@ +import * as React from 'react'; +import { tinycolor } from '@ctrl/tinycolor'; +import { makeStyles, Button, Popover, PopoverSurface, PopoverTrigger } from '@fluentui/react-components'; +import { + ColorPicker, + ColorSlider, + AlphaSlider, + ColorPickerProps, + ColorArea, +} from '@fluentui/react-color-picker-preview'; + +const useStyles = makeStyles({ + example: { + width: '300px', + display: 'flex', + flexDirection: 'column', + gap: '10px', + }, + previewColor: { + margin: '10px 0', + width: '50px', + height: '50px', + borderRadius: '4px', + border: '1px solid #ccc', + '@media (forced-colors: active)': { + forcedColorAdjust: 'none', + }, + }, + row: { + display: 'flex', + gap: '10px', + }, + sliders: { + display: 'flex', + flexDirection: 'column', + }, +}); + +const DEFAULT_COLOR_HSV = { h: 109, s: 1, v: 0.9, a: 1 }; + +export const ColorPickerPopup = () => { + const styles = useStyles(); + const [previewColor, setPreviewColor] = React.useState(DEFAULT_COLOR_HSV); + const [color, setColor] = React.useState(DEFAULT_COLOR_HSV); + + const handleChange: ColorPickerProps['onColorChange'] = (_, data) => { + setPreviewColor({ ...data.color, a: data.color.a ?? 1 }); + }; + + const [popoverOpen, setPopoverOpen] = React.useState(false); + + return ( + <> + setPopoverOpen(data.open)}> + + + + + + + +
+
+ + +
+
+
+ +
+ + +
+ + +
+ + ); +}; 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 c5e5f599235afc..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 @@ -21,10 +21,13 @@ const useStyles = makeStyles({ height: '50px', borderRadius: '4px', border: '1px solid #ccc', + '@media (forced-colors: active)': { + forcedColorAdjust: 'none', + }, }, }); -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(); @@ -36,15 +39,15 @@ export const ColorPickerShape = () => {

Rounded (default)

- - - + + +

Square (default)

+ -
diff --git a/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorSliderChannels.stories.tsx b/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorSliderChannels.stories.tsx new file mode 100644 index 00000000000000..5244f71fa8e92c --- /dev/null +++ b/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/ColorSliderChannels.stories.tsx @@ -0,0 +1,53 @@ +import * as React from 'react'; +import { tinycolor } from '@ctrl/tinycolor'; +import { ColorSlider, type ColorSliderProps } from '@fluentui/react-color-picker-preview'; +import { Button, makeStyles } from '@fluentui/react-components'; + +const useStyles = makeStyles({ + example: { + width: '300px', + display: 'flex', + flexDirection: 'column', + gap: '10px', + }, + previewColor: { + width: '50px', + height: '50px', + borderRadius: '4px', + border: '1px solid #ccc', + }, +}); + +const DEFAULT_COLOR_HSV = tinycolor('#2be700').toHsv(); + +export const ColorSliderChannels = () => { + const styles = useStyles(); + const [color, setColor] = React.useState(DEFAULT_COLOR_HSV); + + const onSliderChange: ColorSliderProps['onChange'] = (_, data) => { + setColor({ ...data.color, a: data.color.a ?? 1 }); + }; + + const resetSlider = () => setColor(DEFAULT_COLOR_HSV); + + return ( +
+

Hue

+ +

Saturation

+ +

Value (Brightness)

+ +
+ +
+ ); +}; + +ColorSliderChannels.parameters = { + docs: { + description: { + story: 'The `ColorSlider` allows users to choose color channels like hue, saturation, and value.', + }, + }, +}; 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 2a14a3d7403594..d1327822453e54 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 @@ -15,28 +15,52 @@ const useStyles = makeStyles({ height: '50px', borderRadius: '4px', border: '1px solid #ccc', + '@media (forced-colors: active)': { + forcedColorAdjust: 'none', + }, }, }); +const DEFAULT_COLOR_HSV = { h: 109, s: 1, v: 0.9, a: 1 }; -const DEFAULT_COLOR_HSV = tinycolor('#2be700').toHsv(); - -export const ColorSliderExample = (props: Partial) => { +export const ColorSliderDefault = (props: Partial) => { const styles = useStyles(); const [color, setColor] = React.useState(DEFAULT_COLOR_HSV); - const onSliderChange: ColorSliderProps['onChange'] = (_, data) => setColor({ ...data.color, a: data.color.a ?? 1 }); + const [hue, setHue] = React.useState(DEFAULT_COLOR_HSV.h); + const [namedColor, setNamedColor] = React.useState(''); + const onSliderChange: ColorSliderProps['onChange'] = (_, data) => { + setColor({ ...data.color, a: data.color.a ?? 1 }); + setHue(data.color.h); + const _namedColor = tinycolor(`hsl(${data.color.h},100%,50%)`).toName(); + if (_namedColor) { + setNamedColor(_namedColor); + } + }; const resetSlider = () => setColor(DEFAULT_COLOR_HSV); return (
- - + +
); }; -ColorSliderExample.parameters = { +ColorSliderDefault.parameters = { docs: { description: { story: 'The `ColorSlider` allows users to change the hue aspect of a color value.', diff --git a/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/index.stories.tsx b/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/index.stories.tsx index aa19d4b2741bea..b4c53d932e5117 100644 --- a/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/index.stories.tsx +++ b/packages/react-components/react-color-picker-preview/stories/src/ColorPicker/index.stories.tsx @@ -5,9 +5,12 @@ import bestPracticesMd from './ColorPickerBestPractices.md'; export { Default } from './ColorPickerDefault.stories'; export { ColorPickerShape } from './ColorPickerShape.stories'; -export { ColorAreaExample } from './ColorAreaDefault.stories'; -export { ColorSliderExample } from './ColorSliderDefault.stories'; -export { AlphaSliderExample } from './AlphaSliderDefault.stories'; +export { ColorAreaDefault } from './ColorAreaDefault.stories'; +export { ColorSliderDefault } from './ColorSliderDefault.stories'; +export { ColorSliderChannels } from './ColorSliderChannels.stories'; +export { AlphaSliderDefault } from './AlphaSliderDefault.stories'; +export { ColorAndSwatchPicker } from './ColorAndSwatchPicker.stories'; +export { ColorPickerPopup } from './ColorPickerPopup.stories'; export default { title: 'Preview Components/ColorPicker', diff --git a/packages/react-components/react-colorpicker-compat/package.json b/packages/react-components/react-colorpicker-compat/package.json index 3ef5d00b7aa72d..0b094aaac00793 100644 --- a/packages/react-components/react-colorpicker-compat/package.json +++ b/packages/react-components/react-colorpicker-compat/package.json @@ -19,9 +19,9 @@ "@fluentui/scripts-api-extractor": "*" }, "dependencies": { - "@fluentui/react-jsx-runtime": "^9.0.47", - "@fluentui/react-theme": "^9.1.23", - "@fluentui/react-utilities": "^9.18.18", + "@fluentui/react-jsx-runtime": "^9.0.50", + "@fluentui/react-theme": "^9.1.24", + "@fluentui/react-utilities": "^9.18.20", "@griffel/react": "^1.5.22", "@swc/helpers": "^0.5.1" }, diff --git a/packages/react-components/react-combobox/library/CHANGELOG.json b/packages/react-components/react-combobox/library/CHANGELOG.json index a5a5afd08bf2f5..e4771c5eaf61bf 100644 --- a/packages/react-components/react-combobox/library/CHANGELOG.json +++ b/packages/react-components/react-combobox/library/CHANGELOG.json @@ -1,6 +1,266 @@ { "name": "@fluentui/react-combobox", "entries": [ + { + "date": "Fri, 21 Feb 2025 14:34:05 GMT", + "tag": "@fluentui/react-combobox_v9.14.0", + "version": "9.14.0", + "comments": { + "minor": [ + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-aria to v9.14.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-field to v9.2.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-portal to v9.5.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-tabster to v9.24.0", + "commit": "5f185f3378d6315879de324ca57f025df37a79d3" + } + ] + } + }, + { + "date": "Mon, 27 Jan 2025 20:27:35 GMT", + "tag": "@fluentui/react-combobox_v9.13.18", + "version": "9.13.18", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-field to v9.1.86", + "commit": "808cd501d50a317249d3d02f01ea3dd88114b252" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-positioning to v9.16.3", + "commit": "808cd501d50a317249d3d02f01ea3dd88114b252" + } + ] + } + }, + { + "date": "Wed, 22 Jan 2025 14:00:16 GMT", + "tag": "@fluentui/react-combobox_v9.13.17", + "version": "9.13.17", + "comments": { + "none": [ + { + "author": "vgenaev@gmail.com", + "package": "@fluentui/react-combobox", + "commit": "fd420e1e0b66e04c8a423cff3eea6d21d9434d2d", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule" + } + ], + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-aria to v9.13.14", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-context-selector to v9.1.72", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-field to v9.1.85", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.50", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-portal to v9.4.42", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-positioning to v9.16.2", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-tabster to v9.23.3", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-utilities to v9.18.20", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + } + ] + } + }, + { + "date": "Wed, 08 Jan 2025 18:33:36 GMT", + "tag": "@fluentui/react-combobox_v9.13.16", + "version": "9.13.16", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-aria to v9.13.13", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-field to v9.1.84", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.49", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-portal to v9.4.41", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-positioning to v9.16.1", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + } + ] + } + }, + { + "date": "Mon, 16 Dec 2024 16:26:49 GMT", + "tag": "@fluentui/react-combobox_v9.13.15", + "version": "9.13.15", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-aria to v9.13.12", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-context-selector to v9.1.71", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-field to v9.1.83", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.48", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-portal to v9.4.40", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-positioning to v9.16.0", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-shared-contexts to v9.21.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-tabster to v9.23.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-theme to v9.1.24", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-utilities to v9.18.19", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + } + ] + } + }, + { + "date": "Mon, 09 Dec 2024 17:38:10 GMT", + "tag": "@fluentui/react-combobox_v9.13.14", + "version": "9.13.14", + "comments": { + "patch": [ + { + "author": "olfedias@microsoft.com", + "package": "@fluentui/react-combobox", + "commit": "cad13936cd49ba0b34b50bc2f58395605c4e8da4", + "comment": "chore: remove usage of \"export *\"" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-aria to v9.13.11", + "commit": "80f2ce07be06e66b369bd18e4484d8faf6b493c7" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-field to v9.1.82", + "commit": "80f2ce07be06e66b369bd18e4484d8faf6b493c7" + }, + { + "author": "beachball", + "package": "@fluentui/react-combobox", + "comment": "Bump @fluentui/react-positioning to v9.15.14", + "commit": "80f2ce07be06e66b369bd18e4484d8faf6b493c7" + } + ] + } + }, { "date": "Fri, 06 Dec 2024 12:53:46 GMT", "tag": "@fluentui/react-combobox_v9.13.13", diff --git a/packages/react-components/react-combobox/library/CHANGELOG.md b/packages/react-components/react-combobox/library/CHANGELOG.md index 0e6734dd157142..74357d16e77111 100644 --- a/packages/react-components/react-combobox/library/CHANGELOG.md +++ b/packages/react-components/react-combobox/library/CHANGELOG.md @@ -1,9 +1,90 @@ # Change Log - @fluentui/react-combobox -This log was last generated on Fri, 06 Dec 2024 12:53:46 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 14:34:05 GMT and should not be manually modified. +## [9.14.0](https://github.com/microsoft/fluentui/tree/@fluentui/react-combobox_v9.14.0) + +Fri, 21 Feb 2025 14:34:05 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-combobox_v9.13.18..@fluentui/react-combobox_v9.14.0) + +### Minor changes + +- Bump @fluentui/react-aria to v9.14.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) +- Bump @fluentui/react-field to v9.2.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) +- Bump @fluentui/react-portal to v9.5.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) +- Bump @fluentui/react-tabster to v9.24.0 ([PR #33876](https://github.com/microsoft/fluentui/pull/33876) by beachball) + +## [9.13.18](https://github.com/microsoft/fluentui/tree/@fluentui/react-combobox_v9.13.18) + +Mon, 27 Jan 2025 20:27:35 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-combobox_v9.13.17..@fluentui/react-combobox_v9.13.18) + +### Patches + +- Bump @fluentui/react-field to v9.1.86 ([PR #33724](https://github.com/microsoft/fluentui/pull/33724) by beachball) +- Bump @fluentui/react-positioning to v9.16.3 ([PR #33724](https://github.com/microsoft/fluentui/pull/33724) by beachball) + +## [9.13.17](https://github.com/microsoft/fluentui/tree/@fluentui/react-combobox_v9.13.17) + +Wed, 22 Jan 2025 14:00:16 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-combobox_v9.13.16..@fluentui/react-combobox_v9.13.17) + +### Patches + +- Bump @fluentui/react-aria to v9.13.14 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-context-selector to v9.1.72 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-field to v9.1.85 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.50 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-portal to v9.4.42 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-positioning to v9.16.2 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-tabster to v9.23.3 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-utilities to v9.18.20 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) + +## [9.13.16](https://github.com/microsoft/fluentui/tree/@fluentui/react-combobox_v9.13.16) + +Wed, 08 Jan 2025 18:33:36 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-combobox_v9.13.15..@fluentui/react-combobox_v9.13.16) + +### Patches + +- Bump @fluentui/react-aria to v9.13.13 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-field to v9.1.84 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.49 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-portal to v9.4.41 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) +- Bump @fluentui/react-positioning to v9.16.1 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) + +## [9.13.15](https://github.com/microsoft/fluentui/tree/@fluentui/react-combobox_v9.13.15) + +Mon, 16 Dec 2024 16:26:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-combobox_v9.13.14..@fluentui/react-combobox_v9.13.15) + +### Patches + +- Bump @fluentui/react-aria to v9.13.12 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-context-selector to v9.1.71 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-field to v9.1.83 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-jsx-runtime to v9.0.48 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-portal to v9.4.40 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-positioning to v9.16.0 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-shared-contexts to v9.21.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-tabster to v9.23.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-theme to v9.1.24 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-utilities to v9.18.19 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) + +## [9.13.14](https://github.com/microsoft/fluentui/tree/@fluentui/react-combobox_v9.13.14) + +Mon, 09 Dec 2024 17:38:10 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-combobox_v9.13.13..@fluentui/react-combobox_v9.13.14) + +### Patches + +- chore: remove usage of "export *" ([PR #33384](https://github.com/microsoft/fluentui/pull/33384) by olfedias@microsoft.com) +- Bump @fluentui/react-aria to v9.13.11 ([PR #33431](https://github.com/microsoft/fluentui/pull/33431) by beachball) +- Bump @fluentui/react-field to v9.1.82 ([PR #33431](https://github.com/microsoft/fluentui/pull/33431) by beachball) +- Bump @fluentui/react-positioning to v9.15.14 ([PR #33431](https://github.com/microsoft/fluentui/pull/33431) by beachball) + ## [9.13.13](https://github.com/microsoft/fluentui/tree/@fluentui/react-combobox_v9.13.13) Fri, 06 Dec 2024 12:53:46 GMT diff --git a/packages/react-components/react-combobox/library/package.json b/packages/react-components/react-combobox/library/package.json index f688aeb07a6c91..f25220a9ab1bd9 100644 --- a/packages/react-components/react-combobox/library/package.json +++ b/packages/react-components/react-combobox/library/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-combobox", - "version": "9.13.13", + "version": "9.14.0", "description": "Fluent UI React Combobox component", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -19,18 +19,18 @@ "@fluentui/scripts-cypress": "*" }, "dependencies": { - "@fluentui/react-aria": "^9.13.10", + "@fluentui/react-aria": "^9.14.0", "@fluentui/keyboard-keys": "^9.0.8", - "@fluentui/react-context-selector": "^9.1.70", - "@fluentui/react-field": "^9.1.81", + "@fluentui/react-context-selector": "^9.1.72", + "@fluentui/react-field": "^9.2.0", "@fluentui/react-icons": "^2.0.245", - "@fluentui/react-jsx-runtime": "^9.0.47", - "@fluentui/react-portal": "^9.4.39", - "@fluentui/react-positioning": "^9.15.13", - "@fluentui/react-shared-contexts": "^9.21.1", - "@fluentui/react-tabster": "^9.23.1", - "@fluentui/react-theme": "^9.1.23", - "@fluentui/react-utilities": "^9.18.18", + "@fluentui/react-jsx-runtime": "^9.0.50", + "@fluentui/react-portal": "^9.5.0", + "@fluentui/react-positioning": "^9.16.3", + "@fluentui/react-shared-contexts": "^9.21.2", + "@fluentui/react-tabster": "^9.24.0", + "@fluentui/react-theme": "^9.1.24", + "@fluentui/react-utilities": "^9.18.20", "@griffel/react": "^1.5.22", "@swc/helpers": "^0.5.1" }, diff --git a/packages/react-components/react-combobox/library/src/Combobox.ts b/packages/react-components/react-combobox/library/src/Combobox.ts index dd7f0f1b1d16a5..b28ee0fb342497 100644 --- a/packages/react-components/react-combobox/library/src/Combobox.ts +++ b/packages/react-components/react-combobox/library/src/Combobox.ts @@ -1 +1,16 @@ -export * from './components/Combobox/index'; +export type { + ActiveOptionChangeData, + ComboboxContextValues, + ComboboxOpenChangeData, + ComboboxOpenEvents, + ComboboxProps, + ComboboxSlots, + ComboboxState, +} from './components/Combobox/index'; +export { + Combobox, + comboboxClassNames, + renderCombobox_unstable, + useComboboxStyles_unstable, + useCombobox_unstable, +} from './components/Combobox/index'; diff --git a/packages/react-components/react-combobox/library/src/Dropdown.ts b/packages/react-components/react-combobox/library/src/Dropdown.ts index 02d5745849f225..f5e46411411cde 100644 --- a/packages/react-components/react-combobox/library/src/Dropdown.ts +++ b/packages/react-components/react-combobox/library/src/Dropdown.ts @@ -1 +1,16 @@ -export * from './components/Dropdown/index'; +export type { + ActiveOptionChangeData, + DropdownContextValues, + DropdownOpenChangeData, + DropdownOpenEvents, + DropdownProps, + DropdownSlots, + DropdownState, +} from './components/Dropdown/index'; +export { + Dropdown, + dropdownClassNames, + renderDropdown_unstable, + useDropdownStyles_unstable, + useDropdown_unstable, +} from './components/Dropdown/index'; diff --git a/packages/react-components/react-combobox/library/src/Listbox.ts b/packages/react-components/react-combobox/library/src/Listbox.ts index 5e8c190f641eec..b82477ff11fb1d 100644 --- a/packages/react-components/react-combobox/library/src/Listbox.ts +++ b/packages/react-components/react-combobox/library/src/Listbox.ts @@ -1 +1,8 @@ -export * from './components/Listbox/index'; +export type { ListboxContextValues, ListboxProps, ListboxSlots, ListboxState } from './components/Listbox/index'; +export { + Listbox, + listboxClassNames, + renderListbox_unstable, + useListboxStyles_unstable, + useListbox_unstable, +} from './components/Listbox/index'; diff --git a/packages/react-components/react-combobox/library/src/Option.ts b/packages/react-components/react-combobox/library/src/Option.ts index 8a103aef846008..36cf32148c8a4a 100644 --- a/packages/react-components/react-combobox/library/src/Option.ts +++ b/packages/react-components/react-combobox/library/src/Option.ts @@ -1 +1,8 @@ -export * from './components/Option/index'; +export type { OptionProps, OptionSlots, OptionState } from './components/Option/index'; +export { + Option, + optionClassNames, + renderOption_unstable, + useOptionStyles_unstable, + useOption_unstable, +} from './components/Option/index'; diff --git a/packages/react-components/react-combobox/library/src/OptionGroup.ts b/packages/react-components/react-combobox/library/src/OptionGroup.ts index a44391207cddb1..4a0eae87a47cf0 100644 --- a/packages/react-components/react-combobox/library/src/OptionGroup.ts +++ b/packages/react-components/react-combobox/library/src/OptionGroup.ts @@ -1 +1,8 @@ -export * from './components/OptionGroup/index'; +export type { OptionGroupProps, OptionGroupSlots, OptionGroupState } from './components/OptionGroup/index'; +export { + OptionGroup, + optionGroupClassNames, + renderOptionGroup_unstable, + useOptionGroupStyles_unstable, + useOptionGroup_unstable, +} from './components/OptionGroup/index'; diff --git a/packages/react-components/react-combobox/library/src/Selection.ts b/packages/react-components/react-combobox/library/src/Selection.ts index d86fba9de50e2c..aa019f0ff4b1d8 100644 --- a/packages/react-components/react-combobox/library/src/Selection.ts +++ b/packages/react-components/react-combobox/library/src/Selection.ts @@ -1 +1 @@ -export * from './utils/Selection.types'; +export type { OptionOnSelectData, SelectionEvents, SelectionProps, SelectionState } from './utils/Selection.types'; diff --git a/packages/react-components/react-combobox/library/src/components/Combobox/index.ts b/packages/react-components/react-combobox/library/src/components/Combobox/index.ts index 1af6008ba433b5..3f0a2df42232a6 100644 --- a/packages/react-components/react-combobox/library/src/components/Combobox/index.ts +++ b/packages/react-components/react-combobox/library/src/components/Combobox/index.ts @@ -1,5 +1,13 @@ -export * from './Combobox'; -export * from './Combobox.types'; -export * from './renderCombobox'; -export * from './useCombobox'; -export * from './useComboboxStyles.styles'; +export { Combobox } from './Combobox'; +export type { + ActiveOptionChangeData, + ComboboxContextValues, + ComboboxOpenChangeData, + ComboboxOpenEvents, + ComboboxProps, + ComboboxSlots, + ComboboxState, +} from './Combobox.types'; +export { renderCombobox_unstable } from './renderCombobox'; +export { useCombobox_unstable } from './useCombobox'; +export { comboboxClassNames, useComboboxStyles_unstable } from './useComboboxStyles.styles'; 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/index.ts b/packages/react-components/react-combobox/library/src/components/Dropdown/index.ts index edd3a4a0372599..e9d62425978ea6 100644 --- a/packages/react-components/react-combobox/library/src/components/Dropdown/index.ts +++ b/packages/react-components/react-combobox/library/src/components/Dropdown/index.ts @@ -1,5 +1,13 @@ -export * from './Dropdown'; -export * from './Dropdown.types'; -export * from './renderDropdown'; -export * from './useDropdown'; -export * from './useDropdownStyles.styles'; +export { Dropdown } from './Dropdown'; +export type { + ActiveOptionChangeData, + DropdownContextValues, + DropdownOpenChangeData, + DropdownOpenEvents, + DropdownProps, + DropdownSlots, + DropdownState, +} from './Dropdown.types'; +export { renderDropdown_unstable } from './renderDropdown'; +export { useDropdown_unstable } from './useDropdown'; +export { dropdownClassNames, useDropdownStyles_unstable } from './useDropdownStyles.styles'; 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/components/Listbox/index.ts b/packages/react-components/react-combobox/library/src/components/Listbox/index.ts index 32df07e927eed0..a970a35469c2b5 100644 --- a/packages/react-components/react-combobox/library/src/components/Listbox/index.ts +++ b/packages/react-components/react-combobox/library/src/components/Listbox/index.ts @@ -1,5 +1,5 @@ -export * from './Listbox'; -export * from './Listbox.types'; -export * from './renderListbox'; -export * from './useListbox'; -export * from './useListboxStyles.styles'; +export { Listbox } from './Listbox'; +export type { ListboxContextValues, ListboxProps, ListboxSlots, ListboxState } from './Listbox.types'; +export { renderListbox_unstable } from './renderListbox'; +export { useListbox_unstable } from './useListbox'; +export { listboxClassNames, useListboxStyles_unstable } from './useListboxStyles.styles'; diff --git a/packages/react-components/react-combobox/library/src/components/Option/index.ts b/packages/react-components/react-combobox/library/src/components/Option/index.ts index ae79dd2478fcf0..57ba8a7053f4f0 100644 --- a/packages/react-components/react-combobox/library/src/components/Option/index.ts +++ b/packages/react-components/react-combobox/library/src/components/Option/index.ts @@ -1,5 +1,5 @@ -export * from './Option'; -export * from './Option.types'; -export * from './renderOption'; -export * from './useOption'; -export * from './useOptionStyles.styles'; +export { Option } from './Option'; +export type { OptionProps, OptionSlots, OptionState } from './Option.types'; +export { renderOption_unstable } from './renderOption'; +export { useOption_unstable } from './useOption'; +export { optionClassNames, useOptionStyles_unstable } from './useOptionStyles.styles'; diff --git a/packages/react-components/react-combobox/library/src/components/OptionGroup/index.ts b/packages/react-components/react-combobox/library/src/components/OptionGroup/index.ts index c23fdf13a47463..2745eb34921fed 100644 --- a/packages/react-components/react-combobox/library/src/components/OptionGroup/index.ts +++ b/packages/react-components/react-combobox/library/src/components/OptionGroup/index.ts @@ -1,5 +1,5 @@ -export * from './OptionGroup'; -export * from './OptionGroup.types'; -export * from './renderOptionGroup'; -export * from './useOptionGroup'; -export * from './useOptionGroupStyles.styles'; +export { OptionGroup } from './OptionGroup'; +export type { OptionGroupProps, OptionGroupSlots, OptionGroupState } from './OptionGroup.types'; +export { renderOptionGroup_unstable } from './renderOptionGroup'; +export { useOptionGroup_unstable } from './useOptionGroup'; +export { optionGroupClassNames, useOptionGroupStyles_unstable } from './useOptionGroupStyles.styles'; 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-combobox/stories/src/Combobox/ComboboxVirtualizer.stories.tsx b/packages/react-components/react-combobox/stories/src/Combobox/ComboboxVirtualizer.stories.tsx index 4a26d4d8a477a8..6273d691e3e86a 100644 --- a/packages/react-components/react-combobox/stories/src/Combobox/ComboboxVirtualizer.stories.tsx +++ b/packages/react-components/react-combobox/stories/src/Combobox/ComboboxVirtualizer.stories.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { Combobox, Option, makeStyles, useId } from '@fluentui/react-components'; +import { Combobox, Option, makeStyles, useId, useMergedRefs, useTimeout } from '@fluentui/react-components'; import type { ComboboxProps } from '@fluentui/react-components'; import { Virtualizer, useStaticVirtualizerMeasure } from '@fluentui/react-components/unstable'; @@ -18,7 +18,8 @@ export const ComboboxVirtualizer = (props: Partial) => { const comboId = useId('combobox'); //This should include the item height (32px) and account for rowGap (2px) - const itemHeight = 34; + const itemHeight = 32; + const rowGap = 2; const numberOfItems = 10000; const { virtualizerLength, bufferItems, bufferSize, scrollRef, containerSizeRef } = useStaticVirtualizerMeasure({ @@ -29,8 +30,12 @@ export const ComboboxVirtualizer = (props: Partial) => { // We need to recalculate index when at least 10 items (+1px) from the bottom or top for page up/down bufferSize: itemHeight * 10 + 1, }); + const selectedIndex = React.useRef(0); const styles = useStyles(); + const mergedRefs = useMergedRefs(scrollRef); + // Scroll timer required to post scrollTo on stack post-open state change + const [setScrollTimer, clearScrollTimer] = useTimeout(); return (
@@ -40,7 +45,20 @@ export const ComboboxVirtualizer = (props: Partial) => { id={`${comboId}`} placeholder="Select a number" positioning={{ autoSize: 'width' }} - listbox={{ ref: scrollRef, className: styles.listbox }} + listbox={{ ref: mergedRefs, className: styles.listbox }} + onOpenChange={(e, data) => { + clearScrollTimer(); + if (data.open) { + setScrollTimer(() => { + mergedRefs.current?.scrollTo({ top: (itemHeight + rowGap) * selectedIndex.current }); + }, 0); + } + }} + onOptionSelect={(e, data) => { + if (data.optionValue) { + selectedIndex.current = parseInt(data.optionValue, 10); + } + }} > ) => { bufferSize={bufferSize} itemSize={itemHeight} containerSizeRef={containerSizeRef} + gap={rowGap} > {index => { return ( @@ -57,7 +76,10 @@ export const ComboboxVirtualizer = (props: Partial) => { aria-posinset={index} aria-setsize={numberOfItems} key={`item-${index}`} - >{`Item ${index + 1}`} + value={index.toString()} + > + {`Item ${index + 1}`} + ); }} diff --git a/packages/react-components/react-combobox/stories/src/Dropdown/DropdownAccessibility.md b/packages/react-components/react-combobox/stories/src/Dropdown/DropdownAccessibility.md index 926abc55f4b97c..fc4849460fd7c4 100644 --- a/packages/react-components/react-combobox/stories/src/Dropdown/DropdownAccessibility.md +++ b/packages/react-components/react-combobox/stories/src/Dropdown/DropdownAccessibility.md @@ -2,15 +2,15 @@ ### Do -- **Provide a label for the Dropdown.** This can be done either by using the `DropdownField` component with a `label` prop, or by using a [custom labeling technique](#TODO). +- **Provide a label for the Dropdown.** This can be done either by using the `Field` component with a `label` prop, or by using a custom labeling technique like a custom `
+ + } + > + {layoutChildren} + + {subtree} + + + + + Edit + {commonMenuItems} + + + + ); +}; + +export const NavigationModeTreeGrid = () => { + return ( + + + item 1 + + + item 1-1 + + item 1-1-1 + item 1-1-2 + item 1-1-3 + + + item 1-2 + item 1-3 + + + + item 2 + + + item 2-1 + + item 2-1-1 + + + + + item 3 + + item 3-1 + item 3-2 + item 3-3 + + + + + + ); +}; + +NavigationModeTreeGrid.parameters = { + docs: { + description: { + story: ` +If \`navigationMode\` is set to \`treegrid\`, the navigation pattern changes to allow navigation between tree items and their actions. + +1. If the treeitem is a branch and it's not expanded, pressing right arrow key will expand the treeitem. +2. If the treeitem is a branch and it's expanded, pressing right arrow key will navigate towards the actions of the treeitem. +3. If focused in the actions, pressing left arrow key will navigate back to the treeitem. +`, + }, + }, +}; diff --git a/packages/react-components/react-tree/stories/src/Tree/index.stories.tsx b/packages/react-components/react-tree/stories/src/Tree/index.stories.tsx index ac5aa99c24248b..cfbc1e6fd3973e 100644 --- a/packages/react-components/react-tree/stories/src/Tree/index.stories.tsx +++ b/packages/react-components/react-tree/stories/src/Tree/index.stories.tsx @@ -20,6 +20,7 @@ export { ExpandIcon } from './TreeExpandIcon.stories'; export { IconBeforeAndAfter } from './TreeIconBeforeAndAfter.stories'; export { Aside } from './TreeAside.stories'; export { Actions } from './TreeActions.stories'; +export { NavigationModeTreeGrid } from './TreeNavigationModeTreeGrid.stories'; // FUNCTIONAL EXAMPLES export { DefaultOpen } from './TreeDefaultOpen.stories'; diff --git a/packages/react-components/react-utilities-compat/library/package.json b/packages/react-components/react-utilities-compat/library/package.json index 1330ebb20c1e9f..807e045afe15f5 100644 --- a/packages/react-components/react-utilities-compat/library/package.json +++ b/packages/react-components/react-utilities-compat/library/package.json @@ -25,10 +25,10 @@ "@fluentui/scripts-api-extractor": "*" }, "dependencies": { - "@fluentui/react-jsx-runtime": "^9.0.47", - "@fluentui/react-shared-contexts": "^9.21.1", - "@fluentui/react-theme": "^9.1.23", - "@fluentui/react-utilities": "^9.18.18", + "@fluentui/react-jsx-runtime": "^9.0.50", + "@fluentui/react-shared-contexts": "^9.21.2", + "@fluentui/react-theme": "^9.1.24", + "@fluentui/react-utilities": "^9.18.20", "@griffel/react": "^1.5.22", "@swc/helpers": "^0.5.1" }, diff --git a/packages/react-components/react-utilities/CHANGELOG.json b/packages/react-components/react-utilities/CHANGELOG.json index cf8ace0d311585..82821b0455d328 100644 --- a/packages/react-components/react-utilities/CHANGELOG.json +++ b/packages/react-components/react-utilities/CHANGELOG.json @@ -1,6 +1,44 @@ { "name": "@fluentui/react-utilities", "entries": [ + { + "date": "Wed, 22 Jan 2025 14:00:12 GMT", + "tag": "@fluentui/react-utilities_v9.18.20", + "version": "9.18.20", + "comments": { + "patch": [ + { + "author": "dmytrokirpa@microsoft.com", + "package": "@fluentui/react-utilities", + "commit": "8cf401d626def27ad679f9e53928533df9f9ef52", + "comment": "fix: add autoCorrect and minLength input properties support to getNativeProps utility" + } + ], + "none": [ + { + "author": "vgenaev@gmail.com", + "package": "@fluentui/react-utilities", + "commit": "fd420e1e0b66e04c8a423cff3eea6d21d9434d2d", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule" + } + ] + } + }, + { + "date": "Mon, 16 Dec 2024 16:26:49 GMT", + "tag": "@fluentui/react-utilities_v9.18.19", + "version": "9.18.19", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-utilities", + "comment": "Bump @fluentui/react-shared-contexts to v9.21.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + } + ] + } + }, { "date": "Fri, 06 Dec 2024 12:53:45 GMT", "tag": "@fluentui/react-utilities_v9.18.18", diff --git a/packages/react-components/react-utilities/CHANGELOG.md b/packages/react-components/react-utilities/CHANGELOG.md index 85ff5951292834..d75cfc7c5792b6 100644 --- a/packages/react-components/react-utilities/CHANGELOG.md +++ b/packages/react-components/react-utilities/CHANGELOG.md @@ -1,9 +1,27 @@ # Change Log - @fluentui/react-utilities -This log was last generated on Fri, 06 Dec 2024 12:53:45 GMT and should not be manually modified. +This log was last generated on Wed, 22 Jan 2025 14:00:12 GMT and should not be manually modified. +## [9.18.20](https://github.com/microsoft/fluentui/tree/@fluentui/react-utilities_v9.18.20) + +Wed, 22 Jan 2025 14:00:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-utilities_v9.18.19..@fluentui/react-utilities_v9.18.20) + +### Patches + +- fix: add autoCorrect and minLength input properties support to getNativeProps utility ([PR #33642](https://github.com/microsoft/fluentui/pull/33642) by dmytrokirpa@microsoft.com) + +## [9.18.19](https://github.com/microsoft/fluentui/tree/@fluentui/react-utilities_v9.18.19) + +Mon, 16 Dec 2024 16:26:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-utilities_v9.18.18..@fluentui/react-utilities_v9.18.19) + +### Patches + +- Bump @fluentui/react-shared-contexts to v9.21.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) + ## [9.18.18](https://github.com/microsoft/fluentui/tree/@fluentui/react-utilities_v9.18.18) Fri, 06 Dec 2024 12:53:45 GMT diff --git a/packages/react-components/react-utilities/package.json b/packages/react-components/react-utilities/package.json index 959d6f0d170b11..e6e0b642888f94 100644 --- a/packages/react-components/react-utilities/package.json +++ b/packages/react-components/react-utilities/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-utilities", - "version": "9.18.18", + "version": "9.18.20", "description": "A set of general React-specific utilities.", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -18,7 +18,7 @@ }, "dependencies": { "@fluentui/keyboard-keys": "^9.0.8", - "@fluentui/react-shared-contexts": "^9.21.1", + "@fluentui/react-shared-contexts": "^9.21.2", "@swc/helpers": "^0.5.1" }, "peerDependencies": { diff --git a/packages/react-components/react-utilities/src/compose/deprecated/getSlots.test.tsx b/packages/react-components/react-utilities/src/compose/deprecated/getSlots.test.tsx index 7ccb934d93a74b..139f83bd1b4eb9 100644 --- a/packages/react-components/react-utilities/src/compose/deprecated/getSlots.test.tsx +++ b/packages/react-components/react-utilities/src/compose/deprecated/getSlots.test.tsx @@ -9,7 +9,7 @@ describe('getSlots', () => { it('returns provided component type for root if the as prop is not provided', () => { type Slots = { root: Slot<'div'> }; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated expect(getSlots({ root: {}, components: { root: 'div' } })).toEqual({ slots: { root: 'div' }, slotProps: { root: {} }, @@ -18,7 +18,7 @@ describe('getSlots', () => { it('returns root slot as a span with no props', () => { type Slots = { root: Slot<'div', 'span'> }; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated expect(getSlots({ root: { as: 'span' }, components: { root: 'div' } })).toEqual({ slots: { root: 'span' }, slotProps: { root: {} }, @@ -29,7 +29,7 @@ describe('getSlots', () => { type Slots = { root: Slot<'button'> }; const invalidProp = { href: 'href' } as React.ButtonHTMLAttributes; expect( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSlots({ root: { as: 'button', id: 'id', ...invalidProp }, components: { root: 'button' } }), ).toEqual({ slots: { root: 'button' }, @@ -39,7 +39,7 @@ describe('getSlots', () => { it('returns root slot as an anchor, leaving the href intact', () => { type Slots = { root: Slot<'a'> }; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated expect(getSlots({ root: { as: 'a', id: 'id', href: 'href' }, components: { root: 'a' } })).toEqual({ slots: { root: 'a' }, slotProps: { root: { id: 'id', href: 'href' } }, @@ -52,7 +52,7 @@ describe('getSlots', () => { icon: Slot; }; expect( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSlots({ icon: {}, components: { root: 'div', icon: Foo }, @@ -70,7 +70,7 @@ describe('getSlots', () => { icon: Slot<'button'>; }; expect( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSlots({ components: { icon: 'button', root: 'div' }, root: { as: 'span' }, @@ -88,7 +88,7 @@ describe('getSlots', () => { icon: Slot<'a'>; }; expect( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSlots({ root: { as: 'div' }, components: { root: 'div', icon: 'a' }, @@ -106,7 +106,7 @@ describe('getSlots', () => { icon: Slot<'a'> | Slot; }; expect( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSlots({ components: { root: 'div', icon: Foo }, root: { as: 'div' }, @@ -124,7 +124,7 @@ describe('getSlots', () => { icon: Slot<'a'>; }; expect( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSlots({ components: { root: 'div', icon: Foo }, root: { as: 'div' }, @@ -143,12 +143,12 @@ describe('getSlots', () => { }; const renderFunction = (C: React.ElementType, p: {}) => ; expect( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSlots({ components: { root: 'div', icon: Foo }, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated root: resolveShorthand({ as: 'div' }, { required: true }), - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated icon: resolveShorthand({ id: 'bar', children: renderFunction }), }), ).toEqual({ @@ -164,7 +164,7 @@ describe('getSlots', () => { icon?: Slot<'a'>; }; expect( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSlots({ root: { as: 'div' }, components: { root: 'div', input: 'input', icon: 'a' }, diff --git a/packages/react-components/react-utilities/src/compose/deprecated/getSlots.ts b/packages/react-components/react-utilities/src/compose/deprecated/getSlots.ts index 0a3c64a7bd3349..c75947a2bc85b6 100644 --- a/packages/react-components/react-utilities/src/compose/deprecated/getSlots.ts +++ b/packages/react-components/react-utilities/src/compose/deprecated/getSlots.ts @@ -59,23 +59,23 @@ export type ObjectSlotProps = { export function getSlots( state: ComponentState, ): { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated slots: Slots; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated slotProps: ObjectSlotProps; } { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const slots = {} as Slots; const slotProps = {} as R; const slotNames: (keyof R)[] = Object.keys(state.components); for (const slotName of slotNames) { const [slot, props] = getSlot(state, slotName); - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated slots[slotName] = slot as Slots[typeof slotName]; slotProps[slotName] = props; } - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated return { slots, slotProps: slotProps as unknown as ObjectSlotProps }; } diff --git a/packages/react-components/react-utilities/src/compose/deprecated/getSlotsNext.test.tsx b/packages/react-components/react-utilities/src/compose/deprecated/getSlotsNext.test.tsx index 054a02b7a6d6bd..73fdf5ae2a7aeb 100644 --- a/packages/react-components/react-utilities/src/compose/deprecated/getSlotsNext.test.tsx +++ b/packages/react-components/react-utilities/src/compose/deprecated/getSlotsNext.test.tsx @@ -16,7 +16,7 @@ describe('getSlotsNext', () => { it('returns provided component type for root if the as prop is not provided', () => { type Slots = { root: Slot<'div'> }; expect( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSlotsNext({ root: resolveShorthandMock>({}), components: { root: 'div' }, @@ -30,7 +30,7 @@ describe('getSlotsNext', () => { it('returns root slot as a span with no props', () => { type Slots = { root: Slot<'div', 'span'> }; expect( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSlotsNext({ root: resolveShorthandMock>({ as: 'span' }), components: { root: 'div' }, @@ -45,7 +45,7 @@ describe('getSlotsNext', () => { type Slots = { root: Slot<'button'> }; const invalidProp = { href: 'href' } as React.ButtonHTMLAttributes; expect( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSlotsNext({ root: resolveShorthandMock>({ as: 'button', id: 'id', ...invalidProp }), components: { root: 'button' }, @@ -59,7 +59,7 @@ describe('getSlotsNext', () => { it('returns root slot as an anchor, leaving the href intact', () => { type Slots = { root: Slot<'a'> }; expect( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSlotsNext({ root: resolveShorthandMock>({ as: 'a', id: 'id', href: 'href' }), components: { root: 'a' }, @@ -76,7 +76,7 @@ describe('getSlotsNext', () => { icon: Slot; }; expect( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSlotsNext({ icon: resolveShorthandMock>({}), components: { root: 'div', icon: Foo }, @@ -97,7 +97,7 @@ describe('getSlotsNext', () => { icon: Slot<'button'>; }; expect( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSlotsNext({ components: { icon: 'button', root: 'div' }, root: resolveShorthandMock>({ as: 'span' }), @@ -118,7 +118,7 @@ describe('getSlotsNext', () => { icon: Slot<'a'>; }; expect( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSlotsNext({ root: resolveShorthandMock>({ as: 'div' }), components: { root: 'div', icon: 'a' }, @@ -143,7 +143,7 @@ describe('getSlotsNext', () => { icon: Slot<'a'> | Slot; }; expect( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSlotsNext({ components: { root: 'div', icon: Foo }, root: resolveShorthandMock>({ as: 'div' }), @@ -169,7 +169,7 @@ describe('getSlotsNext', () => { }; const renderIcon = (C: React.ElementType, p: {}) => ; expect( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSlotsNext({ components: { root: 'div', icon: Foo }, root: resolveShorthandMock>({ as: 'div' }), @@ -191,12 +191,12 @@ describe('getSlotsNext', () => { }; const renderFunction = (C: React.ElementType, p: {}) => ; expect( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSlotsNext({ components: { root: 'div', icon: Foo }, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated root: resolveShorthand>({ as: 'div' }, { required: true }), - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated icon: resolveShorthand>({ id: 'bar', children: renderFunction }), }), ).toEqual({ @@ -219,7 +219,7 @@ describe('getSlotsNext', () => { icon?: Slot<'a'>; }; expect( - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSlotsNext({ root: resolveShorthandMock>({ as: 'div' }), components: { root: 'div', input: 'input', icon: 'a' }, diff --git a/packages/react-components/react-utilities/src/compose/deprecated/getSlotsNext.ts b/packages/react-components/react-utilities/src/compose/deprecated/getSlotsNext.ts index 0bd1a54b951cd0..9889ea0654fdf7 100644 --- a/packages/react-components/react-utilities/src/compose/deprecated/getSlotsNext.ts +++ b/packages/react-components/react-utilities/src/compose/deprecated/getSlotsNext.ts @@ -15,24 +15,24 @@ import { ObjectSlotProps, Slots } from './getSlots'; export function getSlotsNext( state: ComponentState, ): { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated slots: Slots; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated slotProps: ObjectSlotProps; } { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const slots = {} as Slots; const slotProps = {} as R; const slotNames: (keyof R)[] = Object.keys(state.components); for (const slotName of slotNames) { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const [slot, props] = getSlotNext(state, slotName); - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated slots[slotName] = slot as Slots[typeof slotName]; slotProps[slotName] = props; } - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated return { slots, slotProps: slotProps as unknown as ObjectSlotProps }; } diff --git a/packages/react-components/react-utilities/src/compose/deprecated/resolveShorthand.test.tsx b/packages/react-components/react-utilities/src/compose/deprecated/resolveShorthand.test.tsx index 2def23a8ed38cf..ecb2332f10a71e 100644 --- a/packages/react-components/react-utilities/src/compose/deprecated/resolveShorthand.test.tsx +++ b/packages/react-components/react-utilities/src/compose/deprecated/resolveShorthand.test.tsx @@ -13,7 +13,7 @@ type TestProps = { describe('resolveShorthand', () => { it('resolves a string', () => { const props: TestProps = { slotA: 'hello' }; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const resolvedProps = resolveShorthand(props.slotA); expect(resolvedProps).toEqual({ @@ -23,7 +23,7 @@ describe('resolveShorthand', () => { it('resolves a JSX element', () => { const props: TestProps = { slotA:
hello
}; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const resolvedProps = resolveShorthand(props.slotA); expect(resolvedProps).toEqual({ @@ -33,7 +33,7 @@ describe('resolveShorthand', () => { it('resolves a number', () => { const props: TestProps = { slotA: 42 }; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const resolvedProps = resolveShorthand(props.slotA); expect(resolvedProps).toEqual({ @@ -44,7 +44,7 @@ describe('resolveShorthand', () => { it('resolves an object as its copy', () => { const slotA = {}; const props: TestProps = { slotA }; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const resolvedProps = resolveShorthand(props.slotA); expect(resolvedProps).toEqual({}); @@ -54,15 +54,15 @@ describe('resolveShorthand', () => { it('resolves "null" without creating a child element', () => { const props: TestProps = { slotA: null, slotB: null }; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated expect(resolveShorthand(props.slotA)).toEqual(undefined); - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated expect(resolveShorthand(null, { required: true })).toEqual(undefined); }); it('resolves undefined without creating a child element', () => { const props: TestProps = { slotA: undefined }; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const resolvedProps = resolveShorthand(props.slotA); expect(resolvedProps).toEqual(undefined); @@ -70,7 +70,7 @@ describe('resolveShorthand', () => { it('resolves to empty object creating a child element', () => { const props: TestProps = { slotA: undefined }; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated const resolvedProps = resolveShorthand(props.slotA, { required: true }); expect(resolvedProps).toEqual({}); diff --git a/packages/react-components/react-utilities/src/compose/deprecated/resolveShorthand.ts b/packages/react-components/react-utilities/src/compose/deprecated/resolveShorthand.ts index d6c5063ed58b61..5ba28a48fe71c7 100644 --- a/packages/react-components/react-utilities/src/compose/deprecated/resolveShorthand.ts +++ b/packages/react-components/react-utilities/src/compose/deprecated/resolveShorthand.ts @@ -12,9 +12,9 @@ export type ResolveShorthandOptions = R * @deprecated use slot.always or slot.optional combined with assertSlots instead */ export type ResolveShorthandFunction = { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated

(value: P | SlotShorthandValue | undefined, options: ResolveShorthandOptions): P; - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated

(value: P | SlotShorthandValue | null | undefined, options?: ResolveShorthandOptions): | P | undefined; @@ -29,7 +29,7 @@ export type ResolveShorthandFunction = (value, options) => slot.optional(value, { ...options, diff --git a/packages/react-components/react-utilities/src/compose/getIntrinsicElementProps.ts b/packages/react-components/react-utilities/src/compose/getIntrinsicElementProps.ts index 93fdc5ab0674e5..65de47f02e09c9 100644 --- a/packages/react-components/react-utilities/src/compose/getIntrinsicElementProps.ts +++ b/packages/react-components/react-utilities/src/compose/getIntrinsicElementProps.ts @@ -23,7 +23,7 @@ export const getIntrinsicElementProps = < /** List of native props to exclude from the returned value */ excludedPropNames?: ExcludedPropKeys[], ) => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated return getNativeElementProps< DistributiveOmit | ExcludedPropKeys> >(props.as ?? tagName, props, excludedPropNames); diff --git a/packages/react-components/react-utilities/src/compose/index.ts b/packages/react-components/react-utilities/src/compose/index.ts index 20252d1d3a38cf..fb6f26f68e14b7 100644 --- a/packages/react-components/react-utilities/src/compose/index.ts +++ b/packages/react-components/react-utilities/src/compose/index.ts @@ -26,15 +26,15 @@ export { isSlot } from './isSlot'; export { assertSlots } from './assertSlots'; export { getIntrinsicElementProps } from './getIntrinsicElementProps'; -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated export type { ObjectSlotProps, Slots } from './deprecated/getSlots'; -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated export { getSlots } from './deprecated/getSlots'; -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated export type { ResolveShorthandFunction, ResolveShorthandOptions } from './deprecated/resolveShorthand'; -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated export { resolveShorthand } from './deprecated/resolveShorthand'; -// eslint-disable-next-line deprecation/deprecation +// eslint-disable-next-line @typescript-eslint/no-deprecated export { getSlotsNext } from './deprecated/getSlotsNext'; export { slot }; diff --git a/packages/react-components/react-utilities/src/hooks/useOnClickOutside.ts b/packages/react-components/react-utilities/src/hooks/useOnClickOutside.ts index 1ae1f9b3e5f1bc..a5f410ec4f354d 100644 --- a/packages/react-components/react-utilities/src/hooks/useOnClickOutside.ts +++ b/packages/react-components/react-utilities/src/hooks/useOnClickOutside.ts @@ -121,11 +121,11 @@ export const useOnClickOutside = (options: UseOnClickOrScrollOutsideOptions) => const getWindowEvent = (target: Node | Window | null | undefined): Event | undefined => { if (target) { if (typeof (target as Window).window === 'object' && (target as Window).window === target) { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated return target.event; } - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated return (target as Node).ownerDocument?.defaultView?.event ?? undefined; } diff --git a/packages/react-components/react-utilities/src/index.ts b/packages/react-components/react-utilities/src/index.ts index 61a014c8ed2473..2377571564989e 100644 --- a/packages/react-components/react-utilities/src/index.ts +++ b/packages/react-components/react-utilities/src/index.ts @@ -1,12 +1,12 @@ export { slot, isSlot, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSlots, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getSlotsNext, assertSlots, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated resolveShorthand, isResolvedShorthand, getIntrinsicElementProps, @@ -18,12 +18,12 @@ export type { ComponentProps, ComponentState, ForwardRefComponent, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated ResolveShorthandFunction, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated ResolveShorthandOptions, Slot, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated Slots, SlotClassNames, SlotPropsRecord, @@ -60,7 +60,7 @@ export { canUseDOM, useIsSSR, SSRProvider } from './ssr/index'; export { clamp, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getNativeElementProps, getPartitionedNativeProps, getRTLSafeKey, diff --git a/packages/react-components/react-utilities/src/ssr/canUseDOM.ts b/packages/react-components/react-utilities/src/ssr/canUseDOM.ts index 867f967c05b549..84ce6190c2fc4c 100644 --- a/packages/react-components/react-utilities/src/ssr/canUseDOM.ts +++ b/packages/react-components/react-utilities/src/ssr/canUseDOM.ts @@ -7,7 +7,7 @@ export function canUseDOM(): boolean { typeof window !== 'undefined' && !!( window.document && - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated window.document.createElement ) /* eslint-enable @nx/workspace-no-restricted-globals */ diff --git a/packages/react-components/react-utilities/src/utils/getNativeElementProps.test.ts b/packages/react-components/react-utilities/src/utils/getNativeElementProps.test.ts index 7ba810c13f01b4..a30a5be6720e67 100644 --- a/packages/react-components/react-utilities/src/utils/getNativeElementProps.test.ts +++ b/packages/react-components/react-utilities/src/utils/getNativeElementProps.test.ts @@ -2,21 +2,21 @@ import { getNativeElementProps } from './getNativeElementProps'; describe('getNativeElementProps', () => { it('can filter native element properties', () => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated expect(getNativeElementProps('div', { id: '123', checked: true })).toEqual({ id: '123' }); - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated expect(getNativeElementProps('input', { id: '123', checked: true })).toEqual({ id: '123', checked: true }); - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated expect(getNativeElementProps('input', { id: '123', checked: true }, ['id'])).toEqual({ checked: true }); }); it('includes `as` as a native prop', () => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated expect(getNativeElementProps('div', { as: 'span' })).toEqual({ as: 'span' }); }); it('excludes props regardless of the allowed', () => { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated expect(getNativeElementProps('div', { as: 'span' }, ['as'])).toEqual({}); }); }); diff --git a/packages/react-components/react-utilities/src/utils/getNativeElementProps.ts b/packages/react-components/react-utilities/src/utils/getNativeElementProps.ts index c6205e6ed6a528..83960f3c0f7579 100644 --- a/packages/react-components/react-utilities/src/utils/getNativeElementProps.ts +++ b/packages/react-components/react-utilities/src/utils/getNativeElementProps.ts @@ -101,7 +101,7 @@ export const getPartitionedNativeProps = < }) => { return { root: { style: props.style, className: props.className }, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated primary: getNativeElementProps>(primarySlotTagName, props, [ ...(excludedPropNames || []), 'style', diff --git a/packages/react-components/react-utilities/src/utils/index.ts b/packages/react-components/react-utilities/src/utils/index.ts index 0f8340201b76ac..29a60eb017f136 100644 --- a/packages/react-components/react-utilities/src/utils/index.ts +++ b/packages/react-components/react-utilities/src/utils/index.ts @@ -1,6 +1,6 @@ export { clamp } from './clamp'; export { - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated getNativeElementProps, getPartitionedNativeProps, } from './getNativeElementProps'; diff --git a/packages/react-components/react-utilities/src/utils/properties.test.ts b/packages/react-components/react-utilities/src/utils/properties.test.ts index 8b7a6a0735dd0c..a2a25519905150 100644 --- a/packages/react-components/react-utilities/src/utils/properties.test.ts +++ b/packages/react-components/react-utilities/src/utils/properties.test.ts @@ -1,5 +1,5 @@ import * as React from 'react'; -import { getNativeProps, divProperties } from './properties'; +import { getNativeProps, divProperties, inputProperties } from './properties'; describe('getNativeProps', () => { it('can pass through data tags', () => { @@ -43,6 +43,32 @@ describe('getNativeProps', () => { expect(typeof result.onClickCapture).toEqual('function'); }); + it('can pass through input props', () => { + const result = getNativeProps>( + { + autoCapitalize: 'off', + autoCorrect: 'on', + maxLength: 10, + minLength: 1, + value: '123', + // Non-input property + foobar: 1, + }, + inputProperties, + ); + + expect(result).toMatchObject({ + autoCapitalize: 'off', + autoCorrect: 'on', + maxLength: 10, + minLength: 1, + value: '123', + }); + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + expect((result as any).foobar).toBeUndefined(); + }); + it('can remove unexpected properties', () => { const result = getNativeProps>( { diff --git a/packages/react-components/react-utilities/src/utils/properties.ts b/packages/react-components/react-utilities/src/utils/properties.ts index 2f434f8afc95b3..60867cd652f8cb 100644 --- a/packages/react-components/react-utilities/src/utils/properties.ts +++ b/packages/react-components/react-utilities/src/utils/properties.ts @@ -248,6 +248,7 @@ export const buttonProperties = toObjectMap(htmlElementProperties, [ export const inputProperties = toObjectMap(buttonProperties, [ 'accept', // input 'alt', // area, img, input + 'autoCorrect', // input, textarea 'autoCapitalize', // input, textarea 'autoComplete', // form, input 'checked', // input @@ -259,6 +260,7 @@ export const inputProperties = toObjectMap(buttonProperties, [ 'max', // input, meter 'maxLength', // input, textarea 'min', // input, meter + 'minLength', // input, textarea 'multiple', // input, select 'pattern', // input 'placeholder', // input, textarea diff --git a/packages/react-components/react-virtualizer/library/CHANGELOG.json b/packages/react-components/react-virtualizer/library/CHANGELOG.json index 0fa6a760919068..89f4e9240c00c5 100644 --- a/packages/react-components/react-virtualizer/library/CHANGELOG.json +++ b/packages/react-components/react-virtualizer/library/CHANGELOG.json @@ -1,6 +1,104 @@ { "name": "@fluentui/react-virtualizer", "entries": [ + { + "date": "Fri, 07 Feb 2025 10:42:12 GMT", + "tag": "@fluentui/react-virtualizer_v9.0.0-alpha.92", + "version": "9.0.0-alpha.92", + "comments": { + "prerelease": [ + { + "author": "mifraser@microsoft.com", + "package": "@fluentui/react-virtualizer", + "commit": "a17aac2acd61ee1e4cdd59c2637498cabd81cfe9", + "comment": "fix: Fix regression of child render function update" + } + ] + } + }, + { + "date": "Wed, 22 Jan 2025 14:00:13 GMT", + "tag": "@fluentui/react-virtualizer_v9.0.0-alpha.91", + "version": "9.0.0-alpha.91", + "comments": { + "none": [ + { + "author": "vgenaev@gmail.com", + "package": "@fluentui/react-virtualizer", + "commit": "fd420e1e0b66e04c8a423cff3eea6d21d9434d2d", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule" + }, + { + "author": "martinhochel@microsoft.com", + "package": "@fluentui/react-virtualizer", + "commit": "2f88d062a57e6dc44ecd65df2ab067652ae4c7ce", + "comment": "fix: make api.md up to date" + } + ], + "prerelease": [ + { + "author": "beachball", + "package": "@fluentui/react-virtualizer", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.50", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + }, + { + "author": "beachball", + "package": "@fluentui/react-virtualizer", + "comment": "Bump @fluentui/react-utilities to v9.18.20", + "commit": "5e95b13c1b6f513e6bdd9a4c688139748f912695" + } + ] + } + }, + { + "date": "Wed, 08 Jan 2025 18:33:36 GMT", + "tag": "@fluentui/react-virtualizer_v9.0.0-alpha.90", + "version": "9.0.0-alpha.90", + "comments": { + "prerelease": [ + { + "author": "beachball", + "package": "@fluentui/react-virtualizer", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.49", + "commit": "52572e1cdd452d32c67195bdc42f1114f58242bb" + } + ] + } + }, + { + "date": "Mon, 16 Dec 2024 16:26:46 GMT", + "tag": "@fluentui/react-virtualizer_v9.0.0-alpha.89", + "version": "9.0.0-alpha.89", + "comments": { + "prerelease": [ + { + "author": "olfedias@microsoft.com", + "package": "@fluentui/react-virtualizer", + "commit": "f15afa79910b9998044dddcce63e9583e4f8b905", + "comment": "chore: remove usage of \"export *\"" + }, + { + "author": "beachball", + "package": "@fluentui/react-virtualizer", + "comment": "Bump @fluentui/react-jsx-runtime to v9.0.48", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-virtualizer", + "comment": "Bump @fluentui/react-utilities to v9.18.19", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + }, + { + "author": "beachball", + "package": "@fluentui/react-virtualizer", + "comment": "Bump @fluentui/react-shared-contexts to v9.21.2", + "commit": "27a945ec646737e2132d05da293265335ee6d0ff" + } + ] + } + }, { "date": "Fri, 06 Dec 2024 12:53:45 GMT", "tag": "@fluentui/react-virtualizer_v9.0.0-alpha.88", diff --git a/packages/react-components/react-virtualizer/library/CHANGELOG.md b/packages/react-components/react-virtualizer/library/CHANGELOG.md index 87d3e37ea5822d..58c69413865284 100644 --- a/packages/react-components/react-virtualizer/library/CHANGELOG.md +++ b/packages/react-components/react-virtualizer/library/CHANGELOG.md @@ -1,9 +1,49 @@ # Change Log - @fluentui/react-virtualizer -This log was last generated on Fri, 06 Dec 2024 12:53:45 GMT and should not be manually modified. +This log was last generated on Fri, 07 Feb 2025 10:42:12 GMT and should not be manually modified. +## [9.0.0-alpha.92](https://github.com/microsoft/fluentui/tree/@fluentui/react-virtualizer_v9.0.0-alpha.92) + +Fri, 07 Feb 2025 10:42:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-virtualizer_v9.0.0-alpha.91..@fluentui/react-virtualizer_v9.0.0-alpha.92) + +### Changes + +- fix: Fix regression of child render function update ([PR #33788](https://github.com/microsoft/fluentui/pull/33788) by mifraser@microsoft.com) + +## [9.0.0-alpha.91](https://github.com/microsoft/fluentui/tree/@fluentui/react-virtualizer_v9.0.0-alpha.91) + +Wed, 22 Jan 2025 14:00:13 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-virtualizer_v9.0.0-alpha.90..@fluentui/react-virtualizer_v9.0.0-alpha.91) + +### Changes + +- Bump @fluentui/react-jsx-runtime to v9.0.50 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) +- Bump @fluentui/react-utilities to v9.18.20 ([PR #33631](https://github.com/microsoft/fluentui/pull/33631) by beachball) + +## [9.0.0-alpha.90](https://github.com/microsoft/fluentui/tree/@fluentui/react-virtualizer_v9.0.0-alpha.90) + +Wed, 08 Jan 2025 18:33:36 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-virtualizer_v9.0.0-alpha.89..@fluentui/react-virtualizer_v9.0.0-alpha.90) + +### Changes + +- Bump @fluentui/react-jsx-runtime to v9.0.49 ([PR #33550](https://github.com/microsoft/fluentui/pull/33550) by beachball) + +## [9.0.0-alpha.89](https://github.com/microsoft/fluentui/tree/@fluentui/react-virtualizer_v9.0.0-alpha.89) + +Mon, 16 Dec 2024 16:26:46 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-virtualizer_v9.0.0-alpha.88..@fluentui/react-virtualizer_v9.0.0-alpha.89) + +### Changes + +- chore: remove usage of "export *" ([PR #33457](https://github.com/microsoft/fluentui/pull/33457) by olfedias@microsoft.com) +- Bump @fluentui/react-jsx-runtime to v9.0.48 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-utilities to v9.18.19 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) +- Bump @fluentui/react-shared-contexts to v9.21.2 ([PR #33468](https://github.com/microsoft/fluentui/pull/33468) by beachball) + ## [9.0.0-alpha.88](https://github.com/microsoft/fluentui/tree/@fluentui/react-virtualizer_v9.0.0-alpha.88) Fri, 06 Dec 2024 12:53:45 GMT diff --git a/packages/react-components/react-virtualizer/library/etc/react-virtualizer.api.md b/packages/react-components/react-virtualizer/library/etc/react-virtualizer.api.md index 6b3c901b351b61..3bcd16bcd68144 100644 --- a/packages/react-components/react-virtualizer/library/etc/react-virtualizer.api.md +++ b/packages/react-components/react-virtualizer/library/etc/react-virtualizer.api.md @@ -6,10 +6,7 @@ import type { ComponentProps } from '@fluentui/react-utilities'; import type { ComponentState } from '@fluentui/react-utilities'; -import type { FC } from 'react'; -import type { MutableRefObject } from 'react'; import * as React_2 from 'react'; -import type { RefObject } from 'react'; import type { Slot } from '@fluentui/react-utilities'; import type { SlotClassNames } from '@fluentui/react-utilities'; @@ -132,7 +129,7 @@ export const useVirtualizerScrollViewStyles_unstable: (state: VirtualizerScrollV export const useVirtualizerStyles_unstable: (state: VirtualizerState) => VirtualizerState; // @public -export const Virtualizer: FC; +export const Virtualizer: React_2.FC; // @public export type VirtualizerChildRenderFunction = (index: number, isScrolling: boolean) => React_2.ReactNode; @@ -152,10 +149,10 @@ export const VirtualizerContextProvider: React_2.Provider; - nodeSizes: RefObject; + progressiveSizes: React_2.RefObject; + nodeSizes: React_2.RefObject; setFlaggedIndex: (index: number | null) => void; - currentIndex: RefObject; + currentIndex: React_2.RefObject; }; // @public (undocumented) diff --git a/packages/react-components/react-virtualizer/library/package.json b/packages/react-components/react-virtualizer/library/package.json index cf2ca2dd63e667..db3cfe4205a4eb 100644 --- a/packages/react-components/react-virtualizer/library/package.json +++ b/packages/react-components/react-virtualizer/library/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-virtualizer", - "version": "9.0.0-alpha.88", + "version": "9.0.0-alpha.92", "description": "Generic and composable virtualizer framework built on browser intersection observer", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -18,9 +18,9 @@ "@fluentui/scripts-api-extractor": "*" }, "dependencies": { - "@fluentui/react-jsx-runtime": "^9.0.47", - "@fluentui/react-utilities": "^9.18.18", - "@fluentui/react-shared-contexts": "^9.21.1", + "@fluentui/react-jsx-runtime": "^9.0.50", + "@fluentui/react-utilities": "^9.18.20", + "@fluentui/react-shared-contexts": "^9.21.2", "@griffel/react": "^1.5.22", "@swc/helpers": "^0.5.1" }, diff --git a/packages/react-components/react-virtualizer/library/src/Hooks.ts b/packages/react-components/react-virtualizer/library/src/Hooks.ts index 429b7dfe4e808e..66843929c72e8b 100644 --- a/packages/react-components/react-virtualizer/library/src/Hooks.ts +++ b/packages/react-components/react-virtualizer/library/src/Hooks.ts @@ -1 +1,17 @@ -export * from './hooks/index'; +export type { + IndexedResizeCallbackElement, + ResizeCallbackWithRef, + VirtualizerDynamicPaginationProps, + VirtualizerMeasureDynamicProps, + VirtualizerMeasureProps, + VirtualizerStaticPaginationProps, +} from './hooks/index'; +export { + createResizeObserverFromDocument, + getRTLRootMargin, + useDynamicVirtualizerMeasure, + useIntersectionObserver, + useMeasureList, + useResizeObserverRef_unstable, + useStaticVirtualizerMeasure, +} from './hooks/index'; diff --git a/packages/react-components/react-virtualizer/library/src/Utilities.ts b/packages/react-components/react-virtualizer/library/src/Utilities.ts index 91e9ad875428e2..869d0f30c543e5 100644 --- a/packages/react-components/react-virtualizer/library/src/Utilities.ts +++ b/packages/react-components/react-virtualizer/library/src/Utilities.ts @@ -1 +1,14 @@ -export * from './utilities/index'; +export type { + DynamicVirtualizerContextProps, + ScrollToInterface, + ScrollToItemDynamicParams, + ScrollToItemStaticParams, + VirtualizerContextProps, +} from './utilities/index'; +export { + VirtualizerContextProvider, + scrollToItemDynamic, + scrollToItemStatic, + useVirtualizerContextState_unstable, + useVirtualizerContext_unstable, +} from './utilities/index'; diff --git a/packages/react-components/react-virtualizer/library/src/Virtualizer.ts b/packages/react-components/react-virtualizer/library/src/Virtualizer.ts index 5e125d9783e425..88b1c91db8e71d 100644 --- a/packages/react-components/react-virtualizer/library/src/Virtualizer.ts +++ b/packages/react-components/react-virtualizer/library/src/Virtualizer.ts @@ -1 +1,17 @@ -export * from './components/Virtualizer/index'; +export type { + VirtualizerChildRenderFunction, + VirtualizerConfigProps, + VirtualizerConfigState, + VirtualizerDataRef, + VirtualizerProps, + VirtualizerSlots, + VirtualizerState, +} from './components/Virtualizer/index'; +export { + Virtualizer, + renderVirtualizerChildPlaceholder, + renderVirtualizer_unstable, + useVirtualizerStyles_unstable, + useVirtualizer_unstable, + virtualizerClassNames, +} from './components/Virtualizer/index'; diff --git a/packages/react-components/react-virtualizer/library/src/VirtualizerScrollView.ts b/packages/react-components/react-virtualizer/library/src/VirtualizerScrollView.ts index 20bfbaf6a9fcba..637c28ce8d450b 100644 --- a/packages/react-components/react-virtualizer/library/src/VirtualizerScrollView.ts +++ b/packages/react-components/react-virtualizer/library/src/VirtualizerScrollView.ts @@ -1 +1,12 @@ -export * from './components/VirtualizerScrollView/index'; +export type { + VirtualizerScrollViewProps, + VirtualizerScrollViewSlots, + VirtualizerScrollViewState, +} from './components/VirtualizerScrollView/index'; +export { + VirtualizerScrollView, + renderVirtualizerScrollView_unstable, + useVirtualizerScrollViewStyles_unstable, + useVirtualizerScrollView_unstable, + virtualizerScrollViewClassNames, +} from './components/VirtualizerScrollView/index'; diff --git a/packages/react-components/react-virtualizer/library/src/VirtualizerScrollViewDynamic.ts b/packages/react-components/react-virtualizer/library/src/VirtualizerScrollViewDynamic.ts index dd94f542e41270..2b72c0c097ca2f 100644 --- a/packages/react-components/react-virtualizer/library/src/VirtualizerScrollViewDynamic.ts +++ b/packages/react-components/react-virtualizer/library/src/VirtualizerScrollViewDynamic.ts @@ -1 +1,12 @@ -export * from './components/VirtualizerScrollViewDynamic/index'; +export type { + VirtualizerScrollViewDynamicProps, + VirtualizerScrollViewDynamicSlots, + VirtualizerScrollViewDynamicState, +} from './components/VirtualizerScrollViewDynamic/index'; +export { + VirtualizerScrollViewDynamic, + renderVirtualizerScrollViewDynamic_unstable, + useVirtualizerScrollViewDynamicStyles_unstable, + useVirtualizerScrollViewDynamic_unstable, + virtualizerScrollViewDynamicClassNames, +} from './components/VirtualizerScrollViewDynamic/index'; diff --git a/packages/react-components/react-virtualizer/library/src/components/Virtualizer/index.ts b/packages/react-components/react-virtualizer/library/src/components/Virtualizer/index.ts index bf32b1b6c55a5e..2c31666d3c8c85 100644 --- a/packages/react-components/react-virtualizer/library/src/components/Virtualizer/index.ts +++ b/packages/react-components/react-virtualizer/library/src/components/Virtualizer/index.ts @@ -1,5 +1,13 @@ -export * from './Virtualizer'; -export * from './Virtualizer.types'; -export * from './useVirtualizer'; -export * from './renderVirtualizer'; -export * from './useVirtualizerStyles.styles'; +export { Virtualizer } from './Virtualizer'; +export type { + VirtualizerChildRenderFunction, + VirtualizerConfigProps, + VirtualizerConfigState, + VirtualizerDataRef, + VirtualizerProps, + VirtualizerSlots, + VirtualizerState, +} from './Virtualizer.types'; +export { useVirtualizer_unstable } from './useVirtualizer'; +export { renderVirtualizerChildPlaceholder, renderVirtualizer_unstable } from './renderVirtualizer'; +export { useVirtualizerStyles_unstable, virtualizerClassNames } from './useVirtualizerStyles.styles'; diff --git a/packages/react-components/react-virtualizer/library/src/components/Virtualizer/useVirtualizer.ts b/packages/react-components/react-virtualizer/library/src/components/Virtualizer/useVirtualizer.ts index 94bcb9dc0b2782..893b1abde79ef3 100644 --- a/packages/react-components/react-virtualizer/library/src/components/Virtualizer/useVirtualizer.ts +++ b/packages/react-components/react-virtualizer/library/src/components/Virtualizer/useVirtualizer.ts @@ -104,6 +104,8 @@ export function useVirtualizer_unstable(props: VirtualizerProps): VirtualizerSta const initializeScrollingTimer = React.useCallback(() => { if (!enableScrollLoad) { // Disabled by default for reduction of render callbacks + setIsScrolling(false); + clearScrollTimer(); return; } /* @@ -514,7 +516,7 @@ export function useVirtualizer_unstable(props: VirtualizerProps): VirtualizerSta /* * forceUpdate: - * We only want to trigger this when scrollLoading is enabled and set to false, + * We only want to trigger this when child render or scroll loading changes, * it will force re-render all children elements */ const forceUpdate = React.useReducer(() => ({}), {})[1]; @@ -522,9 +524,7 @@ export function useVirtualizer_unstable(props: VirtualizerProps): VirtualizerSta React.useEffect(() => { if (actualIndex >= 0) { updateChildRows(actualIndex); - if (enableScrollLoad && !isScrolling) { - forceUpdate(); - } + forceUpdate(); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [renderChild, isScrolling]); diff --git a/packages/react-components/react-virtualizer/library/src/components/VirtualizerScrollView/index.ts b/packages/react-components/react-virtualizer/library/src/components/VirtualizerScrollView/index.ts index 393efae2e802e5..642f1db8f2afa2 100644 --- a/packages/react-components/react-virtualizer/library/src/components/VirtualizerScrollView/index.ts +++ b/packages/react-components/react-virtualizer/library/src/components/VirtualizerScrollView/index.ts @@ -1,5 +1,12 @@ -export * from './VirtualizerScrollView'; -export * from './VirtualizerScrollView.types'; -export * from './useVirtualizerScrollView'; -export * from './renderVirtualizerScrollView'; -export * from './useVirtualizerScrollViewStyles.styles'; +export { VirtualizerScrollView } from './VirtualizerScrollView'; +export type { + VirtualizerScrollViewProps, + VirtualizerScrollViewSlots, + VirtualizerScrollViewState, +} from './VirtualizerScrollView.types'; +export { useVirtualizerScrollView_unstable } from './useVirtualizerScrollView'; +export { renderVirtualizerScrollView_unstable } from './renderVirtualizerScrollView'; +export { + useVirtualizerScrollViewStyles_unstable, + virtualizerScrollViewClassNames, +} from './useVirtualizerScrollViewStyles.styles'; diff --git a/packages/react-components/react-virtualizer/library/src/components/VirtualizerScrollViewDynamic/index.ts b/packages/react-components/react-virtualizer/library/src/components/VirtualizerScrollViewDynamic/index.ts index bda6da51d22a8e..a34087eee8c3ca 100644 --- a/packages/react-components/react-virtualizer/library/src/components/VirtualizerScrollViewDynamic/index.ts +++ b/packages/react-components/react-virtualizer/library/src/components/VirtualizerScrollViewDynamic/index.ts @@ -1,5 +1,12 @@ -export * from './VirtualizerScrollViewDynamic'; -export * from './VirtualizerScrollViewDynamic.types'; -export * from './useVirtualizerScrollViewDynamic'; -export * from './renderVirtualizerScrollViewDynamic'; -export * from './useVirtualizerScrollViewDynamicStyles.styles'; +export { VirtualizerScrollViewDynamic } from './VirtualizerScrollViewDynamic'; +export type { + VirtualizerScrollViewDynamicProps, + VirtualizerScrollViewDynamicSlots, + VirtualizerScrollViewDynamicState, +} from './VirtualizerScrollViewDynamic.types'; +export { useVirtualizerScrollViewDynamic_unstable } from './useVirtualizerScrollViewDynamic'; +export { renderVirtualizerScrollViewDynamic_unstable } from './renderVirtualizerScrollViewDynamic'; +export { + useVirtualizerScrollViewDynamicStyles_unstable, + virtualizerScrollViewDynamicClassNames, +} from './useVirtualizerScrollViewDynamicStyles.styles'; diff --git a/packages/react-components/react-virtualizer/library/src/hooks/index.ts b/packages/react-components/react-virtualizer/library/src/hooks/index.ts index 1b64be17abdbb0..e81f652686c578 100644 --- a/packages/react-components/react-virtualizer/library/src/hooks/index.ts +++ b/packages/react-components/react-virtualizer/library/src/hooks/index.ts @@ -1,6 +1,13 @@ -export * from './useIntersectionObserver'; -export * from './useVirtualizerMeasure'; -export * from './useDynamicVirtualizerMeasure'; -export * from './useResizeObserverRef'; -export * from './hooks.types'; -export * from './useMeasureList'; +export { getRTLRootMargin, useIntersectionObserver } from './useIntersectionObserver'; +export { useStaticVirtualizerMeasure } from './useVirtualizerMeasure'; +export { useDynamicVirtualizerMeasure } from './useDynamicVirtualizerMeasure'; +export { useResizeObserverRef_unstable } from './useResizeObserverRef'; +export type { + ResizeCallbackWithRef, + VirtualizerDynamicPaginationProps, + VirtualizerMeasureDynamicProps, + VirtualizerMeasureProps, + VirtualizerStaticPaginationProps, +} from './hooks.types'; +export type { IndexedResizeCallbackElement } from './useMeasureList'; +export { createResizeObserverFromDocument, useMeasureList } from './useMeasureList'; diff --git a/packages/react-components/react-virtualizer/library/src/utilities/ImperativeScrolling/index.ts b/packages/react-components/react-virtualizer/library/src/utilities/ImperativeScrolling/index.ts index a9c61a1ea2e47b..67f161d8895ca8 100644 --- a/packages/react-components/react-virtualizer/library/src/utilities/ImperativeScrolling/index.ts +++ b/packages/react-components/react-virtualizer/library/src/utilities/ImperativeScrolling/index.ts @@ -1,3 +1,7 @@ -export * from './imperativeScrolling'; -export * from './imperativeScrolling.types'; -export * from './imperativeScrollingDynamic'; +export { scrollToItemStatic } from './imperativeScrolling'; +export type { + ScrollToInterface, + ScrollToItemDynamicParams, + ScrollToItemStaticParams, +} from './imperativeScrolling.types'; +export { scrollToItemDynamic } from './imperativeScrollingDynamic'; diff --git a/packages/react-components/react-virtualizer/library/src/utilities/VirtualizerContext/index.ts b/packages/react-components/react-virtualizer/library/src/utilities/VirtualizerContext/index.ts index 3eee78749512cc..ab9f63db3b44e8 100644 --- a/packages/react-components/react-virtualizer/library/src/utilities/VirtualizerContext/index.ts +++ b/packages/react-components/react-virtualizer/library/src/utilities/VirtualizerContext/index.ts @@ -1,2 +1,6 @@ -export * from './VirtualizerContext'; -export * from './types'; +export { + VirtualizerContextProvider, + useVirtualizerContextState_unstable, + useVirtualizerContext_unstable, +} from './VirtualizerContext'; +export type { DynamicVirtualizerContextProps, VirtualizerContextProps } from './types'; diff --git a/packages/react-components/react-virtualizer/library/src/utilities/index.ts b/packages/react-components/react-virtualizer/library/src/utilities/index.ts index 7d8ab179c12bcf..26a8df742ea854 100644 --- a/packages/react-components/react-virtualizer/library/src/utilities/index.ts +++ b/packages/react-components/react-virtualizer/library/src/utilities/index.ts @@ -1,2 +1,8 @@ -export * from './VirtualizerContext'; -export * from './ImperativeScrolling'; +export type { DynamicVirtualizerContextProps, VirtualizerContextProps } from './VirtualizerContext'; +export { + VirtualizerContextProvider, + useVirtualizerContextState_unstable, + useVirtualizerContext_unstable, +} from './VirtualizerContext'; +export type { ScrollToInterface, ScrollToItemDynamicParams, ScrollToItemStaticParams } from './ImperativeScrolling'; +export { scrollToItemDynamic, scrollToItemStatic } from './ImperativeScrolling'; diff --git a/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollView/Default.stories.tsx b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollView/Default.stories.tsx index b3253bb6930ee9..cd501df2b69156 100644 --- a/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollView/Default.stories.tsx +++ b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollView/Default.stories.tsx @@ -18,7 +18,12 @@ export const Default = () => { {(index: number) => { return ( diff --git a/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollView/ScrollTo.stories.tsx b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollView/ScrollTo.stories.tsx index bc5bcd0bcf1837..d9a9a58cb8f1b6 100644 --- a/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollView/ScrollTo.stories.tsx +++ b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollView/ScrollTo.stories.tsx @@ -42,7 +42,12 @@ export const ScrollTo = () => { {(index: number) => { diff --git a/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollView/SnapToAlignment.stories.tsx b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollView/SnapToAlignment.stories.tsx index cb1621b11c55b7..40ef03e4dab4ee 100644 --- a/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollView/SnapToAlignment.stories.tsx +++ b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollView/SnapToAlignment.stories.tsx @@ -24,7 +24,12 @@ export const SnapToAlignment = () => { numItems={childLength} itemSize={100} axis={'horizontal'} - container={{ role: 'list', className: styles.container }} + container={{ + role: 'list', + 'aria-label': `Virtualized list with ${childLength} children`, + tabIndex: 0, + className: styles.container, + }} enablePagination > {(index: number) => { diff --git a/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollView/VirtualizerScrollViewAccessibility.md b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollView/VirtualizerScrollViewAccessibility.md new file mode 100644 index 00000000000000..c6ac70514fc04a --- /dev/null +++ b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollView/VirtualizerScrollViewAccessibility.md @@ -0,0 +1,3 @@ +## Accessibility + +When the ScrollView has no focusable children, the container itself should be given `tabIndex: 0` so that it can be scrolled with the keyboard. If it does contain focusable descendants, this is not necessary. diff --git a/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollView/index.stories.ts b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollView/index.stories.ts index 9114b2abdc3538..0110a824b0ee40 100644 --- a/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollView/index.stories.ts +++ b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollView/index.stories.ts @@ -1,5 +1,6 @@ import { VirtualizerScrollView } from '@fluentui/react-virtualizer'; import descriptionMd from './VirtualizerScrollViewDescription.md'; +import accessibilityMd from './VirtualizerScrollViewAccessibility.md'; export { Default } from './Default.stories'; export { ScrollTo } from './ScrollTo.stories'; @@ -11,7 +12,7 @@ export default { parameters: { docs: { description: { - component: [descriptionMd].join('\n'), + component: [descriptionMd, accessibilityMd].join('\n'), }, }, }, diff --git a/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/AutoMeasure.stories.tsx b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/AutoMeasure.stories.tsx index a8e6587a149f12..74d1144e1a7052 100644 --- a/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/AutoMeasure.stories.tsx +++ b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/AutoMeasure.stories.tsx @@ -37,7 +37,12 @@ export const AutoMeasure = () => { numItems={childLength} // We can use itemSize to set average height and reduce unknown whitespace itemSize={minHeight + maxHeightIncrease / 2.0 + 100} - container={{ role: 'list', style: { maxHeight: '80vh', gap: '20px' } }} + container={{ + role: 'list', + 'aria-label': `Virtualized list with ${childLength} children`, + tabIndex: 0, + style: { maxHeight: '80vh', gap: '20px' }, + }} bufferItems={1} bufferSize={minHeight / 2.0} gap={20} diff --git a/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/Default.stories.tsx b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/Default.stories.tsx index c5f241979527fd..ecd85ebe39d1cb 100644 --- a/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/Default.stories.tsx +++ b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/Default.stories.tsx @@ -42,7 +42,12 @@ export const Default = () => { numItems={childLength} itemSize={minHeight + maxHeightMod / 2.0} getItemSize={getItemSizeCallback} - container={{ role: 'list', style: { maxHeight: '80vh' } }} + container={{ + role: 'list', + 'aria-label': `Virtualized list with ${childLength} children`, + tabIndex: 0, + style: { maxHeight: '80vh' }, + }} bufferItems={1} bufferSize={minHeight / 2.0} > diff --git a/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/ScrollLoading.stories.tsx b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/ScrollLoading.stories.tsx index 423c9b3a4e8003..5a3d38ff980bbe 100644 --- a/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/ScrollLoading.stories.tsx +++ b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/ScrollLoading.stories.tsx @@ -41,7 +41,12 @@ export const ScrollLoading = () => { numItems={childLength} itemSize={minHeight} getItemSize={getItemSizeCallback} - container={{ role: 'list', style: { maxHeight: '80vh' } }} + container={{ + role: 'list', + 'aria-label': `Virtualized list with ${childLength} children`, + tabIndex: 0, + style: { maxHeight: '80vh' }, + }} enableScrollLoad={true} > {(index: number, isScrolling = false) => { diff --git a/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/ScrollTo.stories.tsx b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/ScrollTo.stories.tsx index 94904d936c80d2..3d903cf42b9e42 100644 --- a/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/ScrollTo.stories.tsx +++ b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/ScrollTo.stories.tsx @@ -62,14 +62,19 @@ export const ScrollTo = () => {

- {message} + {message} {(index: number) => { const backgroundColor = index % 2 ? '#FFFFFF' : '#ABABAB'; diff --git a/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/SnapToAlignment.stories.tsx b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/SnapToAlignment.stories.tsx index ab593c20e09b2a..cf64b832489c5b 100644 --- a/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/SnapToAlignment.stories.tsx +++ b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/SnapToAlignment.stories.tsx @@ -32,7 +32,12 @@ export const SnapToAlignment = () => { numItems={childLength} // We can use itemSize to set an average height for minimal size change impact itemSize={minHeight + maxHeightIncrease / 2} - container={{ role: 'list', style: { maxHeight: '80vh' } }} + container={{ + role: 'list', + 'aria-label': `Virtualized list with ${childLength} children`, + tabIndex: 0, + style: { maxHeight: '80vh' }, + }} enablePagination > {(index: number) => { diff --git a/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/VirtualizerScrollViewDynamicAccessibility.md b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/VirtualizerScrollViewDynamicAccessibility.md new file mode 100644 index 00000000000000..c6ac70514fc04a --- /dev/null +++ b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/VirtualizerScrollViewDynamicAccessibility.md @@ -0,0 +1,3 @@ +## Accessibility + +When the ScrollView has no focusable children, the container itself should be given `tabIndex: 0` so that it can be scrolled with the keyboard. If it does contain focusable descendants, this is not necessary. diff --git a/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/index.stories.ts b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/index.stories.ts index 9dee7b7a992166..7d9d6866dcdddf 100644 --- a/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/index.stories.ts +++ b/packages/react-components/react-virtualizer/stories/src/VirtualizerScrollViewDynamic/index.stories.ts @@ -1,5 +1,6 @@ import { VirtualizerScrollViewDynamic } from '@fluentui/react-virtualizer'; import descriptionMd from './VirtualizerScrollViewDynamicDescription.md'; +import accessibilityMd from './VirtualizerScrollViewDynamicAccessibility.md'; export { AutoMeasure } from './AutoMeasure.stories'; export { Default } from './Default.stories'; @@ -13,7 +14,7 @@ export default { parameters: { docs: { description: { - component: [descriptionMd].join('\n'), + component: [descriptionMd, accessibilityMd].join('\n'), }, }, }, diff --git a/packages/react-components/recipes/package.json b/packages/react-components/recipes/package.json index c3295ea3a408f0..b507556339793c 100644 --- a/packages/react-components/recipes/package.json +++ b/packages/react-components/recipes/package.json @@ -27,10 +27,10 @@ "@fluentui/react-storybook-addon-export-to-sandbox": "*" }, "dependencies": { - "@fluentui/react-provider": "^9.18.1", - "@fluentui/react-theme": "^9.1.23", - "@fluentui/react-text": "^9.4.28", - "@fluentui/react-utilities": "^9.18.18", + "@fluentui/react-provider": "^9.20.0", + "@fluentui/react-theme": "^9.1.24", + "@fluentui/react-text": "^9.4.32", + "@fluentui/react-utilities": "^9.18.20", "@griffel/react": "^1.5.22", "@swc/helpers": "^0.5.1", "@fluentui/react-icons": "^2.0.245" diff --git a/packages/react-components/recipes/src/recipes/media-object/code-snippets/index.ts b/packages/react-components/recipes/src/recipes/media-object/code-snippets/index.ts index d1f240176219dd..5e3a5756159f33 100644 --- a/packages/react-components/recipes/src/recipes/media-object/code-snippets/index.ts +++ b/packages/react-components/recipes/src/recipes/media-object/code-snippets/index.ts @@ -1 +1 @@ -export * from './MediaObject'; +export { FlexSkeleton, IconMediaObject, TextAlignmentVariations, TextPositionVariations } from './MediaObject'; diff --git a/packages/react-components/recipes/src/templates/index.ts b/packages/react-components/recipes/src/templates/index.ts index 99e30127539411..8d169639b20fe9 100644 --- a/packages/react-components/recipes/src/templates/index.ts +++ b/packages/react-components/recipes/src/templates/index.ts @@ -1 +1 @@ -export * from './Example'; +export { TemplateExample } from './Example'; diff --git a/packages/react-components/theme-designer/package.json b/packages/react-components/theme-designer/package.json index 334162b0144b5b..e737e7bb85f545 100644 --- a/packages/react-components/theme-designer/package.json +++ b/packages/react-components/theme-designer/package.json @@ -17,12 +17,12 @@ "@fluentui/scripts-api-extractor": "*" }, "dependencies": { - "@fluentui/react-components": "^9.56.4", - "@fluentui/react-context-selector": "^9.1.70", + "@fluentui/react-components": "^9.60.0", + "@fluentui/react-context-selector": "^9.1.72", "@fluentui/react-icons": "^2.0.245", "@fluentui/react-storybook-addon-export-to-sandbox": "^0.1.0", - "@fluentui/react-theme": "^9.1.23", - "@fluentui/react-utilities": "^9.18.18", + "@fluentui/react-theme": "^9.1.24", + "@fluentui/react-utilities": "^9.18.20", "@griffel/react": "^1.5.22", "@swc/helpers": "^0.5.1", "dedent": "^1.2.0", diff --git a/packages/react-components/theme-designer/src/colors/index.ts b/packages/react-components/theme-designer/src/colors/index.ts index 7cecca373ae30c..eb71c535281b84 100644 --- a/packages/react-components/theme-designer/src/colors/index.ts +++ b/packages/react-components/theme-designer/src/colors/index.ts @@ -1,5 +1,74 @@ -export * from './csswg'; -export * from './geometry'; -export * from './palettes'; -export * from './templates'; -export * from './types'; +export { + D50_to_D65, + D65_to_D50, + LAB_to_sRGB, + LCH_to_Lab, + LCH_to_P3, + LCH_to_r2020, + LCH_to_sRGB, + Lab_to_LCH, + Lab_to_XYZ, + P3_to_LCH, + XYZ_to_Lab, + XYZ_to_lin_2020, + XYZ_to_lin_P3, + XYZ_to_lin_ProPhoto, + XYZ_to_lin_a98rgb, + XYZ_to_lin_sRGB, + XYZ_to_uv, + XYZ_to_xy, + contrast, + gam_2020, + gam_P3, + gam_ProPhoto, + gam_a98rgb, + gam_sRGB, + hslToRgb, + hueToChannel, + lin_2020, + lin_2020_to_XYZ, + lin_P3, + lin_P3_to_XYZ, + lin_ProPhoto, + lin_ProPhoto_to_XYZ, + lin_a98rgb, + lin_a98rgb_to_XYZ, + lin_sRGB, + lin_sRGB_to_XYZ, + naive_CMYK_to_sRGB, + naive_sRGB_to_CMYK, + r2020_to_LCH, + rgbToHsv, + sRGB_to_LAB, + sRGB_to_LCH, + sRGB_to_luminance, + snap_into_gamut, + xy_to_uv, +} from './csswg'; +export { getPointOnCurvePath, getPointsOnCurvePath } from './geometry'; +export { + Lab_to_hex, + curvePathFromPalette, + hexColorsFromPalette, + hex_to_LCH, + hex_to_sRGB, + paletteShadesFromCurve, + sRGB_to_hex, +} from './palettes'; +export { paletteTemplate, themeTemplate } from './templates'; +export type { + Curve, + CurvePath, + CurvedHelixPath, + NamedPalette, + NamedTheme, + Palette, + PaletteConfig, + Theme, + ThemeCollectionInclude, + TokenPackageConfig, + TokenPackageType, + Vec2, + Vec3, + Vec4, +} from './types'; diff --git a/packages/react-components/theme-designer/src/components/Sidebar/Form.tsx b/packages/react-components/theme-designer/src/components/Sidebar/Form.tsx index 1f85ac0a4d84ad..b6a71e81e27325 100644 --- a/packages/react-components/theme-designer/src/components/Sidebar/Form.tsx +++ b/packages/react-components/theme-designer/src/components/Sidebar/Form.tsx @@ -118,8 +118,10 @@ export const Form: React.FC = () => { }); }, [dispatch, debounceKeyColor, debounceHueTorsion, debounceVibrancy]); - const generateHexColor = (e: React.ChangeEvent) => - '#' + e.target.value.replace(/\W/g, '').toUpperCase(); + const generateHexColor = (e: React.ChangeEvent): string => { + return '#' + e.target.value.replace(/[^0-9A-F]/gi, '').toUpperCase(); + }; + const handleKeyColorChange = (e: React.ChangeEvent) => { // check if the newly inputted hex code has a # const newHexColor = generateHexColor(e); diff --git a/packages/react-conformance/CHANGELOG.json b/packages/react-conformance/CHANGELOG.json index 963ea3f628894e..0ef7a01eab3896 100644 --- a/packages/react-conformance/CHANGELOG.json +++ b/packages/react-conformance/CHANGELOG.json @@ -1,6 +1,36 @@ { "name": "@fluentui/react-conformance", "entries": [ + { + "date": "Wed, 22 Jan 2025 14:00:17 GMT", + "tag": "@fluentui/react-conformance_v0.19.3", + "version": "0.19.3", + "comments": { + "none": [ + { + "author": "vgenaev@gmail.com", + "package": "@fluentui/react-conformance", + "commit": "fd420e1e0b66e04c8a423cff3eea6d21d9434d2d", + "comment": "chore: migrate from deprecation plugin to ts-eslint/no-deprecated rule" + } + ] + } + }, + { + "date": "Wed, 08 Jan 2025 18:33:33 GMT", + "tag": "@fluentui/react-conformance_v0.19.3", + "version": "0.19.3", + "comments": { + "patch": [ + { + "author": "olfedias@microsoft.com", + "package": "@fluentui/react-conformance", + "commit": "dc7bb663e3d93a19b611cf1892556d69c57b1269", + "comment": "chore: remove usage of \"export *\"" + } + ] + } + }, { "date": "Mon, 11 Nov 2024 10:01:11 GMT", "tag": "@fluentui/react-conformance_v0.19.2", diff --git a/packages/react-conformance/CHANGELOG.md b/packages/react-conformance/CHANGELOG.md index 6206fdbd4279cf..0f022441351a42 100644 --- a/packages/react-conformance/CHANGELOG.md +++ b/packages/react-conformance/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/react-conformance -This log was last generated on Mon, 11 Nov 2024 10:01:11 GMT and should not be manually modified. +This log was last generated on Wed, 08 Jan 2025 18:33:33 GMT and should not be manually modified. +## [0.19.3](https://github.com/microsoft/fluentui/tree/@fluentui/react-conformance_v0.19.3) + +Wed, 08 Jan 2025 18:33:33 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-conformance_v0.19.2..@fluentui/react-conformance_v0.19.3) + +### Patches + +- chore: remove usage of "export *" ([PR #33448](https://github.com/microsoft/fluentui/pull/33448) by olfedias@microsoft.com) + ## [0.19.2](https://github.com/microsoft/fluentui/tree/@fluentui/react-conformance_v0.19.2) Mon, 11 Nov 2024 10:01:11 GMT diff --git a/packages/react-conformance/package.json b/packages/react-conformance/package.json index b04b94218ddf49..9ba2de77051081 100644 --- a/packages/react-conformance/package.json +++ b/packages/react-conformance/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-conformance", - "version": "0.19.2", + "version": "0.19.3", "description": "Customizable conformance testing utility for Fluent UI React components.", "main": "lib-commonjs/index.js", "typings": "./dist/index.d.ts", diff --git a/packages/react-conformance/src/isConformant.ts b/packages/react-conformance/src/isConformant.ts index ae8754414c1435..b7c27558ed3a8b 100644 --- a/packages/react-conformance/src/isConformant.ts +++ b/packages/react-conformance/src/isConformant.ts @@ -15,7 +15,7 @@ export function isConformant(...testInfo: Partial +## [8.7.200](https://github.com/microsoft/fluentui/tree/@fluentui/react-date-time_v8.7.200) + +Fri, 21 Feb 2025 07:22:41 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-date-time_v8.7.199..@fluentui/react-date-time_v8.7.200) + +### Patches + +- Bump @fluentui/react to v8.122.11 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/set-version to v8.2.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) + +## [8.7.199](https://github.com/microsoft/fluentui/tree/@fluentui/react-date-time_v8.7.199) + +Wed, 19 Feb 2025 07:21:16 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-date-time_v8.7.198..@fluentui/react-date-time_v8.7.199) + +### Patches + +- Bump @fluentui/react to v8.122.10 ([PR #33867](https://github.com/microsoft/fluentui/pull/33867) by beachball) + +## [8.7.198](https://github.com/microsoft/fluentui/tree/@fluentui/react-date-time_v8.7.198) + +Wed, 29 Jan 2025 07:21:15 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-date-time_v8.7.197..@fluentui/react-date-time_v8.7.198) + +### Patches + +- Bump @fluentui/react to v8.122.9 ([PR #33713](https://github.com/microsoft/fluentui/pull/33713) by beachball) + +## [8.7.197](https://github.com/microsoft/fluentui/tree/@fluentui/react-date-time_v8.7.197) + +Wed, 22 Jan 2025 07:21:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-date-time_v8.7.196..@fluentui/react-date-time_v8.7.197) + +### Patches + +- Bump @fluentui/react to v8.122.8 ([PR #33685](https://github.com/microsoft/fluentui/pull/33685) by beachball) + +## [8.7.196](https://github.com/microsoft/fluentui/tree/@fluentui/react-date-time_v8.7.196) + +Fri, 17 Jan 2025 07:21:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-date-time_v8.7.195..@fluentui/react-date-time_v8.7.196) + +### Patches + +- Bump @fluentui/react to v8.122.7 ([commit](https://github.com/microsoft/fluentui/commit/baf887d95f91874c814a7cae749c20e797f828be) by beachball) + +## [8.7.195](https://github.com/microsoft/fluentui/tree/@fluentui/react-date-time_v8.7.195) + +Mon, 13 Jan 2025 07:21:23 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-date-time_v8.7.194..@fluentui/react-date-time_v8.7.195) + +### Patches + +- Bump @fluentui/react to v8.122.6 ([PR #33148](https://github.com/microsoft/fluentui/pull/33148) by beachball) + +## [8.7.194](https://github.com/microsoft/fluentui/tree/@fluentui/react-date-time_v8.7.194) + +Wed, 08 Jan 2025 07:21:37 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-date-time_v8.7.193..@fluentui/react-date-time_v8.7.194) + +### Patches + +- Bump @fluentui/react to v8.122.5 ([PR #33578](https://github.com/microsoft/fluentui/pull/33578) by beachball) + +## [8.7.193](https://github.com/microsoft/fluentui/tree/@fluentui/react-date-time_v8.7.193) + +Fri, 03 Jan 2025 07:21:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-date-time_v8.7.192..@fluentui/react-date-time_v8.7.193) + +### Patches + +- Bump @fluentui/react to v8.122.4 ([PR #33529](https://github.com/microsoft/fluentui/pull/33529) by beachball) + +## [8.7.192](https://github.com/microsoft/fluentui/tree/@fluentui/react-date-time_v8.7.192) + +Mon, 30 Dec 2024 07:21:29 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-date-time_v8.7.191..@fluentui/react-date-time_v8.7.192) + +### Patches + +- Bump @fluentui/react to v8.122.3 ([PR #33520](https://github.com/microsoft/fluentui/pull/33520) by beachball) + +## [8.7.191](https://github.com/microsoft/fluentui/tree/@fluentui/react-date-time_v8.7.191) + +Mon, 23 Dec 2024 07:22:58 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-date-time_v8.7.190..@fluentui/react-date-time_v8.7.191) + +### Patches + +- Bump @fluentui/react to v8.122.2 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) + +## [8.7.190](https://github.com/microsoft/fluentui/tree/@fluentui/react-date-time_v8.7.190) + +Fri, 13 Dec 2024 07:23:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-date-time_v8.7.189..@fluentui/react-date-time_v8.7.190) + +### Patches + +- Bump @fluentui/react to v8.122.1 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) + +## [8.7.189](https://github.com/microsoft/fluentui/tree/@fluentui/react-date-time_v8.7.189) + +Thu, 12 Dec 2024 07:22:33 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-date-time_v8.7.188..@fluentui/react-date-time_v8.7.189) + +### Patches + +- Bump @fluentui/react to v8.122.0 ([PR #33243](https://github.com/microsoft/fluentui/pull/33243) by beachball) + ## [8.7.188](https://github.com/microsoft/fluentui/tree/@fluentui/react-date-time_v8.7.188) Fri, 22 Nov 2024 07:21:18 GMT diff --git a/packages/react-date-time/package.json b/packages/react-date-time/package.json index 7cfa0d0400b876..ab7d7e0fc9d2ed 100644 --- a/packages/react-date-time/package.json +++ b/packages/react-date-time/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-date-time", - "version": "8.7.188", + "version": "8.7.200", "description": "Date and time related React components for building experiences for Microsoft 365.", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -27,8 +27,8 @@ "@fluentui/scripts-webpack": "*" }, "dependencies": { - "@fluentui/react": "^8.121.13", - "@fluentui/set-version": "^8.2.23", + "@fluentui/react": "^8.122.11", + "@fluentui/set-version": "^8.2.24", "tslib": "^2.1.0" }, "peerDependencies": { diff --git a/packages/react-date-time/src/Calendar.ts b/packages/react-date-time/src/Calendar.ts index c324c90de538b5..ab257cb0200442 100644 --- a/packages/react-date-time/src/Calendar.ts +++ b/packages/react-date-time/src/Calendar.ts @@ -6,7 +6,7 @@ export { FirstWeekOfYear, defaultCalendarNavigationIcons, defaultCalendarStrings, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated defaultDayPickerStrings, } from '@fluentui/react/lib/Calendar'; export type { @@ -19,9 +19,9 @@ export type { ICalendarDayProps, ICalendarDayStyleProps, ICalendarDayStyles, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated ICalendarFormatDateCallbacks, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated ICalendarIconStrings, ICalendarMonth, ICalendarMonthProps, diff --git a/packages/react-date-time/src/DatePicker.ts b/packages/react-date-time/src/DatePicker.ts index 6fe5758c453b6e..0788eb347df958 100644 --- a/packages/react-date-time/src/DatePicker.ts +++ b/packages/react-date-time/src/DatePicker.ts @@ -6,9 +6,9 @@ export { } from '@fluentui/react/lib/DatePicker'; export type { ICalendar, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated ICalendarFormatDateCallbacks, - // eslint-disable-next-line deprecation/deprecation + // eslint-disable-next-line @typescript-eslint/no-deprecated ICalendarIconStrings, ICalendarNavigationIcons, ICalendarProps, diff --git a/packages/react-docsite-components/.eslintrc.json b/packages/react-docsite-components/.eslintrc.json index ec2a316fd41b8f..99f51edd9d841a 100644 --- a/packages/react-docsite-components/.eslintrc.json +++ b/packages/react-docsite-components/.eslintrc.json @@ -2,7 +2,15 @@ "extends": ["plugin:@fluentui/eslint-plugin/react--legacy"], "root": true, "rules": { - "deprecation/deprecation": "off", "no-restricted-globals": "off" - } + }, + "overrides": [ + { + "files": "**/*.{ts,tsx}", + "rules": { + // The components in this package are all deprecated + "@typescript-eslint/no-deprecated": "off" + } + } + ] } diff --git a/packages/react-docsite-components/CHANGELOG.json b/packages/react-docsite-components/CHANGELOG.json index cbb31594ebbbf5..2ecd3132ca4ed6 100644 --- a/packages/react-docsite-components/CHANGELOG.json +++ b/packages/react-docsite-components/CHANGELOG.json @@ -1,6 +1,627 @@ { "name": "@fluentui/react-docsite-components", "entries": [ + { + "date": "Fri, 21 Feb 2025 07:22:41 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.176", + "version": "8.13.176", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react to v8.122.11", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/theme to v2.6.65", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-hooks to v8.8.17", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/set-version to v8.2.24", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.294", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + } + ] + } + }, + { + "date": "Wed, 19 Feb 2025 07:21:16 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.175", + "version": "8.13.175", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react to v8.122.10", + "commit": "8264ce0435583ae69c051f109388005be3c0de2b" + }, + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.293", + "commit": "8264ce0435583ae69c051f109388005be3c0de2b" + } + ] + } + }, + { + "date": "Thu, 13 Feb 2025 07:22:18 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.174", + "version": "8.13.174", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.292", + "commit": "da21d6906904f1c56d4f71f720a18e8cbc45841b" + } + ] + } + }, + { + "date": "Wed, 12 Feb 2025 07:20:52 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.173", + "version": "8.13.173", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.291", + "commit": "90aca06e2500c9dda895c2a220923baf2a602297" + } + ] + } + }, + { + "date": "Tue, 11 Feb 2025 07:21:12 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.172", + "version": "8.13.172", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.290", + "commit": "f45bd1071de1e3a8aa9c7177438e2559498b7920" + } + ] + } + }, + { + "date": "Wed, 05 Feb 2025 07:16:29 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.171", + "version": "8.13.171", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.289", + "commit": "5f1fb069b5da9c7a104063184eacce1927c06f7c" + } + ] + } + }, + { + "date": "Fri, 31 Jan 2025 07:21:30 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.170", + "version": "8.13.170", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.288", + "commit": "171c1b1bda0d403270e828fbad3d8c7b791e21af" + } + ] + } + }, + { + "date": "Thu, 30 Jan 2025 07:20:49 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.169", + "version": "8.13.169", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.287", + "commit": "fa5549e7d9da4865ac079c8c7b284106813a7e82" + } + ] + } + }, + { + "date": "Wed, 29 Jan 2025 07:21:15 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.168", + "version": "8.13.168", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react to v8.122.9", + "commit": "111bf937b3793db68e32a90774b04f3bf61f4be5" + }, + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.286", + "commit": "111bf937b3793db68e32a90774b04f3bf61f4be5" + } + ] + } + }, + { + "date": "Mon, 27 Jan 2025 07:20:35 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.167", + "version": "8.13.167", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.285", + "commit": "87d6ba3bd577a8be9756f4d392b048083d8ef16a" + } + ] + } + }, + { + "date": "Fri, 24 Jan 2025 07:20:37 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.166", + "version": "8.13.166", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.284", + "commit": "cb0f0c9653a8a5c53012d35d81498de263a8f3cf" + } + ] + } + }, + { + "date": "Thu, 23 Jan 2025 07:21:32 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.165", + "version": "8.13.165", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.283", + "commit": "af631b94cfaa3e9a9d79160236a7f0679240777b" + } + ] + } + }, + { + "date": "Wed, 22 Jan 2025 07:21:49 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.164", + "version": "8.13.164", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react to v8.122.8", + "commit": "012298d98651800023aac24c591831e9bc51bea2" + }, + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.282", + "commit": "012298d98651800023aac24c591831e9bc51bea2" + } + ] + } + }, + { + "date": "Tue, 21 Jan 2025 07:13:51 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.163", + "version": "8.13.163", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.281", + "commit": "08575f8e7d2362e9b986bccee516546f88fe562a" + } + ] + } + }, + { + "date": "Mon, 20 Jan 2025 07:21:47 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.162", + "version": "8.13.162", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.280", + "commit": "556fc8e7b9a921cedbb07c2f0670dfabcf8ec0ed" + } + ] + } + }, + { + "date": "Fri, 17 Jan 2025 07:21:32 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.161", + "version": "8.13.161", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react to v8.122.7", + "commit": "baf887d95f91874c814a7cae749c20e797f828be" + }, + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.279", + "commit": "baf887d95f91874c814a7cae749c20e797f828be" + } + ] + } + }, + { + "date": "Mon, 13 Jan 2025 07:21:23 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.160", + "version": "8.13.160", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react to v8.122.6", + "commit": "bf60a56cb23b3af90bcb62462c2423468eb9fa3c" + }, + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.278", + "commit": "bf60a56cb23b3af90bcb62462c2423468eb9fa3c" + } + ] + } + }, + { + "date": "Wed, 08 Jan 2025 07:21:37 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.159", + "version": "8.13.159", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react to v8.122.5", + "commit": "8f763922d713d9ccd35e65db07206c10b170fafd" + }, + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.277", + "commit": "8f763922d713d9ccd35e65db07206c10b170fafd" + } + ] + } + }, + { + "date": "Mon, 06 Jan 2025 07:16:33 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.158", + "version": "8.13.158", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.276", + "commit": "1ffbd975d75f5593a295adcf894cf7d821560e80" + } + ] + } + }, + { + "date": "Fri, 03 Jan 2025 07:21:32 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.157", + "version": "8.13.157", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react to v8.122.4", + "commit": "7bb97f178d73a470dc438a2b19d165d9d0bd4b51" + }, + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.275", + "commit": "7bb97f178d73a470dc438a2b19d165d9d0bd4b51" + } + ] + } + }, + { + "date": "Thu, 02 Jan 2025 07:22:03 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.156", + "version": "8.13.156", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.274", + "commit": "6bd14a98fb5bec1eb26dfbada654fc1588249fa8" + } + ] + } + }, + { + "date": "Wed, 01 Jan 2025 07:21:10 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.155", + "version": "8.13.155", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.273", + "commit": "bf1b91f1fd3cfb580185870b6a4b77738384f9d2" + } + ] + } + }, + { + "date": "Tue, 31 Dec 2024 07:21:45 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.154", + "version": "8.13.154", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.272", + "commit": "d61ac31da90bf8f73f54262e196b3a83b9a85932" + } + ] + } + }, + { + "date": "Mon, 30 Dec 2024 07:21:29 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.153", + "version": "8.13.153", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react to v8.122.3", + "commit": "681a95a732fe385a70b8d4537dc489acbcd1c21e" + }, + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.271", + "commit": "681a95a732fe385a70b8d4537dc489acbcd1c21e" + } + ] + } + }, + { + "date": "Fri, 27 Dec 2024 07:20:59 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.152", + "version": "8.13.152", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.270", + "commit": "99cbe5c9cc9c298d78e10301b37d314b68ba8c52" + } + ] + } + }, + { + "date": "Thu, 26 Dec 2024 07:21:14 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.151", + "version": "8.13.151", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.269", + "commit": "0dd9a713b54a6d5b5929ac7febd1c7e44c83efca" + } + ] + } + }, + { + "date": "Wed, 25 Dec 2024 07:21:56 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.150", + "version": "8.13.150", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.268", + "commit": "fa08fec97a5bc070e2866633c792f7066f0c86e8" + } + ] + } + }, + { + "date": "Mon, 23 Dec 2024 07:22:58 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.149", + "version": "8.13.149", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react to v8.122.2", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + }, + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/theme to v2.6.64", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + }, + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.267", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + } + ] + } + }, + { + "date": "Fri, 20 Dec 2024 07:20:01 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.148", + "version": "8.13.148", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.266", + "commit": "7f1647fadcd193c0d16e51b314d299ee19ae5746" + } + ] + } + }, + { + "date": "Wed, 18 Dec 2024 07:20:30 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.147", + "version": "8.13.147", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.265", + "commit": "6bcbe87a1b1d876c1437a6ae13818f265e5bb5c6" + } + ] + } + }, + { + "date": "Tue, 17 Dec 2024 07:21:19 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.146", + "version": "8.13.146", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.264", + "commit": "4487ca6a37b19e06ed494e819805c1abfb8c7afa" + } + ] + } + }, + { + "date": "Mon, 16 Dec 2024 07:20:45 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.145", + "version": "8.13.145", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.263", + "commit": "b5d571f692b983b6eb39a2dc43a8b95016a32a4c" + } + ] + } + }, + { + "date": "Fri, 13 Dec 2024 07:23:12 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.144", + "version": "8.13.144", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react to v8.122.1", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7" + }, + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.262", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7" + } + ] + } + }, + { + "date": "Thu, 12 Dec 2024 07:22:33 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.143", + "version": "8.13.143", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react to v8.122.0", + "commit": "53dd771e70338065810404663cd6219d1b54c1e2" + }, + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.261", + "commit": "53dd771e70338065810404663cd6219d1b54c1e2" + } + ] + } + }, + { + "date": "Mon, 09 Dec 2024 07:21:03 GMT", + "tag": "@fluentui/react-docsite-components_v8.13.142", + "version": "8.13.142", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-docsite-components", + "comment": "Bump @fluentui/react-monaco-editor to v1.7.260", + "commit": "c688295efb1f16317bea6bff67ea6cdf886155ef" + } + ] + } + }, { "date": "Fri, 06 Dec 2024 07:21:16 GMT", "tag": "@fluentui/react-docsite-components_v8.13.141", diff --git a/packages/react-docsite-components/CHANGELOG.md b/packages/react-docsite-components/CHANGELOG.md index 37bc69e7b8e8cc..4c7460514a1860 100644 --- a/packages/react-docsite-components/CHANGELOG.md +++ b/packages/react-docsite-components/CHANGELOG.md @@ -1,9 +1,340 @@ # Change Log - @fluentui/react-docsite-components -This log was last generated on Fri, 06 Dec 2024 07:21:16 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 07:22:41 GMT and should not be manually modified. +## [8.13.176](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.176) + +Fri, 21 Feb 2025 07:22:41 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.175..@fluentui/react-docsite-components_v8.13.176) + +### Patches + +- Bump @fluentui/react to v8.122.11 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/theme to v2.6.65 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/react-hooks to v8.8.17 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/set-version to v8.2.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/react-monaco-editor to v1.7.294 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) + +## [8.13.175](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.175) + +Wed, 19 Feb 2025 07:21:16 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.174..@fluentui/react-docsite-components_v8.13.175) + +### Patches + +- Bump @fluentui/react to v8.122.10 ([PR #33867](https://github.com/microsoft/fluentui/pull/33867) by beachball) +- Bump @fluentui/react-monaco-editor to v1.7.293 ([PR #33867](https://github.com/microsoft/fluentui/pull/33867) by beachball) + +## [8.13.174](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.174) + +Thu, 13 Feb 2025 07:22:18 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.173..@fluentui/react-docsite-components_v8.13.174) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.292 ([commit](https://github.com/microsoft/fluentui/commit/da21d6906904f1c56d4f71f720a18e8cbc45841b) by beachball) + +## [8.13.173](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.173) + +Wed, 12 Feb 2025 07:20:52 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.172..@fluentui/react-docsite-components_v8.13.173) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.291 ([PR #33814](https://github.com/microsoft/fluentui/pull/33814) by beachball) + +## [8.13.172](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.172) + +Tue, 11 Feb 2025 07:21:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.171..@fluentui/react-docsite-components_v8.13.172) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.290 ([PR #33807](https://github.com/microsoft/fluentui/pull/33807) by beachball) + +## [8.13.171](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.171) + +Wed, 05 Feb 2025 07:16:29 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.170..@fluentui/react-docsite-components_v8.13.171) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.289 ([PR #33773](https://github.com/microsoft/fluentui/pull/33773) by beachball) + +## [8.13.170](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.170) + +Fri, 31 Jan 2025 07:21:30 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.169..@fluentui/react-docsite-components_v8.13.170) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.288 ([PR #33747](https://github.com/microsoft/fluentui/pull/33747) by beachball) + +## [8.13.169](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.169) + +Thu, 30 Jan 2025 07:20:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.168..@fluentui/react-docsite-components_v8.13.169) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.287 ([PR #33696](https://github.com/microsoft/fluentui/pull/33696) by beachball) + +## [8.13.168](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.168) + +Wed, 29 Jan 2025 07:21:15 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.167..@fluentui/react-docsite-components_v8.13.168) + +### Patches + +- Bump @fluentui/react to v8.122.9 ([PR #33713](https://github.com/microsoft/fluentui/pull/33713) by beachball) +- Bump @fluentui/react-monaco-editor to v1.7.286 ([PR #33713](https://github.com/microsoft/fluentui/pull/33713) by beachball) + +## [8.13.167](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.167) + +Mon, 27 Jan 2025 07:20:35 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.166..@fluentui/react-docsite-components_v8.13.167) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.285 ([PR #33725](https://github.com/microsoft/fluentui/pull/33725) by beachball) + +## [8.13.166](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.166) + +Fri, 24 Jan 2025 07:20:37 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.165..@fluentui/react-docsite-components_v8.13.166) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.284 ([PR #33717](https://github.com/microsoft/fluentui/pull/33717) by beachball) + +## [8.13.165](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.165) + +Thu, 23 Jan 2025 07:21:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.164..@fluentui/react-docsite-components_v8.13.165) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.283 ([PR #33659](https://github.com/microsoft/fluentui/pull/33659) by beachball) + +## [8.13.164](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.164) + +Wed, 22 Jan 2025 07:21:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.163..@fluentui/react-docsite-components_v8.13.164) + +### Patches + +- Bump @fluentui/react to v8.122.8 ([PR #33685](https://github.com/microsoft/fluentui/pull/33685) by beachball) +- Bump @fluentui/react-monaco-editor to v1.7.282 ([PR #33685](https://github.com/microsoft/fluentui/pull/33685) by beachball) + +## [8.13.163](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.163) + +Tue, 21 Jan 2025 07:13:51 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.162..@fluentui/react-docsite-components_v8.13.163) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.281 ([PR #33695](https://github.com/microsoft/fluentui/pull/33695) by beachball) + +## [8.13.162](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.162) + +Mon, 20 Jan 2025 07:21:47 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.161..@fluentui/react-docsite-components_v8.13.162) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.280 ([PR #33581](https://github.com/microsoft/fluentui/pull/33581) by beachball) + +## [8.13.161](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.161) + +Fri, 17 Jan 2025 07:21:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.160..@fluentui/react-docsite-components_v8.13.161) + +### Patches + +- Bump @fluentui/react to v8.122.7 ([commit](https://github.com/microsoft/fluentui/commit/baf887d95f91874c814a7cae749c20e797f828be) by beachball) +- Bump @fluentui/react-monaco-editor to v1.7.279 ([commit](https://github.com/microsoft/fluentui/commit/baf887d95f91874c814a7cae749c20e797f828be) by beachball) + +## [8.13.160](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.160) + +Mon, 13 Jan 2025 07:21:23 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.159..@fluentui/react-docsite-components_v8.13.160) + +### Patches + +- Bump @fluentui/react to v8.122.6 ([PR #33148](https://github.com/microsoft/fluentui/pull/33148) by beachball) +- Bump @fluentui/react-monaco-editor to v1.7.278 ([PR #33148](https://github.com/microsoft/fluentui/pull/33148) by beachball) + +## [8.13.159](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.159) + +Wed, 08 Jan 2025 07:21:37 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.158..@fluentui/react-docsite-components_v8.13.159) + +### Patches + +- Bump @fluentui/react to v8.122.5 ([PR #33578](https://github.com/microsoft/fluentui/pull/33578) by beachball) +- Bump @fluentui/react-monaco-editor to v1.7.277 ([PR #33578](https://github.com/microsoft/fluentui/pull/33578) by beachball) + +## [8.13.158](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.158) + +Mon, 06 Jan 2025 07:16:33 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.157..@fluentui/react-docsite-components_v8.13.158) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.276 ([PR #33544](https://github.com/microsoft/fluentui/pull/33544) by beachball) + +## [8.13.157](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.157) + +Fri, 03 Jan 2025 07:21:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.156..@fluentui/react-docsite-components_v8.13.157) + +### Patches + +- Bump @fluentui/react to v8.122.4 ([PR #33529](https://github.com/microsoft/fluentui/pull/33529) by beachball) +- Bump @fluentui/react-monaco-editor to v1.7.275 ([PR #33529](https://github.com/microsoft/fluentui/pull/33529) by beachball) + +## [8.13.156](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.156) + +Thu, 02 Jan 2025 07:22:03 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.155..@fluentui/react-docsite-components_v8.13.156) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.274 ([PR #33538](https://github.com/microsoft/fluentui/pull/33538) by beachball) + +## [8.13.155](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.155) + +Wed, 01 Jan 2025 07:21:10 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.154..@fluentui/react-docsite-components_v8.13.155) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.273 ([PR #33525](https://github.com/microsoft/fluentui/pull/33525) by beachball) + +## [8.13.154](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.154) + +Tue, 31 Dec 2024 07:21:45 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.153..@fluentui/react-docsite-components_v8.13.154) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.272 ([PR #33524](https://github.com/microsoft/fluentui/pull/33524) by beachball) + +## [8.13.153](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.153) + +Mon, 30 Dec 2024 07:21:29 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.152..@fluentui/react-docsite-components_v8.13.153) + +### Patches + +- Bump @fluentui/react to v8.122.3 ([PR #33520](https://github.com/microsoft/fluentui/pull/33520) by beachball) +- Bump @fluentui/react-monaco-editor to v1.7.271 ([PR #33520](https://github.com/microsoft/fluentui/pull/33520) by beachball) + +## [8.13.152](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.152) + +Fri, 27 Dec 2024 07:20:59 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.151..@fluentui/react-docsite-components_v8.13.152) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.270 ([PR #33507](https://github.com/microsoft/fluentui/pull/33507) by beachball) + +## [8.13.151](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.151) + +Thu, 26 Dec 2024 07:21:14 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.150..@fluentui/react-docsite-components_v8.13.151) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.269 ([PR #33518](https://github.com/microsoft/fluentui/pull/33518) by beachball) + +## [8.13.150](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.150) + +Wed, 25 Dec 2024 07:21:56 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.149..@fluentui/react-docsite-components_v8.13.150) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.268 ([PR #33447](https://github.com/microsoft/fluentui/pull/33447) by beachball) + +## [8.13.149](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.149) + +Mon, 23 Dec 2024 07:22:58 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.148..@fluentui/react-docsite-components_v8.13.149) + +### Patches + +- Bump @fluentui/react to v8.122.2 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) +- Bump @fluentui/theme to v2.6.64 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) +- Bump @fluentui/react-monaco-editor to v1.7.267 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) + +## [8.13.148](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.148) + +Fri, 20 Dec 2024 07:20:01 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.147..@fluentui/react-docsite-components_v8.13.148) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.266 ([PR #33282](https://github.com/microsoft/fluentui/pull/33282) by beachball) + +## [8.13.147](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.147) + +Wed, 18 Dec 2024 07:20:30 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.146..@fluentui/react-docsite-components_v8.13.147) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.265 ([PR #33440](https://github.com/microsoft/fluentui/pull/33440) by beachball) + +## [8.13.146](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.146) + +Tue, 17 Dec 2024 07:21:19 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.145..@fluentui/react-docsite-components_v8.13.146) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.264 ([PR #33477](https://github.com/microsoft/fluentui/pull/33477) by beachball) + +## [8.13.145](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.145) + +Mon, 16 Dec 2024 07:20:45 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.144..@fluentui/react-docsite-components_v8.13.145) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.263 ([PR #33460](https://github.com/microsoft/fluentui/pull/33460) by beachball) + +## [8.13.144](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.144) + +Fri, 13 Dec 2024 07:23:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.143..@fluentui/react-docsite-components_v8.13.144) + +### Patches + +- Bump @fluentui/react to v8.122.1 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) +- Bump @fluentui/react-monaco-editor to v1.7.262 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) + +## [8.13.143](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.143) + +Thu, 12 Dec 2024 07:22:33 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.142..@fluentui/react-docsite-components_v8.13.143) + +### Patches + +- Bump @fluentui/react to v8.122.0 ([PR #33243](https://github.com/microsoft/fluentui/pull/33243) by beachball) +- Bump @fluentui/react-monaco-editor to v1.7.261 ([PR #33243](https://github.com/microsoft/fluentui/pull/33243) by beachball) + +## [8.13.142](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.142) + +Mon, 09 Dec 2024 07:21:03 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-docsite-components_v8.13.141..@fluentui/react-docsite-components_v8.13.142) + +### Patches + +- Bump @fluentui/react-monaco-editor to v1.7.260 ([PR #33379](https://github.com/microsoft/fluentui/pull/33379) by beachball) + ## [8.13.141](https://github.com/microsoft/fluentui/tree/@fluentui/react-docsite-components_v8.13.141) Fri, 06 Dec 2024 07:21:16 GMT diff --git a/packages/react-docsite-components/package.json b/packages/react-docsite-components/package.json index d7738e69188dad..20a8aeb93e15bc 100644 --- a/packages/react-docsite-components/package.json +++ b/packages/react-docsite-components/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-docsite-components", - "version": "8.13.141", + "version": "8.13.176", "description": "Fluent UI React components for building documentation sites.", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -35,14 +35,14 @@ "react-dom": ">=16.8.0 <19.0.0" }, "dependencies": { - "@fluentui/react": "^8.121.13", - "@fluentui/theme": "^2.6.63", + "@fluentui/react": "^8.122.11", + "@fluentui/theme": "^2.6.65", "@microsoft/load-themed-styles": "^1.10.26", "@fluentui/example-data": "^8.4.25", "@fluentui/public-docsite-setup": "^0.3.34", - "@fluentui/react-hooks": "^8.8.16", - "@fluentui/set-version": "^8.2.23", - "@fluentui/react-monaco-editor": "^1.7.259", + "@fluentui/react-hooks": "^8.8.17", + "@fluentui/set-version": "^8.2.24", + "@fluentui/react-monaco-editor": "^1.7.294", "color-check": "0.0.2", "markdown-to-jsx": "^7.0.0", "office-ui-fabric-core": "^11.0.0", diff --git a/packages/react-examples/package.json b/packages/react-examples/package.json index 3e47e2aa5ce452..a2b499dbb8316a 100644 --- a/packages/react-examples/package.json +++ b/packages/react-examples/package.json @@ -27,28 +27,28 @@ "@fluentui/scripts-tasks": "*" }, "dependencies": { - "@fluentui/azure-themes": "^8.6.112", - "@fluentui/date-time-utilities": "^8.6.9", - "@fluentui/dom-utilities": "^2.3.9", + "@fluentui/azure-themes": "^8.6.124", + "@fluentui/date-time-utilities": "^8.6.10", + "@fluentui/dom-utilities": "^2.3.10", "@fluentui/example-data": "^8.4.25", - "@fluentui/font-icons-mdl2": "^8.5.55", - "@fluentui/foundation-legacy": "^8.4.21", - "@fluentui/merge-styles": "^8.6.13", - "@fluentui/react": "^8.121.13", - "@fluentui/react-cards": "^0.205.188", - "@fluentui/react-charting": "^5.23.21", - "@fluentui/react-docsite-components": "^8.13.141", - "@fluentui/react-experiments": "^8.14.185", - "@fluentui/react-file-type-icons": "^8.12.5", - "@fluentui/react-focus": "^8.9.18", - "@fluentui/react-hooks": "^8.8.16", - "@fluentui/react-icons-mdl2": "^1.3.80", - "@fluentui/react-window-provider": "^2.2.28", - "@fluentui/scheme-utilities": "^8.3.64", - "@fluentui/style-utilities": "^8.11.4", - "@fluentui/theme": "^2.6.63", - "@fluentui/theme-samples": "^8.7.188", - "@fluentui/utilities": "^8.15.19", + "@fluentui/font-icons-mdl2": "^8.5.58", + "@fluentui/foundation-legacy": "^8.4.24", + "@fluentui/merge-styles": "^8.6.14", + "@fluentui/react": "^8.122.11", + "@fluentui/react-cards": "^0.205.200", + "@fluentui/react-charting": "^5.23.56", + "@fluentui/react-docsite-components": "^8.13.176", + "@fluentui/react-experiments": "^8.14.197", + "@fluentui/react-file-type-icons": "^8.12.8", + "@fluentui/react-focus": "^8.9.21", + "@fluentui/react-hooks": "^8.8.17", + "@fluentui/react-icons-mdl2": "^1.3.83", + "@fluentui/react-window-provider": "^2.2.29", + "@fluentui/scheme-utilities": "^8.3.66", + "@fluentui/style-utilities": "^8.11.7", + "@fluentui/theme": "^2.6.65", + "@fluentui/theme-samples": "^8.7.200", + "@fluentui/utilities": "^8.15.20", "@microsoft/load-themed-styles": "^1.10.26", "d3-fetch": "3.0.1", "d3-format": "^3.0.0", diff --git a/packages/react-examples/src/react-cards/Card/Card.Configure.Example.tsx b/packages/react-examples/src/react-cards/Card/Card.Configure.Example.tsx index 41d361293f475b..7b567cc65bd149 100644 --- a/packages/react-examples/src/react-cards/Card/Card.Configure.Example.tsx +++ b/packages/react-examples/src/react-cards/Card/Card.Configure.Example.tsx @@ -20,7 +20,7 @@ import { ITextStyles, } from '@fluentui/react'; -/* eslint-disable deprecation/deprecation */ +/* eslint-disable @typescript-eslint/no-deprecated */ export type FilledSectionKey = '0' | '1' | '2' | '3'; diff --git a/packages/react-examples/src/react-cards/Card/Card.Horizontal.Example.tsx b/packages/react-examples/src/react-cards/Card/Card.Horizontal.Example.tsx index c6dcddeece1c83..4772ebe8231d5c 100644 --- a/packages/react-examples/src/react-cards/Card/Card.Horizontal.Example.tsx +++ b/packages/react-examples/src/react-cards/Card/Card.Horizontal.Example.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { Card, ICardTokens, ICardSectionStyles, ICardSectionTokens } from '@fluentui/react-cards'; import { FontWeights, Icon, IIconStyles, Image, Stack, IStackTokens, Text, ITextStyles } from '@fluentui/react'; -/* eslint-disable deprecation/deprecation */ +/* eslint-disable @typescript-eslint/no-deprecated */ const alertClicked = (): void => { alert('Clicked'); diff --git a/packages/react-examples/src/react-cards/Card/Card.Vertical.Example.tsx b/packages/react-examples/src/react-cards/Card/Card.Vertical.Example.tsx index c6af4631cb2c6c..6b12b903ecbd88 100644 --- a/packages/react-examples/src/react-cards/Card/Card.Vertical.Example.tsx +++ b/packages/react-examples/src/react-cards/Card/Card.Vertical.Example.tsx @@ -14,7 +14,7 @@ import { ITextStyles, } from '@fluentui/react'; -/* eslint-disable deprecation/deprecation */ +/* eslint-disable @typescript-eslint/no-deprecated */ const alertClicked = (): void => { alert('Clicked'); diff --git a/packages/react-examples/src/react-charting/AreaChart/AreaChart.Basic.Example.tsx b/packages/react-examples/src/react-charting/AreaChart/AreaChart.Basic.Example.tsx index d2ed2a327f98b2..1c65e5376cb2a5 100644 --- a/packages/react-examples/src/react-charting/AreaChart/AreaChart.Basic.Example.tsx +++ b/packages/react-examples/src/react-charting/AreaChart/AreaChart.Basic.Example.tsx @@ -9,6 +9,8 @@ interface IAreaChartBasicState { height: number; isCalloutselected: boolean; showAxisTitles: boolean; + legendMultiSelect: boolean; + changeChartMode: boolean; } const options: IChoiceGroupOption[] = [ @@ -24,6 +26,8 @@ export class AreaChartBasicExample extends React.Component<{}, IAreaChartBasicSt height: 300, isCalloutselected: false, showAxisTitles: true, + legendMultiSelect: false, + changeChartMode: false, }; } public componentDidMount(): void { @@ -68,6 +72,16 @@ export class AreaChartBasicExample extends React.Component<{}, IAreaChartBasicSt this.setState({ showAxisTitles: checked }); }; + private _onToggleLegendMultiSelect = (ev: React.MouseEvent, checked: boolean) => { + this.forceUpdate(); + this.setState({ legendMultiSelect: checked }); + }; + + private _onToggleChartMode = (ev: React.MouseEvent, checked: boolean) => { + this.forceUpdate(); + this.setState({ changeChartMode: checked }); + }; + private _basicExample(): JSX.Element { const chart1Points = [ { @@ -162,11 +176,37 @@ export class AreaChartBasicExample extends React.Component<{}, IAreaChartBasicSt }, ]; + const chart2Points = chart1Points.map((point, index) => { + return { + x: point.x, + y: point.y + 5000, + xAxisCalloutData: point.xAxisCalloutData, + yAxisCalloutData: point.yAxisCalloutData, + }; + }); + + const chart3Points = chart1Points.map((point, index) => { + return { + x: point.x, + y: point.y + 7000, + xAxisCalloutData: point.xAxisCalloutData, + yAxisCalloutData: point.yAxisCalloutData, + }; + }); + const chartPoints = [ { legend: 'legend1', data: chart1Points, }, + { + legend: 'legend2', + data: chart2Points, + }, + { + legend: 'legend3', + data: chart3Points, + }, ]; const chartData = { @@ -208,6 +248,22 @@ export class AreaChartBasicExample extends React.Component<{}, IAreaChartBasicSt onChange={this._onToggleAxisTitlesCheckChange} styles={{ root: { marginTop: '10px' } }} /> + + {this.state.showAxisTitles && (
)} @@ -253,6 +313,10 @@ export class AreaChartBasicExample extends React.Component<{}, IAreaChartBasicSt ) : null } enableReflow={true} + legendProps={{ + canSelectMultipleLegends: this.state.legendMultiSelect, + }} + mode={this.state.changeChartMode ? 'tozeroy' : 'tonexty'} />
)} diff --git a/packages/react-examples/src/react-charting/DeclarativeChart/DeclarativeChart.Basic.Example.tsx b/packages/react-examples/src/react-charting/DeclarativeChart/DeclarativeChart.Basic.Example.tsx index e9b67f09913939..4009fddcc52871 100644 --- a/packages/react-examples/src/react-charting/DeclarativeChart/DeclarativeChart.Basic.Example.tsx +++ b/packages/react-examples/src/react-charting/DeclarativeChart/DeclarativeChart.Basic.Example.tsx @@ -1,9 +1,40 @@ import * as React from 'react'; import { Dropdown, IDropdownOption } from '@fluentui/react/lib/Dropdown'; -import { DeclarativeChart, DeclarativeChartProps, Schema } from '@fluentui/react-charting'; +import { TextField, ITextFieldStyles } from '@fluentui/react/lib/TextField'; +import { DeclarativeChart, DeclarativeChartProps, IDeclarativeChart, Schema } from '@fluentui/react-charting'; + +interface IErrorBoundaryProps { + children: React.ReactNode; +} + +interface IErrorBoundaryState { + hasError: boolean; + error: string; +} + +class ErrorBoundary extends React.Component { + public static getDerivedStateFromError(error: Error) { + // Update state so the next render will show the fallback UI. + return { hasError: true, error: `${error.message} ${error.stack}` }; + } + + constructor(props: IErrorBoundaryProps) { + super(props); + this.state = { hasError: false, error: '' }; + } + + public render() { + if (this.state.hasError) { + return

${this.state.error}

; + } + + return this.props.children; + } +} interface IDeclarativeChartState { selectedChoice: string; + selectedLegends: string; } const options: IDropdownOption[] = [ @@ -34,12 +65,39 @@ const schemas: any[] = [ const dropdownStyles = { dropdown: { width: 200 } }; +const textFieldStyles: Partial = { root: { maxWidth: 300 } }; + +function fileSaver(url: string) { + const saveLink = document.createElement('a'); + saveLink.href = url; + saveLink.download = 'converted-image.png'; + document.body.appendChild(saveLink); + saveLink.click(); + document.body.removeChild(saveLink); +} + export class DeclarativeChartBasicExample extends React.Component<{}, IDeclarativeChartState> { + private _declarativeChartRef: React.RefObject; + private _lastKnownValidLegends: string[] | undefined; + constructor(props: DeclarativeChartProps) { super(props); + const defaultselection = 'donutchart'; + const selectedPlotlySchema = this._getSchemaByKey(defaultselection); + const { selectedLegends } = selectedPlotlySchema; this.state = { - selectedChoice: 'donutchart', + selectedChoice: defaultselection, + selectedLegends: JSON.stringify(selectedLegends), }; + + this._declarativeChartRef = React.createRef(); + this._lastKnownValidLegends = selectedLegends; + } + + public componentDidMount() { + document.addEventListener('contextmenu', e => { + e.preventDefault(); + }); } public render(): JSX.Element { @@ -47,7 +105,21 @@ export class DeclarativeChartBasicExample extends React.Component<{}, IDeclarati } private _onChange = (ev: React.FormEvent, option: IDropdownOption): void => { - this.setState({ selectedChoice: option.key as string }); + const selectedPlotlySchema = this._getSchemaByKey(option.key as string); + const { selectedLegends } = selectedPlotlySchema; + this.setState({ selectedChoice: option.key as string, selectedLegends: JSON.stringify(selectedLegends) }); + }; + + private _onSelectedLegendsEdited = ( + event: React.FormEvent, + newValue?: string, + ): void => { + this.setState({ selectedLegends: newValue ?? '' }); + }; + + private _handleChartSchemaChanged = (eventData: Schema) => { + const { selectedLegends } = eventData.plotlySchema; + this.setState({ selectedLegends: JSON.stringify(selectedLegends) }); }; private _getSchemaByKey(key: string): any { @@ -56,22 +128,58 @@ export class DeclarativeChartBasicExample extends React.Component<{}, IDeclarati } private _createDeclarativeChart(): JSX.Element { - const selectedPlotlySchema = this._getSchemaByKey(this.state.selectedChoice); - const inputSchema: Schema = { plotlySchema: selectedPlotlySchema }; + const uniqueKey = `${this.state.selectedChoice}`; + const currentPlotlySchema = this._getSchemaByKey(this.state.selectedChoice); + const { data, layout } = currentPlotlySchema; + if (this.state.selectedLegends === '') { + this._lastKnownValidLegends = undefined; + } else { + try { + this._lastKnownValidLegends = JSON.parse(this.state.selectedLegends); + } catch (error) { + // Nothing to do here + } + } + const plotlySchema = { data, layout, selectedLegends: this._lastKnownValidLegends }; + const inputSchema: Schema = { plotlySchema }; return ( - <> - + +
+ +     +

+
- - + +
+ +
); } } diff --git a/packages/react-examples/src/react-charting/DeclarativeChart/schema/fluent_area.json b/packages/react-examples/src/react-charting/DeclarativeChart/schema/fluent_area.json index 90940675770645..9bb4f973a4df9a 100644 --- a/packages/react-examples/src/react-charting/DeclarativeChart/schema/fluent_area.json +++ b/packages/react-examples/src/react-charting/DeclarativeChart/schema/fluent_area.json @@ -99,5 +99,6 @@ "plot_bgcolor": "#F5F6F9", "paper_bgcolor": "#F5F6F9" }, - "frames": [] + "frames": [], + "selectedLegends": ["a"] } diff --git a/packages/react-examples/src/react-charting/DeclarativeChart/schema/fluent_donut.json b/packages/react-examples/src/react-charting/DeclarativeChart/schema/fluent_donut.json index 27aa22a439d13d..41426b2dbbd8ea 100644 --- a/packages/react-examples/src/react-charting/DeclarativeChart/schema/fluent_donut.json +++ b/packages/react-examples/src/react-charting/DeclarativeChart/schema/fluent_donut.json @@ -60,5 +60,6 @@ "hovermode": "closest", "showlegend": true }, - "frames": [] + "frames": [], + "selectedLegends": ["Cadillac"] } diff --git a/packages/react-examples/src/react-charting/DeclarativeChart/schema/fluent_horizontalbar.json b/packages/react-examples/src/react-charting/DeclarativeChart/schema/fluent_horizontalbar.json index fcb62084212738..23cb372f1e7f0b 100644 --- a/packages/react-examples/src/react-charting/DeclarativeChart/schema/fluent_horizontalbar.json +++ b/packages/react-examples/src/react-charting/DeclarativeChart/schema/fluent_horizontalbar.json @@ -60,7 +60,7 @@ ], "layout": { "title": "PHP Framework Popularity at Work - SitePoint, 2015", - "width": 1151, + "width": 850, "xaxis": { "type": "linear", "range": [-198.2562959184288, 1830.6731869091736], diff --git a/packages/react-examples/src/react-charting/DeclarativeChart/schema/fluent_line.json b/packages/react-examples/src/react-charting/DeclarativeChart/schema/fluent_line.json index 4197999e2576fe..3890cb761358e0 100644 --- a/packages/react-examples/src/react-charting/DeclarativeChart/schema/fluent_line.json +++ b/packages/react-examples/src/react-charting/DeclarativeChart/schema/fluent_line.json @@ -435,5 +435,6 @@ "plot_bgcolor": "#F5F6F9", "paper_bgcolor": "#F5F6F9" }, - "frames": [] + "frames": [], + "selectedLegends": ["Trace 0", "Trace 1"] } diff --git a/packages/react-examples/src/react-charting/DonutChart/DonutChart.Basic.Example.tsx b/packages/react-examples/src/react-charting/DonutChart/DonutChart.Basic.Example.tsx index 71be65bd695da7..ac96c767bef0e6 100644 --- a/packages/react-examples/src/react-charting/DonutChart/DonutChart.Basic.Example.tsx +++ b/packages/react-examples/src/react-charting/DonutChart/DonutChart.Basic.Example.tsx @@ -14,6 +14,7 @@ import { Toggle } from '@fluentui/react/lib/Toggle'; interface IDonutChartState { enableGradient: boolean; roundCorners: boolean; + legendMultiSelect: boolean; } export class DonutChartBasicExample extends React.Component { @@ -22,6 +23,7 @@ export class DonutChartBasicExample extends React.Component +    +
); @@ -92,4 +159,8 @@ export class DonutChartBasicExample extends React.Component, checked: boolean) => { this.setState({ roundCorners: checked }); }; + + private _onToggleLegendMultiSelect = (ev: React.MouseEvent, checked: boolean) => { + this.setState({ legendMultiSelect: checked }); + }; } diff --git a/packages/react-examples/src/react-charting/GaugeChart/GaugeChart.Basic.Example.tsx b/packages/react-examples/src/react-charting/GaugeChart/GaugeChart.Basic.Example.tsx index 66e1541b397947..8fca0a04b362be 100644 --- a/packages/react-examples/src/react-charting/GaugeChart/GaugeChart.Basic.Example.tsx +++ b/packages/react-examples/src/react-charting/GaugeChart/GaugeChart.Basic.Example.tsx @@ -16,6 +16,7 @@ interface IGCBasicExampleState { hideMinMax: boolean; enableGradient: boolean; roundedCorners: boolean; + legendMultiSelect: boolean; } export class GaugeChartBasicExample extends React.Component<{}, IGCBasicExampleState> { @@ -29,6 +30,7 @@ export class GaugeChartBasicExample extends React.Component<{}, IGCBasicExampleS hideMinMax: false, enableGradient: false, roundedCorners: false, + legendMultiSelect: false, }; } @@ -99,6 +101,14 @@ export class GaugeChartBasicExample extends React.Component<{}, IGCBasicExampleS checked={this.state.roundedCorners} onChange={this._onToggleRoundedCorners} /> +    +
); @@ -155,4 +168,8 @@ export class GaugeChartBasicExample extends React.Component<{}, IGCBasicExampleS private _onToggleRoundedCorners = (ev: React.MouseEvent, checked: boolean) => { this.setState({ roundedCorners: checked }); }; + + private _onToggleLegendMultiSelect = (ev: React.MouseEvent, checked: boolean) => { + this.setState({ legendMultiSelect: checked }); + }; } diff --git a/packages/react-examples/src/react-charting/GroupedVerticalBarChart/GroupedVerticalBarChart.Basic.Example.tsx b/packages/react-examples/src/react-charting/GroupedVerticalBarChart/GroupedVerticalBarChart.Basic.Example.tsx index d514c24099ff2d..be8a4d5999a243 100644 --- a/packages/react-examples/src/react-charting/GroupedVerticalBarChart/GroupedVerticalBarChart.Basic.Example.tsx +++ b/packages/react-examples/src/react-charting/GroupedVerticalBarChart/GroupedVerticalBarChart.Basic.Example.tsx @@ -16,6 +16,7 @@ interface IGroupedBarChartState { hideLabels: boolean; enableGradient: boolean; roundCorners: boolean; + selectMultipleLegends: boolean; } export class GroupedVerticalBarChartBasicExample extends React.Component<{}, IGroupedBarChartState> { @@ -29,6 +30,7 @@ export class GroupedVerticalBarChartBasicExample extends React.Component<{}, IGr hideLabels: false, enableGradient: false, roundCorners: false, + selectMultipleLegends: false, }; } @@ -60,6 +62,10 @@ export class GroupedVerticalBarChartBasicExample extends React.Component<{}, IGr this.setState({ roundCorners: checked }); }; + private _onLegendMultiSelectChange = (ev: React.MouseEvent, checked: boolean) => { + this.setState({ selectMultipleLegends: checked }); + }; + private _basicExample(): JSX.Element { const data = [ { @@ -87,6 +93,28 @@ export class GroupedVerticalBarChartBasicExample extends React.Component<{}, IGr ariaLabel: 'Group Jan - Mar 1 of 4, Bar series 2 of 2 2023, x value 2023/04/30, y value 44%', }, }, + { + key: 'series3', + data: 54000, + color: getColorFromToken(DataVizPalette.color5), + legend: '2024', + xAxisCalloutData: '2024/04/30', + yAxisCalloutData: '44%', + callOutAccessibilityData: { + ariaLabel: 'Group Jan - Mar 1 of 4, Bar series 3 of 4 2022, x value 2024/04/30, y value 44%', + }, + }, + { + key: 'series4', + data: 24000, + color: getColorFromToken(DataVizPalette.color6), + legend: '2021', + xAxisCalloutData: '2021/04/30', + yAxisCalloutData: '44%', + callOutAccessibilityData: { + ariaLabel: 'Group Jan - Mar 1 of 4, Bar series 4 of 4 2021, x value 2021/04/30, y value 44%', + }, + }, ], }, { @@ -114,6 +142,28 @@ export class GroupedVerticalBarChartBasicExample extends React.Component<{}, IGr ariaLabel: 'Group Apr - Jun 2 of 4, Bar series 2 of 2 2023, x value 2023/05/30, y value 3%', }, }, + { + key: 'series3', + data: 9000, + color: getColorFromToken(DataVizPalette.color5), + legend: '2024', + xAxisCalloutData: '2024/05/30', + yAxisCalloutData: '3%', + callOutAccessibilityData: { + ariaLabel: 'Group Apr - Jun 2 of 4, Bar series 3 of 4 2024, x value 2024/05/30, y value 3%', + }, + }, + { + key: 'series4', + data: 12000, + color: getColorFromToken(DataVizPalette.color6), + legend: '2021', + xAxisCalloutData: '2021/05/30', + yAxisCalloutData: '3%', + callOutAccessibilityData: { + ariaLabel: 'Group Apr - Jun 2 of 4, Bar series 4 of 4 2021, x value 2021/05/30, y value 3%', + }, + }, ], }, @@ -142,6 +192,28 @@ export class GroupedVerticalBarChartBasicExample extends React.Component<{}, IGr ariaLabel: 'Group Jul - Sep 3 of 4, Bar series 2 of 2 2023, x value 2023/06/30, y value 50%', }, }, + { + key: 'series3', + data: 60000, + color: getColorFromToken(DataVizPalette.color5), + legend: '2024', + xAxisCalloutData: '2024/06/30', + yAxisCalloutData: '50%', + callOutAccessibilityData: { + ariaLabel: 'Group Jul - Sep 3 of 4, Bar series 3 of 4 2024, x value 2024/06/30, y value 50%', + }, + }, + { + key: 'series4', + data: 10000, + color: getColorFromToken(DataVizPalette.color6), + legend: '2021', + xAxisCalloutData: '2021/06/30', + yAxisCalloutData: '50%', + callOutAccessibilityData: { + ariaLabel: 'Group Jul - Sep 3 of 4, Bar series 4 of 4 2021, x value 2021/06/30, y value 50%', + }, + }, ], }, { @@ -169,6 +241,28 @@ export class GroupedVerticalBarChartBasicExample extends React.Component<{}, IGr ariaLabel: 'Group Oct - Dec 4 of 4, Bar series 2 of 2 2023, x value 2023/07/30, y value 3%', }, }, + { + key: 'series3', + data: 6000, + color: getColorFromToken(DataVizPalette.color5), + legend: '2024', + xAxisCalloutData: '2024/07/30', + yAxisCalloutData: '3%', + callOutAccessibilityData: { + ariaLabel: 'Group Oct - Dec 4 of 4, Bar series 3 of 4 2024, x value 2024/07/30, y value 3%', + }, + }, + { + key: 'series4', + data: 15000, + color: getColorFromToken(DataVizPalette.color6), + legend: '2021', + xAxisCalloutData: '2021/07/30', + yAxisCalloutData: '3%', + callOutAccessibilityData: { + ariaLabel: 'Group Oct - Dec 4 of 4, Bar series 4 of 4 2021, x value 2021/07/30, y value 3%', + }, + }, ], }, ]; @@ -234,6 +328,13 @@ export class GroupedVerticalBarChartBasicExample extends React.Component<{}, IGr    +    +
diff --git a/packages/react-examples/src/react-charting/HorizontalBarChartWithAxis/HorizontalBarChartWithAxis.Basic.Example.tsx b/packages/react-examples/src/react-charting/HorizontalBarChartWithAxis/HorizontalBarChartWithAxis.Basic.Example.tsx index 2aeb08145031c1..47db675033e174 100644 --- a/packages/react-examples/src/react-charting/HorizontalBarChartWithAxis/HorizontalBarChartWithAxis.Basic.Example.tsx +++ b/packages/react-examples/src/react-charting/HorizontalBarChartWithAxis/HorizontalBarChartWithAxis.Basic.Example.tsx @@ -18,6 +18,7 @@ interface IHorizontalBarChartWithAxisState { useSingleColor: boolean; enableGradient: boolean; roundCorners: boolean; + selectMultipleLegends: boolean; } const options: IChoiceGroupOption[] = [ @@ -38,6 +39,7 @@ export class HorizontalBarChartWithAxisBasicExample extends React.Component< useSingleColor: false, enableGradient: false, roundCorners: false, + selectMultipleLegends: false, }; } @@ -71,6 +73,10 @@ export class HorizontalBarChartWithAxisBasicExample extends React.Component< this.setState({ roundCorners: checked }); }; + private _onToggleRoundMultipleLegendSelection = (ev: React.MouseEvent, checked: boolean) => { + this.setState({ selectMultipleLegends: checked }); + }; + private _basicExample(): JSX.Element { const points: IHorizontalBarChartWithAxisDataPoint[] = [ { @@ -148,6 +154,13 @@ export class HorizontalBarChartWithAxisBasicExample extends React.Component<    +    +

@@ -168,6 +181,9 @@ export class HorizontalBarChartWithAxisBasicExample extends React.Component< enableReflow={true} enableGradient={this.state.enableGradient} roundCorners={this.state.roundCorners} + legendProps={{ + canSelectMultipleLegends: this.state.selectMultipleLegends, + }} />
diff --git a/packages/react-examples/src/react-charting/Legends/Legends.Controlled.Example.tsx b/packages/react-examples/src/react-charting/Legends/Legends.Controlled.Example.tsx new file mode 100644 index 00000000000000..e4eafe10336fba --- /dev/null +++ b/packages/react-examples/src/react-charting/Legends/Legends.Controlled.Example.tsx @@ -0,0 +1,64 @@ +/* eslint-disable react/jsx-no-bind */ +import * as React from 'react'; +import { Legends, ILegend, DataVizPalette, getColorFromToken } from '@fluentui/react-charting'; +import { DefaultButton, Stack } from '@fluentui/react'; + +const legends: ILegend[] = [ + { + title: 'Legend 1', + color: getColorFromToken(DataVizPalette.color1), + }, + { + title: 'Legend 2', + color: getColorFromToken(DataVizPalette.color2), + }, + { + title: 'Legend 3', + color: getColorFromToken(DataVizPalette.color3), + shape: 'diamond', + }, + { + title: 'Legend 4', + color: getColorFromToken(DataVizPalette.color4), + shape: 'triangle', + }, +]; + +export const LegendsControlledExample: React.FunctionComponent = () => { + const [selectedLegends, setSelectedLegends] = React.useState([]); + + const onChange = (keys: string[]) => { + setSelectedLegends(keys); + }; + + const handleSelect1And3 = () => { + setSelectedLegends(['Legend 1', 'Legend 3']); + }; + + const handleSelect2And4 = () => { + setSelectedLegends(['Legend 2', 'Legend 4']); + }; + + const handleSelectAll = () => { + setSelectedLegends(legends.map(legend => legend.title)); + }; + + return ( +
+ + Select 1 and 3 + Select 2 and 4 + Select all + + + Selected legends: {selectedLegends.join(', ')} +
+ ); +}; diff --git a/packages/react-examples/src/react-charting/Legends/Legends.doc.tsx b/packages/react-examples/src/react-charting/Legends/Legends.doc.tsx index e4983e05acb328..f51a8455aa881f 100644 --- a/packages/react-examples/src/react-charting/Legends/Legends.doc.tsx +++ b/packages/react-examples/src/react-charting/Legends/Legends.doc.tsx @@ -6,6 +6,7 @@ import { LegendOverflowExample } from './Legends.Overflow.Example'; import { LegendBasicExample } from './Legends.Basic.Example'; import { LegendWrapLinesExample } from './Legends.WrapLines.Example'; import { LegendStyledExample } from './Legends.Styled.Example'; +import { LegendsControlledExample } from './Legends.Controlled.Example'; const LegendsOverflowExampleCode = require('!raw-loader?esModule=false!@fluentui/react-examples/src/react-charting/Legends/Legends.Overflow.Example.tsx') as string; @@ -15,6 +16,8 @@ const LegendsBasicExampleCode = require('!raw-loader?esModule=false!@fluentui/react-examples/src/react-charting/Legends/Legends.Basic.Example.tsx') as string; const LegendsStyledExampleCode = require('!raw-loader?esModule=false!@fluentui/react-examples/src/react-charting/Legends/Legends.Styled.Example.tsx') as string; +const LegendsControlledExampleCode = + require('!raw-loader?esModule=false!@fluentui/react-examples/src/react-charting/Legends/Legends.Controlled.Example.tsx') as string; export const LegendsPageProps: IDocPageProps = { title: 'Legends', @@ -42,6 +45,11 @@ export const LegendsPageProps: IDocPageProps = { code: LegendsStyledExampleCode, view: , }, + { + title: 'Legend controlled selection', + code: LegendsControlledExampleCode, + view: , + }, ], overview: require('!raw-loader?esModule=false!@fluentui/react-examples/src/react-charting/Legends/docs/LegendsOverview.md'), bestPractices: require('!raw-loader?esModule=false!@fluentui/react-examples/src/react-charting/Legends/docs/LegendsBestPractices.md'), diff --git a/packages/react-examples/src/react-charting/Legends/LegendsPage.tsx b/packages/react-examples/src/react-charting/Legends/LegendsPage.tsx index 6b10896df2a189..d4cbe324a27b88 100644 --- a/packages/react-examples/src/react-charting/Legends/LegendsPage.tsx +++ b/packages/react-examples/src/react-charting/Legends/LegendsPage.tsx @@ -13,6 +13,7 @@ import { LegendBasicExample } from './Legends.Basic.Example'; import { LegendWrapLinesExample } from './Legends.WrapLines.Example'; import { LegendStyledExample } from './Legends.Styled.Example'; import { LegendsOnChangeExample } from './Legends.OnChange.Example'; +import { LegendsControlledExample } from './Legends.Controlled.Example'; const LegendsOverflowExampleCode = require('!raw-loader?esModule=false!@fluentui/react-examples/src/react-charting/Legends/Legends.Overflow.Example.tsx') as string; @@ -24,6 +25,8 @@ const LegendsStyledExampleCode = require('!raw-loader?esModule=false!@fluentui/react-examples/src/react-charting/Legends/Legends.Styled.Example.tsx') as string; const LegendsOnChangeExampleCode = require('!raw-loader?esModule=false!@fluentui/react-examples/src/react-charting/Legends/Legends.OnChange.Example.tsx') as string; +const LegendsControlledExampleCode = + require('!raw-loader?esModule=false!@fluentui/react-examples/src/react-charting/Legends/Legends.Controlled.Example.tsx') as string; export class LegendsPage extends React.Component { public render(): JSX.Element { @@ -52,6 +55,10 @@ export class LegendsPage extends React.Component { + + + + } propertiesTables={ diff --git a/packages/react-examples/src/react-charting/Legends/index.stories.tsx b/packages/react-examples/src/react-charting/Legends/index.stories.tsx index d8d3d731b3b3ca..0dc6d687b07944 100644 --- a/packages/react-examples/src/react-charting/Legends/index.stories.tsx +++ b/packages/react-examples/src/react-charting/Legends/index.stories.tsx @@ -5,6 +5,7 @@ import { LegendsOnChangeExample } from './Legends.OnChange.Example'; import { LegendOverflowExample } from './Legends.Overflow.Example'; import { LegendStyledExample } from './Legends.Styled.Example'; import { LegendWrapLinesExample } from './Legends.WrapLines.Example'; +import { LegendsControlledExample } from './Legends.Controlled.Example'; export const Basic = () => ; @@ -16,6 +17,8 @@ export const Styled = () => ; export const WrapLines = () => ; +export const Controlled = () => ; + export default { title: 'Components/Legends', }; diff --git a/packages/react-examples/src/react-charting/VerticalBarChart/VerticalBarChart.Basic.Example.tsx b/packages/react-examples/src/react-charting/VerticalBarChart/VerticalBarChart.Basic.Example.tsx index e9cbcb71d7828a..045c52bbad61a8 100644 --- a/packages/react-examples/src/react-charting/VerticalBarChart/VerticalBarChart.Basic.Example.tsx +++ b/packages/react-examples/src/react-charting/VerticalBarChart/VerticalBarChart.Basic.Example.tsx @@ -23,6 +23,7 @@ interface IVerticalChartState { showAxisTitles: boolean; enableGradient: boolean; roundCorners: boolean; + selectMultipleLegends: boolean; } const options: IChoiceGroupOption[] = [ @@ -42,6 +43,7 @@ export class VerticalBarChartBasicExample extends React.Component, checked: boolean) => { + this.setState({ selectMultipleLegends: checked }); + }; + private _basicExample(): JSX.Element { const points: IVerticalBarChartDataPoint[] = [ { @@ -234,6 +240,13 @@ export class VerticalBarChartBasicExample extends React.Component    +    + {this.state.showAxisTitles && (
@@ -259,6 +272,9 @@ export class VerticalBarChartBasicExample extends React.Component
)} @@ -284,6 +300,9 @@ export class VerticalBarChartBasicExample extends React.Component )} diff --git a/packages/react-examples/src/react-charting/VerticalBarChart/VerticalBarChart.Dynamic.Example.tsx b/packages/react-examples/src/react-charting/VerticalBarChart/VerticalBarChart.Dynamic.Example.tsx index f7377d40b70d42..88bf85c6bbe49e 100644 --- a/packages/react-examples/src/react-charting/VerticalBarChart/VerticalBarChart.Dynamic.Example.tsx +++ b/packages/react-examples/src/react-charting/VerticalBarChart/VerticalBarChart.Dynamic.Example.tsx @@ -238,6 +238,7 @@ export class VerticalBarChartDynamicExample extends React.Component
diff --git a/packages/react-examples/src/react-charting/VerticalStackedBarChart/VerticalStackedBarChart.Basic.Example.tsx b/packages/react-examples/src/react-charting/VerticalStackedBarChart/VerticalStackedBarChart.Basic.Example.tsx index d8c71162218f1a..d90e45872e4888 100644 --- a/packages/react-examples/src/react-charting/VerticalStackedBarChart/VerticalStackedBarChart.Basic.Example.tsx +++ b/packages/react-examples/src/react-charting/VerticalStackedBarChart/VerticalStackedBarChart.Basic.Example.tsx @@ -21,6 +21,7 @@ interface IVerticalStackedBarState { margins: {}; enableGradient: boolean; roundCorners: boolean; + legendMultiSelect: boolean; } export class VerticalStackedBarChartBasicExample extends React.Component<{}, IVerticalStackedBarState> { @@ -41,6 +42,7 @@ export class VerticalStackedBarChartBasicExample extends React.Component<{}, IVe }, enableGradient: false, roundCorners: false, + legendMultiSelect: false, }; } @@ -94,6 +96,10 @@ export class VerticalStackedBarChartBasicExample extends React.Component<{}, IVe this.setState({ roundCorners: checked }); }; + private _onToggleLegendMultiSelect = (ev: React.MouseEvent, checked: boolean) => { + this.setState({ legendMultiSelect: checked }); + }; + private _basicExample(): JSX.Element { const { showLine } = this.state; const firstChartPoints: IVSChartDataPoint[] = [ @@ -307,6 +313,13 @@ export class VerticalStackedBarChartBasicExample extends React.Component<{}, IVe    +    +
{this.state.showAxisTitles && (
@@ -321,6 +334,7 @@ export class VerticalStackedBarChartBasicExample extends React.Component<{}, IVe lineOptions={lineOptions} legendProps={{ allowFocusOnLegends: true, + canSelectMultipleLegends: this.state.legendMultiSelect, }} hideLabels={this.state.hideLabels} enableReflow={true} @@ -344,6 +358,7 @@ export class VerticalStackedBarChartBasicExample extends React.Component<{}, IVe lineOptions={lineOptions} legendProps={{ allowFocusOnLegends: true, + canSelectMultipleLegends: this.state.legendMultiSelect, }} hideLabels={this.state.hideLabels} enableReflow={true} 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..ac6d30760a83b2 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 @@ -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/ContextualMenu/ContextualMenu.CustomMenuList.Example.tsx b/packages/react-examples/src/react/ContextualMenu/ContextualMenu.CustomMenuList.Example.tsx index 0305e62a024bcf..a741d95ea8ed6a 100644 --- a/packages/react-examples/src/react/ContextualMenu/ContextualMenu.CustomMenuList.Example.tsx +++ b/packages/react-examples/src/react/ContextualMenu/ContextualMenu.CustomMenuList.Example.tsx @@ -72,6 +72,12 @@ export const ContextualMenuWithCustomMenuListExample: React.FunctionComponent = const menuProps = React.useMemo( () => ({ + calloutProps: { + // This is needed for Android devices since focus automatically goes to the first focusable element in the + // callout, which in this case is the SearchBox. This in turn opens the keyboard, which on the aforementioned + // Android devices causes a window resize that will dismiss the menu if this prop is not set to true. + preventDismissOnResize: true, + }, onRenderMenuList: renderMenuList, title: 'Actions', shouldFocusOnMount: true, 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/PeoplePicker.List.Example.tsx b/packages/react-examples/src/react/PeoplePicker/PeoplePicker.List.Example.tsx index 480611b64991b9..ee575b0a6fcff0 100644 --- a/packages/react-examples/src/react/PeoplePicker/PeoplePicker.List.Example.tsx +++ b/packages/react-examples/src/react/PeoplePicker/PeoplePicker.List.Example.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { TextField } from '@fluentui/react/lib/TextField'; import { Checkbox } from '@fluentui/react/lib/Checkbox'; import { IPersonaProps, IPersonaStyles } from '@fluentui/react/lib/Persona'; import { @@ -42,6 +43,9 @@ const personaStyles: Partial = { export const PeoplePickerListExample: React.FunctionComponent = () => { const [delayResults, setDelayResults] = React.useState(false); const [isPickerDisabled, setIsPickerDisabled] = React.useState(false); + const [pickerLabel, setPickerLabel] = React.useState('Choose People'); + const [showPickerLabel, setShowPickerLabel] = React.useState(false); + const [isPickerRequired, setIsPickerRequired] = React.useState(false); const [mostRecentlyUsed, setMostRecentlyUsed] = React.useState(mru); const [peopleList, setPeopleList] = React.useState(people); @@ -102,6 +106,18 @@ export const PeoplePickerListExample: React.FunctionComponent = () => { setIsPickerDisabled(!isPickerDisabled); }; + const onShowLabelButtonClick = (): void => { + setShowPickerLabel(!showPickerLabel); + }; + + const onPickerLabelChange = (_: React.FormEvent, newValue?: string): void => { + setPickerLabel(newValue ?? ''); + }; + + const onRequiredButtonClick = (): void => { + setIsPickerRequired(!isPickerRequired); + }; + const onToggleDelayResultsChange = (): void => { setDelayResults(!delayResults); }; @@ -115,9 +131,17 @@ export const PeoplePickerListExample: React.FunctionComponent = () => { ); }; + const onGetErrorMessage = React.useCallback( + (items: IPersonaProps[]): string | JSX.Element | PromiseLike | undefined => { + return isPickerRequired && (items || []).length === 0 ? 'Please fill out this field.' : undefined; + }, + [isPickerRequired], + ); + return (
{ componentRef={picker} resolveDelay={300} disabled={isPickerDisabled} + required={isPickerRequired} + onGetErrorMessage={onGetErrorMessage} /> { onChange={onToggleDelayResultsChange} styles={checkboxStyles} /> + + + {showPickerLabel && ( + + )}
); }; diff --git a/packages/react-examples/src/react/PeoplePicker/PeoplePicker.Normal.Example.tsx b/packages/react-examples/src/react/PeoplePicker/PeoplePicker.Normal.Example.tsx index 410efaa4a71457..f12398e2db5810 100644 --- a/packages/react-examples/src/react/PeoplePicker/PeoplePicker.Normal.Example.tsx +++ b/packages/react-examples/src/react/PeoplePicker/PeoplePicker.Normal.Example.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { TextField } from '@fluentui/react/lib/TextField'; import { Checkbox } from '@fluentui/react/lib/Checkbox'; import { IPersonaProps } from '@fluentui/react/lib/Persona'; import { @@ -29,6 +30,9 @@ const checkboxStyles = { export const PeoplePickerNormalExample: React.FunctionComponent = () => { const [delayResults, setDelayResults] = React.useState(false); const [isPickerDisabled, setIsPickerDisabled] = React.useState(false); + const [pickerLabel, setPickerLabel] = React.useState('Choose People'); + const [showPickerLabel, setShowPickerLabel] = React.useState(false); + const [isPickerRequired, setIsPickerRequired] = React.useState(false); const [showSecondaryText, setShowSecondaryText] = React.useState(false); const [mostRecentlyUsed, setMostRecentlyUsed] = React.useState(mru); const [peopleList, setPeopleList] = React.useState(people); @@ -103,6 +107,18 @@ export const PeoplePickerNormalExample: React.FunctionComponent = () => { setIsPickerDisabled(!isPickerDisabled); }; + const onShowLabelButtonClick = (): void => { + setShowPickerLabel(!showPickerLabel); + }; + + const onPickerLabelChange = (_: React.FormEvent, newValue?: string): void => { + setPickerLabel(newValue ?? ''); + }; + + const onRequiredButtonClick = (): void => { + setIsPickerRequired(!isPickerRequired); + }; + const onToggleDelayResultsChange = (): void => { setDelayResults(!delayResults); }; @@ -111,9 +127,17 @@ export const PeoplePickerNormalExample: React.FunctionComponent = () => { setShowSecondaryText(!showSecondaryText); }; + const onGetErrorMessage = React.useCallback( + (items: IPersonaProps[]): string | JSX.Element | PromiseLike | undefined => { + return isPickerRequired && (items || []).length === 0 ? 'Please fill out this field.' : undefined; + }, + [isPickerRequired], + ); + return (
{ onInputChange={onInputChange} resolveDelay={300} disabled={isPickerDisabled} + required={isPickerRequired} + onGetErrorMessage={onGetErrorMessage} /> { onChange={onToggleShowSecondaryText} styles={checkboxStyles} /> + + + {showPickerLabel && ( + + )}
); }; 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.197](https://github.com/microsoft/fluentui/tree/@fluentui/react-experiments_v8.14.197) + +Fri, 21 Feb 2025 07:22:41 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-experiments_v8.14.196..@fluentui/react-experiments_v8.14.197) + +### Patches + +- Bump @fluentui/react to v8.122.11 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/theme to v2.6.65 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/foundation-legacy to v8.4.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/font-icons-mdl2 to v8.5.58 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/merge-styles to v8.6.14 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/react-hooks to v8.8.17 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/set-version to v8.2.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/style-utilities to v8.11.7 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/utilities to v8.15.20 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) + +## [8.14.196](https://github.com/microsoft/fluentui/tree/@fluentui/react-experiments_v8.14.196) + +Wed, 19 Feb 2025 07:21:16 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-experiments_v8.14.195..@fluentui/react-experiments_v8.14.196) + +### Patches + +- Bump @fluentui/react to v8.122.10 ([PR #33867](https://github.com/microsoft/fluentui/pull/33867) by beachball) + +## [8.14.195](https://github.com/microsoft/fluentui/tree/@fluentui/react-experiments_v8.14.195) + +Wed, 29 Jan 2025 07:21:15 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-experiments_v8.14.194..@fluentui/react-experiments_v8.14.195) + +### Patches + +- Bump @fluentui/react to v8.122.9 ([PR #33713](https://github.com/microsoft/fluentui/pull/33713) by beachball) + +## [8.14.194](https://github.com/microsoft/fluentui/tree/@fluentui/react-experiments_v8.14.194) + +Wed, 22 Jan 2025 07:21:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-experiments_v8.14.193..@fluentui/react-experiments_v8.14.194) + +### Patches + +- Bump @fluentui/react to v8.122.8 ([PR #33685](https://github.com/microsoft/fluentui/pull/33685) by beachball) + +## [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 +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-experiments_v8.14.191..@fluentui/react-experiments_v8.14.192) + +### Patches + +- Bump @fluentui/react to v8.122.6 ([PR #33148](https://github.com/microsoft/fluentui/pull/33148) by beachball) + +## [8.14.191](https://github.com/microsoft/fluentui/tree/@fluentui/react-experiments_v8.14.191) + +Wed, 08 Jan 2025 07:21:37 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-experiments_v8.14.190..@fluentui/react-experiments_v8.14.191) + +### Patches + +- Bump @fluentui/react to v8.122.5 ([PR #33578](https://github.com/microsoft/fluentui/pull/33578) by beachball) + +## [8.14.190](https://github.com/microsoft/fluentui/tree/@fluentui/react-experiments_v8.14.190) + +Fri, 03 Jan 2025 07:21:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-experiments_v8.14.189..@fluentui/react-experiments_v8.14.190) + +### Patches + +- Bump @fluentui/react to v8.122.4 ([PR #33529](https://github.com/microsoft/fluentui/pull/33529) by beachball) + +## [8.14.189](https://github.com/microsoft/fluentui/tree/@fluentui/react-experiments_v8.14.189) + +Mon, 30 Dec 2024 07:21:29 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-experiments_v8.14.188..@fluentui/react-experiments_v8.14.189) + +### Patches + +- Bump @fluentui/react to v8.122.3 ([PR #33520](https://github.com/microsoft/fluentui/pull/33520) by beachball) + +## [8.14.188](https://github.com/microsoft/fluentui/tree/@fluentui/react-experiments_v8.14.188) + +Mon, 23 Dec 2024 07:22:58 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-experiments_v8.14.187..@fluentui/react-experiments_v8.14.188) + +### Patches + +- Bump @fluentui/react to v8.122.2 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) +- Bump @fluentui/theme to v2.6.64 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) +- Bump @fluentui/foundation-legacy to v8.4.23 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) +- Bump @fluentui/font-icons-mdl2 to v8.5.57 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) +- Bump @fluentui/style-utilities to v8.11.6 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) + +## [8.14.187](https://github.com/microsoft/fluentui/tree/@fluentui/react-experiments_v8.14.187) + +Fri, 13 Dec 2024 07:23:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-experiments_v8.14.186..@fluentui/react-experiments_v8.14.187) + +### Patches + +- Bump @fluentui/react to v8.122.1 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) +- Bump @fluentui/foundation-legacy to v8.4.22 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) +- Bump @fluentui/font-icons-mdl2 to v8.5.56 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) +- Bump @fluentui/style-utilities to v8.11.5 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) + +## [8.14.186](https://github.com/microsoft/fluentui/tree/@fluentui/react-experiments_v8.14.186) + +Thu, 12 Dec 2024 07:22:33 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-experiments_v8.14.185..@fluentui/react-experiments_v8.14.186) + +### Patches + +- Bump @fluentui/react to v8.122.0 ([PR #33243](https://github.com/microsoft/fluentui/pull/33243) by beachball) + ## [8.14.185](https://github.com/microsoft/fluentui/tree/@fluentui/react-experiments_v8.14.185) Fri, 22 Nov 2024 07:21:18 GMT diff --git a/packages/react-experiments/package.json b/packages/react-experiments/package.json index 8fff86f8335c21..334e03c9c04503 100644 --- a/packages/react-experiments/package.json +++ b/packages/react-experiments/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-experiments", - "version": "8.14.185", + "version": "8.14.197", "description": "Experimental React components for building experiences for Microsoft 365.", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -38,17 +38,17 @@ "@fluentui/scripts-webpack": "*" }, "dependencies": { - "@fluentui/react": "^8.121.13", - "@fluentui/theme": "^2.6.63", + "@fluentui/react": "^8.122.11", + "@fluentui/theme": "^2.6.65", "@microsoft/load-themed-styles": "^1.10.26", "@fluentui/example-data": "^8.4.25", - "@fluentui/foundation-legacy": "^8.4.21", - "@fluentui/font-icons-mdl2": "^8.5.55", - "@fluentui/merge-styles": "^8.6.13", - "@fluentui/react-hooks": "^8.8.16", - "@fluentui/set-version": "^8.2.23", - "@fluentui/style-utilities": "^8.11.4", - "@fluentui/utilities": "^8.15.19", + "@fluentui/foundation-legacy": "^8.4.24", + "@fluentui/font-icons-mdl2": "^8.5.58", + "@fluentui/merge-styles": "^8.6.14", + "@fluentui/react-hooks": "^8.8.17", + "@fluentui/set-version": "^8.2.24", + "@fluentui/style-utilities": "^8.11.7", + "@fluentui/utilities": "^8.15.20", "deep-assign": "^2.0.0", "prop-types": "^15.7.2", "tslib": "^2.1.0" 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/Pagination/__snapshots__/Pagination.test.tsx.snap b/packages/react-experiments/src/components/Pagination/__snapshots__/Pagination.test.tsx.snap index 5d792ca0c57ca3..ace3981b0a5b91 100644 --- a/packages/react-experiments/src/components/Pagination/__snapshots__/Pagination.test.tsx.snap +++ b/packages/react-experiments/src/components/Pagination/__snapshots__/Pagination.test.tsx.snap @@ -1837,6 +1837,7 @@ exports[`Pagination render comboBox Pagination correctly 1`] = ` ( // 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..73cf681c0e082c 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,7 +268,7 @@ 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) { diff --git a/packages/react-experiments/src/components/Slider/Slider.base.tsx b/packages/react-experiments/src/components/Slider/Slider.base.tsx index 6da62030cbce49..d2b0ecf25ffbee 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 { 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..3f844b461e1903 100644 --- a/packages/react-experiments/src/components/UnifiedPicker/UnifiedPicker.tsx +++ b/packages/react-experiments/src/components/UnifiedPicker/UnifiedPicker.tsx @@ -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: diff --git a/packages/react-file-type-icons/CHANGELOG.json b/packages/react-file-type-icons/CHANGELOG.json index 0493641befe9f5..cfb5a5369074a5 100644 --- a/packages/react-file-type-icons/CHANGELOG.json +++ b/packages/react-file-type-icons/CHANGELOG.json @@ -1,6 +1,63 @@ { "name": "@fluentui/react-file-type-icons", "entries": [ + { + "date": "Fri, 21 Feb 2025 07:22:41 GMT", + "tag": "@fluentui/react-file-type-icons_v8.12.8", + "version": "8.12.8", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-file-type-icons", + "comment": "Bump @fluentui/set-version to v8.2.24", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react-file-type-icons", + "comment": "Bump @fluentui/style-utilities to v8.11.7", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + } + ] + } + }, + { + "date": "Mon, 23 Dec 2024 07:22:58 GMT", + "tag": "@fluentui/react-file-type-icons_v8.12.7", + "version": "8.12.7", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-file-type-icons", + "comment": "Bump @fluentui/style-utilities to v8.11.6", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + } + ] + } + }, + { + "date": "Fri, 13 Dec 2024 07:23:12 GMT", + "tag": "@fluentui/react-file-type-icons_v8.12.6", + "version": "8.12.6", + "comments": { + "patch": [ + { + "author": "caperez@microsoft.com", + "package": "@fluentui/react-file-type-icons", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7", + "comment": "Adding cliptemplate and listform filetype and itemtype mappings & updating corresponding fabric-cdn URL" + }, + { + "author": "beachball", + "package": "@fluentui/react-file-type-icons", + "comment": "Bump @fluentui/style-utilities to v8.11.5", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7" + } + ] + } + }, { "date": "Fri, 22 Nov 2024 07:21:17 GMT", "tag": "@fluentui/react-file-type-icons_v8.12.5", diff --git a/packages/react-file-type-icons/CHANGELOG.md b/packages/react-file-type-icons/CHANGELOG.md index 5ac4e4f2904edf..0eb3e45f6da6e7 100644 --- a/packages/react-file-type-icons/CHANGELOG.md +++ b/packages/react-file-type-icons/CHANGELOG.md @@ -1,9 +1,38 @@ # Change Log - @fluentui/react-file-type-icons -This log was last generated on Fri, 22 Nov 2024 07:21:17 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 07:22:41 GMT and should not be manually modified. +## [8.12.8](https://github.com/microsoft/fluentui/tree/@fluentui/react-file-type-icons_v8.12.8) + +Fri, 21 Feb 2025 07:22:41 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-file-type-icons_v8.12.7..@fluentui/react-file-type-icons_v8.12.8) + +### Patches + +- Bump @fluentui/set-version to v8.2.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/style-utilities to v8.11.7 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) + +## [8.12.7](https://github.com/microsoft/fluentui/tree/@fluentui/react-file-type-icons_v8.12.7) + +Mon, 23 Dec 2024 07:22:58 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-file-type-icons_v8.12.6..@fluentui/react-file-type-icons_v8.12.7) + +### Patches + +- Bump @fluentui/style-utilities to v8.11.6 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) + +## [8.12.6](https://github.com/microsoft/fluentui/tree/@fluentui/react-file-type-icons_v8.12.6) + +Fri, 13 Dec 2024 07:23:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-file-type-icons_v8.12.5..@fluentui/react-file-type-icons_v8.12.6) + +### Patches + +- Adding cliptemplate and listform filetype and itemtype mappings & updating corresponding fabric-cdn URL ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by caperez@microsoft.com) +- Bump @fluentui/style-utilities to v8.11.5 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) + ## [8.12.5](https://github.com/microsoft/fluentui/tree/@fluentui/react-file-type-icons_v8.12.5) Fri, 22 Nov 2024 07:21:17 GMT diff --git a/packages/react-file-type-icons/package.json b/packages/react-file-type-icons/package.json index 96b699676c7806..626119f04f22a0 100644 --- a/packages/react-file-type-icons/package.json +++ b/packages/react-file-type-icons/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-file-type-icons", - "version": "8.12.5", + "version": "8.12.8", "description": "Fluent UI React file type icon set.", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -27,8 +27,8 @@ "@fluentui/scripts-tasks": "*" }, "dependencies": { - "@fluentui/set-version": "^8.2.23", - "@fluentui/style-utilities": "^8.11.4", + "@fluentui/set-version": "^8.2.24", + "@fluentui/style-utilities": "^8.11.7", "tslib": "^2.1.0" }, "peerDependencies": { diff --git a/packages/react-file-type-icons/src/FileIconType.ts b/packages/react-file-type-icons/src/FileIconType.ts index f4279ecdb1b70d..22a7ee22bfcf81 100644 --- a/packages/react-file-type-icons/src/FileIconType.ts +++ b/packages/react-file-type-icons/src/FileIconType.ts @@ -27,6 +27,7 @@ export enum FileIconType { todoItem = 19, portfolio = 20, album = 21, + listForm = 22, } export type FileIconTypeInput = @@ -50,4 +51,5 @@ export type FileIconTypeInput = | 18 | 19 | 20 - | 21; + | 21 + | 22; diff --git a/packages/react-file-type-icons/src/FileTypeIconMap.ts b/packages/react-file-type-icons/src/FileTypeIconMap.ts index e2b770aa3683e0..125af0017b6660 100644 --- a/packages/react-file-type-icons/src/FileTypeIconMap.ts +++ b/packages/react-file-type-icons/src/FileTypeIconMap.ts @@ -48,6 +48,9 @@ export const FileTypeIconMap: { [key: string]: { extensions?: string[] } } = { clipchamp: { extensions: ['clipchamp'], }, + cliptemplate: { + extensions: ['cliptemplate'], + }, code: { extensions: [ 'abap', @@ -301,6 +304,7 @@ export const FileTypeIconMap: { [key: string]: { extensions?: string[] } } = { extensions: ['lnk', 'link', 'url', 'website', 'webloc'], }, linkedfolder: {}, + listform: {}, listitem: {}, loop: { extensions: ['fluid', 'loop', 'note'], diff --git a/packages/react-file-type-icons/src/getFileTypeIconProps.ts b/packages/react-file-type-icons/src/getFileTypeIconProps.ts index f8772e473c17cc..f0a13076e346ef 100644 --- a/packages/react-file-type-icons/src/getFileTypeIconProps.ts +++ b/packages/react-file-type-icons/src/getFileTypeIconProps.ts @@ -25,6 +25,7 @@ const TODOITEM = 'todoitem'; const PLANNER = 'planner'; const PORTFOLIO = 'portfolio'; const ALBUM = 'album'; +const LIST_FORM = 'listform'; export const DEFAULT_ICON_SIZE: FileTypeIconSize = 16; export type FileTypeIconSize = 16 | 20 | 24 | 32 | 40 | 48 | 64 | 96; @@ -163,6 +164,9 @@ export function getFileTypeIconNameFromExtensionOrType( case FileIconType.album: iconBaseName = ALBUM; break; + case FileIconType.listForm: + iconBaseName = LIST_FORM; + break; } } return iconBaseName || GENERIC_FILE; diff --git a/packages/react-focus/CHANGELOG.json b/packages/react-focus/CHANGELOG.json index f6825ce919e922..ba1d6efb340fcd 100644 --- a/packages/react-focus/CHANGELOG.json +++ b/packages/react-focus/CHANGELOG.json @@ -1,6 +1,84 @@ { "name": "@fluentui/react-focus", "entries": [ + { + "date": "Fri, 21 Feb 2025 07:22:41 GMT", + "tag": "@fluentui/react-focus_v8.9.21", + "version": "8.9.21", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-focus", + "comment": "Bump @fluentui/merge-styles to v8.6.14", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react-focus", + "comment": "Bump @fluentui/set-version to v8.2.24", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react-focus", + "comment": "Bump @fluentui/style-utilities to v8.11.7", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react-focus", + "comment": "Bump @fluentui/utilities to v8.15.20", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + } + ] + } + }, + { + "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", + "version": "8.9.20", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-focus", + "comment": "Bump @fluentui/style-utilities to v8.11.6", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + } + ] + } + }, + { + "date": "Fri, 13 Dec 2024 07:23:12 GMT", + "tag": "@fluentui/react-focus_v8.9.19", + "version": "8.9.19", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-focus", + "comment": "Bump @fluentui/style-utilities to v8.11.5", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7" + } + ] + } + }, { "date": "Fri, 01 Nov 2024 07:23:21 GMT", "tag": "@fluentui/react-focus_v8.9.18", diff --git a/packages/react-focus/CHANGELOG.md b/packages/react-focus/CHANGELOG.md index 9ed3d524146298..d13b24b31bc6fc 100644 --- a/packages/react-focus/CHANGELOG.md +++ b/packages/react-focus/CHANGELOG.md @@ -1,9 +1,39 @@ # Change Log - @fluentui/react-focus -This log was last generated on Fri, 01 Nov 2024 07:23:21 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 07:22:41 GMT and should not be manually modified. +## [8.9.21](https://github.com/microsoft/fluentui/tree/@fluentui/react-focus_v8.9.21) + +Fri, 21 Feb 2025 07:22:41 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-focus_v8.9.20..@fluentui/react-focus_v8.9.21) + +### Patches + +- Bump @fluentui/merge-styles to v8.6.14 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/set-version to v8.2.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/style-utilities to v8.11.7 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/utilities to v8.15.20 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) + +## [8.9.20](https://github.com/microsoft/fluentui/tree/@fluentui/react-focus_v8.9.20) + +Mon, 23 Dec 2024 07:22:58 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-focus_v8.9.19..@fluentui/react-focus_v8.9.20) + +### Patches + +- Bump @fluentui/style-utilities to v8.11.6 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) + +## [8.9.19](https://github.com/microsoft/fluentui/tree/@fluentui/react-focus_v8.9.19) + +Fri, 13 Dec 2024 07:23:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-focus_v8.9.18..@fluentui/react-focus_v8.9.19) + +### Patches + +- Bump @fluentui/style-utilities to v8.11.5 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) + ## [8.9.18](https://github.com/microsoft/fluentui/tree/@fluentui/react-focus_v8.9.18) Fri, 01 Nov 2024 07:23:21 GMT diff --git a/packages/react-focus/package.json b/packages/react-focus/package.json index 8709f4ec87d939..40c875baec2946 100644 --- a/packages/react-focus/package.json +++ b/packages/react-focus/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-focus", - "version": "8.9.18", + "version": "8.9.21", "description": "Focus helpers to be used in React applications.", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -36,10 +36,10 @@ }, "dependencies": { "@fluentui/keyboard-key": "^0.4.23", - "@fluentui/merge-styles": "^8.6.13", - "@fluentui/set-version": "^8.2.23", - "@fluentui/style-utilities": "^8.11.4", - "@fluentui/utilities": "^8.15.19", + "@fluentui/merge-styles": "^8.6.14", + "@fluentui/set-version": "^8.2.24", + "@fluentui/style-utilities": "^8.11.7", + "@fluentui/utilities": "^8.15.20", "tslib": "^2.1.0" }, "peerDependencies": { 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/CHANGELOG.json b/packages/react-hooks/CHANGELOG.json index 24609071049ccc..3a4c2846429fef 100644 --- a/packages/react-hooks/CHANGELOG.json +++ b/packages/react-hooks/CHANGELOG.json @@ -1,6 +1,33 @@ { "name": "@fluentui/react-hooks", "entries": [ + { + "date": "Fri, 21 Feb 2025 07:22:41 GMT", + "tag": "@fluentui/react-hooks_v8.8.17", + "version": "8.8.17", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-hooks", + "comment": "Bump @fluentui/react-window-provider to v2.2.29", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react-hooks", + "comment": "Bump @fluentui/set-version to v8.2.24", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react-hooks", + "comment": "Bump @fluentui/utilities to v8.15.20", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + } + ] + } + }, { "date": "Wed, 20 Nov 2024 07:21:54 GMT", "tag": "@fluentui/react-hooks_v8.8.16", diff --git a/packages/react-hooks/CHANGELOG.md b/packages/react-hooks/CHANGELOG.md index 8d39dfab72d417..ed58928007867d 100644 --- a/packages/react-hooks/CHANGELOG.md +++ b/packages/react-hooks/CHANGELOG.md @@ -1,9 +1,20 @@ # Change Log - @fluentui/react-hooks -This log was last generated on Fri, 11 Oct 2024 16:51:54 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 07:22:41 GMT and should not be manually modified. +## [8.8.17](https://github.com/microsoft/fluentui/tree/@fluentui/react-hooks_v8.8.17) + +Fri, 21 Feb 2025 07:22:41 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-hooks_v8.8.16..@fluentui/react-hooks_v8.8.17) + +### Patches + +- Bump @fluentui/react-window-provider to v2.2.29 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/set-version to v8.2.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/utilities to v8.15.20 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) + ## [8.8.16](https://github.com/microsoft/fluentui/tree/@fluentui/react-hooks_v8.8.16) Fri, 11 Oct 2024 16:51:54 GMT diff --git a/packages/react-hooks/package.json b/packages/react-hooks/package.json index d96dcf97b8d823..d524c19458e7d8 100644 --- a/packages/react-hooks/package.json +++ b/packages/react-hooks/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-hooks", - "version": "8.8.16", + "version": "8.8.17", "description": "Fluent UI React hooks.", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -31,9 +31,9 @@ "@fluentui/scripts-webpack": "*" }, "dependencies": { - "@fluentui/react-window-provider": "^2.2.28", - "@fluentui/set-version": "^8.2.23", - "@fluentui/utilities": "^8.15.19", + "@fluentui/react-window-provider": "^2.2.29", + "@fluentui/set-version": "^8.2.24", + "@fluentui/utilities": "^8.15.20", "tslib": "^2.1.0" }, "peerDependencies": { 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-icon-provider/CHANGELOG.json b/packages/react-icon-provider/CHANGELOG.json index b980aa3a76d8ff..08eebb49d1edb1 100644 --- a/packages/react-icon-provider/CHANGELOG.json +++ b/packages/react-icon-provider/CHANGELOG.json @@ -1,6 +1,63 @@ { "name": "@fluentui/react-icon-provider", "entries": [ + { + "date": "Fri, 21 Feb 2025 07:22:41 GMT", + "tag": "@fluentui/react-icon-provider_v1.3.79", + "version": "1.3.79", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-icon-provider", + "comment": "Bump @fluentui/set-version to v8.2.24", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react-icon-provider", + "comment": "Bump @fluentui/style-utilities to v8.11.7", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + } + ] + } + }, + { + "date": "Mon, 23 Dec 2024 07:22:57 GMT", + "tag": "@fluentui/react-icon-provider_v1.3.78", + "version": "1.3.78", + "comments": { + "patch": [ + { + "author": "olfedias@microsoft.com", + "package": "@fluentui/react-icon-provider", + "commit": "dc7bb663e3d93a19b611cf1892556d69c57b1269", + "comment": "chore: remove usage of \"export *\"" + }, + { + "author": "beachball", + "package": "@fluentui/react-icon-provider", + "comment": "Bump @fluentui/style-utilities to v8.11.6", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + } + ] + } + }, + { + "date": "Fri, 13 Dec 2024 07:23:12 GMT", + "tag": "@fluentui/react-icon-provider_v1.3.77", + "version": "1.3.77", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-icon-provider", + "comment": "Bump @fluentui/style-utilities to v8.11.5", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7" + } + ] + } + }, { "date": "Fri, 01 Nov 2024 07:23:21 GMT", "tag": "@fluentui/react-icon-provider_v1.3.76", diff --git a/packages/react-icon-provider/CHANGELOG.md b/packages/react-icon-provider/CHANGELOG.md index 8490c8749b1653..51e833142ba4f9 100644 --- a/packages/react-icon-provider/CHANGELOG.md +++ b/packages/react-icon-provider/CHANGELOG.md @@ -1,9 +1,38 @@ # Change Log - @fluentui/react-icon-provider -This log was last generated on Fri, 01 Nov 2024 07:23:21 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 07:22:41 GMT and should not be manually modified. +## [1.3.79](https://github.com/microsoft/fluentui/tree/@fluentui/react-icon-provider_v1.3.79) + +Fri, 21 Feb 2025 07:22:41 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-icon-provider_v1.3.78..@fluentui/react-icon-provider_v1.3.79) + +### Patches + +- Bump @fluentui/set-version to v8.2.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/style-utilities to v8.11.7 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) + +## [1.3.78](https://github.com/microsoft/fluentui/tree/@fluentui/react-icon-provider_v1.3.78) + +Mon, 23 Dec 2024 07:22:57 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-icon-provider_v1.3.77..@fluentui/react-icon-provider_v1.3.78) + +### Patches + +- chore: remove usage of "export *" ([PR #33448](https://github.com/microsoft/fluentui/pull/33448) by olfedias@microsoft.com) +- Bump @fluentui/style-utilities to v8.11.6 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) + +## [1.3.77](https://github.com/microsoft/fluentui/tree/@fluentui/react-icon-provider_v1.3.77) + +Fri, 13 Dec 2024 07:23:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-icon-provider_v1.3.76..@fluentui/react-icon-provider_v1.3.77) + +### Patches + +- Bump @fluentui/style-utilities to v8.11.5 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) + ## [1.3.76](https://github.com/microsoft/fluentui/tree/@fluentui/react-icon-provider_v1.3.76) Fri, 01 Nov 2024 07:23:21 GMT diff --git a/packages/react-icon-provider/package.json b/packages/react-icon-provider/package.json index 5d0b805e9fde49..1f14280191671e 100644 --- a/packages/react-icon-provider/package.json +++ b/packages/react-icon-provider/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-icon-provider", - "version": "1.3.76", + "version": "1.3.79", "description": "Package for applying icon overrides to Fluent UI React SVG icons", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -29,8 +29,8 @@ "@fluentui/scripts-webpack": "*" }, "dependencies": { - "@fluentui/set-version": "^8.2.23", - "@fluentui/style-utilities": "^8.11.4", + "@fluentui/set-version": "^8.2.24", + "@fluentui/style-utilities": "^8.11.7", "tslib": "^2.1.0" }, "peerDependencies": { diff --git a/packages/react-icon-provider/src/index.ts b/packages/react-icon-provider/src/index.ts index b77b5beee663cc..9e6599b016afe5 100644 --- a/packages/react-icon-provider/src/index.ts +++ b/packages/react-icon-provider/src/index.ts @@ -1,4 +1,9 @@ import './version'; -export * from './IconProvider'; -export * from './IconProvider.types'; +export { + // eslint-disable-next-line @fluentui/ban-context-export + IconContext, + IconProvider, + useIconSubset, +} from './IconProvider'; +export type { IconProviderProps } from './IconProvider.types'; diff --git a/packages/react-icons-mdl2-branded/CHANGELOG.json b/packages/react-icons-mdl2-branded/CHANGELOG.json index 100d6473d92f88..f847cabd6c751a 100644 --- a/packages/react-icons-mdl2-branded/CHANGELOG.json +++ b/packages/react-icons-mdl2-branded/CHANGELOG.json @@ -1,6 +1,57 @@ { "name": "@fluentui/react-icons-mdl2-branded", "entries": [ + { + "date": "Fri, 21 Feb 2025 07:22:41 GMT", + "tag": "@fluentui/react-icons-mdl2-branded_v1.2.85", + "version": "1.2.85", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-icons-mdl2-branded", + "comment": "Bump @fluentui/set-version to v8.2.24", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react-icons-mdl2-branded", + "comment": "Bump @fluentui/react-icons-mdl2 to v1.3.83", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + } + ] + } + }, + { + "date": "Mon, 23 Dec 2024 07:22:58 GMT", + "tag": "@fluentui/react-icons-mdl2-branded_v1.2.84", + "version": "1.2.84", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-icons-mdl2-branded", + "comment": "Bump @fluentui/react-icons-mdl2 to v1.3.82", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + } + ] + } + }, + { + "date": "Fri, 13 Dec 2024 07:23:12 GMT", + "tag": "@fluentui/react-icons-mdl2-branded_v1.2.83", + "version": "1.2.83", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-icons-mdl2-branded", + "comment": "Bump @fluentui/react-icons-mdl2 to v1.3.81", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7" + } + ] + } + }, { "date": "Fri, 01 Nov 2024 07:23:21 GMT", "tag": "@fluentui/react-icons-mdl2-branded_v1.2.82", diff --git a/packages/react-icons-mdl2-branded/CHANGELOG.md b/packages/react-icons-mdl2-branded/CHANGELOG.md index 7826febdb2997d..c216562b214d78 100644 --- a/packages/react-icons-mdl2-branded/CHANGELOG.md +++ b/packages/react-icons-mdl2-branded/CHANGELOG.md @@ -1,9 +1,37 @@ # Change Log - @fluentui/react-icons-mdl2-branded -This log was last generated on Fri, 01 Nov 2024 07:23:21 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 07:22:41 GMT and should not be manually modified. +## [1.2.85](https://github.com/microsoft/fluentui/tree/@fluentui/react-icons-mdl2-branded_v1.2.85) + +Fri, 21 Feb 2025 07:22:41 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-icons-mdl2-branded_v1.2.84..@fluentui/react-icons-mdl2-branded_v1.2.85) + +### Patches + +- Bump @fluentui/set-version to v8.2.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/react-icons-mdl2 to v1.3.83 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) + +## [1.2.84](https://github.com/microsoft/fluentui/tree/@fluentui/react-icons-mdl2-branded_v1.2.84) + +Mon, 23 Dec 2024 07:22:58 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-icons-mdl2-branded_v1.2.83..@fluentui/react-icons-mdl2-branded_v1.2.84) + +### Patches + +- Bump @fluentui/react-icons-mdl2 to v1.3.82 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) + +## [1.2.83](https://github.com/microsoft/fluentui/tree/@fluentui/react-icons-mdl2-branded_v1.2.83) + +Fri, 13 Dec 2024 07:23:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-icons-mdl2-branded_v1.2.82..@fluentui/react-icons-mdl2-branded_v1.2.83) + +### Patches + +- Bump @fluentui/react-icons-mdl2 to v1.3.81 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) + ## [1.2.82](https://github.com/microsoft/fluentui/tree/@fluentui/react-icons-mdl2-branded_v1.2.82) Fri, 01 Nov 2024 07:23:21 GMT diff --git a/packages/react-icons-mdl2-branded/package.json b/packages/react-icons-mdl2-branded/package.json index 546c5158b61f84..cacd3be70c30d1 100644 --- a/packages/react-icons-mdl2-branded/package.json +++ b/packages/react-icons-mdl2-branded/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-icons-mdl2-branded", - "version": "1.2.82", + "version": "1.2.85", "description": "Branded SVG icons from the MDL2 icon set", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -25,8 +25,8 @@ "@fluentui/scripts-tasks": "*" }, "dependencies": { - "@fluentui/set-version": "^8.2.23", - "@fluentui/react-icons-mdl2": "^1.3.80", + "@fluentui/set-version": "^8.2.24", + "@fluentui/react-icons-mdl2": "^1.3.83", "tslib": "^2.1.0" }, "peerDependencies": { diff --git a/packages/react-icons-mdl2/CHANGELOG.json b/packages/react-icons-mdl2/CHANGELOG.json index d1118b3c48ce3d..28527df508d3ca 100644 --- a/packages/react-icons-mdl2/CHANGELOG.json +++ b/packages/react-icons-mdl2/CHANGELOG.json @@ -1,6 +1,63 @@ { "name": "@fluentui/react-icons-mdl2", "entries": [ + { + "date": "Fri, 21 Feb 2025 07:22:41 GMT", + "tag": "@fluentui/react-icons-mdl2_v1.3.83", + "version": "1.3.83", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-icons-mdl2", + "comment": "Bump @fluentui/react-icon-provider to v1.3.79", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react-icons-mdl2", + "comment": "Bump @fluentui/set-version to v8.2.24", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react-icons-mdl2", + "comment": "Bump @fluentui/utilities to v8.15.20", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + } + ] + } + }, + { + "date": "Mon, 23 Dec 2024 07:22:58 GMT", + "tag": "@fluentui/react-icons-mdl2_v1.3.82", + "version": "1.3.82", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-icons-mdl2", + "comment": "Bump @fluentui/react-icon-provider to v1.3.78", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + } + ] + } + }, + { + "date": "Fri, 13 Dec 2024 07:23:12 GMT", + "tag": "@fluentui/react-icons-mdl2_v1.3.81", + "version": "1.3.81", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-icons-mdl2", + "comment": "Bump @fluentui/react-icon-provider to v1.3.77", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7" + } + ] + } + }, { "date": "Fri, 01 Nov 2024 07:23:21 GMT", "tag": "@fluentui/react-icons-mdl2_v1.3.80", diff --git a/packages/react-icons-mdl2/CHANGELOG.md b/packages/react-icons-mdl2/CHANGELOG.md index 269b8ea90dbb27..d475b806aaefff 100644 --- a/packages/react-icons-mdl2/CHANGELOG.md +++ b/packages/react-icons-mdl2/CHANGELOG.md @@ -1,9 +1,38 @@ # Change Log - @fluentui/react-icons-mdl2 -This log was last generated on Fri, 01 Nov 2024 07:23:21 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 07:22:41 GMT and should not be manually modified. +## [1.3.83](https://github.com/microsoft/fluentui/tree/@fluentui/react-icons-mdl2_v1.3.83) + +Fri, 21 Feb 2025 07:22:41 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-icons-mdl2_v1.3.82..@fluentui/react-icons-mdl2_v1.3.83) + +### Patches + +- Bump @fluentui/react-icon-provider to v1.3.79 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/set-version to v8.2.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/utilities to v8.15.20 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) + +## [1.3.82](https://github.com/microsoft/fluentui/tree/@fluentui/react-icons-mdl2_v1.3.82) + +Mon, 23 Dec 2024 07:22:58 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-icons-mdl2_v1.3.81..@fluentui/react-icons-mdl2_v1.3.82) + +### Patches + +- Bump @fluentui/react-icon-provider to v1.3.78 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) + +## [1.3.81](https://github.com/microsoft/fluentui/tree/@fluentui/react-icons-mdl2_v1.3.81) + +Fri, 13 Dec 2024 07:23:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-icons-mdl2_v1.3.80..@fluentui/react-icons-mdl2_v1.3.81) + +### Patches + +- Bump @fluentui/react-icon-provider to v1.3.77 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) + ## [1.3.80](https://github.com/microsoft/fluentui/tree/@fluentui/react-icons-mdl2_v1.3.80) Fri, 01 Nov 2024 07:23:21 GMT diff --git a/packages/react-icons-mdl2/package.json b/packages/react-icons-mdl2/package.json index 675ec9fe177228..546fee5cfbf4db 100644 --- a/packages/react-icons-mdl2/package.json +++ b/packages/react-icons-mdl2/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-icons-mdl2", - "version": "1.3.80", + "version": "1.3.83", "description": "SVG icon components for @fluentui/react", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -31,9 +31,9 @@ }, "dependencies": { "@microsoft/load-themed-styles": "^1.10.26", - "@fluentui/react-icon-provider": "^1.3.76", - "@fluentui/set-version": "^8.2.23", - "@fluentui/utilities": "^8.15.19", + "@fluentui/react-icon-provider": "^1.3.79", + "@fluentui/set-version": "^8.2.24", + "@fluentui/utilities": "^8.15.20", "tslib": "^2.1.0" }, "peerDependencies": { diff --git a/packages/react-monaco-editor/CHANGELOG.json b/packages/react-monaco-editor/CHANGELOG.json index 38339fd36b7141..02ac858c227123 100644 --- a/packages/react-monaco-editor/CHANGELOG.json +++ b/packages/react-monaco-editor/CHANGELOG.json @@ -1,6 +1,617 @@ { "name": "@fluentui/react-monaco-editor", "entries": [ + { + "date": "Fri, 21 Feb 2025 07:22:41 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.294", + "version": "1.7.294", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react to v8.122.11", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-hooks to v8.8.17", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.56", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + } + ] + } + }, + { + "date": "Wed, 19 Feb 2025 07:21:16 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.293", + "version": "1.7.293", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react to v8.122.10", + "commit": "8264ce0435583ae69c051f109388005be3c0de2b" + }, + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.55", + "commit": "8264ce0435583ae69c051f109388005be3c0de2b" + } + ] + } + }, + { + "date": "Thu, 13 Feb 2025 07:22:18 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.292", + "version": "1.7.292", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.54", + "commit": "da21d6906904f1c56d4f71f720a18e8cbc45841b" + } + ] + } + }, + { + "date": "Wed, 12 Feb 2025 07:20:52 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.291", + "version": "1.7.291", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.53", + "commit": "90aca06e2500c9dda895c2a220923baf2a602297" + } + ] + } + }, + { + "date": "Tue, 11 Feb 2025 07:21:12 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.290", + "version": "1.7.290", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.52", + "commit": "f45bd1071de1e3a8aa9c7177438e2559498b7920" + } + ] + } + }, + { + "date": "Wed, 05 Feb 2025 07:16:29 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.289", + "version": "1.7.289", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.51", + "commit": "5f1fb069b5da9c7a104063184eacce1927c06f7c" + } + ] + } + }, + { + "date": "Fri, 31 Jan 2025 07:21:30 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.288", + "version": "1.7.288", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.50", + "commit": "171c1b1bda0d403270e828fbad3d8c7b791e21af" + } + ] + } + }, + { + "date": "Thu, 30 Jan 2025 07:20:49 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.287", + "version": "1.7.287", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.49", + "commit": "fa5549e7d9da4865ac079c8c7b284106813a7e82" + } + ] + } + }, + { + "date": "Wed, 29 Jan 2025 07:21:15 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.286", + "version": "1.7.286", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react to v8.122.9", + "commit": "111bf937b3793db68e32a90774b04f3bf61f4be5" + }, + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.48", + "commit": "111bf937b3793db68e32a90774b04f3bf61f4be5" + } + ] + } + }, + { + "date": "Mon, 27 Jan 2025 07:20:35 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.285", + "version": "1.7.285", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.47", + "commit": "87d6ba3bd577a8be9756f4d392b048083d8ef16a" + } + ] + } + }, + { + "date": "Fri, 24 Jan 2025 07:20:37 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.284", + "version": "1.7.284", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.46", + "commit": "cb0f0c9653a8a5c53012d35d81498de263a8f3cf" + } + ] + } + }, + { + "date": "Thu, 23 Jan 2025 07:21:32 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.283", + "version": "1.7.283", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.45", + "commit": "af631b94cfaa3e9a9d79160236a7f0679240777b" + } + ] + } + }, + { + "date": "Wed, 22 Jan 2025 07:21:49 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.282", + "version": "1.7.282", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react to v8.122.8", + "commit": "012298d98651800023aac24c591831e9bc51bea2" + }, + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.44", + "commit": "012298d98651800023aac24c591831e9bc51bea2" + } + ] + } + }, + { + "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", + "version": "1.7.278", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react to v8.122.6", + "commit": "bf60a56cb23b3af90bcb62462c2423468eb9fa3c" + }, + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.40", + "commit": "bf60a56cb23b3af90bcb62462c2423468eb9fa3c" + } + ] + } + }, + { + "date": "Wed, 08 Jan 2025 07:21:37 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.277", + "version": "1.7.277", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react to v8.122.5", + "commit": "8f763922d713d9ccd35e65db07206c10b170fafd" + }, + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.39", + "commit": "8f763922d713d9ccd35e65db07206c10b170fafd" + } + ] + } + }, + { + "date": "Mon, 06 Jan 2025 07:16:33 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.276", + "version": "1.7.276", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.38", + "commit": "1ffbd975d75f5593a295adcf894cf7d821560e80" + } + ] + } + }, + { + "date": "Fri, 03 Jan 2025 07:21:32 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.275", + "version": "1.7.275", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react to v8.122.4", + "commit": "7bb97f178d73a470dc438a2b19d165d9d0bd4b51" + }, + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.37", + "commit": "7bb97f178d73a470dc438a2b19d165d9d0bd4b51" + } + ] + } + }, + { + "date": "Thu, 02 Jan 2025 07:22:03 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.274", + "version": "1.7.274", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.36", + "commit": "6bd14a98fb5bec1eb26dfbada654fc1588249fa8" + } + ] + } + }, + { + "date": "Wed, 01 Jan 2025 07:21:10 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.273", + "version": "1.7.273", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.35", + "commit": "bf1b91f1fd3cfb580185870b6a4b77738384f9d2" + } + ] + } + }, + { + "date": "Tue, 31 Dec 2024 07:21:45 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.272", + "version": "1.7.272", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.34", + "commit": "d61ac31da90bf8f73f54262e196b3a83b9a85932" + } + ] + } + }, + { + "date": "Mon, 30 Dec 2024 07:21:29 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.271", + "version": "1.7.271", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react to v8.122.3", + "commit": "681a95a732fe385a70b8d4537dc489acbcd1c21e" + }, + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.33", + "commit": "681a95a732fe385a70b8d4537dc489acbcd1c21e" + } + ] + } + }, + { + "date": "Fri, 27 Dec 2024 07:20:59 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.270", + "version": "1.7.270", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.32", + "commit": "99cbe5c9cc9c298d78e10301b37d314b68ba8c52" + } + ] + } + }, + { + "date": "Thu, 26 Dec 2024 07:21:14 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.269", + "version": "1.7.269", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.31", + "commit": "0dd9a713b54a6d5b5929ac7febd1c7e44c83efca" + } + ] + } + }, + { + "date": "Wed, 25 Dec 2024 07:21:56 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.268", + "version": "1.7.268", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.30", + "commit": "fa08fec97a5bc070e2866633c792f7066f0c86e8" + } + ] + } + }, + { + "date": "Mon, 23 Dec 2024 07:22:58 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.267", + "version": "1.7.267", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react to v8.122.2", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + }, + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.29", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + } + ] + } + }, + { + "date": "Fri, 20 Dec 2024 07:20:01 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.266", + "version": "1.7.266", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.28", + "commit": "7f1647fadcd193c0d16e51b314d299ee19ae5746" + } + ] + } + }, + { + "date": "Wed, 18 Dec 2024 07:20:30 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.265", + "version": "1.7.265", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.27", + "commit": "6bcbe87a1b1d876c1437a6ae13818f265e5bb5c6" + } + ] + } + }, + { + "date": "Tue, 17 Dec 2024 07:21:19 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.264", + "version": "1.7.264", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.26", + "commit": "4487ca6a37b19e06ed494e819805c1abfb8c7afa" + } + ] + } + }, + { + "date": "Mon, 16 Dec 2024 07:20:45 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.263", + "version": "1.7.263", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.25", + "commit": "b5d571f692b983b6eb39a2dc43a8b95016a32a4c" + } + ] + } + }, + { + "date": "Fri, 13 Dec 2024 07:23:12 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.262", + "version": "1.7.262", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react to v8.122.1", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7" + }, + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.24", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7" + } + ] + } + }, + { + "date": "Thu, 12 Dec 2024 07:22:33 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.261", + "version": "1.7.261", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react to v8.122.0", + "commit": "53dd771e70338065810404663cd6219d1b54c1e2" + }, + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.23", + "commit": "53dd771e70338065810404663cd6219d1b54c1e2" + } + ] + } + }, + { + "date": "Mon, 09 Dec 2024 07:21:03 GMT", + "tag": "@fluentui/react-monaco-editor_v1.7.260", + "version": "1.7.260", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-monaco-editor", + "comment": "Bump @fluentui/react-charting to v5.23.22", + "commit": "c688295efb1f16317bea6bff67ea6cdf886155ef" + } + ] + } + }, { "date": "Fri, 06 Dec 2024 07:21:16 GMT", "tag": "@fluentui/react-monaco-editor_v1.7.259", diff --git a/packages/react-monaco-editor/CHANGELOG.md b/packages/react-monaco-editor/CHANGELOG.md index 826bfa33d55607..9626ee1ba821a7 100644 --- a/packages/react-monaco-editor/CHANGELOG.md +++ b/packages/react-monaco-editor/CHANGELOG.md @@ -1,9 +1,337 @@ # Change Log - @fluentui/react-monaco-editor -This log was last generated on Fri, 06 Dec 2024 07:21:16 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 07:22:41 GMT and should not be manually modified. +## [1.7.294](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.294) + +Fri, 21 Feb 2025 07:22:41 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.293..@fluentui/react-monaco-editor_v1.7.294) + +### Patches + +- Bump @fluentui/react to v8.122.11 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/react-hooks to v8.8.17 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/react-charting to v5.23.56 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) + +## [1.7.293](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.293) + +Wed, 19 Feb 2025 07:21:16 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.292..@fluentui/react-monaco-editor_v1.7.293) + +### Patches + +- Bump @fluentui/react to v8.122.10 ([PR #33867](https://github.com/microsoft/fluentui/pull/33867) by beachball) +- Bump @fluentui/react-charting to v5.23.55 ([PR #33867](https://github.com/microsoft/fluentui/pull/33867) by beachball) + +## [1.7.292](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.292) + +Thu, 13 Feb 2025 07:22:18 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.291..@fluentui/react-monaco-editor_v1.7.292) + +### Patches + +- Bump @fluentui/react-charting to v5.23.54 ([commit](https://github.com/microsoft/fluentui/commit/da21d6906904f1c56d4f71f720a18e8cbc45841b) by beachball) + +## [1.7.291](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.291) + +Wed, 12 Feb 2025 07:20:52 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.290..@fluentui/react-monaco-editor_v1.7.291) + +### Patches + +- Bump @fluentui/react-charting to v5.23.53 ([PR #33814](https://github.com/microsoft/fluentui/pull/33814) by beachball) + +## [1.7.290](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.290) + +Tue, 11 Feb 2025 07:21:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.289..@fluentui/react-monaco-editor_v1.7.290) + +### Patches + +- Bump @fluentui/react-charting to v5.23.52 ([PR #33807](https://github.com/microsoft/fluentui/pull/33807) by beachball) + +## [1.7.289](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.289) + +Wed, 05 Feb 2025 07:16:29 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.288..@fluentui/react-monaco-editor_v1.7.289) + +### Patches + +- Bump @fluentui/react-charting to v5.23.51 ([PR #33773](https://github.com/microsoft/fluentui/pull/33773) by beachball) + +## [1.7.288](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.288) + +Fri, 31 Jan 2025 07:21:30 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.287..@fluentui/react-monaco-editor_v1.7.288) + +### Patches + +- Bump @fluentui/react-charting to v5.23.50 ([PR #33747](https://github.com/microsoft/fluentui/pull/33747) by beachball) + +## [1.7.287](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.287) + +Thu, 30 Jan 2025 07:20:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.286..@fluentui/react-monaco-editor_v1.7.287) + +### Patches + +- Bump @fluentui/react-charting to v5.23.49 ([PR #33696](https://github.com/microsoft/fluentui/pull/33696) by beachball) + +## [1.7.286](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.286) + +Wed, 29 Jan 2025 07:21:15 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.285..@fluentui/react-monaco-editor_v1.7.286) + +### Patches + +- Bump @fluentui/react to v8.122.9 ([PR #33713](https://github.com/microsoft/fluentui/pull/33713) by beachball) +- Bump @fluentui/react-charting to v5.23.48 ([PR #33713](https://github.com/microsoft/fluentui/pull/33713) by beachball) + +## [1.7.285](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.285) + +Mon, 27 Jan 2025 07:20:35 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.284..@fluentui/react-monaco-editor_v1.7.285) + +### Patches + +- Bump @fluentui/react-charting to v5.23.47 ([PR #33725](https://github.com/microsoft/fluentui/pull/33725) by beachball) + +## [1.7.284](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.284) + +Fri, 24 Jan 2025 07:20:37 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.283..@fluentui/react-monaco-editor_v1.7.284) + +### Patches + +- Bump @fluentui/react-charting to v5.23.46 ([PR #33717](https://github.com/microsoft/fluentui/pull/33717) by beachball) + +## [1.7.283](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.283) + +Thu, 23 Jan 2025 07:21:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.282..@fluentui/react-monaco-editor_v1.7.283) + +### Patches + +- Bump @fluentui/react-charting to v5.23.45 ([PR #33659](https://github.com/microsoft/fluentui/pull/33659) by beachball) + +## [1.7.282](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.282) + +Wed, 22 Jan 2025 07:21:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.281..@fluentui/react-monaco-editor_v1.7.282) + +### Patches + +- Bump @fluentui/react to v8.122.8 ([PR #33685](https://github.com/microsoft/fluentui/pull/33685) by beachball) +- Bump @fluentui/react-charting to v5.23.44 ([PR #33685](https://github.com/microsoft/fluentui/pull/33685) by beachball) + +## [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 +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.277..@fluentui/react-monaco-editor_v1.7.278) + +### Patches + +- Bump @fluentui/react to v8.122.6 ([PR #33148](https://github.com/microsoft/fluentui/pull/33148) by beachball) +- Bump @fluentui/react-charting to v5.23.40 ([PR #33148](https://github.com/microsoft/fluentui/pull/33148) by beachball) + +## [1.7.277](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.277) + +Wed, 08 Jan 2025 07:21:37 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.276..@fluentui/react-monaco-editor_v1.7.277) + +### Patches + +- Bump @fluentui/react to v8.122.5 ([PR #33578](https://github.com/microsoft/fluentui/pull/33578) by beachball) +- Bump @fluentui/react-charting to v5.23.39 ([PR #33578](https://github.com/microsoft/fluentui/pull/33578) by beachball) + +## [1.7.276](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.276) + +Mon, 06 Jan 2025 07:16:33 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.275..@fluentui/react-monaco-editor_v1.7.276) + +### Patches + +- Bump @fluentui/react-charting to v5.23.38 ([PR #33544](https://github.com/microsoft/fluentui/pull/33544) by beachball) + +## [1.7.275](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.275) + +Fri, 03 Jan 2025 07:21:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.274..@fluentui/react-monaco-editor_v1.7.275) + +### Patches + +- Bump @fluentui/react to v8.122.4 ([PR #33529](https://github.com/microsoft/fluentui/pull/33529) by beachball) +- Bump @fluentui/react-charting to v5.23.37 ([PR #33529](https://github.com/microsoft/fluentui/pull/33529) by beachball) + +## [1.7.274](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.274) + +Thu, 02 Jan 2025 07:22:03 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.273..@fluentui/react-monaco-editor_v1.7.274) + +### Patches + +- Bump @fluentui/react-charting to v5.23.36 ([PR #33538](https://github.com/microsoft/fluentui/pull/33538) by beachball) + +## [1.7.273](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.273) + +Wed, 01 Jan 2025 07:21:10 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.272..@fluentui/react-monaco-editor_v1.7.273) + +### Patches + +- Bump @fluentui/react-charting to v5.23.35 ([PR #33525](https://github.com/microsoft/fluentui/pull/33525) by beachball) + +## [1.7.272](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.272) + +Tue, 31 Dec 2024 07:21:45 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.271..@fluentui/react-monaco-editor_v1.7.272) + +### Patches + +- Bump @fluentui/react-charting to v5.23.34 ([PR #33524](https://github.com/microsoft/fluentui/pull/33524) by beachball) + +## [1.7.271](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.271) + +Mon, 30 Dec 2024 07:21:29 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.270..@fluentui/react-monaco-editor_v1.7.271) + +### Patches + +- Bump @fluentui/react to v8.122.3 ([PR #33520](https://github.com/microsoft/fluentui/pull/33520) by beachball) +- Bump @fluentui/react-charting to v5.23.33 ([PR #33520](https://github.com/microsoft/fluentui/pull/33520) by beachball) + +## [1.7.270](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.270) + +Fri, 27 Dec 2024 07:20:59 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.269..@fluentui/react-monaco-editor_v1.7.270) + +### Patches + +- Bump @fluentui/react-charting to v5.23.32 ([PR #33507](https://github.com/microsoft/fluentui/pull/33507) by beachball) + +## [1.7.269](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.269) + +Thu, 26 Dec 2024 07:21:14 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.268..@fluentui/react-monaco-editor_v1.7.269) + +### Patches + +- Bump @fluentui/react-charting to v5.23.31 ([PR #33518](https://github.com/microsoft/fluentui/pull/33518) by beachball) + +## [1.7.268](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.268) + +Wed, 25 Dec 2024 07:21:56 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.267..@fluentui/react-monaco-editor_v1.7.268) + +### Patches + +- Bump @fluentui/react-charting to v5.23.30 ([PR #33447](https://github.com/microsoft/fluentui/pull/33447) by beachball) + +## [1.7.267](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.267) + +Mon, 23 Dec 2024 07:22:58 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.266..@fluentui/react-monaco-editor_v1.7.267) + +### Patches + +- Bump @fluentui/react to v8.122.2 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) +- Bump @fluentui/react-charting to v5.23.29 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) + +## [1.7.266](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.266) + +Fri, 20 Dec 2024 07:20:01 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.265..@fluentui/react-monaco-editor_v1.7.266) + +### Patches + +- Bump @fluentui/react-charting to v5.23.28 ([PR #33282](https://github.com/microsoft/fluentui/pull/33282) by beachball) + +## [1.7.265](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.265) + +Wed, 18 Dec 2024 07:20:30 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.264..@fluentui/react-monaco-editor_v1.7.265) + +### Patches + +- Bump @fluentui/react-charting to v5.23.27 ([PR #33440](https://github.com/microsoft/fluentui/pull/33440) by beachball) + +## [1.7.264](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.264) + +Tue, 17 Dec 2024 07:21:19 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.263..@fluentui/react-monaco-editor_v1.7.264) + +### Patches + +- Bump @fluentui/react-charting to v5.23.26 ([PR #33477](https://github.com/microsoft/fluentui/pull/33477) by beachball) + +## [1.7.263](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.263) + +Mon, 16 Dec 2024 07:20:45 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.262..@fluentui/react-monaco-editor_v1.7.263) + +### Patches + +- Bump @fluentui/react-charting to v5.23.25 ([PR #33460](https://github.com/microsoft/fluentui/pull/33460) by beachball) + +## [1.7.262](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.262) + +Fri, 13 Dec 2024 07:23:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.261..@fluentui/react-monaco-editor_v1.7.262) + +### Patches + +- Bump @fluentui/react to v8.122.1 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) +- Bump @fluentui/react-charting to v5.23.24 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) + +## [1.7.261](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.261) + +Thu, 12 Dec 2024 07:22:33 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.260..@fluentui/react-monaco-editor_v1.7.261) + +### Patches + +- Bump @fluentui/react to v8.122.0 ([PR #33243](https://github.com/microsoft/fluentui/pull/33243) by beachball) +- Bump @fluentui/react-charting to v5.23.23 ([PR #33243](https://github.com/microsoft/fluentui/pull/33243) by beachball) + +## [1.7.260](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.260) + +Mon, 09 Dec 2024 07:21:03 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-monaco-editor_v1.7.259..@fluentui/react-monaco-editor_v1.7.260) + +### Patches + +- Bump @fluentui/react-charting to v5.23.22 ([PR #33379](https://github.com/microsoft/fluentui/pull/33379) by beachball) + ## [1.7.259](https://github.com/microsoft/fluentui/tree/@fluentui/react-monaco-editor_v1.7.259) Fri, 06 Dec 2024 07:21:16 GMT diff --git a/packages/react-monaco-editor/package.json b/packages/react-monaco-editor/package.json index 7b928dc1883472..8088ed863dd8f4 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.259", + "version": "1.7.294", "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.121.13", + "@fluentui/react": "^8.122.11", "@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.21", + "@fluentui/react-hooks": "^8.8.17", + "@fluentui/react-charting": "^5.23.56", "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-window-provider/CHANGELOG.json b/packages/react-window-provider/CHANGELOG.json index ec4e1491553e8e..7653c4cd3d0a20 100644 --- a/packages/react-window-provider/CHANGELOG.json +++ b/packages/react-window-provider/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@fluentui/react-window-provider", "entries": [ + { + "date": "Fri, 21 Feb 2025 07:22:41 GMT", + "tag": "@fluentui/react-window-provider_v2.2.29", + "version": "2.2.29", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react-window-provider", + "comment": "Bump @fluentui/set-version to v8.2.24", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + } + ] + } + }, { "date": "Thu, 01 Aug 2024 07:24:47 GMT", "tag": "@fluentui/react-window-provider_v2.2.28", diff --git a/packages/react-window-provider/CHANGELOG.md b/packages/react-window-provider/CHANGELOG.md index 9ed82526069502..a7128d4e713a83 100644 --- a/packages/react-window-provider/CHANGELOG.md +++ b/packages/react-window-provider/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @fluentui/react-window-provider -This log was last generated on Thu, 01 Aug 2024 07:24:47 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 07:22:41 GMT and should not be manually modified. +## [2.2.29](https://github.com/microsoft/fluentui/tree/@fluentui/react-window-provider_v2.2.29) + +Fri, 21 Feb 2025 07:22:41 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react-window-provider_v2.2.28..@fluentui/react-window-provider_v2.2.29) + +### Patches + +- Bump @fluentui/set-version to v8.2.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) + ## [2.2.28](https://github.com/microsoft/fluentui/tree/@fluentui/react-window-provider_v2.2.28) Thu, 01 Aug 2024 07:24:47 GMT diff --git a/packages/react-window-provider/package.json b/packages/react-window-provider/package.json index 21a9abe7877e29..220a335402a497 100644 --- a/packages/react-window-provider/package.json +++ b/packages/react-window-provider/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react-window-provider", - "version": "2.2.28", + "version": "2.2.29", "description": "Utilities for providing and consuming the window/document objects even across portal/iframe/child-window boundaries.", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -31,7 +31,7 @@ "@fluentui/scripts-tasks": "*" }, "dependencies": { - "@fluentui/set-version": "^8.2.23", + "@fluentui/set-version": "^8.2.24", "tslib": "^2.1.0" }, "peerDependencies": { diff --git a/packages/react/CHANGELOG.json b/packages/react/CHANGELOG.json index 0119b2f612cc93..06404a380227a0 100644 --- a/packages/react/CHANGELOG.json +++ b/packages/react/CHANGELOG.json @@ -1,6 +1,330 @@ { "name": "@fluentui/react", "entries": [ + { + "date": "Fri, 21 Feb 2025 07:22:41 GMT", + "tag": "@fluentui/react_v8.122.11", + "version": "8.122.11", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react", + "comment": "Bump @fluentui/date-time-utilities to v8.6.10", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react", + "comment": "Bump @fluentui/foundation-legacy to v8.4.24", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react", + "comment": "Bump @fluentui/font-icons-mdl2 to v8.5.58", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react", + "comment": "Bump @fluentui/merge-styles to v8.6.14", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react", + "comment": "Bump @fluentui/react-focus to v8.9.21", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react", + "comment": "Bump @fluentui/react-hooks to v8.8.17", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react", + "comment": "Bump @fluentui/react-window-provider to v2.2.29", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react", + "comment": "Bump @fluentui/set-version to v8.2.24", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react", + "comment": "Bump @fluentui/style-utilities to v8.11.7", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react", + "comment": "Bump @fluentui/theme to v2.6.65", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + }, + { + "author": "beachball", + "package": "@fluentui/react", + "comment": "Bump @fluentui/utilities to v8.15.20", + "commit": "37cb222b6d035ea02d490aa26a2aaf7dfd94c761" + } + ] + } + }, + { + "date": "Wed, 19 Feb 2025 07:21:16 GMT", + "tag": "@fluentui/react_v8.122.10", + "version": "8.122.10", + "comments": { + "patch": [ + { + "author": "walterb@microsoft.com", + "package": "@fluentui/react", + "commit": "8264ce0435583ae69c051f109388005be3c0de2b", + "comment": "fix(KeytipTree): refactor updateNode to improve parent handling" + } + ] + } + }, + { + "date": "Wed, 29 Jan 2025 07:21:15 GMT", + "tag": "@fluentui/react_v8.122.9", + "version": "8.122.9", + "comments": { + "patch": [ + { + "author": "estebanmu@microsoft.com", + "package": "@fluentui/react", + "commit": "75fc0440a890f12af8845061d9cafd983d9a4e33", + "comment": "fix(Autofill): Only apply selection logic if the current value does not match the previous value to avoid using the value before state is set and handle del key as delete in the keydown event." + } + ] + } + }, + { + "date": "Wed, 22 Jan 2025 07:21:49 GMT", + "tag": "@fluentui/react_v8.122.8", + "version": "8.122.8", + "comments": { + "patch": [ + { + "author": "706967+KevinTCoughlin@users.noreply.github.com", + "package": "@fluentui/react", + "commit": "012298d98651800023aac24c591831e9bc51bea2", + "comment": "Async dispose to release references" + } + ] + } + }, + { + "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", + "version": "8.122.6", + "comments": { + "patch": [ + { + "author": "behowell@microsoft.com", + "package": "@fluentui/react", + "commit": "74641ca04daeda5a6cd644513351d675ccd4dbad", + "comment": "fix: Remove deprecation warning from Callout's preventDismissOnResize and similar props" + } + ] + } + }, + { + "date": "Wed, 08 Jan 2025 07:21:37 GMT", + "tag": "@fluentui/react_v8.122.5", + "version": "8.122.5", + "comments": { + "patch": [ + { + "author": "Humberto.Morimoto@microsoft.com", + "package": "@fluentui/react", + "commit": "8f763922d713d9ccd35e65db07206c10b170fafd", + "comment": "chore: Adding key to inner slot in Stack component." + } + ] + } + }, + { + "date": "Fri, 03 Jan 2025 07:21:31 GMT", + "tag": "@fluentui/react_v8.122.4", + "version": "8.122.4", + "comments": { + "patch": [ + { + "author": "sarah.higley@microsoft.com", + "package": "@fluentui/react", + "commit": "7bb97f178d73a470dc438a2b19d165d9d0bd4b51", + "comment": "fix(Combobox and Dropdown): add aria-invalid when errorMessage is set" + } + ] + } + }, + { + "date": "Mon, 30 Dec 2024 07:21:29 GMT", + "tag": "@fluentui/react_v8.122.3", + "version": "8.122.3", + "comments": { + "patch": [ + { + "author": "estebanmu@microsoft.com", + "package": "@fluentui/react", + "commit": "681a95a732fe385a70b8d4537dc489acbcd1c21e", + "comment": "fix: Add event listener to Panel in order to update the footer's sticky property correctly when content changes dynamically." + } + ] + } + }, + { + "date": "Mon, 23 Dec 2024 07:22:58 GMT", + "tag": "@fluentui/react_v8.122.2", + "version": "8.122.2", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react", + "comment": "Bump @fluentui/foundation-legacy to v8.4.23", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + }, + { + "author": "beachball", + "package": "@fluentui/react", + "comment": "Bump @fluentui/font-icons-mdl2 to v8.5.57", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + }, + { + "author": "beachball", + "package": "@fluentui/react", + "comment": "Bump @fluentui/react-focus to v8.9.20", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + }, + { + "author": "beachball", + "package": "@fluentui/react", + "comment": "Bump @fluentui/style-utilities to v8.11.6", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + }, + { + "author": "beachball", + "package": "@fluentui/react", + "comment": "Bump @fluentui/theme to v2.6.64", + "commit": "7b4a3785c6c1d7c207602cad0a1795e3df9122ee" + } + ] + } + }, + { + "date": "Fri, 20 Dec 2024 07:20:00 GMT", + "tag": "@fluentui/react_v8.122.1", + "version": "8.122.1", + "comments": { + "none": [ + { + "author": "vgenaev@gmail.com", + "package": "@fluentui/react", + "commit": "00fada2af3a290e83ba3812ab3440b5ae8a903cf", + "comment": "chore: update react.api.md" + } + ] + } + }, + { + "date": "Fri, 13 Dec 2024 07:23:12 GMT", + "tag": "@fluentui/react_v8.122.1", + "version": "8.122.1", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@fluentui/react", + "comment": "Bump @fluentui/foundation-legacy to v8.4.22", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7" + }, + { + "author": "beachball", + "package": "@fluentui/react", + "comment": "Bump @fluentui/font-icons-mdl2 to v8.5.56", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7" + }, + { + "author": "beachball", + "package": "@fluentui/react", + "comment": "Bump @fluentui/react-focus to v8.9.19", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7" + }, + { + "author": "beachball", + "package": "@fluentui/react", + "comment": "Bump @fluentui/style-utilities to v8.11.5", + "commit": "6dfe27e984d9633129c79178b40c6a0a189e29c7" + } + ] + } + }, + { + "date": "Thu, 12 Dec 2024 07:22:32 GMT", + "tag": "@fluentui/react_v8.122.0", + "version": "8.122.0", + "comments": { + "minor": [ + { + "author": "tpalacino@users.noreply.github.com", + "package": "@fluentui/react", + "commit": "53dd771e70338065810404663cd6219d1b54c1e2", + "comment": "fix: Added label, required, and error properties to BasePicker." + } + ] + } + }, { "date": "Fri, 22 Nov 2024 07:21:17 GMT", "tag": "@fluentui/react_v8.121.13", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 00254cbb322a87..88ff448e27f1e7 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,9 +1,136 @@ # Change Log - @fluentui/react -This log was last generated on Fri, 22 Nov 2024 07:21:17 GMT and should not be manually modified. +This log was last generated on Fri, 21 Feb 2025 07:22:41 GMT and should not be manually modified. +## [8.122.11](https://github.com/microsoft/fluentui/tree/@fluentui/react_v8.122.11) + +Fri, 21 Feb 2025 07:22:41 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react_v8.122.10..@fluentui/react_v8.122.11) + +### Patches + +- Bump @fluentui/date-time-utilities to v8.6.10 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/foundation-legacy to v8.4.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/font-icons-mdl2 to v8.5.58 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/merge-styles to v8.6.14 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/react-focus to v8.9.21 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/react-hooks to v8.8.17 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/react-window-provider to v2.2.29 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/set-version to v8.2.24 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/style-utilities to v8.11.7 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/theme to v2.6.65 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) +- Bump @fluentui/utilities to v8.15.20 ([PR #33879](https://github.com/microsoft/fluentui/pull/33879) by beachball) + +## [8.122.10](https://github.com/microsoft/fluentui/tree/@fluentui/react_v8.122.10) + +Wed, 19 Feb 2025 07:21:16 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react_v8.122.9..@fluentui/react_v8.122.10) + +### Patches + +- fix(KeytipTree): refactor updateNode to improve parent handling ([PR #33867](https://github.com/microsoft/fluentui/pull/33867) by walterb@microsoft.com) + +## [8.122.9](https://github.com/microsoft/fluentui/tree/@fluentui/react_v8.122.9) + +Wed, 29 Jan 2025 07:21:15 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react_v8.122.8..@fluentui/react_v8.122.9) + +### Patches + +- fix(Autofill): Only apply selection logic if the current value does not match the previous value to avoid using the value before state is set and handle del key as delete in the keydown event. ([PR #33700](https://github.com/microsoft/fluentui/pull/33700) by estebanmu@microsoft.com) + +## [8.122.8](https://github.com/microsoft/fluentui/tree/@fluentui/react_v8.122.8) + +Wed, 22 Jan 2025 07:21:49 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react_v8.122.7..@fluentui/react_v8.122.8) + +### Patches + +- Async dispose to release references ([PR #33685](https://github.com/microsoft/fluentui/pull/33685) by 706967+KevinTCoughlin@users.noreply.github.com) + +## [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 +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react_v8.122.5..@fluentui/react_v8.122.6) + +### Patches + +- fix: Remove deprecation warning from Callout's preventDismissOnResize and similar props ([PR #33493](https://github.com/microsoft/fluentui/pull/33493) by behowell@microsoft.com) + +## [8.122.5](https://github.com/microsoft/fluentui/tree/@fluentui/react_v8.122.5) + +Wed, 08 Jan 2025 07:21:37 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react_v8.122.4..@fluentui/react_v8.122.5) + +### Patches + +- chore: Adding key to inner slot in Stack component. ([PR #33578](https://github.com/microsoft/fluentui/pull/33578) by Humberto.Morimoto@microsoft.com) + +## [8.122.4](https://github.com/microsoft/fluentui/tree/@fluentui/react_v8.122.4) + +Fri, 03 Jan 2025 07:21:31 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react_v8.122.3..@fluentui/react_v8.122.4) + +### Patches + +- fix(Combobox and Dropdown): add aria-invalid when errorMessage is set ([PR #33529](https://github.com/microsoft/fluentui/pull/33529) by sarah.higley@microsoft.com) + +## [8.122.3](https://github.com/microsoft/fluentui/tree/@fluentui/react_v8.122.3) + +Mon, 30 Dec 2024 07:21:29 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react_v8.122.2..@fluentui/react_v8.122.3) + +### Patches + +- fix: Add event listener to Panel in order to update the footer's sticky property correctly when content changes dynamically. ([PR #33520](https://github.com/microsoft/fluentui/pull/33520) by estebanmu@microsoft.com) + +## [8.122.2](https://github.com/microsoft/fluentui/tree/@fluentui/react_v8.122.2) + +Mon, 23 Dec 2024 07:22:58 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react_v8.122.1..@fluentui/react_v8.122.2) + +### Patches + +- Bump @fluentui/foundation-legacy to v8.4.23 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) +- Bump @fluentui/font-icons-mdl2 to v8.5.57 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) +- Bump @fluentui/react-focus to v8.9.20 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) +- Bump @fluentui/style-utilities to v8.11.6 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) +- Bump @fluentui/theme to v2.6.64 ([PR #33445](https://github.com/microsoft/fluentui/pull/33445) by beachball) + +## [8.122.1](https://github.com/microsoft/fluentui/tree/@fluentui/react_v8.122.1) + +Fri, 13 Dec 2024 07:23:12 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react_v8.122.0..@fluentui/react_v8.122.1) + +### Patches + +- Bump @fluentui/foundation-legacy to v8.4.22 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) +- Bump @fluentui/font-icons-mdl2 to v8.5.56 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) +- Bump @fluentui/react-focus to v8.9.19 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) +- Bump @fluentui/style-utilities to v8.11.5 ([PR #33455](https://github.com/microsoft/fluentui/pull/33455) by beachball) + +## [8.122.0](https://github.com/microsoft/fluentui/tree/@fluentui/react_v8.122.0) + +Thu, 12 Dec 2024 07:22:32 GMT +[Compare changes](https://github.com/microsoft/fluentui/compare/@fluentui/react_v8.121.13..@fluentui/react_v8.122.0) + +### Minor changes + +- fix: Added label, required, and error properties to BasePicker. ([PR #33243](https://github.com/microsoft/fluentui/pull/33243) by tpalacino@users.noreply.github.com) + ## [8.121.13](https://github.com/microsoft/fluentui/tree/@fluentui/react_v8.121.13) Fri, 22 Nov 2024 07:21:17 GMT diff --git a/packages/react/etc/react.api.md b/packages/react/etc/react.api.md index 8c7178e88da5d5..92fb7502442736 100644 --- a/packages/react/etc/react.api.md +++ b/packages/react/etc/react.api.md @@ -477,7 +477,7 @@ export class Autofill extends React_2.Component // Warning: (ae-forgotten-export) The symbol "ICursorLocation" needs to be exported by the entry point index.d.ts // // (undocumented) - componentDidUpdate(_: any, _1: any, cursor: ICursorLocation | null): void; + componentDidUpdate(_: any, previousState: IAutofillState, cursor: ICursorLocation | null): void; // (undocumented) componentWillUnmount(): void; // (undocumented) @@ -716,6 +716,8 @@ export class BasePicker> extends Rea static getDerivedStateFromProps(newProps: IBasePickerProps): { items: any[]; } | null; + // (undocumented) + protected _getDescribedBy: (items: T[], hasError: boolean) => string; // @deprecated (undocumented) protected getSuggestionsAlert(suggestionAlertClassName?: string): JSX.Element | undefined; // (undocumented) @@ -764,8 +766,12 @@ export class BasePicker> extends Rea // (undocumented) protected renderCustomAlert(alertClassName?: string): JSX.Element; // (undocumented) + protected renderError(className?: string): JSX.Element | null; + // (undocumented) protected renderItems(): JSX.Element[]; // (undocumented) + protected renderLabel(inputId: string, styles: IStyleFunctionOrObject | undefined): JSX.Element | null; + // (undocumented) protected renderSuggestions(): JSX.Element | null; // (undocumented) protected resetFocus(index?: number): void; @@ -1598,49 +1604,49 @@ export { FabricPerformance } // @public (undocumented) export enum FabricSlots { // (undocumented) - black = 21, + black = 21,// BaseSlots.primaryColor, Shade[Shade.Unshaded]); // (undocumented) - neutralDark = 20, + neutralDark = 20,// BaseSlots.primaryColor, Shade[Shade.Shade1]); // (undocumented) - neutralLight = 11, + neutralLight = 11,// BaseSlots.primaryColor, Shade[Shade.Shade2]); // (undocumented) - neutralLighter = 10, + neutralLighter = 10,// BaseSlots.primaryColor, Shade[Shade.Shade3]); // (undocumented) - neutralLighterAlt = 9, + neutralLighterAlt = 9,// BaseSlots.primaryColor, Shade[Shade.Shade4]); // (undocumented) - neutralPrimary = 19, + neutralPrimary = 19,// BaseSlots.primaryColor, Shade[Shade.Shade5]); // (undocumented) - neutralPrimaryAlt = 18, + neutralPrimaryAlt = 18,// BaseSlots.primaryColor, Shade[Shade.Shade6]); // (undocumented) - neutralQuaternary = 13, + neutralQuaternary = 13,// BaseSlots.primaryColor, Shade[Shade.Shade7]); // (undocumented) - neutralQuaternaryAlt = 12, + neutralQuaternaryAlt = 12,// BaseSlots.primaryColor, Shade[Shade.Shade8]); // (undocumented) - neutralSecondary = 17, + neutralSecondary = 17,// BaseSlots.backgroundColor, Shade[Shade.Shade1]); // (undocumented) - neutralSecondaryAlt = 16, + neutralSecondaryAlt = 16,// BaseSlots.backgroundColor, Shade[Shade.Shade2]); // (undocumented) - neutralTertiary = 15, + neutralTertiary = 15,// BaseSlots.backgroundColor, Shade[Shade.Shade3]); // (undocumented) - neutralTertiaryAlt = 14, + neutralTertiaryAlt = 14,// BaseSlots.backgroundColor, Shade[Shade.Shade4]); // (undocumented) - themeDark = 7, + themeDark = 7,// BaseSlots.backgroundColor, Shade[Shade.Shade5]); // (undocumented) - themeDarkAlt = 6, + themeDarkAlt = 6,// BaseSlots.backgroundColor, Shade[Shade.Shade6]); // bg6 or fg2 // (undocumented) - themeDarker = 8, + themeDarker = 8,// BaseSlots.foregroundColor, Shade[Shade.Shade3]); // (undocumented) - themeLight = 3, + themeLight = 3,// BaseSlots.foregroundColor, Shade[Shade.Shade4]); // (undocumented) - themeLighter = 2, + themeLighter = 2,// BaseSlots.foregroundColor, Shade[Shade.Shade5]); // (undocumented) - themeLighterAlt = 1, + themeLighterAlt = 1,// BaseSlots.foregroundColor, Shade[Shade.Shade6]); // (undocumented) - themePrimary = 0, + themePrimary = 0,// BaseSlots.foregroundColor, Shade[Shade.Unshaded]); // (undocumented) - themeSecondary = 5, + themeSecondary = 5,// BaseSlots.foregroundColor, Shade[Shade.Shade7]); // (undocumented) - themeTertiary = 4, + themeTertiary = 4,// BaseSlots.foregroundColor, Shade[Shade.Shade8]); // (undocumented) white = 22 } @@ -2382,9 +2388,11 @@ export interface IBasePickerProps extends IReactProps { defaultSelectedItems?: T[]; disabled?: boolean; enableSelectedSuggestionAlert?: boolean; + errorMessage?: string | JSX.Element; getTextFromItem?: (item: T, currentValue?: string) => string; inputProps?: IInputProps; itemLimit?: number; + label?: string; onBlur?: React_2.FocusEventHandler; onChange?: (items?: T[]) => void; onDismiss?: (ev?: any, selectedItem?: T) => boolean | void; @@ -2393,6 +2401,7 @@ export interface IBasePickerProps extends IReactProps { onEmptyResolveSuggestions?: (selectedItems?: T[]) => T[] | PromiseLike; // @deprecated onFocus?: React_2.FocusEventHandler; + onGetErrorMessage?: (items: T[]) => string | JSX.Element | PromiseLike | undefined; onGetMoreResults?: (filter: string, selectedItems?: T[]) => T[] | PromiseLike; onInputChange?: (input: string) => string; onItemSelected?: (selectedItem?: T) => T | PromiseLike | null; @@ -2405,6 +2414,7 @@ export interface IBasePickerProps extends IReactProps { pickerSuggestionsProps?: IBasePickerSuggestionsProps; removeButtonAriaLabel?: string; removeButtonIconProps?: IIconProps; + required?: boolean; resolveDelay?: number; searchingText?: ((props: { input: string; @@ -2419,6 +2429,8 @@ export interface IBasePickerProps extends IReactProps { // @public (undocumented) export interface IBasePickerState { + // (undocumented) + errorMessage?: string | JSX.Element; // (undocumented) isFocused?: boolean; // (undocumented) @@ -2447,16 +2459,20 @@ export interface IBasePickerState { // @public export type IBasePickerStyleProps = Pick, 'theme' | 'className' | 'disabled'> & { + hasErrorMessage: boolean; isFocused?: boolean; inputClassName?: string; }; // @public export interface IBasePickerStyles { + error: IStyle; input: IStyle; itemsWrapper: IStyle; root: IStyle; screenReaderText: IStyle; + // Warning: (ae-forgotten-export) The symbol "IBasePickerSubComponentStyles" needs to be exported by the entry point index.d.ts + subComponentStyles: IBasePickerSubComponentStyles; text: IStyle; } @@ -3227,11 +3243,8 @@ export interface ICalloutProps extends React_2.HTMLAttributes, R popupProps?: IPopupProps; preferScrollResizePositioning?: boolean; preventDismissOnEvent?: (ev: Event | React_2.FocusEvent | React_2.KeyboardEvent | React_2.MouseEvent) => boolean; - // @deprecated preventDismissOnLostFocus?: boolean; - // @deprecated preventDismissOnResize?: boolean; - // @deprecated preventDismissOnScroll?: boolean; role?: string; setInitialFocus?: boolean; @@ -7700,6 +7713,7 @@ export type IPickerAriaIds = { selectedItems: string; suggestionList: string; combobox: string; + error: string; }; // @public @@ -9191,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/jest.config.js b/packages/react/jest.config.js index c16374ebe05fe4..849b164a495bb7 100644 --- a/packages/react/jest.config.js +++ b/packages/react/jest.config.js @@ -3,6 +3,9 @@ const { createV8Config: createConfig } = require('@fluentui/scripts-jest'); const config = createConfig({ setupFiles: ['./config/tests.js'], snapshotSerializers: ['@fluentui/jest-serializer-merge-styles'], + // Keeps Jest from using too much memory as GC gets invoked more often, makes tests slower + // https://stackoverflow.com/a/75857711 + workerIdleMemoryLimit: '1024MB', }); module.exports = config; diff --git a/packages/react/package.json b/packages/react/package.json index 2e8034679ba2ba..708aeabf8f9952 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@fluentui/react", - "version": "8.121.13", + "version": "8.122.11", "description": "Reusable React components for building web experiences.", "main": "lib-commonjs/index.js", "module": "lib/index.js", @@ -48,18 +48,18 @@ "@fluentui/scripts-webpack": "*" }, "dependencies": { - "@fluentui/date-time-utilities": "^8.6.9", - "@fluentui/foundation-legacy": "^8.4.21", - "@fluentui/font-icons-mdl2": "^8.5.55", - "@fluentui/merge-styles": "^8.6.13", - "@fluentui/react-focus": "^8.9.18", - "@fluentui/react-hooks": "^8.8.16", + "@fluentui/date-time-utilities": "^8.6.10", + "@fluentui/foundation-legacy": "^8.4.24", + "@fluentui/font-icons-mdl2": "^8.5.58", + "@fluentui/merge-styles": "^8.6.14", + "@fluentui/react-focus": "^8.9.21", + "@fluentui/react-hooks": "^8.8.17", "@fluentui/react-portal-compat-context": "^9.0.13", - "@fluentui/react-window-provider": "^2.2.28", - "@fluentui/set-version": "^8.2.23", - "@fluentui/style-utilities": "^8.11.4", - "@fluentui/theme": "^2.6.63", - "@fluentui/utilities": "^8.15.19", + "@fluentui/react-window-provider": "^2.2.29", + "@fluentui/set-version": "^8.2.24", + "@fluentui/style-utilities": "^8.11.7", + "@fluentui/theme": "^2.6.65", + "@fluentui/utilities": "^8.15.20", "@microsoft/load-themed-styles": "^1.10.26", "tslib": "^2.1.0" }, 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..67d9aec65280a6 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 @@ -98,7 +98,7 @@ export class Autofill extends React.Component im return this._inputElement.current; } - public componentDidUpdate(_: any, _1: any, cursor: ICursorLocation | null) { + public componentDidUpdate(_: any, previousState: IAutofillState, cursor: ICursorLocation | null) { const { suggestedDisplayValue, shouldSelectFullInputValueInComponentDidUpdate, preventValueSelection } = this.props; let differenceIndex = 0; @@ -114,7 +114,8 @@ export class Autofill extends React.Component im this._autoFillEnabled && this.value && suggestedDisplayValue && - _doesTextStartWith(suggestedDisplayValue, this.value) + _doesTextStartWith(suggestedDisplayValue, this.value) && + previousState.inputValue !== this.value ) { let shouldSelectFullRange = false; @@ -247,8 +248,9 @@ 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.del: case KeyCodes.backspace: this._autoFillEnabled = false; break; @@ -263,7 +265,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 +341,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/Callout.types.ts b/packages/react/src/components/Callout/Callout.types.ts index 6907bb11cb8989..b00e10355e5e69 100644 --- a/packages/react/src/components/Callout/Callout.types.ts +++ b/packages/react/src/components/Callout/Callout.types.ts @@ -87,23 +87,23 @@ export interface ICalloutProps extends React.HTMLAttributes, Rea isBeakVisible?: boolean; /** - * If true then the callout will not dismiss on scroll + * If true then the callout will not dismiss on scroll. + * *Note:* This property will be ignored if using `preventDismissOnEvent`. * @defaultvalue false - * @deprecated use preventDismissOnEvent callback instead */ preventDismissOnScroll?: boolean; /** - * If true then the callout will not dismiss on resize + * If true then the callout will not dismiss on resize. + * *Note:* This property will be ignored if using `preventDismissOnEvent`. * @defaultvalue false - * @deprecated use preventDismissOnEvent callback instead */ preventDismissOnResize?: boolean; /** - * If true then the callout will not dismiss when it loses focus + * If true then the callout will not dismiss when it loses focus. + * *Note:* This property will be ignored if using `preventDismissOnEvent`. * @defaultvalue false - * @deprecated use preventDismissOnEvent callback instead */ preventDismissOnLostFocus?: boolean; diff --git a/packages/react/src/components/Callout/CalloutContent.base.tsx b/packages/react/src/components/Callout/CalloutContent.base.tsx index e4acb42562bfc0..89550932965a2f 100644 --- a/packages/react/src/components/Callout/CalloutContent.base.tsx +++ b/packages/react/src/components/Callout/CalloutContent.base.tsx @@ -337,11 +337,8 @@ function useDismissHandlers( { hidden, onDismiss, - // eslint-disable-next-line deprecation/deprecation preventDismissOnScroll, - // eslint-disable-next-line deprecation/deprecation preventDismissOnResize, - // eslint-disable-next-line deprecation/deprecation preventDismissOnLostFocus, dismissOnTargetClick, shouldDismissOnWindowFocus, @@ -495,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.test.tsx b/packages/react/src/components/ComboBox/ComboBox.test.tsx index cd1c4eb315c519..235039068bf7c9 100644 --- a/packages/react/src/components/ComboBox/ComboBox.test.tsx +++ b/packages/react/src/components/ComboBox/ComboBox.test.tsx @@ -122,6 +122,15 @@ describe('ComboBox', () => { expect(combobox.getAttribute('aria-disabled')).toEqual('true'); }); + it('sets alert message and aria-invalid when errorMessage is set', () => { + const { getByRole } = render( + , + ); + const alert = getByRole('alert'); + expect(alert.textContent).toBe('This is an example error.'); + expect(getByRole('combobox').getAttribute('aria-invalid')).toBe('true'); + }); + it('Renders no selected item in default case', () => { const { getByRole } = render(); expect(getByRole('combobox').getAttribute('value')).toEqual(''); diff --git a/packages/react/src/components/ComboBox/ComboBox.tsx b/packages/react/src/components/ComboBox/ComboBox.tsx index 6e558e4fa347d2..9b6823d72a6d7d 100644 --- a/packages/react/src/components/ComboBox/ComboBox.tsx +++ b/packages/react/src/components/ComboBox/ComboBox.tsx @@ -646,6 +646,8 @@ class ComboBoxInternal extends React.Component 0 ? true : false; + return (
): void => { const doc = getDocumentEx(this.context); // Do nothing if the blur is coming from something @@ -2105,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; } @@ -2303,7 +2306,7 @@ class ComboBoxInternal extends React.Component 123) /* F12 */ ) { ev.stopPropagation(); @@ -2615,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/ComboBox/__snapshots__/ComboBox.test.tsx.snap b/packages/react/src/components/ComboBox/__snapshots__/ComboBox.test.tsx.snap index 3b70af4eeb29a7..0c88b4eb66d0d8 100644 --- a/packages/react/src/components/ComboBox/__snapshots__/ComboBox.test.tsx.snap +++ b/packages/react/src/components/ComboBox/__snapshots__/ComboBox.test.tsx.snap @@ -145,6 +145,7 @@ exports[`ComboBox Renders correctly 1`] = ` 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 945165847f8d70..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) { @@ -149,7 +149,7 @@ const _getMenuItemStylesFunction = memoizeFunction( ...styles: (IStyleFunctionOrObject | undefined)[] ): IStyleFunctionOrObject => { return (styleProps: IContextualMenuItemStyleProps) => - concatStyleSetsWithProps(styleProps, getItemStyles, ...styles); + concatStyleSetsWithProps(styleProps, getItemStyles, ...styles) as IContextualMenuItemStyles; }, ); @@ -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 27c4675521c1b7..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 { // If option is selected render title, otherwise render the placeholder text @@ -492,7 +492,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/Dropdown/Dropdown.test.tsx b/packages/react/src/components/Dropdown/Dropdown.test.tsx index f8a89af7a4ae05..dc2cfd17cfa653 100644 --- a/packages/react/src/components/Dropdown/Dropdown.test.tsx +++ b/packages/react/src/components/Dropdown/Dropdown.test.tsx @@ -710,12 +710,13 @@ describe('Dropdown', () => { expect(dropdownRoot.getAttribute('aria-labelledby')).not.toBeNull(); }); - it('sets role=error on included error message', () => { + it('sets alert message and aria-invalid when errorMessage is set', () => { const { getByRole } = render( , ); const alert = getByRole('alert'); expect(alert.textContent).toBe('This is an example error.'); + expect(getByRole('combobox').getAttribute('aria-invalid')).toBe('true'); }); }); diff --git a/packages/react/src/components/Dropdown/__snapshots__/Dropdown.test.tsx.snap b/packages/react/src/components/Dropdown/__snapshots__/Dropdown.test.tsx.snap index a3f91242ae665a..d226380e10f15c 100644 --- a/packages/react/src/components/Dropdown/__snapshots__/Dropdown.test.tsx.snap +++ b/packages/react/src/components/Dropdown/__snapshots__/Dropdown.test.tsx.snap @@ -8,6 +8,7 @@ exports[`Dropdown multi-select Renders correctly 1`] = ` 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 329e90467153e8..527285aa738ab5 100644 --- a/packages/react/src/components/Panel/Panel.base.tsx +++ b/packages/react/src/components/Panel/Panel.base.tsx @@ -61,6 +61,7 @@ export class PanelBase extends React.Component impleme private _hasCustomNavigation: boolean = !!(this.props.onRenderNavigation || this.props.onRenderNavigationContent); private _headerTextId: string | undefined; private _allowTouchBodyScroll: boolean; + private _resizeObserver: ResizeObserver | null; public static getDerivedStateFromProps( nextProps: Readonly, @@ -149,13 +150,14 @@ export class PanelBase extends React.Component impleme public componentWillUnmount(): void { this._async.dispose(); this._events.dispose(); + this._resizeObserver?.disconnect(); } public render(): JSX.Element | null { const { className = '', elementToFocusOnDismiss, - /* eslint-disable deprecation/deprecation */ + /* eslint-disable @typescript-eslint/no-deprecated */ firstFocusableSelector, focusTrapZoneProps, forceFocusInsideTrap, @@ -310,9 +312,27 @@ export class PanelBase extends React.Component impleme ); } + private _createResizeObserver(callback: ResizeObserverCallback): ResizeObserver | null { + const doc = getDocumentEx(this.context); + let resizeObserver: ResizeObserver | null = null; + + if (doc?.defaultView?.ResizeObserver) { + resizeObserver = new doc.defaultView.ResizeObserver(callback); + } + + return resizeObserver; + } + // Allow the user to scroll within the panel but not on the body private _allowScrollOnPanel = (elt: HTMLDivElement | null): void => { + this._resizeObserver = this._createResizeObserver(entries => { + if (entries.length > 0 && entries[0].target === elt) { + this._updateFooterPosition(); + } + }); + if (elt) { + this._resizeObserver?.observe(elt); if (this._allowTouchBodyScroll) { allowOverscrollOnElement(elt, this._events); } else { 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 3caa6aa3d37fb7..30cf4eaea89e5f 100644 --- a/packages/react/src/components/Stack/Stack.tsx +++ b/packages/react/src/components/Stack/Stack.tsx @@ -2,6 +2,7 @@ /** @jsx withSlots */ import * as React from 'react'; import { withSlots, createComponent, getSlots } from '@fluentui/foundation-legacy'; +import { useId } from '@fluentui/react-hooks'; import { css, getNativeProps, htmlElementProperties, warnDeprecations } from '../../Utilities'; import { styles, GlobalClassNames as StackGlobalClassNames } from './Stack.styles'; import { StackItem } from './StackItem/StackItem'; @@ -12,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, @@ -26,6 +27,8 @@ const StackView: IStackComponent['view'] = props => { padding: 'tokens.padding', }); + const stackInnerId = useId('stack-inner'); + const stackChildren = _processStackChildren(props.children, { disableShrink, enableScopedSelectors, @@ -42,7 +45,7 @@ const StackView: IStackComponent['view'] = props => { if (wrap) { return ( - {stackChildren} + {stackChildren} ); } 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/TeachingBubble/__snapshots__/TeachingBubble.deprecated.test.tsx.snap b/packages/react/src/components/TeachingBubble/__snapshots__/TeachingBubble.deprecated.test.tsx.snap index 538429c8d9bda9..1cadc860cd9c60 100644 --- a/packages/react/src/components/TeachingBubble/__snapshots__/TeachingBubble.deprecated.test.tsx.snap +++ b/packages/react/src/components/TeachingBubble/__snapshots__/TeachingBubble.deprecated.test.tsx.snap @@ -326,7 +326,7 @@ exports[`TeachingBubble renders renders with hasCloseIcon which is deprecated 1` margin-right: 4px; margin-top: 0; } - id="id__3" + id="id__4" > Test Primary Button @@ -481,7 +481,7 @@ exports[`TeachingBubble renders renders with hasCloseIcon which is deprecated 1` margin-right: 4px; margin-top: 0; } - id="id__6" + id="id__7" > Test Secondary Button diff --git a/packages/react/src/components/TeachingBubble/__snapshots__/TeachingBubble.test.tsx.snap b/packages/react/src/components/TeachingBubble/__snapshots__/TeachingBubble.test.tsx.snap index 9fd15c657e6be6..15cbda84535c98 100644 --- a/packages/react/src/components/TeachingBubble/__snapshots__/TeachingBubble.test.tsx.snap +++ b/packages/react/src/components/TeachingBubble/__snapshots__/TeachingBubble.test.tsx.snap @@ -610,7 +610,7 @@ exports[`TeachingBubble renders TeachingBubbleContent with buttons correctly 1`] margin-right: 4px; margin-top: 0; } - id="id__3" + id="id__4" > Test Primary Button @@ -765,7 +765,7 @@ exports[`TeachingBubble renders TeachingBubbleContent with buttons correctly 1`] margin-right: 4px; margin-top: 0; } - id="id__6" + id="id__7" > Test Secondary Button 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/TimePicker/__snapshots__/TimePicker.test.tsx.snap b/packages/react/src/components/TimePicker/__snapshots__/TimePicker.test.tsx.snap index 653fc0d856eb44..97a83b42543428 100644 --- a/packages/react/src/components/TimePicker/__snapshots__/TimePicker.test.tsx.snap +++ b/packages/react/src/components/TimePicker/__snapshots__/TimePicker.test.tsx.snap @@ -174,6 +174,7 @@ exports[`TimePicker renders correctly 1`] = ` aria-autocomplete="inline" aria-describedby="ComboBox0-error" aria-expanded={false} + aria-invalid={false} aria-labelledby="ComboBox0-label" autoCapitalize="off" autoComplete="off" 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.styles.ts b/packages/react/src/components/pickers/BasePicker.styles.ts index b6965fe710a14d..fee94d4d0bf67b 100644 --- a/packages/react/src/components/pickers/BasePicker.styles.ts +++ b/packages/react/src/components/pickers/BasePicker.styles.ts @@ -10,13 +10,15 @@ import type { IStyle } from '../../Styling'; const GlobalClassNames = { root: 'ms-BasePicker', + label: 'ms-BasePicker-label', text: 'ms-BasePicker-text', itemsWrapper: 'ms-BasePicker-itemsWrapper', input: 'ms-BasePicker-input', + error: 'ms-BasePicker-error', }; export function getStyles(props: IBasePickerStyleProps): IBasePickerStyles { - const { className, theme, isFocused, inputClassName, disabled } = props; + const { className, theme, isFocused, inputClassName, disabled, hasErrorMessage } = props; if (!theme) { throw new Error('theme is undefined or null in base BasePicker getStyles function.'); @@ -56,8 +58,22 @@ export function getStyles(props: IBasePickerStyleProps): IBasePickerStyles { // const disabledOverlayColor = rgbColor ? `rgba(${rgbColor.r}, ${rgbColor.g}, ${rgbColor.b}, 0.29)` : 'transparent'; const disabledOverlayColor = 'rgba(218, 218, 218, 0.29)'; + const focusColor = isFocused && !disabled && (hasErrorMessage ? semanticColors.errorText : inputFocusBorderAlt); + return { root: [classNames.root, className, { position: 'relative' }], + error: [ + classNames.error, + { + fontSize: 12, + fontWeight: 400, + color: semanticColors.errorText, + margin: 0, + paddingTop: 5, + display: hasErrorMessage ? 'flex' : 'none', + alignItems: 'center', + }, + ], text: [ classNames.text, { @@ -79,7 +95,7 @@ export function getStyles(props: IBasePickerStyleProps): IBasePickerStyles { }, }, }, - isFocused && !disabled && getInputFocusStyle(inputFocusBorderAlt, effects.roundedCorner2), + focusColor && getInputFocusStyle(focusColor, effects.roundedCorner2), disabled && { borderColor: disabledOverlayColor, selectors: { @@ -102,6 +118,14 @@ export function getStyles(props: IBasePickerStyleProps): IBasePickerStyles { }, }, }, + hasErrorMessage && { + borderColor: semanticColors.errorText, + selectors: { + ':hover': { + borderColor: semanticColors.errorText, + }, + }, + }, ], itemsWrapper: [ classNames.itemsWrapper, @@ -138,5 +162,8 @@ export function getStyles(props: IBasePickerStyleProps): IBasePickerStyles { inputClassName, ], screenReaderText: hiddenContentStyle, + subComponentStyles: { + label: {}, + }, }; } diff --git a/packages/react/src/components/pickers/BasePicker.tsx b/packages/react/src/components/pickers/BasePicker.tsx index acf894a7ca8e51..f9a15be205724e 100644 --- a/packages/react/src/components/pickers/BasePicker.tsx +++ b/packages/react/src/components/pickers/BasePicker.tsx @@ -9,6 +9,7 @@ import { classNamesFunction, styled, initializeComponentRef, + IStyleFunctionOrObject, } from '../../Utilities'; import { Callout } from '../../Callout'; import { Selection, SelectionZone, SelectionMode } from '../../utilities/selection/index'; @@ -19,6 +20,7 @@ import { SuggestionsController } from './Suggestions/SuggestionsController'; import { ValidationState } from './BasePicker.types'; import { Autofill } from '../Autofill/index'; import * as stylesImport from './BasePicker.scss'; +import { Label } from '../../Label'; import type { IProcessedStyleSet } from '../../Styling'; import type { ISuggestions, @@ -31,6 +33,7 @@ import type { IAutofill } from '../Autofill/index'; import type { IPickerItemProps } from './PickerItem.types'; import { WindowContext } from '@fluentui/react-window-provider'; import { getDocumentEx } from '../../utilities/dom'; +import type { ILabelStyleProps, ILabelStyles } from '../../Label'; const legacyStyles: any = stylesImport; @@ -49,6 +52,7 @@ export interface IBasePickerState { isResultsFooterVisible?: boolean; selectedIndices?: number[]; selectionRemoved?: T; + errorMessage?: string | JSX.Element; } /** @@ -72,6 +76,10 @@ export type IPickerAriaIds = { * Aria id for element with role=combobox */ combobox: string; + /** + * Aria id for error message component + */ + error: string; }; const getClassNames = classNamesFunction(); @@ -111,10 +119,11 @@ 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; + private _isMounted: boolean = false; private _onResolveSuggestionsDebounced: (updatedValue: string) => void; private _overrideScrollDismiss = false; private _overrideScrollDimissTimeout: number; @@ -139,6 +148,7 @@ export class BasePicker> selectedSuggestionAlert: `selected-suggestion-alert-${this._id}`, suggestionList: `suggestion-list-${this._id}`, combobox: `combobox-${this._id}`, + error: `error-${this._id}`, }; this.suggestionStore = new SuggestionsController(); this.selection = new Selection({ onSelectionChanged: () => this.onSelectionChange() }); @@ -160,7 +170,9 @@ export class BasePicker> } public componentDidMount(): void { + this._isMounted = true; this._async = new Async(this); + this._updateErrorMessage(this.state.items); this.selection.setItems(this.state.items); this._onResolveSuggestionsDebounced = this._async.debounce(this._onResolveSuggestions, this.props.resolveDelay); } @@ -183,6 +195,8 @@ export class BasePicker> } } + this._updateErrorMessage(this.state.items); + // handle dismiss buffer after suggestions are opened if (this.state.suggestionsVisible && !oldState.suggestionsVisible) { this._overrideScrollDismiss = true; @@ -194,6 +208,7 @@ export class BasePicker> } public componentWillUnmount(): void { + this._isMounted = false; if (this.currentPromise) { this.currentPromise = undefined; } @@ -269,6 +284,7 @@ export class BasePicker> const suggestionsVisible = !!this.state.suggestionsVisible; const suggestionsAvailable = suggestionsVisible ? this._ariaMap.suggestionList : undefined; + const hasError = !!(this.state.errorMessage ?? this.props.errorMessage); // TODO // Clean this up by leaving only the first part after removing support for SASS. // Currently we can not remove the SASS styles from BasePicker class because it @@ -284,10 +300,12 @@ export class BasePicker> className, isFocused, disabled, + hasErrorMessage: hasError, inputClassName: inputProps && inputProps.className, }) : { root: css('ms-BasePicker', className ? className : ''), + error: 'ms-BasePicker-error', text: css('ms-BasePicker-text', legacyStyles.pickerText, this.state.isFocused && legacyStyles.inputFocused), itemsWrapper: legacyStyles.pickerItems, input: css('ms-BasePicker-input', legacyStyles.pickerInput, inputProps && inputProps.className), @@ -295,6 +313,7 @@ export class BasePicker> }; const comboLabel = this.props['aria-label'] || inputProps?.['aria-label']; + const inputId = inputProps?.id ?? this._ariaMap.combobox; // selectionAriaLabel is contained in a separate rather than an aria-label on the items list // because if the items list has an aria-label, the aria-describedby on the input will only read @@ -309,6 +328,7 @@ export class BasePicker> onBlur={this.onBlur} onClick={this.onWrapperClick} > + {this.renderLabel(inputId, classNames.subComponentStyles?.label)} {this.renderCustomAlert(classNames.screenReaderText)}
+ {this.renderError(classNames.error)} {this.renderSuggestions()}
); } + protected _getDescribedBy = (items: T[], hasError: boolean): string => { + let describedBy = ''; + if (items.length > 0) { + describedBy += this._ariaMap.selectedItems + ' '; + } + if (hasError) { + describedBy += this._ariaMap.error; + } + return describedBy; + }; + protected canAddItems(): boolean { const { items } = this.state; const { itemLimit } = this.props; return itemLimit === undefined || items.length < itemLimit; } + protected renderLabel( + inputId: string, + styles: IStyleFunctionOrObject | undefined, + ): JSX.Element | null { + const { label, disabled, required } = this.props; + if (!label) { + return null; + } + return ( + + ); + } + + protected renderError(className?: string): JSX.Element | null { + const { errorMessage = this.state.errorMessage } = this.props; + if (!errorMessage) { + return null; + } + return ( + + ); + } + protected renderSuggestions(): JSX.Element | null { const StyledTypedSuggestions: React.FunctionComponent> = this._styledSuggestions; @@ -468,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 @@ -647,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: @@ -895,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: @@ -903,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; } @@ -964,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} @@ -1010,6 +1069,44 @@ export class BasePicker> } } + private async _getErrorMessage(items: T[]): Promise { + if (this.props.errorMessage) { + return this.props.errorMessage; + } + if (this.props.onGetErrorMessage) { + try { + const errorMessage = this.props.onGetErrorMessage(items); + if (errorMessage) { + if ((errorMessage as PromiseLike).then) { + return await (errorMessage as PromiseLike); + } else { + return errorMessage as string | JSX.Element; + } + } else { + return undefined; + } + } catch (err) { + /* NO-OP */ + } + } + } + + private _updateErrorMessage(items: T[]): void { + let newErrorMessage: string | JSX.Element | undefined; + this._getErrorMessage(items) + .then(errorMessage => { + newErrorMessage = errorMessage; + }) + .catch(() => { + /* NO-OP */ + }) + .finally(() => { + if (this._isMounted && newErrorMessage !== this.state.errorMessage) { + this.setState({ errorMessage: newErrorMessage }); + } + }); + } + /** * Controls what happens whenever there is an action that impacts the selected items. * If `selectedItems` is provided, this will act as a controlled component and it will not update its own state. @@ -1020,6 +1117,7 @@ export class BasePicker> this.onChange(items); } else { this.setState({ items }, () => { + this._updateErrorMessage(items); this._onSelectedItemsUpdated(items); }); } @@ -1101,12 +1199,13 @@ export class BasePicker> export class BasePickerListBelow> extends BasePicker { public render(): JSX.Element { - const { suggestedDisplayValue, isFocused } = this.state; + const { suggestedDisplayValue, isFocused, items } = this.state; const { className, inputProps, disabled, selectionAriaLabel, selectionRole = 'list', theme, styles } = this.props; const suggestionsVisible = !!this.state.suggestionsVisible; const suggestionsAvailable: string | undefined = suggestionsVisible ? this._ariaMap.suggestionList : undefined; + const hasError = !!(this.state.errorMessage ?? this.props.errorMessage); // TODO // Clean this up by leaving only the first part after removing support for SASS. // Currently we can not remove the SASS styles from BasePicker class because it @@ -1121,10 +1220,13 @@ export class BasePickerListBelow> ex theme, className, isFocused, + disabled, + hasErrorMessage: hasError, inputClassName: inputProps && inputProps.className, }) : { root: css('ms-BasePicker', legacyStyles.picker, className ? className : ''), + error: 'ms-BasePicker-error', text: css( 'ms-BasePicker-text', legacyStyles.pickerText, @@ -1137,9 +1239,11 @@ export class BasePickerListBelow> ex }; const comboLabel = this.props['aria-label'] || inputProps?.['aria-label']; + const inputId = inputProps?.id ?? this._ariaMap.combobox; return (
+ {this.renderLabel(inputId, classNames.subComponentStyles?.label)}
{this.renderCustomAlert(classNames.screenReaderText)}
+ {this.renderError(classNames.error)}
); } diff --git a/packages/react/src/components/pickers/BasePicker.types.ts b/packages/react/src/components/pickers/BasePicker.types.ts index 44d73a57365b32..bc078808bba3e9 100644 --- a/packages/react/src/components/pickers/BasePicker.types.ts +++ b/packages/react/src/components/pickers/BasePicker.types.ts @@ -7,6 +7,7 @@ import type { ICalloutProps } from '../../Callout'; import type { ITheme, IStyle } from '../../Styling'; import type { ISuggestionItemProps } from '../pickers/Suggestions/SuggestionsItem.types'; import { IIconProps } from '../Icon/Icon.types'; +import { ILabelStyleProps, ILabelStyles } from '../Label/Label.types'; /** * BasePicker component. @@ -44,6 +45,11 @@ export interface IBasePickerProps extends IReactProps { */ componentRef?: IRefObject>; + /** + * Descriptive label for the field. + */ + label?: string; + /** * Function that specifies how the selected item will appear. */ @@ -135,6 +141,28 @@ export interface IBasePickerProps extends IReactProps { */ inputProps?: IInputProps; + /** + * Static error message displayed below the selection zone of the field. Use `onGetErrorMessage` to dynamically + * change the error message displayed (if any) based on the current value. `errorMessage` and + * `onGetErrorMessage` are mutually exclusive (`errorMessage` takes precedence). + */ + errorMessage?: string | JSX.Element; + + /** + * Function used to determine whether the selected items are valid and get an error message if not. + * Mutually exclusive with the static string `errorMessage` (it will take precedence over this). + * + * When it returns `string | JSX.Element`: + * - If valid, it returns empty string. + * - If invalid, it returns the error message and the text field will + * show a red border and show an error message below the text field. + * + * When it returns `Promise`: + * - The resolved value is displayed as the error message. + * - If rejected, the value is thrown away. + */ + onGetErrorMessage?: (items: T[]) => string | JSX.Element | PromiseLike | undefined; + /** * A callback for when an item is removed from the suggestion list */ @@ -156,6 +184,12 @@ export interface IBasePickerProps extends IReactProps { */ disabled?: boolean; + /** + * Whether or not the field is required. + * @defaultvalue false + */ + required?: boolean; + /** * Restrict the amount of selectable items. * @defaultvalue undefined @@ -317,6 +351,9 @@ export interface IInputProps extends React.InputHTMLAttributes * {@docCategory Pickers} */ export type IBasePickerStyleProps = Pick, 'theme' | 'className' | 'disabled'> & { + /** Whether the element has an error message or not. */ + hasErrorMessage: boolean; + /** Whether text style area is focused */ isFocused?: boolean; @@ -324,6 +361,14 @@ export type IBasePickerStyleProps = Pick, 'theme' | 'class inputClassName?: string; }; +/** + * {@docCategory Pickers} + */ +export interface IBasePickerSubComponentStyles { + /** Styling for Label child component. */ + label: IStyleFunctionOrObject; +} + /** * Represents the stylable areas of the control. * {@docCategory Pickers} @@ -332,12 +377,18 @@ export interface IBasePickerStyles { /** Root element of any picker extending from BasePicker (wraps all the elements). */ root: IStyle; + /** Refers fo the error message element. */ + error: IStyle; + /** * Refers to the elements already selected (picked) wrapped by `itemsWrapper` along with the input to type * a new selection. */ text: IStyle; + /** Styling for subcomponents. */ + subComponentStyles: IBasePickerSubComponentStyles; + /** Refers to the items already selected (picked). */ itemsWrapper: IStyle; 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} />