diff --git a/.devops/templates/cleanup.yml b/.devops/templates/cleanup.yml index dd967838ff6cc..5e6fb5430aa57 100644 --- a/.devops/templates/cleanup.yml +++ b/.devops/templates/cleanup.yml @@ -12,7 +12,7 @@ steps: # In theory the "workspace: clean: all" setting should handle this, but it doesn't always seem to work. # ReallyClean is a custom task from our internal UI Fabric azure-devops-tasks repo which attempts to # delete the given directory with multiple retries. - - task: ReallyClean@0 - inputs: - directory: $(Agent.BuildDirectory) - condition: always() + # - task: ReallyClean@0 + # inputs: + # directory: $(Agent.BuildDirectory) + # condition: always() diff --git a/.devops/templates/runpublishvrscreenshot.yml b/.devops/templates/runpublishvrscreenshot.yml new file mode 100644 index 0000000000000..28575d15929bd --- /dev/null +++ b/.devops/templates/runpublishvrscreenshot.yml @@ -0,0 +1,75 @@ +parameters: + - name: fluentVersion + type: string + default: v8 + - name: vrTestPackageName + type: string + default: '@fluentui/vr-tests' + - name: vrTestPackagePath + type: string + default: 'apps/vr-tests' + - name: shouldBuildstorybookaddon + type: boolean + default: false + - name: shouldBuildNorthstar + type: boolean + default: false + +steps: + - task: Bash@3 + inputs: + filePath: yarn-ci.sh + displayName: yarn (install packages) + + - script: | + isPR=${{lower(eq(variables['Build.Reason'], 'PullRequest'))}} + echo $isPR + if [[ $isPR == true ]]; then + packageAffected=$(yarn --silent check:affected-package --packages ${{ parameters.vrTestPackageName }} --pr=true) + if [[ $packageAffected == false ]]; then + echo "In PR pipeline but NOT affecting test package. Skipping test run" + echo "##vso[task.setvariable variable=vrTestSkip;]yes" + else + echo "In PR pipeline and affecting test package. NOT Skipping test run" + echo "##vso[task.setvariable variable=vrTestSkip;]no" + fi + else + echo "Not in PR pipeline. NOT Skipping test run" + echo "##vso[task.setvariable variable=vrTestSkip;]no" + fi + displayName: Check if vrTests should be skipped + + - ${{ if eq(parameters.shouldBuildstorybookaddon, 'true') }}: + - script: | + yarn build --to @fluentui/react-storybook-addon + displayName: Build react-storybook-addon + condition: eq(variables['vrTestSkip'], 'no') + + - ${{ if eq(parameters.shouldBuildNorthstar, 'true') }}: + - script: | + yarn build --to @fluentui/docs + displayName: Build react-northstar + condition: eq(variables['vrTestSkip'], 'no') + + - script: | + yarn workspace ${{ parameters.vrTestPackageName }} vr:build + displayName: Build VR tests components package + condition: eq(variables['vrTestSkip'], 'no') + + - script: | + yarn workspace ${{ parameters.vrTestPackageName }} vr:test --verbose + displayName: 'Run VR tests' + condition: eq(variables['vrTestSkip'], 'no') + + - script: | + mkdir -p screenshots + cp -rf ${{ parameters.vrTestPackagePath }}/dist/screenshots/*.png screenshots/ + displayName: Collate Artifacts + condition: eq(variables['vrTestSkip'], 'no') + + - task: PublishBuildArtifacts@1 + inputs: + PathtoPublish: 'screenshots' + ArtifactName: 'vrscreenshot${{ parameters.fluentVersion }}' + publishLocation: 'Container' + condition: eq(variables['vrTestSkip'], 'no') diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index ba27a4691dba7..80e036d32da0d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -28,7 +28,6 @@ /.githooks @microsoft/fluentui-react-build /.storybook @microsoft/fluentui-react-build /.vscode @microsoft/fluentui-react-build -/scripts @microsoft/fluentui-react-build /tools @microsoft/fluentui-react-build #### Root Build files @@ -53,10 +52,36 @@ /migrations.json @microsoft/fluentui-react-build #### Meta and License stuff -/LICENSE @microsoft/fluentui-react-build @justSlone @jurokapsiar -/packages/react/LICENSE @microsoft/fluentui-react-build @justSlone @jurokapsiar -/.github/CODEOWNERS @microsoft/fluentui-react-build @justSlone @jurokapsiar -/.github/ISSUE_TEMPLATE* @justSlone @jurokapsiar +/LICENSE @microsoft/fluentui-react-build @justSlone @jurokapsiar @tudorpopams +/packages/react/LICENSE @microsoft/fluentui-react-build @justSlone @jurokapsiar @tudorpopams +/.github/CODEOWNERS @microsoft/fluentui-react-build @justSlone @jurokapsiar @tudorpopams +/.github/ISSUE_TEMPLATE* @justSlone @jurokapsiar @tudorpopams + +## Tooling packages +scripts/api-extractor @microsoft/fluentui-react-build +scripts/babel @microsoft/fluentui-react-build +scripts/beachball @microsoft/fluentui-react-build +scripts/cypress @microsoft/fluentui-react-build +scripts/dangerjs @microsoft/fluentui-react-build +scripts/executors @microsoft/fluentui-react-build +scripts/fluentui-publish @microsoft/fluentui-react-build +scripts/generators @microsoft/fluentui-react-build +scripts/github @microsoft/fluentui-react-build +scripts/gulp @microsoft/fluentui-react-build @microsoft/teams-prg +scripts/jest @microsoft/fluentui-react-build +scripts/lint-staged @microsoft/fluentui-react-build +scripts/monorepo @microsoft/fluentui-react-build +scripts/package-manager @microsoft/fluentui-react-build +scripts/prettier @microsoft/fluentui-react-build +scripts/projects-test @microsoft/fluentui-react-build +scripts/puppeteer @microsoft/fluentui-react-build +scripts/storybook @microsoft/fluentui-react-build +scripts/tasks @microsoft/fluentui-react-build +scripts/triage-bot @microsoft/fluentui-react-build @microsoft/cxe-prg +scripts/ts-node @microsoft/fluentui-react-build +scripts/update-release-notes @microsoft/fluentui-react-build +scripts/utils @microsoft/fluentui-react-build +scripts/webpack @microsoft/fluentui-react-build #### Fluent UI N* packages/a11y-rules @microsoft/fluentui-northstar @@ -84,11 +109,12 @@ apps/public-docsite-v9 @microsoft/cxe-red @microsoft/cxe-coastal @microsoft/flue apps/theming-designer @microsoft/fluentui-react apps/ssr-tests-v9 @microsoft/fluentui-react-build apps/stress-test @microsoft/cxe-red @spmonahan @micahgodbolt +apps/recipes-react-components @microsoft/cxe-red @microsoft/cxe-coastal @microsoft/fluentui-react-build @sopranopillow #### Packages -packages/azure-themes @hyoshis @Jacqueline-ms +packages/azure-themes @robtaft-ms @Jacqueline-ms packages/bundle-size @microsoft/teams-prg -packages/date-time-utilities @microsoft/fluent-date-time +packages/date-time-utilities @microsoft/cxe-red packages/eslint-plugin @microsoft/fluentui-react-build packages/foundation-legacy @microsoft/cxe-red @khmakoto # packages/font-icons-mdl2 @@ -103,7 +129,7 @@ packages/react-cards @microsoft/cxe-red @khmakoto packages/react-charting @microsoft/charting-team packages/react-components/react-conformance-griffel @microsoft/teams-prg packages/react-components/react-context-selector @microsoft/teams-prg -packages/react-date-time @microsoft/fluent-date-time +packages/react-date-time @microsoft/cxe-red packages/react-docsite-components @microsoft/fluentui-v8-website packages/react-file-type-icons @jahnp @bigbadcapers packages/react-hooks @microsoft/cxe-red @@ -111,7 +137,6 @@ packages/react-monaco-editor @microsoft/fluentui-v8-website packages/react-components/react-positioning @microsoft/teams-prg packages/react-components/react-overflow @microsoft/teams-prg packages/react-components/react-shared-contexts @microsoft/teams-prg -packages/react-components/react-storybook @microsoft/cxe-prg @microsoft/teams-prg packages/react-components/react-storybook-addon @microsoft/cxe-prg packages/react-components/react-tabster @microsoft/teams-prg packages/react-components/react-theme @microsoft/teams-prg @@ -175,26 +200,35 @@ packages/react-components/react-progress @microsoft/cxe-red @tomi-msft packages/react-components/react-persona @microsoft/cxe-red @sopranopillow packages/react-components/react-avatar-context @microsoft/teams-prg packages/react-components/react-infobutton @microsoft/cxe-red @sopranopillow -packages/react-migration-v8-v9 @microsoft/cxe-coastal @geoffcoxmsft packages/react-components/react-tree @microsoft/teams-prg +packages/react-components/react-virtualizer @microsoft/xc-uxe @Mitch-At-Work +packages/react-components/react-skeleton @microsoft/cxe-red +packages/tokens @microsoft/teams-prg +packages/react-components/react-tags @microsoft/cxe-coastal @TristanWatanabe +packages/react-components/react-data-grid-react-window @microsoft/teams-prg +packages/react-components/react-migration-v0-v9 @microsoft/teams-prg +packages/react-components/react-datepicker @microsoft/cxe-red @sopranopillow @khmakoto +packages/react-components/react-migration-v8-v9 @microsoft/cxe-red @microsoft/cxe-coastal @geoffcoxmsft +packages/react-components/react-breadcrumb @microsoft/cxe-prg +packages/react-components/react-drawer @microsoft/cxe-prg +packages/react-components/react-storybook-addon-codesandbox @microsoft/fluentui-react-build +packages/react-components/babel-preset-storybook-full-source @microsoft/fluentui-react-build # <%= NX-CODEOWNER-PLACEHOLDER %> - - ## Components packages/react @microsoft/cxe-red @microsoft/cxe-coastal packages/react/src/components/ActivityItem @microsoft/cxe-red @microsoft/cxe-coastal @khmakoto packages/react/src/components/Announced @microsoft/cxe-red @microsoft/cxe-coastal @khmakoto packages/react/src/components/Breadcrumb @microsoft/cxe-red @microsoft/cxe-coastal @khmakoto packages/react/src/components/Button @microsoft/cxe-red @microsoft/cxe-coastal @khmakoto -packages/react/src/components/Calendar @microsoft/fluent-date-time -packages/react/src/components/CalendarDayGrid @microsoft/fluent-date-time +packages/react/src/components/Calendar @microsoft/cxe-red +packages/react/src/components/CalendarDayGrid @microsoft/cxe-red packages/react/src/components/Check @microsoft/cxe-red @microsoft/cxe-coastal @ThomasMichon @khmakoto packages/react/src/components/Checkbox @microsoft/cxe-red @microsoft/cxe-coastal @khmakoto packages/react/src/components/ChoiceGroup @microsoft/cxe-red @microsoft/cxe-coastal packages/react/src/components/Coachmark @microsoft/cxe-red @microsoft/cxe-coastal @leddie24 packages/react/src/components/ColorPicker @microsoft/cxe-red @microsoft/cxe-coastal -packages/react/src/components/DatePicker @microsoft/fluent-date-time +packages/react/src/components/DatePicker @microsoft/cxe-red packages/react/src/components/DetailsList @microsoft/cxe-red @microsoft/cxe-coastal @ThomasMichon packages/react/src/components/DocumentCard @microsoft/cxe-red @microsoft/cxe-coastal @yiminwu packages/react/src/components/Fabric @microsoft/cxe-red @microsoft/cxe-coastal @dzearing @@ -226,12 +260,25 @@ packages/react/src/components/Text @microsoft/cxe-red @microsoft/cxe-coastal @kh packages/react/src/components/TextField @microsoft/cxe-red @microsoft/cxe-coastal packages/react/src/components/Toggle @microsoft/cxe-red @microsoft/cxe-coastal @khmakoto packages/react/src/components/Tooltip @microsoft/cxe-red @microsoft/cxe-coastal @behowell -packages/react/src/components/WeeklyDayPicker @microsoft/fluent-date-time +packages/react/src/components/WeeklyDayPicker @microsoft/cxe-red ## Theming and styling packages/react/src/utilities/ThemeProvider @microsoft/cxe-red @microsoft/cxe-coastal @dzearing - +packages/fluent2-theme @microsoft/cxe-red @microsoft/cxe-coastal @geoffcoxmsft ## Experiments packages/react-experiments/src/components/Signals @ThomasMichon packages/react-experiments/src/components/Tile @ThomasMichon packages/react-experiments/src/components/TileList @ThomasMichon + +### generic rules for v-build. Might be tweaked based on needs. +**/just.config.ts @microsoft/fluentui-react-build +**/jest.config.js @microsoft/fluentui-react-build +**/webpack.*.js @microsoft/fluentui-react-build +**/.eslintrc.js @microsoft/fluentui-react-build +**/.eslintrc.json @microsoft/fluentui-react-build +**/tsconfig.json @microsoft/fluentui-react-build +**/tsconfig.lib.json @microsoft/fluentui-react-build +**/tsconfig.spec.json @microsoft/fluentui-react-build +**/cypress.config.ts @microsoft/fluentui-react-build +**/api-extractor.json @microsoft/fluentui-react-build +**/api-extractor.unstable.json @microsoft/fluentui-react-build diff --git a/.github/ISSUE_TEMPLATE/convergence_epic.md b/.github/ISSUE_TEMPLATE/convergence_epic.md index ca5b1b2522ffe..a5eb943d41d50 100644 --- a/.github/ISSUE_TEMPLATE/convergence_epic.md +++ b/.github/ISSUE_TEMPLATE/convergence_epic.md @@ -1,48 +1,52 @@ --- -name: (internal) Component convergence epic -about: (team member use only) Epic issue tracking convergence of a particular component +name: (internal) Component implementation epic +about: (team member use only) Epic issue tracking implementation of a particular component --- -## Preparation: +💡 When you create a PR for any of the checklist items, add a link to this Epic under the PR's **Related Issues** section. -- [ ] Open UI Research +## Preparation + +- [ ] [Open UI Research](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#open-ui-research) - [link to https://open-ui.org/] -- [ ] Open GitHub issues related to component +- [ ] [Open GitHub issues related to component](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#find-open-issues-on-github) - [link to each issue] -- [ ] react-\* package scaffolded with the right ownership in CODEOWNERS - - [link to package / PR] -- [ ] Component Spec authored and reviewed - - [link to spec in component package / PR] +- [ ] [Create react-\* package and component from template](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#component-package) + - [link to package: https://github.com/microsoft/fluentui/tree/master/packages/react-components/react-(your-component)] +- [ ] (Optional) [Draft implementation](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#draft-implementation) + - [link to draft implementation, if applicable] +- [ ] [Component Spec authored](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#component-spec) and [reviewed](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#spec-review) ## Implementation -[link to react-* package folder] - -- [ ] Component implementation - - [link(s) to component implementation related PRs] -- [ ] Storybook stories - - [link(s) to stories PRs] -- [ ] Add tests: Conformance, Unit, and VR -- add PRs to all - - [ ] Bundle size fixtures - - [ ] Conformance tests - - [ ] Unit tests - - [ ] VR tests - - [ ] Accessibility behavior tests - - [ ] Create an issue and run [manual accessibility tests](https://github.com/microsoft/fluentui/wiki/Manual-Accessibility-Review-Checklist): (issue link) - - [ ] Performance test scenario -- [ ] README.md covering basic usage -- [ ] MIGRATION.md guide (include v8 and v0) +- [ ] [Component implementation](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#implementation) +- [ ] Initial conformance and unit tests (validate basic functionality) +- [ ] [Initial documentation](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#documentation) + - [ ] [Storybook stories](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#storybook-stories) + - [ ] README.md covering basic usage + - [ ] MIGRATION.md guide (include v8 and v0) +- [ ] [Component released as unstable](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#unstable-release) from `@fluentui/react-components/unstable` ## Validation -- [ ] Add and validate in UI Builder -- [ ] Add and validate in docs site -- [ ] Validate with token pipeline -- [ ] Validate in product -- [ ] Finalize migration guide - - [ ] Author codemods +- [ ] [Add tests](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#tests) + - [ ] Unit and conformance tests + - [ ] VR tests + - [ ] Bundle size fixtures + - [ ] Performance test scenario + - [ ] Accessibility behavior tests + - [ ] Create an issue and run [manual accessibility tests](https://github.com/microsoft/fluentui/wiki/Manual-Accessibility-Review-Checklist): [link to issue] +- [ ] [Validate with partners](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#validation) +- [ ] [Run a bug bash with other FUI crews](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#bug-bash) +- [ ] [Finalize documentation](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#finalize-documentation) + - [ ] Review and add any missing storybook stories + - [ ] Finalize migration guide +- [ ] [Component released as stable](https://github.com/microsoft/fluentui/wiki/Component-Implementation-Guide#stable-release) from `@fluentui/react-components` + - [ ] Ensure exports are removed from from `@fluentui/react-components/unstable` + - [ ] In package.json: Remove the alpha/beta tag from the version number in package.json + - [ ] In package.json: Change beachball's `disallowedChangeTypes` to `"major", "prerelease"` diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 390a0a4303eb3..7edd467849899 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -12,7 +12,7 @@ PR flow tips: * [ ] Once you're ready (ideally the pipeline is passing) promote your PR to Ready for Review. This step will auto-assign reviewers for your PR. --> -## Current Behavior +## Previous Behavior @@ -24,4 +24,4 @@ PR flow tips: -Fixes # +- Fixes # diff --git a/.github/workflows/check-packages.yml b/.github/workflows/check-packages.yml index 875957b38b1a3..32a67668aeeae 100644 --- a/.github/workflows/check-packages.yml +++ b/.github/workflows/check-packages.yml @@ -15,7 +15,7 @@ jobs: node-version: 14.18.1 cache: 'yarn' - - uses: tj-actions/changed-files@v32 + - uses: tj-actions/changed-files@v34 id: changed-files-specific with: files: | @@ -38,7 +38,7 @@ jobs: dependency-mismatches: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: @@ -62,7 +62,7 @@ jobs: change-files: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 @@ -83,5 +83,5 @@ jobs: core.exportVariable('BEACHBALL_VERSION', beachballVersion); - run: | - npx beachball@$BEACHBALL_VERSION check -b web-components-v3 + npx beachball@$BEACHBALL_VERSION check --scope packages/web-components -b web-components-v3 node ./scripts/beachball/check-wc-3-changefiles diff --git a/.github/workflows/create-milestone.yml b/.github/workflows/create-milestone.yml index ad38254db1f9a..f34c3719932e1 100644 --- a/.github/workflows/create-milestone.yml +++ b/.github/workflows/create-milestone.yml @@ -16,10 +16,12 @@ jobs: - name: Create milestone run: | month=$(date +"%B") + month_numeric=$(date +"%m") quarter=$(date +"%q") year=$(date +"%Y") title="${month} Project Cycle Q${quarter} ${year}" - echo "Using title '${title}'" - gh api --method POST repos/microsoft/fluentui/milestones -f title="${title}" + due_on=$(date -v1d -v${month_numeric}m -v-1d +"%Y-%m-%dT%H:%M:%S%z") + echo "Using title '${title}' and setting due date: '${due-on}'" + gh api --method POST repos/microsoft/fluentui/milestones -f title="${title} -f due_on="${due_on}" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/docsite-publish-chromatic.yml b/.github/workflows/docsite-publish-chromatic.yml index 2369a9478b303..fc8ef562d8eba 100644 --- a/.github/workflows/docsite-publish-chromatic.yml +++ b/.github/workflows/docsite-publish-chromatic.yml @@ -20,7 +20,7 @@ jobs: name: Checkout [master] - name: Verify react-compoenents has changed - uses: tj-actions/changed-files@v23.1 + uses: tj-actions/changed-files@v34 id: verify-react-components-changed with: files: | diff --git a/.github/workflows/docsite-publish-ghpages.yml b/.github/workflows/docsite-publish-ghpages.yml index fa9e24a32e514..f358f4ce03052 100644 --- a/.github/workflows/docsite-publish-ghpages.yml +++ b/.github/workflows/docsite-publish-ghpages.yml @@ -20,7 +20,7 @@ jobs: name: Checkout [master] - name: Verify react-compoenents has changed - uses: tj-actions/changed-files@v23.1 + uses: tj-actions/changed-files@v34 id: verify-react-components-changed with: files: | diff --git a/.github/workflows/issues.yml b/.github/workflows/issues.yml index 6464862d7e331..8abcb77c26b3f 100644 --- a/.github/workflows/issues.yml +++ b/.github/workflows/issues.yml @@ -12,7 +12,7 @@ jobs: issues: write steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: actions/github-script@v6 with: script: | diff --git a/.github/workflows/pr-housekeeping.yml b/.github/workflows/pr-housekeeping.yml index 6a1909aca67a4..7af9503414458 100644 --- a/.github/workflows/pr-housekeeping.yml +++ b/.github/workflows/pr-housekeeping.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Assign to latest milestone - uses: andrefcdias/add-to-milestone@v1.2.4 + uses: andrefcdias/add-to-milestone@v1.3.0 with: repo-token: '${{ secrets.GITHUB_TOKEN }}' use-expression: true diff --git a/.github/workflows/screener-build.yml b/.github/workflows/screener-build.yml deleted file mode 100644 index f4ddf2e6633f1..0000000000000 --- a/.github/workflows/screener-build.yml +++ /dev/null @@ -1,283 +0,0 @@ -name: Screener build - -on: - push: - branches: - - master - pull_request: - types: [opened, reopened, synchronize, ready_for_review] - -env: - DEPLOYHOST: 'fluentuipr.z22.web.core.windows.net' - -jobs: - environment-upload: - runs-on: ubuntu-latest - steps: - - run: mkdir artifacts - - ########################################### - # BROWSERSLIST_IGNORE_OLD_DATA = Prevents failures on CI when "caniuse-lite" becomes outdated - # DEPLOYHOST = address of host for screener tests deployment - # BUILD_BUILDID = unique ID of the workflow run within the repo - ########################################### - - name: Set base env variables - run: | - cat <> artifacts/environment - BROWSERSLIST_IGNORE_OLD_DATA=true - BUILD_BUILDID=${{ github.run_id }} - SCREENER_BUILD=1 - EOT - - - name: Set env variables if there is not a PR - run: | - cat <> artifacts/environment - DEPLOYBASEPATH=heads/${{github.ref_name}} - DEPLOYURL=https://${{env.DEPLOYHOST}}/heads/${{github.ref_name}} - BUILD_SOURCEBRANCHNAME=${{ github.ref_name }} - EOT - if: github.event_name == 'push' - - - name: Check if draft PR has 'Ready for VR' label - uses: actions/github-script@v6 - with: - script: | - let labels = await github.rest.issues.listLabelsOnIssue({ - issue_number: ${{github.event.pull_request.number}}, - owner: context.repo.owner, - repo: context.repo.repo - }); - - let foundLabel = labels.data.find((label) => {return label.name == 'Ready for VR'}); - if(foundLabel === undefined) - core.exportVariable('SKIP_SCREENER', true); - if: github.event_name == 'pull_request' && github.event.pull_request.draft == true - - - run: echo "SKIP_SCREENER=${{env.SKIP_SCREENER}}" >> skip-screener - - - name: Upload environment variables artifact - uses: actions/upload-artifact@v3 - with: - name: skip-screener - path: skip-screener - - ########################################### - # SYSTEM_PULLREQUEST_TARGETBRANCH = target branch name - # SYSTEM_PULLREQUEST_SOURCEBRANCH = source branch name - # SYSTEM_PULLREQUEST_PULLREQUESTID = ID of the PR - # SYSTEM_PULLREQUEST_SOURCECOMMITID = commit SHA of PR - # DEPLOYBASEPATH = path for deploy URL -> pull/ for PRs - # DEPLOYURL= address for tests deployment, uses DEPLOYHOST and DEPLOYBASEPATH - # BUILD_SOURCEBRANCHNAME = 'merge' for PRs - ########################################### - - name: Set env variables if there is a PR - run: | - cat <> artifacts/environment - SYSTEM_PULLREQUEST_TARGETBRANCH=${{ github.event.pull_request.base.ref }} - SYSTEM_PULLREQUEST_PULLREQUESTID=${{ github.event.pull_request.id }} - SYSTEM_PULLREQUEST_SOURCECOMMITID=${{ github.event.pull_request.head.sha }} - DEPLOYBASEPATH=pull/${{github.event.pull_request.number}} - DEPLOYURL=https://${{env.DEPLOYHOST}}/pull/${{github.event.pull_request.number}} - BUILD_SOURCEBRANCHNAME=${{ github.event.pull_request.head.ref }} - EOT - if: ${{ github.event_name == 'pull_request' && env.SKIP_SCREENER == ''}} - - - name: Upload environment variables artifact - uses: actions/upload-artifact@v3 - with: - name: env-artifact - path: artifacts/environment - if: ${{ env.SKIP_SCREENER == '' }} - - outputs: - SKIP_SCREENER: ${{env.SKIP_SCREENER}} - - screener-react-northstar: - if: needs.environment-upload.outputs.SKIP_SCREENER == '' - needs: environment-upload - runs-on: 'ubuntu-latest' - name: Screener @fluentui/react-northstar - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Download env variables artifact - uses: actions/download-artifact@v3 - with: - name: env-artifact - - - name: Define env variables - run: | - input_file="environment" - while read line - do - echo "$line" >> $GITHUB_ENV - done < "$input_file" - - - name: Delete environment file - run: | - rm environment - - - uses: actions/setup-node@v3 - with: - node-version: 14.18.1 - cache: 'yarn' - - - name: Install dependencies - run: yarn install --frozen-lockfile - - - run: | - echo "Is PR build? ${{startsWith(github.ref, 'refs/pull/')}}" - packageAffected=$(yarn --silent check:affected-package --packages @fluentui/docs --pr=${{startsWith(github.ref, 'refs/pull/')}}) - if [[ $packageAffected == false ]]; then - echo "Should skip screener" - echo "SKIP_SCREENER_BUILD=true" >> $GITHUB_ENV - else - echo "SKIP_SCREENER_BUILD=false" >> $GITHUB_ENV - echo "Should NOT skip screener" - fi - name: Check if northstar packages were affected - - - name: Log environment variables (Linux) - if: runner.os == 'Linux' - run: | - printenv | sort ;\ - echo "SHELLOPTS $SHELLOPTS" ;\ - - - name: build FUI N* VR Test - run: yarn workspace @fluentui/docs vr:build - env: - SCREENER_BUILD: 1 - if: ${{env.SKIP_SCREENER_BUILD == 'false'}} - - - uses: actions/upload-artifact@v3 - with: - name: northstar-artifact - path: packages/fluentui/docs/dist - if: ${{env.SKIP_SCREENER_BUILD == 'false'}} - - screener-react: - if: needs.environment-upload.outputs.SKIP_SCREENER == '' - needs: environment-upload - runs-on: 'ubuntu-latest' - name: Screener @fluentui/react - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Download a single artifact - uses: actions/download-artifact@v3 - with: - name: env-artifact - - - name: Define env variables - run: | - input_file="environment" - while read line - do - echo "$line" >> $GITHUB_ENV - done < "$input_file" - - - name: Delete environment file - run: | - rm environment - - - uses: actions/setup-node@v3 - with: - node-version: 14.18.1 - cache: 'yarn' - - - name: Install dependencies - run: yarn install --frozen-lockfile - - - run: | - echo "Is PR build? ${{startsWith(github.ref, 'refs/pull/')}}" - packageAffected=$(yarn --silent check:affected-package --packages @fluentui/vr-tests --pr=${{startsWith(github.ref, 'refs/pull/')}}) - if [[ $packageAffected == false ]]; then - echo "Should skip screener" - echo "SKIP_SCREENER_BUILD=true" >> $GITHUB_ENV - else - echo "SKIP_SCREENER_BUILD=false" >> $GITHUB_ENV - echo "Should NOT skip screener" - fi - name: Check if v8 packages were affected - - - name: Log environment variables (Linux) - if: runner.os == 'Linux' - run: | - printenv | sort ;\ - echo "SHELLOPTS $SHELLOPTS" ;\ - - - name: build vr-tests storybook - run: yarn workspace @fluentui/vr-tests screener:build - if: ${{env.SKIP_SCREENER_BUILD == 'false'}} - - - uses: actions/upload-artifact@v3 - with: - name: screener-artifact - path: apps/vr-tests/dist/storybook - if: ${{env.SKIP_SCREENER_BUILD == 'false'}} - - screener-react-components: - if: needs.environment-upload.outputs.SKIP_SCREENER == '' - needs: environment-upload - runs-on: 'ubuntu-latest' - name: Screener @fluentui/react-components - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Download a single artifact - uses: actions/download-artifact@v3 - with: - name: env-artifact - - - name: Define env variables - run: | - input_file="environment" - while read line - do - echo "$line" >> $GITHUB_ENV - done < "$input_file" - - - name: Delete environment file - run: | - rm environment - - - uses: actions/setup-node@v3 - with: - node-version: 14.18.1 - cache: 'yarn' - - name: Install dependencies - run: yarn install --frozen-lockfile - - - run: | - echo "Is PR build? ${{startsWith(github.ref, 'refs/pull/')}}" - packageAffected=$(yarn --silent check:affected-package --packages @fluentui/vr-tests-react-components --pr=${{startsWith(github.ref, 'refs/pull/')}}) - if [[ $packageAffected == false ]]; then - echo "Should skip screener" - echo "SKIP_SCREENER_BUILD=true" >> $GITHUB_ENV - else - echo "SKIP_SCREENER_BUILD=false" >> $GITHUB_ENV - echo "Should NOT skip screener" - fi - name: Check if v9 packages were affected - - - name: Log environment variables (Linux) - if: runner.os == 'Linux' - run: | - printenv | sort ;\ - echo "SHELLOPTS $SHELLOPTS" ;\ - - - name: build vr-tests-react-components storybook - run: yarn workspace @fluentui/vr-tests-react-components screener:build - if: ${{env.SKIP_SCREENER_BUILD == 'false'}} - - - uses: actions/upload-artifact@v3 - with: - name: vnext-artifact - path: apps/vr-tests-react-components/dist/storybook - if: ${{env.SKIP_SCREENER_BUILD == 'false'}} diff --git a/.github/workflows/screener-run.yml b/.github/workflows/screener-run.yml deleted file mode 100644 index 6ddd0a26c50be..0000000000000 --- a/.github/workflows/screener-run.yml +++ /dev/null @@ -1,259 +0,0 @@ -name: Screener run -on: - workflow_run: - workflows: - - Screener build - types: - - completed - -env: - AZURE_STORAGE_CONNECTION_STRING: ${{secrets.AZURE_STORAGE_CONNECTION_STRING}} -jobs: - determine-if-skipping: - runs-on: 'ubuntu-latest' - steps: - - name: Download artifact to determine if skipping jobs - uses: dawidd6/action-download-artifact@v2 - with: - workflow: screener-build.yml - run_id: ${{github.event.workflow_run.id}} - name: skip-screener - - - name: Define env variable - run: | - var=$(head -1 skip-screener) - echo "$var" >> $GITHUB_ENV - outputs: - SKIP_SCREENER: ${{env.SKIP_SCREENER}} - - screener-react-northstar: - if: needs.determine-if-skipping.outputs.SKIP_SCREENER == '' - needs: determine-if-skipping - runs-on: 'ubuntu-latest' - name: Screener @fluentui/react-northstar - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - uses: actions/setup-node@v3 - with: - node-version: 14.18.1 - cache: 'yarn' - - - name: Check if test app artifact deployed - uses: actions/github-script@v6 - id: skip-screener - with: - script: | - let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: context.payload.workflow_run.id, - - }); - let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => { - return artifact.name == "northstar-artifact" - })[0]; - core.exportVariable('IS_ARTIFACT_PRESENT', (matchArtifact !== undefined).toString()); - - - name: Download environment variables artifact - uses: dawidd6/action-download-artifact@v2 - with: - workflow: screener-build.yml - run_id: ${{github.event.workflow_run.id}} - name: env-artifact - - - name: Download N* storybook artifact - uses: dawidd6/action-download-artifact@v2 - with: - workflow: screener-build.yml - run_id: ${{github.event.workflow_run.id}} - name: northstar-artifact - # downloads artifact to where it would be 'built' - path: packages/fluentui/docs/dist - if: ${{ env.IS_ARTIFACT_PRESENT == 'true' }} - - - name: Define env variables - run: | - input_file="environment" - while read line - do - echo "$line" >> $GITHUB_ENV - done < "$input_file" - - - name: Log environment variables (Linux) - if: runner.os == 'Linux' - run: | - printenv | sort ;\ - echo "SHELLOPTS $SHELLOPTS" ;\ - - - name: Install dependencies - run: yarn install --frozen-lockfile - - - name: Upload N* VR test site - uses: azure/CLI@v1 - with: - inlineScript: | - az storage blob upload-batch -d '$web/${{env.DEPLOYBASEPATH}}/react-northstar-screener' -s 'packages/fluentui/docs/dist' --overwrite - if: ${{ env.IS_ARTIFACT_PRESENT == 'true' }} - - - name: Start @fluentui/react-northstar VR Test - run: yarn workspace @fluentui/docs vr:test - env: - SCREENER_ENDPOINT: ${{secrets.SCREENER_ENDPOINT}} - SCREENER_PROXY_ENDPOINT: ${{secrets.SCREENER_PROXY_ENDPOINT}} - SCREENER_API_KEY: ${{secrets.SCREENER_API_KEY}} - - screener-react: - if: needs.determine-if-skipping.outputs.SKIP_SCREENER == '' - needs: determine-if-skipping - runs-on: 'ubuntu-latest' - name: Screener @fluentui/react - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - uses: actions/setup-node@v3 - with: - node-version: 14.18.1 - cache: 'yarn' - - - name: Check if test app artifact deployed - uses: actions/github-script@v6 - id: skip-screener - with: - script: | - let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: context.payload.workflow_run.id, - }); - let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => { - return artifact.name == "screener-artifact" - })[0]; - core.exportVariable('IS_ARTIFACT_PRESENT', (matchArtifact !== undefined).toString()); - - - name: Download environment variables artifact - uses: dawidd6/action-download-artifact@v2 - with: - workflow: screener-build.yml - run_id: ${{github.event.workflow_run.id}} - name: env-artifact - - - name: Download screener storybook artifact - uses: dawidd6/action-download-artifact@v2 - with: - workflow: screener-build.yml - run_id: ${{github.event.workflow_run.id}} - name: screener-artifact - path: apps/vr-tests/dist/storybook - if: ${{ env.IS_ARTIFACT_PRESENT == 'true' }} - - - name: Define env variables - run: | - input_file="environment" - while read line - do - echo "$line" >> $GITHUB_ENV - done < "$input_file" - - - name: Log environment variables (Linux) - if: runner.os == 'Linux' - run: | - printenv | sort ;\ - echo "SHELLOPTS $SHELLOPTS" ;\ - - - name: Install dependencies - run: yarn install --frozen-lockfile - - name: Upload @fluentui/react VR test site - uses: azure/CLI@v1 - with: - inlineScript: | - az storage blob upload-batch -d '$web/${{env.DEPLOYBASEPATH}}/react-screener' -s 'apps/vr-tests/dist/storybook' --overwrite - if: ${{ env.IS_ARTIFACT_PRESENT == 'true' }} - - - name: Start @fluentui/react VR Test - run: yarn workspace @fluentui/vr-tests screener - env: - SCREENER_ENDPOINT: ${{secrets.SCREENER_ENDPOINT}} - SCREENER_PROXY_ENDPOINT: ${{secrets.SCREENER_PROXY_ENDPOINT}} - SCREENER_API_KEY: ${{secrets.SCREENER_API_KEY}} - - screener-react-components: - if: needs.determine-if-skipping.outputs.SKIP_SCREENER == '' - needs: determine-if-skipping - runs-on: 'ubuntu-latest' - name: Screener @fluentui/react-components - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - uses: actions/setup-node@v3 - with: - node-version: 14.18.1 - cache: 'yarn' - - - name: Check if test app artifact deployed - uses: actions/github-script@v6 - id: skip-screener - with: - script: | - let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: context.payload.workflow_run.id, - }); - let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => { - return artifact.name == "vnext-artifact" - })[0]; - core.exportVariable('IS_ARTIFACT_PRESENT', (matchArtifact !== undefined).toString()); - - - name: Download environment variables artifact - uses: dawidd6/action-download-artifact@v2 - with: - workflow: screener-build.yml - run_id: ${{github.event.workflow_run.id}} - name: env-artifact - - - name: Download VNext storybook artifact - uses: dawidd6/action-download-artifact@v2 - with: - workflow: screener-build.yml - run_id: ${{github.event.workflow_run.id}} - name: vnext-artifact - path: apps/vr-tests-react-components/dist/storybook - if: ${{ env.IS_ARTIFACT_PRESENT == 'true' }} - - - name: Define env variables - run: | - input_file="environment" - while read line - do - echo "$line" >> $GITHUB_ENV - done < "$input_file" - - - name: Log environment variables (Linux) - if: runner.os == 'Linux' - run: | - printenv | sort ;\ - echo "SHELLOPTS $SHELLOPTS" ;\ - - - name: Install dependencies - run: yarn install --frozen-lockfile - - - name: Upload @fluentui/react-components VR test site - uses: azure/CLI@v1 - with: - inlineScript: | - az storage blob upload-batch -d '$web/${{env.DEPLOYBASEPATH}}/react-components-screener' -s 'apps/vr-tests-react-components/dist/storybook' --overwrite - if: ${{ env.IS_ARTIFACT_PRESENT == 'true' }} - - - name: Start @fluentui/react-components VR Test - run: yarn workspace @fluentui/vr-tests-react-components screener - env: - SCREENER_ENDPOINT: ${{secrets.SCREENER_ENDPOINT}} - SCREENER_PROXY_ENDPOINT: ${{secrets.SCREENER_PROXY_ENDPOINT}} - SCREENER_API_KEY: ${{secrets.SCREENER_API_KEY}} diff --git a/.gulp.js b/.gulp.js index 92421f5eba985..e75f16fd1a21e 100644 --- a/.gulp.js +++ b/.gulp.js @@ -1,6 +1,6 @@ // https://github.com/gulpjs/gulp-cli#configuration module.exports = { flags: { - require: '@fluentui/scripts/babel/register', + require: '@fluentui/scripts-babel/register', }, }; diff --git a/.prettierignore b/.prettierignore index a3930f814d2d5..7aa372589e0d7 100644 --- a/.prettierignore +++ b/.prettierignore @@ -17,6 +17,7 @@ lib-amd lib-esm lib-commonjs dist +temp common/changes common/scripts coverage diff --git a/.storybook/docs-root.css b/.storybook/docs-root.css index e1f8fe7f8d97f..556379d237f3d 100644 --- a/.storybook/docs-root.css +++ b/.storybook/docs-root.css @@ -62,6 +62,11 @@ padding: 48px 0 0 0; } +#docs-root .sbdocs-h2 code { + border-radius: 4px; + font-size: 20px; +} + #docs-root .sbdocs-h3 { font-family: 'Segoe UI', 'Segoe UI Web (West European)', -apple-system, BlinkMacSystemFont, Roboto, 'Helvetica Neue', sans-serif; @@ -72,6 +77,11 @@ color: #000000; } +#docs-root .sbdocs-h3 code { + border-radius: 3px; + font-size: 16px; +} + /* Only apply to H3s inside of stories which have a parent with an ID */ #docs-root [id] > .sbdocs-h3:before { content: ''; @@ -285,7 +295,7 @@ #docs-root .docblock-argstable-body > tr > td:nth-child(2) > div:nth-child(2) span, #docs-root .docblock-argstable-body > tr > td:nth-child(2) > div:nth-child(1) > div > span, #docs-root .css-16d4d7t { - font-family: Menlo, monospace; + font-family: 'Cascadia Code', Menlo, 'Courier New', Courier, monospace; font-style: normal; font-weight: normal; font-size: 14px; @@ -318,7 +328,10 @@ } #docs-root code { - margin: 1px 0 1px 0; + padding: 0.1em 0.2em; + display: inline-block; + background-color: rgba(17, 16, 15, 0.1); + border-radius: 2px; } .os-content-glue { @@ -329,6 +342,12 @@ overflow: hidden; } +#docs-root .os-content .prismjs * { + font-family: 'Cascadia Code', Menlo, 'Courier New', Courier, monospace; + font-size: 14px; + line-height: 1.4em; +} + #docs-root .sbdocs-preview .prismjs code { color: white; background: #11100f; diff --git a/.storybook/main.js b/.storybook/main.js index cce2e61868cd3..4d7988a2c5447 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -1,9 +1,9 @@ const path = require('path'); const fs = require('fs'); -const { TsconfigPathsPlugin } = require('tsconfig-paths-webpack-plugin'); -const exportToCodesandboxAddon = require('storybook-addon-export-to-codesandbox'); -const { loadWorkspaceAddon, getCodesandboxBabelOptions } = require('../scripts/storybook'); +const { loadWorkspaceAddon, registerTsPaths, registerRules, rules } = require('@fluentui/scripts-storybook'); + +const tsConfigPath = path.resolve(__dirname, '../tsconfig.base.json'); /** * @typedef {import('@storybook/core-common').StorybookConfig} StorybookBaseConfig @@ -19,14 +19,6 @@ const { loadWorkspaceAddon, getCodesandboxBabelOptions } = require('../scripts/s * } StorybookConfig */ -/** - * @typedef {{loader: string; options: { [index: string]: any }}} LoaderObjectDef - */ - -/** - * @typedef {import('@babel/core').TransformOptions & Partial<{customize: string | null}>} BabelLoaderOptions - */ - const previewHeadTemplate = fs.readFileSync(path.resolve(__dirname, 'preview-head-template.html'), 'utf8'); module.exports = /** @type {Omit} */ ({ @@ -36,8 +28,33 @@ module.exports = /** @type {Omit} */ ({ }, stories: [], addons: [ + { + name: 'storybook-addon-swc', + options: /** @type {import('storybook-addon-swc').StoryBookAddonSwcOptions} */ ({ + swcLoaderOptions: { + jsc: { + target: 'es2019', + parser: { + syntax: 'typescript', + tsx: true, + decorators: true, + dynamicImport: true, + }, + transform: { + decoratorMetadata: true, + legacyDecorator: true, + }, + keepClassNames: true, + externalHelpers: true, + loose: true, + }, + }, + swcMinifyOptions: { mangle: false }, + }), + }, '@storybook/addon-essentials', '@storybook/addon-a11y', + '@storybook/addon-links', '@storybook/addon-knobs/preset', 'storybook-addon-performance', @@ -49,43 +66,11 @@ module.exports = /** @type {Omit} */ ({ // internal monorepo custom addons /** @see ../packages/react-components/react-storybook-addon */ - loadWorkspaceAddon('@fluentui/react-storybook-addon'), + loadWorkspaceAddon('@fluentui/react-storybook-addon', { tsConfigPath }), ], webpackFinal: config => { - const tsPaths = new TsconfigPathsPlugin({ - configFile: path.resolve(__dirname, '../tsconfig.base.json'), - }); - - if (config.resolve) { - config.resolve.plugins ? config.resolve.plugins.push(tsPaths) : (config.resolve.plugins = [tsPaths]); - } - - if (config.module && config.module.rules) { - /** - * @type {import("webpack").RuleSetRule} - */ - const codesandboxRule = { - /** - * why the usage of 'post' ? - we need to run this loader after all storybook webpack rules/loaders have been executed. - * while we can use Array.prototype.unshift to "override" the indexes this approach is more declarative without additional hacks. - */ - enforce: 'post', - test: /\.stories\.tsx$/, - //TODO: simplify once all v9 packages have been migrated to new package structure. Tracking work: https://github.com/microsoft/fluentui/issues/24129 - include: /stories|src/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: processBabelLoaderOptions({ - plugins: [[exportToCodesandboxAddon.babelPlugin, getCodesandboxBabelOptions()]], - }), - }, - }; - - config.module.rules.push(codesandboxRule); - - overrideDefaultBabelLoader(/** @type {import("webpack").RuleSetRule[]} */ (config.module.rules)); - } + registerTsPaths({ config, configFile: tsConfigPath }); + registerRules({ config, rules: [rules.codesandboxRule] }); if ((process.env.CI || process.env.TF_BUILD || process.env.LAGE_PACKAGE_NAME) && config.plugins) { // Disable ProgressPlugin in PR/CI builds to reduce log verbosity (warnings and errors are still logged) @@ -97,6 +82,7 @@ module.exports = /** @type {Omit} */ ({ core: { builder: 'webpack5', lazyCompilation: true, + disableTelemetry: true, }, /** * Programmatically enhance previewHead as inheriting just static file `preview-head.html` doesn't work in monorepo @@ -104,62 +90,3 @@ module.exports = /** @type {Omit} */ ({ */ previewHead: head => head + previewHeadTemplate, }); - -/** - * Adds custom config to any `babel-loader` usage. Needs to be used on all manually added rules with babel-loader to webpack configuration. - * - * Why is this needed: - * - `options.babelrc` is ignored by `babel-loader` thus we need to use `customize` api to exclude specific babel presets/plugins - * - * @param {BabelLoaderOptions} loaderConfig - */ -function processBabelLoaderOptions(loaderConfig) { - const customLoaderPath = path.resolve(__dirname, './custom-loader.js'); - const customOptions = { customize: customLoaderPath }; - Object.assign(loaderConfig, customOptions); - - return loaderConfig; -} - -/** - * Overrides storybooks babel-loader setup - * - * We might remove this once we'll came up with robust solution (or proper behaviors will be added to babel-loader). For more context @see https://github.com/microsoft/fluentui/issues/18775 - * - * Note: - * - this function mutates `rules` argument which is a reference to `modules.rules` webpack config property - * - to print used babel-loader config run: `yarn start-storybook --no-manager-cache --debug-webpack` and look for - * webpack rule set containing both: - * - `test: /\.(mjs|tsx?|jsx?)$/` - * - `node_modules/babel-loader/lib/index.js` as `loader` within module.rules - * - * @param {import("webpack").RuleSetRule[]} rules - */ -function overrideDefaultBabelLoader(rules) { - const loader = getBabelLoader(); - processBabelLoaderOptions(loader.options); - - function getBabelLoader() { - const ruleIdx = rules.findIndex(rule => { - return String(/** @type {import("webpack").RuleSetRule}*/ (rule).test) === '/\\.(mjs|tsx?|jsx?)$/'; - }); - - const rule = /** @type {import("webpack").RuleSetRule}*/ (rules[ruleIdx]); - - if (!Array.isArray(rule.use)) { - throw new Error('storybook webpack rules changed'); - } - - const loaderIdx = rule.use.findIndex(loaderConfig => { - return /** @type {LoaderObjectDef} */ (loaderConfig).loader.includes('babel-loader'); - }); - - const loader = /** @type {LoaderObjectDef}*/ (rule.use[loaderIdx]); - - if (!Object.prototype.hasOwnProperty.call(loader, 'options')) { - throw new Error('storybook webpack #module.rules changed!'); - } - - return loader; - } -} diff --git a/.storybook/preview.js b/.storybook/preview.js index 4d5b76dfc83a8..4000008cd53fa 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -1,7 +1,7 @@ -import { withFluentProvider, withStrictMode } from '@fluentui/react-storybook'; import 'cypress-storybook/react'; import * as dedent from 'dedent'; import './docs-root.css'; +import { withLinks } from '@storybook/addon-links'; // This patches globals set up by cypress-storybook to work around its usage of the deprecated // forceReRender API that no longer works with storyStoreV7 @@ -23,7 +23,7 @@ window.__setCurrentStory = function (categorization, story) { }; /** @type {NonNullable} */ -export const decorators = [withFluentProvider, withStrictMode]; +export const decorators = [withLinks]; /** @type {import('@storybook/addons').Parameters} */ export const parameters = { @@ -35,7 +35,10 @@ export const parameters = { docs: { source: { excludeDecorators: true, + type: 'source', }, + // This config reuses sources generated for CodeSandbox export feature (storybook-addon-export-to-codesandbox). + transformSource: (snippet, story) => story.parameters.fullSource, }, exportToCodeSandbox: { requiredDependencies: { diff --git a/.vscode/launch.json b/.vscode/launch.json index 743eeae1d54bd..db3efb7177c52 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,7 +5,7 @@ "name": "Debug test", "type": "node", "request": "launch", - "program": "${workspaceRoot}/scripts/debug-test.js", + "program": "${workspaceRoot}/scripts/executors/debug-test.js", "cwd": "${fileDirname}", "stopOnEntry": false, "args": ["-i", "--watch"], @@ -22,7 +22,7 @@ "name": "Debug current open test", "type": "node", "request": "launch", - "program": "${workspaceRoot}/scripts/debug-test.js", + "program": "${workspaceRoot}/scripts/executors/debug-test.js", "cwd": "${fileDirname}", "stopOnEntry": false, "args": ["-i", "--testPathPattern=\\b${fileBasenameNoExtension}", "--watch"], @@ -39,7 +39,7 @@ "name": "Debug current open test (v0)", "type": "node", "request": "launch", - "program": "${workspaceRoot}/scripts/debug-test.js", + "program": "${workspaceRoot}/scripts/executors/debug-test.js", "cwd": "${fileDirname}", "stopOnEntry": false, "args": ["-i", "--testPathPattern=\\b${fileBasenameNoExtension}", "--watch"], @@ -137,7 +137,7 @@ "--age", "10" ], - "runtimeArgs": ["--nolazy", "--inspect", "-r", "${workspaceRoot}/scripts/ts-node-register"], + "runtimeArgs": ["--nolazy", "--inspect", "-r", "${workspaceRoot}/scripts/ts-node/register"], "env": { "NODE_ENV": "development" }, diff --git a/README.md b/README.md index 4662d73f44d70..5e375cbe8493e 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,10 @@ The following table will help you navigate the 3 projects and understand their d | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | | Watch EP01: Positioning | Watch EP02: Styling | Watch EP03: Griffel | +| EP04: Foundational APIs | +| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| Watch EP04: Foundational APIs | + ## Licenses All files on the Fluent UI React GitHub repository are subject to the MIT license. Please read the License file at the root of the project. diff --git a/apps/perf-test-react-components/just.config.ts b/apps/perf-test-react-components/just.config.ts index 5929fd3ee0fc5..be016c1495657 100644 --- a/apps/perf-test-react-components/just.config.ts +++ b/apps/perf-test-react-components/just.config.ts @@ -1,5 +1,5 @@ import { getPerfRegressions } from './tasks/perf-test'; -import { preset, task, series } from '@fluentui/scripts'; +import { preset, task, series } from '@fluentui/scripts-tasks'; preset(); diff --git a/apps/perf-test-react-components/package.json b/apps/perf-test-react-components/package.json index 55c092e105bb7..5fc65f6964bd3 100644 --- a/apps/perf-test-react-components/package.json +++ b/apps/perf-test-react-components/package.json @@ -12,16 +12,20 @@ "code-style": "just-scripts code-style" }, "devDependencies": { - "@fluentui/eslint-plugin": "*" + "@fluentui/eslint-plugin": "*", + "@fluentui/scripts-tasks": "*", + "@fluentui/scripts-webpack": "*" }, "dependencies": { - "@griffel/core": "^1.8.0", - "@fluentui/react-avatar": "^9.2.4", - "@fluentui/react-button": "^9.1.6", - "@fluentui/react-provider": "^9.1.5", - "@fluentui/react-spinbutton": "^9.0.6", - "@fluentui/react-theme": "^9.1.1", - "@fluentui/scripts": "^1.0.0", + "@griffel/core": "^1.9.0", + "@fluentui/react-avatar": "^9.3.3", + "@fluentui/react-button": "^9.2.3", + "@fluentui/react-field": "9.0.0-alpha.19", + "@fluentui/react-infobutton": "9.0.0-beta.13", + "@fluentui/react-persona": "^9.1.9", + "@fluentui/react-provider": "^9.3.3", + "@fluentui/react-spinbutton": "^9.1.2", + "@fluentui/react-theme": "^9.1.5", "@microsoft/load-themed-styles": "^1.10.26", "flamegrill": "0.2.0", "lodash": "^4.17.15", diff --git a/apps/perf-test-react-components/src/scenarioIterations.js b/apps/perf-test-react-components/src/scenarioIterations.js deleted file mode 100644 index 830d33392c04f..0000000000000 --- a/apps/perf-test-react-components/src/scenarioIterations.js +++ /dev/null @@ -1,7 +0,0 @@ -// You don't have to add scenarios to this structure unless you want their iterations to differ from the default. -const scenarioIterations = { - MakeStyles: 50000, - FluentProviderWithTheme: 10, -}; - -module.exports = scenarioIterations; diff --git a/apps/perf-test-react-components/src/scenarioIterations.ts b/apps/perf-test-react-components/src/scenarioIterations.ts new file mode 100644 index 0000000000000..aa2482f34f6cb --- /dev/null +++ b/apps/perf-test-react-components/src/scenarioIterations.ts @@ -0,0 +1,5 @@ +// You don't have to add scenarios to this structure unless you want their iterations to differ from the default. +export const scenarioIterations = { + MakeStyles: 50000, + FluentProviderWithTheme: 10, +}; diff --git a/apps/perf-test-react-components/src/scenarioNames.js b/apps/perf-test-react-components/src/scenarioNames.js deleted file mode 100644 index 982cd8fe1b9a6..0000000000000 --- a/apps/perf-test-react-components/src/scenarioNames.js +++ /dev/null @@ -1,5 +0,0 @@ -// You don't have to add scenarios to this structure unless you want their display name to differ -// from their scenario name. -const scenarioNames = {}; - -module.exports = scenarioNames; diff --git a/apps/perf-test-react-components/src/scenarioNames.ts b/apps/perf-test-react-components/src/scenarioNames.ts new file mode 100644 index 0000000000000..7bb7aa2c2d28d --- /dev/null +++ b/apps/perf-test-react-components/src/scenarioNames.ts @@ -0,0 +1,3 @@ +// You don't have to add scenarios to this structure unless you want their display name to differ +// from their scenario name. +export const scenarioNames = {}; diff --git a/apps/perf-test-react-components/src/scenarioRenderTypes.js b/apps/perf-test-react-components/src/scenarioRenderTypes.js deleted file mode 100644 index 8868c41f361e7..0000000000000 --- a/apps/perf-test-react-components/src/scenarioRenderTypes.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * You don't have to add scenarios to this structure unless - * you want their render types to differ from the default (mount only). - * - * Note: - * You should not need to have virtual-rerender tests in most cases because mount test provides enough coverage. - * It is mostly usefual for cases where component has memoization logics. And in case of re-rendering, - * memoization logic help avoid certain code paths. - */ - -const AllRenderTypes = ['mount', 'virtual-rerender', 'virtual-rerender-with-unmount']; -const DefaultRenderTypes = ['mount']; - -const scenarioRenderTypes = { - FluentProviderWithTheme: AllRenderTypes, -}; - -module.exports = { - scenarioRenderTypes, - DefaultRenderTypes, -}; diff --git a/apps/perf-test-react-components/src/scenarioRenderTypes.ts b/apps/perf-test-react-components/src/scenarioRenderTypes.ts new file mode 100644 index 0000000000000..e72be02dacf71 --- /dev/null +++ b/apps/perf-test-react-components/src/scenarioRenderTypes.ts @@ -0,0 +1,16 @@ +/** + * You don't have to add scenarios to this structure unless + * you want their render types to differ from the default (mount only). + * + * Note: + * You should not need to have virtual-rerender tests in most cases because mount test provides enough coverage. + * It is mostly usefual for cases where component has memoization logics. And in case of re-rendering, + * memoization logic help avoid certain code paths. + */ + +const AllRenderTypes = ['mount', 'virtual-rerender', 'virtual-rerender-with-unmount']; +export const DefaultRenderTypes = ['mount']; + +export const scenarioRenderTypes = { + FluentProviderWithTheme: AllRenderTypes, +}; diff --git a/apps/perf-test-react-components/src/scenarios/Field.tsx b/apps/perf-test-react-components/src/scenarios/Field.tsx new file mode 100644 index 0000000000000..dc19a247fade2 --- /dev/null +++ b/apps/perf-test-react-components/src/scenarios/Field.tsx @@ -0,0 +1,16 @@ +import * as React from 'react'; +import { Field } from '@fluentui/react-field'; +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/perf-test-react-components/src/scenarios/InfoButton.tsx b/apps/perf-test-react-components/src/scenarios/InfoButton.tsx new file mode 100644 index 0000000000000..51fd802f21bb5 --- /dev/null +++ b/apps/perf-test-react-components/src/scenarios/InfoButton.tsx @@ -0,0 +1,12 @@ +import * as React from 'react'; +import { InfoButton } from '@fluentui/react-infobutton'; +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/perf-test-react-components/src/scenarios/Persona.tsx b/apps/perf-test-react-components/src/scenarios/Persona.tsx new file mode 100644 index 0000000000000..bc0dbd40b4bcd --- /dev/null +++ b/apps/perf-test-react-components/src/scenarios/Persona.tsx @@ -0,0 +1,24 @@ +import * as React from 'react'; +import { Persona } from '@fluentui/react-persona'; +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/perf-test-react-components/tasks/perf-test.ts b/apps/perf-test-react-components/tasks/perf-test.ts index 80ed1801149c2..794ed65e9b1ce 100644 --- a/apps/perf-test-react-components/tasks/perf-test.ts +++ b/apps/perf-test-react-components/tasks/perf-test.ts @@ -1,9 +1,11 @@ import fs from 'fs'; import path from 'path'; import flamegrill, { CookResults, Scenarios, ScenarioConfig, CookResult } from 'flamegrill'; -import scenarioIterations from '../src/scenarioIterations'; +import { scenarioIterations } from '../src/scenarioIterations'; import { scenarioRenderTypes, DefaultRenderTypes } from '../src/scenarioRenderTypes'; -import { argv } from '@fluentui/scripts'; +import { argv } from '@fluentui/scripts-tasks'; + +type ScenarioSetting = Record; // TODO: consolidate with newer version of fluent perf-test @@ -145,13 +147,15 @@ export async function getPerfRegressions() { const scenarioList = scenariosArg.length > 0 ? scenariosArg : scenariosAvailable; const scenarios: Scenarios = {}; - const scenarioSettings = {}; + const scenarioSettings: ScenarioSetting = {}; scenarioList.forEach(scenarioName => { if (!scenariosAvailable.includes(scenarioName)) { throw new Error(`Invalid scenario: ${scenarioName}.`); } - const iterations = iterationsArg || scenarioIterations[scenarioName] || iterationsDefault; - const renderTypes = scenarioRenderTypes[scenarioName] || DefaultRenderTypes; + const iterations = + iterationsArg || scenarioIterations[scenarioName as keyof typeof scenarioIterations] || iterationsDefault; + const renderTypes: string[] = + scenarioRenderTypes[scenarioName as keyof typeof scenarioRenderTypes] || DefaultRenderTypes; renderTypes.forEach(renderType => { const scenarioKey = `${scenarioName}-${renderType}`; @@ -221,7 +225,7 @@ export async function getPerfRegressions() { /** * Create test summary based on test results. */ -function createReport(scenarioSettings, testResults: CookResults) { +function createReport(scenarioSettings: ScenarioSetting, testResults: CookResults) { const report = '## [Perf Analysis (`@fluentui/react-components`)](https://github.com/microsoft/fluentui/wiki/Perf-Testing)\n' // Show only significant changes by default. @@ -239,13 +243,9 @@ function createReport(scenarioSettings, testResults: CookResults) { * Create a table of scenario results. * @param showAll Show only significant results by default. */ -function createScenarioTable(scenarioSettings, testResults: CookResults, showAll: boolean) { +function createScenarioTable(scenarioSettings: ScenarioSetting, testResults: CookResults, showAll: boolean) { const resultsToDisplay = Object.keys(testResults).filter( - key => - showAll || - (testResults[key].analysis && - testResults[key].analysis.regression && - testResults[key].analysis.regression.isRegression), + key => showAll || testResults[key].analysis?.regression?.isRegression, ); if (resultsToDisplay.length === 0) { diff --git a/apps/perf-test-react-components/tsconfig.json b/apps/perf-test-react-components/tsconfig.json index f3c612b74211c..399abe363dcad 100644 --- a/apps/perf-test-react-components/tsconfig.json +++ b/apps/perf-test-react-components/tsconfig.json @@ -6,16 +6,10 @@ "module": "commonjs", "jsx": "react", "declaration": true, - "sourceMap": true, "experimentalDecorators": true, - "forceConsistentCasingInFileNames": true, - "moduleResolution": "node", "preserveConstEnums": true, - "strictNullChecks": true, - "noImplicitAny": true, - "lib": ["es2016", "dom"], - "types": ["webpack-env"], - "skipLibCheck": true + "lib": ["ES2015", "DOM"], + "types": ["webpack-env"] }, "include": ["src"] } diff --git a/apps/perf-test-react-components/webpack.config.js b/apps/perf-test-react-components/webpack.config.js index f066ba3fe9eef..545d23fe7806e 100644 --- a/apps/perf-test-react-components/webpack.config.js +++ b/apps/perf-test-react-components/webpack.config.js @@ -1,4 +1,4 @@ -const resources = require('../../scripts/webpack/webpack-resources'); +const { resources } = require('@fluentui/scripts-webpack'); // The issue here is making readable Flamegraphs that don't have complicated paths like: // ~Fabric.../../packages/react/lib/components/DetailsList/DetailsRow.base.js.DetailsRowBase.render diff --git a/apps/perf-test/just.config.ts b/apps/perf-test/just.config.ts index 5929fd3ee0fc5..be016c1495657 100644 --- a/apps/perf-test/just.config.ts +++ b/apps/perf-test/just.config.ts @@ -1,5 +1,5 @@ import { getPerfRegressions } from './tasks/perf-test'; -import { preset, task, series } from '@fluentui/scripts'; +import { preset, task, series } from '@fluentui/scripts-tasks'; preset(); diff --git a/apps/perf-test/package.json b/apps/perf-test/package.json index 3fe0d492ca0c6..885f3d9df2d55 100644 --- a/apps/perf-test/package.json +++ b/apps/perf-test/package.json @@ -12,12 +12,13 @@ "code-style": "just-scripts code-style" }, "devDependencies": { - "@fluentui/eslint-plugin": "*" + "@fluentui/eslint-plugin": "*", + "@fluentui/scripts-tasks": "*", + "@fluentui/scripts-webpack": "*" }, "dependencies": { - "@fluentui/example-data": "^8.4.2", - "@fluentui/react": "^8.99.0", - "@fluentui/scripts": "^1.0.0", + "@fluentui/example-data": "^8.4.6", + "@fluentui/react": "^8.105.6", "@microsoft/load-themed-styles": "^1.10.26", "flamegrill": "0.2.0", "lodash": "^4.17.15", diff --git a/apps/perf-test/src/scenarioIterations.js b/apps/perf-test/src/scenarioIterations.js deleted file mode 100644 index 1e81dfe7943cb..0000000000000 --- a/apps/perf-test/src/scenarioIterations.js +++ /dev/null @@ -1,21 +0,0 @@ -// You don't have to add scenarios to this structure unless you want their iterations to differ from the default. -const scenarioIterations = { - DocumentCardTitle: 1000, - Breadcrumb: 1000, - CommandBar: 1000, - Nav: 1000, - Pivot: 1000, - Tabs: 1000, - Panel: 1000, - Dialog: 1000, - ComboBox: 1000, - Persona: 1000, - ContextualMenu: 1000, - /* List performance is generally more influenced by the size - * of the list rather than the number of lists on a page. - */ - GroupedList: 2, - GroupedListV2: 2, -}; - -module.exports = scenarioIterations; diff --git a/apps/perf-test/src/scenarioIterations.ts b/apps/perf-test/src/scenarioIterations.ts new file mode 100644 index 0000000000000..e04633b61ae23 --- /dev/null +++ b/apps/perf-test/src/scenarioIterations.ts @@ -0,0 +1,19 @@ +// You don't have to add scenarios to this structure unless you want their iterations to differ from the default. +export const scenarioIterations = { + DocumentCardTitle: 1000, + Breadcrumb: 1000, + CommandBar: 1000, + Nav: 1000, + Pivot: 1000, + Tabs: 1000, + Panel: 1000, + Dialog: 1000, + ComboBox: 1000, + Persona: 1000, + ContextualMenu: 1000, + /* List performance is generally more influenced by the size + * of the list rather than the number of lists on a page. + */ + GroupedList: 2, + GroupedListV2: 2, +}; diff --git a/apps/perf-test/src/scenarioNames.js b/apps/perf-test/src/scenarioNames.js deleted file mode 100644 index e9bdcd6b11db3..0000000000000 --- a/apps/perf-test/src/scenarioNames.js +++ /dev/null @@ -1,11 +0,0 @@ -// You don't have to add scenarios to this structure unless you want their display name to differ -// from their scenario name. -const scenarioNames = { - DetailsRowFast: 'DetailsRow (fast icons)', - DetailsRowNoStyles: 'DetailsRow without styles', - DocumentCardTitle: 'DocumentCardTitle with truncation', - StackWithIntrinsicChildren: 'Stack with Intrinsic children', - StackWithTextChildren: 'Stack with Text children', -}; - -module.exports = scenarioNames; diff --git a/apps/perf-test/src/scenarioNames.ts b/apps/perf-test/src/scenarioNames.ts new file mode 100644 index 0000000000000..4a2dd120f69fa --- /dev/null +++ b/apps/perf-test/src/scenarioNames.ts @@ -0,0 +1,9 @@ +// You don't have to add scenarios to this structure unless you want their display name to differ +// from their scenario name. +export const scenarioNames = { + DetailsRowFast: 'DetailsRow (fast icons)', + DetailsRowNoStyles: 'DetailsRow without styles', + DocumentCardTitle: 'DocumentCardTitle with truncation', + StackWithIntrinsicChildren: 'Stack with Intrinsic children', + StackWithTextChildren: 'Stack with Text children', +}; diff --git a/apps/perf-test/src/scenarioRenderTypes.js b/apps/perf-test/src/scenarioRenderTypes.js deleted file mode 100644 index e30c3c4aaff06..0000000000000 --- a/apps/perf-test/src/scenarioRenderTypes.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * You don't have to add scenarios to this structure unless - * you want their render types to differ from the default (mount only). - * - * Note: - * You should not need to have virtual-rerender tests in most cases because mount test provides enough coverage. - * It is mostly usefual for cases where component has memoization logics. And in case of re-rendering, - * memoization logic help avoid certain code paths. - */ - -const AllRenderTypes = ['mount', 'virtual-rerender', 'virtual-rerender-with-unmount']; -const DefaultRenderTypes = ['mount']; - -const scenarioRenderTypes = { - ThemeProvider: AllRenderTypes, - GroupedList: AllRenderTypes, - GroupedListV2: AllRenderTypes, -}; - -module.exports = { - scenarioRenderTypes, - DefaultRenderTypes, -}; diff --git a/apps/perf-test/src/scenarioRenderTypes.ts b/apps/perf-test/src/scenarioRenderTypes.ts new file mode 100644 index 0000000000000..58018e5e5df72 --- /dev/null +++ b/apps/perf-test/src/scenarioRenderTypes.ts @@ -0,0 +1,18 @@ +/** + * You don't have to add scenarios to this structure unless + * you want their render types to differ from the default (mount only). + * + * Note: + * You should not need to have virtual-rerender tests in most cases because mount test provides enough coverage. + * It is mostly usefual for cases where component has memoization logics. And in case of re-rendering, + * memoization logic help avoid certain code paths. + */ + +const AllRenderTypes = ['mount', 'virtual-rerender', 'virtual-rerender-with-unmount']; +export const DefaultRenderTypes = ['mount']; + +export const scenarioRenderTypes = { + ThemeProvider: AllRenderTypes, + GroupedList: AllRenderTypes, + GroupedListV2: AllRenderTypes, +}; diff --git a/apps/perf-test/tasks/perf-test.ts b/apps/perf-test/tasks/perf-test.ts index d11a357df84a3..ffe9d0c336473 100644 --- a/apps/perf-test/tasks/perf-test.ts +++ b/apps/perf-test/tasks/perf-test.ts @@ -1,10 +1,11 @@ import fs from 'fs'; import path from 'path'; import flamegrill, { CookResults, Scenarios, ScenarioConfig, CookResult } from 'flamegrill'; -import scenarioIterations from '../src/scenarioIterations'; +import { scenarioIterations } from '../src/scenarioIterations'; import { scenarioRenderTypes, DefaultRenderTypes } from '../src/scenarioRenderTypes'; -import { argv } from '@fluentui/scripts'; +import { argv } from '@fluentui/scripts-tasks'; +type ScenarioSetting = Record; // TODO: consolidate with newer version of fluent perf-test // A high number of iterations are needed to get visualization of lower level calls that are infrequently hit by ticks. @@ -143,13 +144,15 @@ export async function getPerfRegressions() { const scenarioList = scenariosArg.length > 0 ? scenariosArg : scenariosAvailable; const scenarios: Scenarios = {}; - const scenarioSettings = {}; + const scenarioSettings: ScenarioSetting = {}; scenarioList.forEach(scenarioName => { if (!scenariosAvailable.includes(scenarioName)) { throw new Error(`Invalid scenario: ${scenarioName}.`); } - const iterations = iterationsArg || scenarioIterations[scenarioName] || iterationsDefault; - const renderTypes = scenarioRenderTypes[scenarioName] || DefaultRenderTypes; + const iterations: number = + iterationsArg || scenarioIterations[scenarioName as keyof typeof scenarioIterations] || iterationsDefault; + const renderTypes: string[] = + scenarioRenderTypes[scenarioName as keyof typeof scenarioRenderTypes] || DefaultRenderTypes; renderTypes.forEach(renderType => { const scenarioKey = `${scenarioName}-${renderType}`; @@ -217,7 +220,7 @@ export async function getPerfRegressions() { /** * Create test summary based on test results. */ -function createReport(scenarioSettings, testResults: CookResults) { +function createReport(scenarioSettings: ScenarioSetting, testResults: CookResults) { const report = '## [Perf Analysis (`@fluentui/react`)](https://github.com/microsoft/fluentui/wiki/Perf-Testing)\n' // Show only significant changes by default. @@ -235,13 +238,9 @@ function createReport(scenarioSettings, testResults: CookResults) { * Create a table of scenario results. * @param showAll Show only significant results by default. */ -function createScenarioTable(scenarioSettings, testResults: CookResults, showAll: boolean) { +function createScenarioTable(scenarioSettings: ScenarioSetting, testResults: CookResults, showAll: boolean) { const resultsToDisplay = Object.keys(testResults).filter( - key => - showAll || - (testResults[key].analysis && - testResults[key].analysis.regression && - testResults[key].analysis.regression.isRegression), + key => showAll || testResults[key].analysis?.regression?.isRegression, ); if (resultsToDisplay.length === 0) { diff --git a/apps/perf-test/tsconfig.json b/apps/perf-test/tsconfig.json index 74a7815df7fd5..1ad60241b65c2 100644 --- a/apps/perf-test/tsconfig.json +++ b/apps/perf-test/tsconfig.json @@ -1,21 +1,15 @@ { - "extends": "../../tsconfig.base.json", + "extends": "../../tsconfig.base.v8.json", "compilerOptions": { "target": "es5", "outDir": "lib", "module": "commonjs", "jsx": "react", "declaration": true, - "sourceMap": true, "experimentalDecorators": true, - "forceConsistentCasingInFileNames": true, - "moduleResolution": "node", "preserveConstEnums": true, - "strictNullChecks": true, - "noImplicitAny": true, - "lib": ["es6", "dom"], - "types": ["webpack-env"], - "skipLibCheck": true + "lib": ["ES2015", "DOM"], + "types": ["webpack-env", "node"] }, "include": ["src"] } diff --git a/apps/perf-test/webpack.config.js b/apps/perf-test/webpack.config.js index f066ba3fe9eef..545d23fe7806e 100644 --- a/apps/perf-test/webpack.config.js +++ b/apps/perf-test/webpack.config.js @@ -1,4 +1,4 @@ -const resources = require('../../scripts/webpack/webpack-resources'); +const { resources } = require('@fluentui/scripts-webpack'); // The issue here is making readable Flamegraphs that don't have complicated paths like: // ~Fabric.../../packages/react/lib/components/DetailsList/DetailsRow.base.js.DetailsRowBase.render diff --git a/apps/pr-deploy-site/chiclet-test.html b/apps/pr-deploy-site/chiclet-test.html index b353f9ec833e7..87fe6ecdd5bf6 100644 --- a/apps/pr-deploy-site/chiclet-test.html +++ b/apps/pr-deploy-site/chiclet-test.html @@ -16,7 +16,7 @@ /> Chiclet Test Page diff --git a/apps/pr-deploy-site/index.html b/apps/pr-deploy-site/index.html index 0c14cc1bdc51e..dd5086c2e3e46 100644 --- a/apps/pr-deploy-site/index.html +++ b/apps/pr-deploy-site/index.html @@ -5,7 +5,7 @@ PR Deployed Sites diff --git a/apps/pr-deploy-site/just.config.ts b/apps/pr-deploy-site/just.config.ts index be6e56c8715f9..e398612f0585c 100644 --- a/apps/pr-deploy-site/just.config.ts +++ b/apps/pr-deploy-site/just.config.ts @@ -1,7 +1,7 @@ import fs from 'fs'; import path from 'path'; -import { series, task, copyInstructionsTask, copyInstructions, cleanTask } from '@fluentui/scripts'; -import { findGitRoot, getAllPackageInfo } from '@fluentui/scripts/monorepo/index'; +import { series, task, copyInstructionsTask, copyInstructions, cleanTask } from '@fluentui/scripts-tasks'; +import { findGitRoot, getAllPackageInfo } from '@fluentui/scripts-monorepo'; task('clean', cleanTask()); diff --git a/apps/pr-deploy-site/package.json b/apps/pr-deploy-site/package.json index 1358952b5e2e3..27d5253cdb438 100644 --- a/apps/pr-deploy-site/package.json +++ b/apps/pr-deploy-site/package.json @@ -13,6 +13,7 @@ "license": "MIT", "devDependencies": { "@fluentui/eslint-plugin": "*", - "@fluentui/scripts": "^1.0.0" + "@fluentui/scripts-tasks": "*", + "@fluentui/scripts-monorepo": "*" } } diff --git a/apps/pr-deploy-site/pr-deploy-site.js b/apps/pr-deploy-site/pr-deploy-site.js index 1600436c62b07..17fba636fddf4 100644 --- a/apps/pr-deploy-site/pr-deploy-site.js +++ b/apps/pr-deploy-site/pr-deploy-site.js @@ -92,7 +92,9 @@ if (hrefMatch) { link.href = repoUrl + '/tree/' + hrefMatch[2]; // remove the PR-specific explanation var prExplanation = document.getElementById('prExplanation'); - prExplanation.parentElement.removeChild(prExplanation); + if (prExplanation && prExplanation.parentElement) { + prExplanation.parentElement.removeChild(prExplanation); + } } else { // PR // eslint-disable-next-line @microsoft/sdl/no-inner-html -- Only used during PR publish, not production code. @@ -118,6 +120,8 @@ siteInfo.forEach(function (info) { info.title + ''; - siteLink.appendChild(li); + if (siteLink) { + siteLink.appendChild(li); + } } }); diff --git a/apps/pr-deploy-site/tsconfig.json b/apps/pr-deploy-site/tsconfig.json index 164cfd41d215f..86a30cc955bed 100644 --- a/apps/pr-deploy-site/tsconfig.json +++ b/apps/pr-deploy-site/tsconfig.json @@ -1,9 +1,10 @@ { - "extends": "../../scripts/tsconfig.json", + "extends": "@tsconfig/node14/tsconfig.json", "compilerOptions": { "noEmit": true, "allowJs": true, "lib": ["ES2020", "DOM"] }, - "include": ["pr-deploy-site.js", "just.config.ts"] + "include": ["pr-deploy-site.js", "just.config.ts"], + "files": ["../../typings/find-free-port/index.d.ts"] } diff --git a/apps/public-docsite-resources/config/api-docs.js b/apps/public-docsite-resources/config/api-docs.js index bf324b5371c9d..b3041f7ac06d9 100644 --- a/apps/public-docsite-resources/config/api-docs.js +++ b/apps/public-docsite-resources/config/api-docs.js @@ -3,7 +3,7 @@ const fs = require('fs'); const path = require('path'); -const { findRepoDeps, findGitRoot } = require('@fluentui/scripts/monorepo'); +const { findRepoDeps, findGitRoot } = require('@fluentui/scripts-monorepo'); const gitRoot = findGitRoot(); diff --git a/apps/public-docsite-resources/just.config.ts b/apps/public-docsite-resources/just.config.ts index e690e4c847eab..4e67a31a4ac52 100644 --- a/apps/public-docsite-resources/just.config.ts +++ b/apps/public-docsite-resources/just.config.ts @@ -1,4 +1,4 @@ -import { preset, task, series } from '@fluentui/scripts'; +import { preset, task, series } from '@fluentui/scripts-tasks'; import { generatePageJsonFiles } from '@fluentui/api-docs'; preset(); @@ -6,5 +6,5 @@ preset(); task('generate-json', () => generatePageJsonFiles(require('./config/api-docs'))); // copied from scripts/just.config.js with addition of generate-json -task('build', series('clean', 'copy', 'sass', 'generate-json', 'ts')).cached(); +task('build', series('clean', 'copy', 'sass', 'generate-json', 'ts')).cached!(); task('dev', series('copy', 'sass', 'generate-json', 'webpack-dev-server')); diff --git a/apps/public-docsite-resources/package.json b/apps/public-docsite-resources/package.json index cdf52607e80de..88271cdbdd931 100644 --- a/apps/public-docsite-resources/package.json +++ b/apps/public-docsite-resources/package.json @@ -27,20 +27,22 @@ "update-snapshots": "just-scripts jest -u" }, "devDependencies": { - "@fluentui/api-docs": "^8.2.3", + "@fluentui/api-docs": "^8.2.6", "@fluentui/eslint-plugin": "*", - "@fluentui/scripts": "^1.0.0" + "@fluentui/scripts-monorepo": "*", + "@fluentui/scripts-tasks": "*", + "@fluentui/scripts-webpack": "*" }, "dependencies": { - "@fluentui/react": "^8.99.0", + "@fluentui/react": "^8.105.6", "@fluentui/react-examples": "^8.34.4", "@microsoft/load-themed-styles": "^1.10.26", - "@fluentui/azure-themes": "^8.5.18", - "@fluentui/react-docsite-components": "^8.10.18", - "@fluentui/font-icons-mdl2": "^8.5.2", - "@fluentui/set-version": "^8.2.2", - "@fluentui/theme-samples": "^8.7.18", - "@fluentui/react-monaco-editor": "^1.7.18", + "@fluentui/azure-themes": "^8.5.57", + "@fluentui/react-docsite-components": "^8.11.18", + "@fluentui/font-icons-mdl2": "^8.5.8", + "@fluentui/set-version": "^8.2.5", + "@fluentui/theme-samples": "^8.7.53", + "@fluentui/react-monaco-editor": "^1.7.53", "office-ui-fabric-core": "^11.0.0", "react": "17.0.2", "react-dom": "17.0.2", diff --git a/apps/public-docsite-resources/tsconfig.json b/apps/public-docsite-resources/tsconfig.json index 59faae6dc58f6..15242005deed6 100644 --- a/apps/public-docsite-resources/tsconfig.json +++ b/apps/public-docsite-resources/tsconfig.json @@ -1,4 +1,5 @@ { + "extends": "../../tsconfig.base.v8.json", "compilerOptions": { "baseUrl": ".", "outDir": "lib", @@ -6,19 +7,11 @@ "module": "commonjs", "jsx": "react", "declaration": true, - "sourceMap": true, "experimentalDecorators": true, "importHelpers": true, "noUnusedLocals": true, - "forceConsistentCasingInFileNames": true, - "strictNullChecks": true, - "noImplicitAny": true, - "moduleResolution": "node", "preserveConstEnums": true, - "noImplicitThis": true, - "skipLibCheck": true, "lib": ["es5", "dom", "es2015.promise"], - "typeRoots": ["../../node_modules/@types", "../../typings"], "types": ["webpack-env", "custom-global"] }, "include": ["src"] diff --git a/apps/public-docsite-resources/webpack.serve.config.js b/apps/public-docsite-resources/webpack.serve.config.js index 00dfb3f33ec9c..e0af52225d409 100644 --- a/apps/public-docsite-resources/webpack.serve.config.js +++ b/apps/public-docsite-resources/webpack.serve.config.js @@ -1,7 +1,6 @@ // @ts-check const path = require('path'); -const getResolveAlias = require('@fluentui/scripts/webpack/getResolveAlias'); -const resources = require('@fluentui/scripts/webpack/webpack-resources'); +const { resources, getResolveAlias } = require('@fluentui/scripts-webpack'); const { addMonacoWebpackConfig } = require('@fluentui/react-monaco-editor/scripts/addMonacoWebpackConfig'); const BUNDLE_NAME = 'demo-app'; diff --git a/apps/public-docsite-v9/.storybook/main.js b/apps/public-docsite-v9/.storybook/main.js index a9ba66ecd41ff..a460739ddccc7 100644 --- a/apps/public-docsite-v9/.storybook/main.js +++ b/apps/public-docsite-v9/.storybook/main.js @@ -1,21 +1,35 @@ -const utils = require('./main.utils'); +// @ts-check + +const { + getPackageStoriesGlob, + createPathAliasesConfig, + registerTsPaths, + rules, + registerRules, +} = require('@fluentui/scripts-storybook'); + const rootMain = require('../../../.storybook/main'); +const { tsConfigAllPath } = createPathAliasesConfig(); + module.exports = /** @type {Omit} */ ({ ...rootMain, stories: [ ...rootMain.stories, '../src/**/*.stories.mdx', '../src/**/*.stories.@(ts|tsx)', - ...utils.getVnextStories(), - '../../../packages/react-migration-v8-v9/src/**/@(index.stories.@(ts|tsx)|*.stories.mdx)', + ...getPackageStoriesGlob({ packageName: '@fluentui/react-components', callerPath: __dirname }), + '../../../packages/react-components/react-migration-v0-v9/src/**/@(index.stories.@(ts|tsx)|*.stories.mdx)', + '../../../packages/react-components/react-migration-v8-v9/src/**/@(index.stories.@(ts|tsx)|*.stories.mdx)', ], staticDirs: ['../public'], addons: [...rootMain.addons], webpackFinal: (config, options) => { - const localConfig = { ...rootMain.webpackFinal(config, options) }; + const localConfig = /** @type config */ ({ ...rootMain.webpackFinal(config, options) }); // add your own webpack tweaks if needed + registerTsPaths({ configFile: tsConfigAllPath, config: localConfig }); + registerRules({ rules: [rules.scssRule], config: localConfig }); return localConfig; }, diff --git a/apps/public-docsite-v9/.storybook/main.utils.js b/apps/public-docsite-v9/.storybook/main.utils.js deleted file mode 100644 index 3dd9fe4e367b9..0000000000000 --- a/apps/public-docsite-v9/.storybook/main.utils.js +++ /dev/null @@ -1,38 +0,0 @@ -/** - * This file contains utils for main.js to mitigate diffs when migration generator is being invoked in batch (via --all flag) - * Code in this module is supposed to run only against node js env (webpack) - thus it uses commonjs modules - */ - -const fs = require('fs'); -const path = require('path'); - -// Dependencies to exclude stories loading -const excludedDependencies = ['@fluentui/react-overflow']; - -function getVnextStories() { - /** @type {Record} */ - const packageJson = JSON.parse( - fs.readFileSync( - path.resolve(__dirname, '../../../packages/react-components/react-components/package.json'), - 'utf-8', - ), - ); - - const dependencies = /** @type {Record} */ (packageJson.dependencies); - - return Object.keys({ ...dependencies, '@fluentui/react-components': '' }) - .filter(pkgName => pkgName.startsWith('@fluentui/') && !excludedDependencies.includes(pkgName)) - .map(pkgName => { - const name = pkgName.replace('@fluentui/', ''); - const storiesGlob = '**/@(index.stories.@(ts|tsx)|*.stories.mdx)'; - - //TODO: simplify once v9 migration [https://github.com/microsoft/fluentui/issues/24129] is complete. - if (fs.existsSync(`../../packages/react-components/${name}/stories/`)) { - return `../../../packages/react-components/${name}/stories/${storiesGlob}`; - } else { - return `../../../packages/react-components/${name}/src/${storiesGlob}`; - } - }); -} - -exports.getVnextStories = getVnextStories; diff --git a/apps/public-docsite-v9/.storybook/main.utils.test.js b/apps/public-docsite-v9/.storybook/main.utils.test.js deleted file mode 100644 index b1df0f4d1aa5f..0000000000000 --- a/apps/public-docsite-v9/.storybook/main.utils.test.js +++ /dev/null @@ -1,21 +0,0 @@ -/// -const utils = require('./main.utils'); - -describe(`main utils`, () => { - describe(`#getVnextStories`, () => { - it(`should generate storybook stories string array of glob based on package.json#dependencies field`, () => { - const actual = utils.getVnextStories(); - - const expected = [ - expect.stringContaining('../../../packages/react-'), - expect.stringContaining('/src/**/*.stories.@(ts|tsx|mdx)'), - ]; - - expect(actual).toEqual(expect.arrayContaining(expected)); - - const first = actual[0]; - expect(first.startsWith('../../../packages/react-')).toBeTruthy(); - expect(first.endsWith('/src/**/*.stories.@(ts|tsx|mdx)')).toBeTruthy(); - }); - }); -}); diff --git a/apps/public-docsite-v9/.storybook/preview.js b/apps/public-docsite-v9/.storybook/preview.js index 93c8712239c74..90cd58429aa7b 100644 --- a/apps/public-docsite-v9/.storybook/preview.js +++ b/apps/public-docsite-v9/.storybook/preview.js @@ -25,12 +25,12 @@ export const parameters = { [ 'Introduction', 'Developer', - ['Quick Start', 'Styling Components', 'Positioning Components', 'Component Poster'], + ['Quick Start', 'Styling Components', 'Positioning Components', 'Component Poster', 'Server-Side Rendering'], 'Migration', [ - 'Overview', - 'Important changes', - 'Planning your journey', + 'Getting Started', + 'Keeping Design Consistent', + 'Handling Breaking Changes', 'from v8', ['Component Mapping', 'Color Mapping', 'Troubleshooting'], 'from v0', diff --git a/apps/public-docsite-v9/README.md b/apps/public-docsite-v9/README.md new file mode 100644 index 0000000000000..7427bec5facac --- /dev/null +++ b/apps/public-docsite-v9/README.md @@ -0,0 +1,15 @@ +# public-docsite-v9 + +This app is official documentation for Fluentui react-components published to https://react.fluentui.dev + +**Fluent UI V9 React Components** + +Fluent UI is a collection of projects that represent the Fluent design language in code. This website helps document the components and styles that make up Fluent UI. + +## Start the website + +Run `yarn workspace @fluentui/public-docsite-v9 start` + +## Notes + +- `Open in CodeSandbox` button is located in different [repo](https://github.com/microsoft/fluentui-storybook-addons). diff --git a/apps/public-docsite-v9/just.config.ts b/apps/public-docsite-v9/just.config.ts index 6ba74c8de1f03..242d94f1f0210 100644 --- a/apps/public-docsite-v9/just.config.ts +++ b/apps/public-docsite-v9/just.config.ts @@ -1,5 +1,5 @@ -import { preset, task } from '@fluentui/scripts'; +import { preset, task } from '@fluentui/scripts-tasks'; preset(); -task('build', 'build:node-lib').cached(); +task('build', 'build:node-lib').cached!(); diff --git a/apps/public-docsite-v9/package.json b/apps/public-docsite-v9/package.json index b0177f01b787b..1587975e0a6c0 100644 --- a/apps/public-docsite-v9/package.json +++ b/apps/public-docsite-v9/package.json @@ -18,18 +18,20 @@ }, "devDependencies": { "@fluentui/eslint-plugin": "*", - "@fluentui/scripts": "^1.0.0" + "@fluentui/scripts-storybook": "*", + "@fluentui/scripts-tasks": "*" }, "dependencies": { - "@fluentui/react": "^8.99.0", - "@fluentui/react-northstar": "^0.64.0", - "@fluentui/react-icons-northstar": "^0.64.0", - "@fluentui/scripts": "^1.0.0", + "@fluentui/react-migration-v8-v9": "^9.1.3", + "@fluentui/react-migration-v0-v9": "9.0.0-alpha.0", + "@fluentui/react": "^8.105.6", + "@fluentui/react-northstar": "^0.66.1", + "@fluentui/react-icons-northstar": "^0.66.1", "@fluentui/storybook": "^1.0.0", - "@fluentui/react-components": "^9.6.1", - "@fluentui/react-storybook-addon": "^9.0.0-rc.1", - "@fluentui/react-theme": "^9.1.1", - "@griffel/react": "^1.4.1", + "@fluentui/react-components": "^9.15.0", + "@fluentui/react-storybook-addon": "9.0.0-rc.1", + "@fluentui/react-theme": "^9.1.5", + "@griffel/react": "^1.5.2", "react": "17.0.2", "react-dom": "17.0.2", "react-window": "^1.8.6", diff --git a/apps/public-docsite-v9/src/Concepts/AdvancedConfiguration.stories.mdx b/apps/public-docsite-v9/src/Concepts/AdvancedConfiguration.stories.mdx new file mode 100644 index 0000000000000..b81cda6dc04b8 --- /dev/null +++ b/apps/public-docsite-v9/src/Concepts/AdvancedConfiguration.stories.mdx @@ -0,0 +1,60 @@ +import { Meta } from '@storybook/addon-docs'; + + + +## Advanced Configuration + +### Child Window Rendering + +When rendering on the main browser window, many components need access to `window` or `document` for applying styling, listening for events, or measuring things. However it is possible to render to child windows and elements hosted in `iframe` elements. + +In these cases, the target element is hosted in a different context, and thus have a different `window` reference. To aid in providing components with the correct instances of `window` or `document`, React context can be used to provide the tree of React components with the correct instance. + +#### Configuring rendering + +We need to configure a renderer for `makeStyles()` and pass a `targetDocument` to `RendererProvider` & `FluentProvider`: + +```jsx +import { createDOMRenderer, FluentProvider, RendererProvider } from '@fluentui/react-components'; +import * as React from 'react'; + +function MyComponent(props) { + const { children, targetDocument } = props; + const renderer = React.useMemo(() => createDOMRenderer(targetDocument), [targetDocument]); + + return ( + + {children} + + ); +} +``` + +You can check complete example at [CodeSandbox](https://codesandbox.io/s/fluentuireact-components-render-into-iframe-l62ke). + +### Content Security Policies + +To add `nonce` attribute need for [Content Security Policies](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP), please use `styleElementAttributes` to specify it: + +```jsx +import { createDOMRenderer, FluentProvider, RendererProvider } from '@fluentui/react-components'; +import * as React from 'react'; + +function MyComponent(props) { + const { children } = props; + const renderer = React.useMemo( + () => createDOMRenderer(document, { styleElementAttributes: { nonce: 'random' } }), + [], + ); + + return ( + + {children} + + ); +} +``` + +## References + +- https://griffel.js.org/react/api/create-dom-renderer diff --git a/apps/public-docsite-v9/src/Concepts/ChildWindow.stories.mdx b/apps/public-docsite-v9/src/Concepts/ChildWindow.stories.mdx deleted file mode 100644 index ec77bd58cc644..0000000000000 --- a/apps/public-docsite-v9/src/Concepts/ChildWindow.stories.mdx +++ /dev/null @@ -1,31 +0,0 @@ -import { Meta } from '@storybook/addon-docs'; - - - -## Child Window Rendering - -When rendering on the main browser window, many components need access to `window` or `document` for applying styling, listening for events, or measuring things. However it is possible to render to child windows and elements hosted in `iframe` elements. - -In these cases, the target element is hosted in a different context, and thus have a different `window` reference. To aid in providing components with the correct instances of `window` or `document`, React context can be used to provide the tree of React components with the correct instance. - -### Configuring rendering - -We need to configure a renderer for `makeStyles()` and pass a `targetDocument` to `RendererProvider` & `FluentProvider`: - -```js -import { createDOMRenderer, FluentProvider, RendererProvider } from '@fluentui/react-components'; -import * as React from 'react'; - -function MyComponent(props) { - const { children, targetDocument } = props; - const renderer = React.useMemo(() => createDOMRenderer(targetDocument), [targetDocument]); - - return ( - - {children} - - ); -} -``` - -You can check complete example at [CodeSandbox](https://codesandbox.io/s/fluentuireact-components-render-into-iframe-l62ke). diff --git a/apps/public-docsite-v9/src/Concepts/Migration/FromV0/Components/Card/Card.stories.mdx b/apps/public-docsite-v9/src/Concepts/Migration/FromV0/Components/Card/Card.stories.mdx new file mode 100644 index 0000000000000..9f48013a06043 --- /dev/null +++ b/apps/public-docsite-v9/src/Concepts/Migration/FromV0/Components/Card/Card.stories.mdx @@ -0,0 +1,227 @@ +import { Meta } from '@storybook/addon-docs'; + + + +# Card Migration + +## Overview + +Before: + +```tsx +import { Card } from '@fluentui/react-northstar'; +const Component = () => Lorem ipsum, dolor sit amet consectetur adipisicing elit.; +``` + +After: + +```tsx +import { Card } from '@fluentui/react-components/unstable'; +const Component = () => Lorem ipsum, dolor sit amet consectetur adipisicing elit.; +``` + +## How to migrate props: + +| Card props | migration guide | +| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| as, className | keep it as is | +| variables, styles | see Migrate `style` overrides in this document | +| accessibility | see [migrate-custom-accessibility.md](?path=/docs/concepts-migrating-from-v0-custom-accessibility--page). Also check the focusMode new prop | +| centered | REMOVED: see Migrate `centered` prop in this document | +| compact | use `size="small"` | +| disabled | REMOVED: No equivalent functionality. Can be created by overriding the styles. | +| elevated | REMOVED: All cards are now elevated by default. To change that, use the `appearance` property. | +| expandable | REMOVED: No equivalent functionality. | +| fluid | REMOVED: see Migrate `fluid` prop in this document | +| ghost | use `appearance="subtle"` | +| inverted | use `appearance="filled-alternative"` | +| size | keep it as is. Values: `small`, `medium`(default) and `large` | + +## Migrate style overrides + +⚠️ **If this is your first migration**, please read [the general guide on how to migrate styles](?path=/docs/concepts-migrating-from-v0-custom-style-overrides--page). + +### Example for migrate boolean `variables`: + +Before: + +```tsx +// in COMPONENT_NAME.tsx +import { Card } from '@fluentui/react-northstar'; + +export const Component = () => ; + +// in Card-styles.ts +export const CardStyles1 = { + root: ({ variables: { isActionCard } }) => ({ + ...(isActionCard && { + color: colors.grey['250'], + }), + }), +}; +``` + +After: + +```tsx +// in COMPONENT_NAME.tsx +import { Card } from '@fluentui/react-components/unstable'; +import { useStyles } from './COMPONENT_NAME.styles.ts'; + +export const Component = () => { + const classes = useStyles(); + + return ; +}; + +// in COMPONENT_NAME.styles.ts +import { makeStyles, tokens } from '@fluentui/react-components/unstable'; + +export const useStyles = makeStyles({ + actionCard: { + color: colors.colorNeutralForeground1, + }, +}); +``` + +### Example for migrate namespaced styles, with conditional styles via `variableProps`: + +Before: + +```tsx +// in COMPONENT_NAME.tsx +import { Card, useUIProviderContext } from '@fluentui/react-northstar'; + +export const Component = props => { + const { vars } = useUIProviderContext(); + const { enableUsingChatListGroupTitleAsHeader } = props; + return ( + + ); +}; + +// in Card-namespace-flyout.ts +export default { + root: { + filterCard: ({ variableProps: { enableUsingChatListGroupTitleAsHeader } }) => ({ + ...(enableUsingChatListGroupTitleAsHeader && { + height: '3rem', + width: '8rem', + minWidth: '8rem', + }), + }), + }, +}; +``` + +After: + +```tsx +// in COMPONENT_NAME.tsx +import { Card, mergeClasses } from '@fluentui/react-components/unstable'; +import { useStyles } from './COMPONENT_NAME.styles.ts'; + +export const Component = props => { + const classes = useStyles(); + + return ( + + ); +}; + +// in COMPONENT_NAME.styles.ts +import { makeStyles } from '@fluentui/react-components/unstable'; + +export const useStyles = makeStyles({ + chatListGroupTitleAsHeader: { + height: '3rem', + width: '8rem', + minWidth: '8rem', + }, +}); +``` + +## Migrate `centered` prop + +Can be achieved by overriding the styles of the Card component. + +Before: + +```tsx +import { Card } from '@fluentui/react-northstar'; + +const Component = () => Lorem ipsum, dolor sit amet consectetur adipisicing elit.; +``` + +After: + +```tsx +import * as React from 'react'; +import { makeStyles } from '@fluentui/react-components/unstable'; +import { Card } from '@fluentui/react-components/unstable'; + +const useStyles = makeStyles({ + centeredCard: { + justifyItems: 'center', + }, +}); + +export const CenteredCard = () => { + const styles = useStyles(); + + return ( + +

Lorem ipsum dolor sit amet.

+
+ ); +}; +``` + +## Migrate `size` prop + +All cards are fluid by default. To change that, use a parent container with a defined size. + +Before: + +```tsx +import { Card } from '@fluentui/react-northstar'; + +const Component = () => Lorem ipsum, dolor sit amet consectetur adipisicing elit.; +``` + +After: + +```jsx +import * as React from 'react'; +import { makeStyles } from '@fluentui/react-components/unstable'; +import { Card } from '@fluentui/react-components/unstable'; + +const useStyles = makeStyles({ + parent: { + width: '500px', + }, +}); + +export const SizedCard = () => { + const styles = useStyles(); + + return ( +
+ +

Lorem ipsum dolor sit amet.

+
+
+ ); +}; +``` diff --git a/apps/public-docsite-v9/src/Concepts/Migration/FromV0/Components/Card/CardBody.stories.mdx b/apps/public-docsite-v9/src/Concepts/Migration/FromV0/Components/Card/CardBody.stories.mdx new file mode 100644 index 0000000000000..fabc5c78b04f2 --- /dev/null +++ b/apps/public-docsite-v9/src/Concepts/Migration/FromV0/Components/Card/CardBody.stories.mdx @@ -0,0 +1,35 @@ +import { Meta } from '@storybook/addon-docs'; + + + +# Card Body Migration + +## Overview + +This component is not needed anymore. Instead, pass any content under the main Card component. + +Before: + +```jsx +import { Card, CardBody } from '@fluentui/react-northstar'; + +export const CardBodyExample = () => ( + + +

Lorem ipsum dolor sit amet.

+
+
+); +``` + +After: + +```jsx +import { Card } from '@fluentui/react-components/unstable'; + +export const CardBodyExample = () => ( + +

Lorem ipsum dolor sit amet.

+
+); +``` diff --git a/apps/public-docsite-v9/src/Concepts/Migration/FromV0/Components/Card/CardFooter.stories.mdx b/apps/public-docsite-v9/src/Concepts/Migration/FromV0/Components/Card/CardFooter.stories.mdx new file mode 100644 index 0000000000000..a2424498a0764 --- /dev/null +++ b/apps/public-docsite-v9/src/Concepts/Migration/FromV0/Components/Card/CardFooter.stories.mdx @@ -0,0 +1,40 @@ +import { Meta } from '@storybook/addon-docs'; + + + +# Card Footer Migration + +## Overview + +Before: + +```tsx +import { CardFooter } from '@fluentui/react-northstar'; + +const Component = () => Lorem ipsum; +``` + +After: + +```tsx +import { CardFooter } from '@fluentui/react-components/unstable'; + +const Component = () => ; +``` + +## How to migrate props: + +| CardFooter props | migration guide | +| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| as, className | keep it as is | +| variables, styles | see Migrate `style` overrides in this document | +| accessibility | see [migrate-custom-accessibility.md](?path=/docs/concepts-migrating-from-v0-custom-accessibility--page). Also check the focusMode new prop | +| fitted | REMOVED: By default, all Footers are fitted | + +## Migrate style overrides + +⚠️ **If this is your first migration**, please read [the general guide on how to migrate styles](?path=/docs/concepts-migrating-from-v0-custom-style-overrides--page). + +### Example for migrate boolean `variables`: + +Follow the same patterns as in the Card [migration guide](?path=/docs/concepts-migration-from-v0-components-card-migration-card--page). diff --git a/apps/public-docsite-v9/src/Concepts/Migration/FromV0/Components/Card/CardHeader.stories.mdx b/apps/public-docsite-v9/src/Concepts/Migration/FromV0/Components/Card/CardHeader.stories.mdx new file mode 100644 index 0000000000000..186602ac8c0cb --- /dev/null +++ b/apps/public-docsite-v9/src/Concepts/Migration/FromV0/Components/Card/CardHeader.stories.mdx @@ -0,0 +1,40 @@ +import { Meta } from '@storybook/addon-docs'; + + + +# Card Header Migration + +## Overview + +Before: + +```tsx +import { CardHeader } from '@fluentui/react-northstar'; + +const Component = () => Lorem ipsum; +``` + +After: + +```tsx +import { CardHeader } from '@fluentui/react-components/unstable'; + +const Component = () => ; +``` + +## How to migrate props: + +| CardHeader props | migration guide | +| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| as, className | keep it as is | +| variables, styles | see Migrate `style` overrides in this document | +| accessibility | see [migrate-custom-accessibility.md](?path=/docs/concepts-migrating-from-v0-custom-accessibility--page). Also check the focusMode new prop | +| fitted | REMOVED: by default, all headers are fitted | + +## Migrate style overrides + +⚠️ **If this is your first migration**, please read [the general guide on how to migrate styles](?path=/docs/concepts-migrating-from-v0-custom-style-overrides--page). + +### Example for migrate boolean `variables`: + +Follow the same patterns as in the Card [migration guide](?path=/docs/concepts-migration-from-v0-components-card-migration-card--page). diff --git a/apps/public-docsite-v9/src/Concepts/Migration/FromV0/Components/Card/CardPreview.stories.mdx b/apps/public-docsite-v9/src/Concepts/Migration/FromV0/Components/Card/CardPreview.stories.mdx new file mode 100644 index 0000000000000..2d4766c606c4a --- /dev/null +++ b/apps/public-docsite-v9/src/Concepts/Migration/FromV0/Components/Card/CardPreview.stories.mdx @@ -0,0 +1,49 @@ +import { Meta } from '@storybook/addon-docs'; + + + +# Card Preview Migration + +## Overview + +Before: + +```tsx +import { CardPreview, Image } from '@fluentui/react-northstar'; + +const Component = () => ( + + Preview of a Word document + +); +``` + +After: + +```tsx +import { CardPreview } from '@fluentui/react-components/unstable'; + +const Component = () => ( + + Preview of a Word document + +); +``` + +## How to migrate props: + +| CardPreview props | migration guide | +| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| as, className | keep it as is | +| variables, styles | see Migrate `style` overrides in this document | +| accessibility | see [migrate-custom-accessibility.md](?path=/docs/concepts-migrating-from-v0-custom-accessibility--page). Also check the focusMode new prop | +| fitted | REMOVED: by default, all Previews are fitted | +| horizontal | REMOVED: no longer supported | + +## Migrate style overrides + +⚠️ **If this is your first migration**, please read [the general guide on how to migrate styles](?path=/docs/concepts-migrating-from-v0-custom-style-overrides--page). + +### Example for migrate boolean `variables`: + +Follow the same patterns as in the Card [migration guide](?path=/docs/concepts-migration-from-v0-components-card-migration-card--page). diff --git a/apps/public-docsite-v9/src/Concepts/Migration/FromV0/Components/Toolbar.stories.mdx b/apps/public-docsite-v9/src/Concepts/Migration/FromV0/Components/Toolbar.stories.mdx new file mode 100644 index 0000000000000..c6eb2c09fbf7a --- /dev/null +++ b/apps/public-docsite-v9/src/Concepts/Migration/FromV0/Components/Toolbar.stories.mdx @@ -0,0 +1,414 @@ +import { Meta } from '@storybook/addon-docs'; + + + +# Toolbar Migration + +## Overview: + +Before: + +```tsx +import { Toolbar } from '@fluentui/react-northstar'; +const Component = () => ( + + ), + key: 'bold', + kind: 'toggle', + active: state.bold, + title: 'Toggle bold', + }, + { + icon: ( + + ), + key: 'italic', + kind: 'toggle', + active: state.italic, + title: 'Toggle italic', + }, + { + icon: ( + + ), + key: 'underline', + kind: 'toggle', + active: state.underline, + title: 'Toggle underline', + }, + { + key: 'divider-1', + kind: 'divider', + }, + { + icon: ( + + ), + key: 'font-size', + title: 'Font size', + }, + { + icon: ( + + ), + key: 'remove-format', + title: 'Remove formatting', + }, + { + key: 'divider-2', + kind: 'divider', + }, + { + icon: ( + + ), + key: 'outdent', + title: 'Outdent', + }, + { + icon: ( + + ), + key: 'indent', + title: 'Indent', + }, + { + key: 'divider-3', + kind: 'divider', + }, + { + icon: ( + + ), + key: 'more', + active: state.more, + title: 'More', + menu: [ + { + key: 'quote', + content: 'Quote', + icon: , + }, + { + key: 'link', + content: 'Link', + icon: , + disabled: true, + }, + { + key: 'code', + content: 'Code snippet', + icon: , + }, + ], + }, + ]} + /> +); +``` + +After: + +```tsx +import { Toolbar, ToolbarToggleButton, ToolbarDivider, ToolbarButton } from '@fluentui/react-components'; + +export const Component = () => { + + } /> + } /> + } /> + + } /> + } /> + + } /> + } /> + + + + } /> + + + + + New + New Window + Open File + Open Folder + + + + ; +}; +``` + +## Controlled + +V0 only allows to set an item active in a controlled way through `active` property in a toolbar item. V9 Toolbar doesn't need that by default by can also be controlled. + +V9 Controlled: + +```javascript +import { + Toolbar, + ToolbarToggleButton, + ToolbarDivider, + ToolbarButton +} from '@fluentui/react-components'; + + + +const Component = () => { + const [checkedValues, setCheckedValues] = React.useState>({ + textOptions: ['bold', 'italic'], + }); + const onChange: ToolbarProps['onCheckedValueChange'] = (e, { name, checkedItems }) => { + setCheckedValues(s => { + return s ? { ...s, [name]: checkedItems } : { [name]: checkedItems }; + }); + }; + + return ( + + } name="textOptions" value="bold" /> + } name="textOptions" value="italic" /> + } + name="textOptions" + value="underline" + /> + + ); +} +``` + +## How to migrate props: + +| `Toolbar` props | migrate guide | +| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | +| as, className | keep it as is | +| variables, styles, design | see [Migrate style overrides](#./Migrate-style-overrides) in this document | +| accessibility | see [migrate-custom-accessibility.md](../migrate-custom-accessibility.md) | +| content | see [Migrate content prop](#./Migrate-`content`-prop) in this document | +| ref, key | keep it as is | +| getOverflowItems | REMOVED: Use @fluentui/react-overflow to render overflow items | +| items | REMOVED: Only supports children API | +| onOverflow | use `isOverflowing` from `useOverflowMenu` from @fluentui/react-overflow. See [migrate overflow props](#migrate-%60overflow%60-props) | +| onOverflowOpenChange | REMOVED: handle the needed changes in the overflow component. See [migrate overflow props](#migrate-%60overflow%60-props) | +| overflow | REMOVED: Use @fluentui/react-overflow | +| overflowItem | REMOVED: Should be implemented in the Overflow component that is using `useOverflowMenu`. See [migrate overflow props](#migrate-%60overflow%60-props) | +| overflowOpen | REMOVED: Should be handled by the component that will be using `useOverflowMenu` | +| overflowSentinel | REMOVED: Can be set as `padding` in the `Overflow` component from @fluentui/react-overflow. See [migrate overflow props](#migrate-%60overflow%60-props) | + +| `ToolbarItem` props | migrate guide | +| ------------------- | ------------------------------------------------------------------------------------------------------------------- | +| as, className | keep it as is | +| content | see [Migrate content prop](#./Migrate-`content`-prop) in this document | +| variables, styles | see [Migrate style overrides](#./Migrate-style-overrides) in this document | +| accessibility | see [migrate-custom-accessibility.md](?path=/docs/concepts-migration-from-v0-custom-accessibility--page) | +| circular | replace with `shape="circular"` | +| disabled | keep it as is | +| disabledFocusable | keep it as is | +| fluid | replace with `block` | +| icon | keep it as is. | +| menu | REMOVED: use `@fluentui/react-menu` | +| menuOpen | REMOVED: use `@fluentui/react-menu` | +| onMenuOpenChange | REMOVED: use `@fluentui/react-menu` | +| popup | REMOVED: use `@fluentui/react-popover`, [see example](?path=/docs/preview-components-toolbar--default#with-popover) | +| wrapper | REMOVED | + +`ToolbarCustomItem` in V9 is replaced by direct adding the content as `Toolbar` children. + +V0 + +```javascript + + Click Here} /> + +``` + +V9 + +```javascript + + Click Here + +``` + +Here is comparison for both versions: [Sandbox](https://codesandbox.io/s/toolbar-migration-fluentui-iyhl1j) + +--- + +## Migrate style overrides + +⚠️ **If this is your first migration**, please read [the general guide on how to migrate styles](../migrate-styles.md). + +### Example for migrate boolean `variables`: + +Before: + +```tsx +// in COMPONENT_NAME.tsx +import { Toolbar } from '@fluentui/react-components'; + +export const Component = () => ; + +// in toolbar-button-styles.ts +export const toolbarStyles = { + root: ({ variables: { fluid } }) => ({ + ...(fluid && { + width: '100%', + }), + }), +}; +``` + +After: + +```tsx +// in COMPONENT_NAME.tsx +import { useStyles } from './COMPONENT_NAME.styles.ts'; +import { Toolbar, ToolbarButton } from '@fluentui/react-components'; + +export const Component = () => { + const classes = useStyles(); + return ( + + Italic + + ); +}; + +// in COMPONENT_NAME.styles.ts +import { makeStyles } from '@fluentui/react-components'; + +export const useStyles = makeStyles({ + breakoutRoomsAssignmentToolbar: { + width: '100%', + }, +}); +``` + +### Example for migrate namespaced styles, with conditional styles via `variableProps`: + +Before: + +```tsx +// in COMPONENT_NAME.tsx +import { Toolbar, useUIProviderContext } from '@fluentui/react-components'; + +export const Component = props => { + const { vars } = useUIProviderContext(); + const { isLive } = props; + return ; +}; + +// in toolbar-styles.ts +export default { + root: ({ variables: { isLive } }) => ({ + ...(isLive && { + height: '100%', + alignItems: 'center', + color: isLive ? colorSchemeSilver.foreground1 : 'inherit', + }), + }), +}; +``` + +After: + +```tsx +// in COMPONENT_NAME.tsx +import { useStyles } from './COMPONENT_NAME.styles.ts'; +import { Toolbar, Button, mergeClasses } from '@fluentui/react-components'; + +export const Component = props => { + const classes = useStyles(); + const { isLive } = props; + return ( + + Italic + + ); +}; + +// in COMPONENT_NAME.styles.ts +import { makeStyles, shorthands, tokens } from '@fluentui/react-components'; + +export const useStyles = makeStyles({ + tabItemToolbar: { + height: '100%', + display: 'inline-flex', + alignItems: 'center', + color: 'inherit', + }, + liveTabItemToolbar: { + color: tokens.colorPaletteSilverForeground1, + }, +}); +``` + +## Migrate `overflow` props + +Before: + +```tsx +import { Toolbar } from '@fluentui/react-components'; +const Component = () => ( + { + setOverflowOpen(overflowOpen); + }} + getOverflowItems={startIndex => itemData.slice(startIndex)} + /> +); +``` + +After: + +See [Toolbar Overflow Items example](https://react.fluentui.dev/?path=/docs/preview-components-toolbar--default#overflow-items) diff --git a/apps/public-docsite-v9/src/Concepts/Migration/FromV0/Icons.stories.mdx b/apps/public-docsite-v9/src/Concepts/Migration/FromV0/Icons.stories.mdx index 21cc1be52f89d..4388c80a1423a 100644 --- a/apps/public-docsite-v9/src/Concepts/Migration/FromV0/Icons.stories.mdx +++ b/apps/public-docsite-v9/src/Concepts/Migration/FromV0/Icons.stories.mdx @@ -3,7 +3,100 @@ import { IconCatalog } from './Components/IconCatalog/IconCatalog.tsx'; -# v0 - v9 Icon Catalog +# Icons Migration + +## createSvgIcon + +V0 exports a `createSvgIcon` function that allows creating a custom icon such as: + +```jsx +export const MyIcon = createSvgIcon({ + svg: ({ classes }) => ( + + + + + + + + + ), + displayName: 'MyIcon', +}); +``` + +And its usage would be like: + +```jsx +// Usage Example + +// Default filled icon + + +// Outline Icon + +``` + +To achieve the same using V9 we have to make usage of a combination with `wrapIcon` and `bundleIcon`. + +```jsx +// MyIcon.tsx +import { FluentIconsProps, bundleIcon, wrapIcon } from '@fluentui/react-icons'; + +export const MyOutlineIcon = wrapIcon((props: FluentIconsProps) => { + return ( + + + + + + ); +}, 'MyOutlineIcon'); + +export const MyFilledIcon = wrapIcon((props: FluentIconsProps) => { + return ( + + + + + + ); +}, 'MyFilledIcon'); + +export const MyIcon = bundleIcon(MyFilledIcon, MyOutlineIcon); +``` + +And its usage would be like: + +```jsx +// Usage Example + +// Default outlined icon + + +// Filled Icon + +``` + +An Icon created with `createSvgIcon` is filled by default while an Icon created with `wrapIcon` is outline by default, so when replacing the usage of `createSvgIcon` remember to add filled prop to the Icon usage. + +### Sizing + +`createSvgIcon` from V0 will allow you to set a range of pre-defined size values (`small`,`smaller`,`smallest`,`medium`,`large`,`largest`,`larger`). e.g.: + +```jsx + +``` + +The V9 wrapIcon has a different approach allowing to set the fontSize which would change directly the icon size. + +```jsx + +``` + +In the V9 Icon it is also possible to style it by using css `font-size` propertie. + +## v0 - v9 Icon Catalog This catalog can help you find the equivalent v9 icon if you are using v0 icons. Not all icons have a direct equivalent, and you will see clearly when this is case in the catalog. diff --git a/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Components/Card/Card.stories.mdx b/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Components/Card/Card.stories.mdx new file mode 100644 index 0000000000000..0902bbe6cc889 --- /dev/null +++ b/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Components/Card/Card.stories.mdx @@ -0,0 +1,86 @@ +import { Meta } from '@storybook/addon-docs'; + + + +# Card Migration + +Fluent UI v8 provides the `DocumentCard` component and it's variants. Fluent UI v9 provides a `Card` control, but has a different API. `Card` is more generic is less opinionated about its content. + +This table maps `DocumentCard` v8 props to the `Card` v9 equivalent. + +| v8 | v9 | Notes | +| ------------- | --------- | ---------------------------------------- | +| className | className | | +| componentRef | ref | | +| onClick | onClick | | +| onClickHref | n/a | Can be implemented using `onClick` | +| onClickTarget | n/a | Can be implemented using `onClick` | +| role | role | | +| styles | className | | +| theme | n/a | Use `FluentProvider` to customize themes | +| type | n/a | see Migrate `type` prop in this document | + +## Migrate `type` prop + +The `type` prop is no longer supported. To migrate, the property `orientation="horizontal"` can be used to achieve the same effect. + +Before: + +```tsx +import { + DocumentCard, + DocumentCardActivity, + DocumentCardDetails, + DocumentCardPreview, + DocumentCardTitle, + DocumentCardType, +} from '@fluentui/react/lib/DocumentCard'; +import { TestImages } from '@fluentui/example-data'; + +const previewImage = { + name: 'Revenue stream proposal fiscal year 2016 version02.pptx', + linkProps: { + href: 'http://bing.com', + target: '_blank', + }, + previewImageSrc: TestImages.documentPreview, + iconSrc: TestImages.iconPpt, + width: 144, +}; + +const Component = () => ( + + + + + + + +); +``` + +After: + +```tsx +import * as React from 'react'; +import { Text, Avatar, Caption1 } from '@fluentui/react-components'; +import { Card, CardHeader, CardPreview } from '@fluentui/react-card/unstable'; + +export const SizedCard = () => { + const styles = useStyles(); + + return ( + + + Company Logo + + + } + header={Strategy 2021} + description={https://aka.ms/fluentui} + /> + + ); +}; +``` diff --git a/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Components/Card/CardFooter.stories.mdx b/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Components/Card/CardFooter.stories.mdx new file mode 100644 index 0000000000000..2c0874400df78 --- /dev/null +++ b/apps/public-docsite-v9/src/Concepts/Migration/FromV8/Components/Card/CardFooter.stories.mdx @@ -0,0 +1,91 @@ +import { Meta } from '@storybook/addon-docs'; + + + +# CardFooter Migration + +Fluent UI v8 provides the `DocumentCardActions` component. Fluent UI v9 provides a more consistent and opinionated `CardFooter` instead. + +This table maps `DocumentCard` v8 props to the `Card` v9 equivalent. + +| v8 | v9 | Notes | +| ------------ | --------- | ----------------------------------------- | +| className | className | | +| componentRef | ref | | +| views | n/a | see Migrate `views` prop in this document | +| role | role | | +| styles | className | | +| theme | n/a | Use `FluentProvider` to customize themes | + +## Migrate `views` prop + +The `views` prop is no longer supported. To migrate, create an element that displays the number of views and pass it to the `CardFooter` `action` prop. + +Before: + +```tsx +import { DocumentCard, DocumentCardActions } from '@fluentui/react/lib/DocumentCard'; + +const documentCardActions = [ + { + iconProps: { iconName: 'Share' }, + ariaLabel: 'share action', + }, + { + iconProps: { iconName: 'Pin' }, + ariaLabel: 'pin action', + }, + { + iconProps: { iconName: 'Ringer' }, + ariaLabel: 'notifications action', + }, +]; + +export const DocumentCardCompleteExample: React.FunctionComponent = () => ( + + + +); +``` + +After: + +```jsx +import * as React from 'react'; +import { Button, shorthands, makeStyles } from '@fluentui/react-components'; +import { Pin20Regular, Share20Regular, ServiceBell20Regular, Eye20Regular } from '@fluentui/react-icons'; +import { Card, CardFooter } from '@fluentui/react-card/unstable'; + +const useStyles = makeStyles({ + card: { + width: '300px', + }, + + actions: { + ...shorthands.gap('4px'), + ...shorthands.padding('4px'), + display: 'flex', + alignItems: 'center', + }, +}); + +export const Default = () => { + const styles = useStyles(); + + return ( + + + 432 + + } + > + + + + + + + + New Item + Open Item + ... + + + +``` + +### You can map data props to children + +If you have complex code that builds up the data props, you can author your own map call to convert the data to children. + +Continuing the contextual menu button example: +If you want to keep your `menuProps` data, you can map the items to `MenuItem` children. + +```tsx + + + + + + + + {menuProps.map(menuItem => ( + {menuItem.text} + ))} + + + +``` + +## Breaking Change: Render props to slots + +In v9, components provide slots to customize parts. +If you use the render props callbacks to customize the children, items, or parts of a component, you will need to update them to use slots. + +For example, the v8 CheckBox has an onRenderLabel() callback. + +```tsx +const onRenderBoldLabel = (props: ITextFieldProps) => {props.label} + + +``` + +To customize the label for a v9 CheckBox, you would use the label slot. +The slot accepts a string literal, JSX, or a render function. + +```tsx +const StrongLabel = (props: LabelProps) => + +Customer Name +``` + +## Breaking Change: Custom styles to className + +In v9, styles are customized by using makeStyles and mergeClasses to set the className prop. +The className prop can be set on the component as well as on individual slots. + +If you have customized v8 components using the styles prop and passed custom style objects, you will need to convert them to class names. +There may not be a one-to-one mapping between the parts from a v8 styles object to the slots of a v9 component. + +For example, a v8 Persona with customized styles to display the primary text as steel blue and the secondary text to have extra top and left margin. + +```tsx +const personaStyles: Partial = { + primaryText: { + color: 'steelblue', + }, + secondaryText: { + margin: '5px 0 0 10px', + }, +}; + +; +``` + +To keep this customization in v9 Persona, you will need to create styles with makeStyles and then apply them to the associated slot. + +```tsx +const usePersonaStyles = makeStyles({ + primaryText: { + color: 'steelblue', + }, + secondaryText: { + ...shorthands.margin('5px', '0', '0', '10px'), + }, +}); + +const personaStyles = usePersonaStyles(); + +//... + +; +``` diff --git a/apps/public-docsite-v9/src/Concepts/Migration/ImportantChanges.stories.mdx b/apps/public-docsite-v9/src/Concepts/Migration/ImportantChanges.stories.mdx deleted file mode 100644 index bba2de6cb427a..0000000000000 --- a/apps/public-docsite-v9/src/Concepts/Migration/ImportantChanges.stories.mdx +++ /dev/null @@ -1,182 +0,0 @@ -import { Meta } from '@storybook/addon-docs'; - - - -# Important changes you should know about - -v9 introduces several paradigm shifts that were necessary to improve performance, ease development, and reduce bundle size. -This resulted in some breaking changes you will need to handle as you migrate. - -## Props vs. Children - -### v8 - -In v8, several components had props that accepted arrays of data and used a map function to render the children. -To allow control over rendering individual items, render props callbacks were added. - -Components that rendered large lists of items had lots of specific behavior (such as virtualization) hard coded within the component. - -For example, `ContextualMenuButton` takes `menuProps` containing menu data, -an optional `menuAs` to control the rendering of menu items, -and an optional `onMenuClick`. - -```tsx -const menuProps: IContextualMenuProps = { - items: [ - { - key: 'emailMessage', - text: 'Email message', - }, - { - key: 'calendarEvent', - text: 'Calendar event', - }, - ], - directionalHintFixed: true, -}; - -function _getMenu(props: IContextualMenuProps): JSX.Element { - return ; -} - -function _onMenuClick(ev?: React.SyntheticEvent) { - console.log(ev); -} - -; -``` - -### v0 - -For v0, array props are also not used. Render props callback works very similarly in v9 as it was in v0. - -### v9 - -Components in v9 give you full control of rendering items by allowing you to pass child elements instead of data props. -This allows you to define and compose children however you like: declaring JSX elements or writing your own map function. -You don't have to define and pass separate renderprops functions to control the rendering of children. - -This means that your existing code passing arrays of data will need to be updated to render child elements. - -In v9, you get much more control over menus including what component triggers the display of the menu or submenu. -By specifying the children you directly control the rendering of each child and can wire up onClick handlers directly -rather than having to figure out which menuItem was clicked. - -```tsx - - - - - - - Email message - Calendar event - - - -``` - -You can continue to leverage existing data structures by writing a map function. -With the map function separate from the Menu component, you get a lot more control. - -```tsx - - - - - - - {menuItems.map(item => {item.name}) - - - -``` - -## Custom Styling & Theming - -There are significant styling and theming differences between v8 and v9. - -### v8 - -In v8, the `styles` prop on components accepts javascript objects (IStyle). -These could be parameterized to generate styles at runtime. -Unfortunately, this has a negative impact on rendering performance. - -The ThemeProvider provided a theme object on the context. -The theme contains a collection of component styles, color palettes, fonts, and spacing values. -Components consumed the theme through the theme object in state or by using the `useTheme` hook. -Legacy themes are supported through loadTheme and the theme customizer. - -For example, a `Button` can be styled to look like a primary button when hovered. - -```tsx -const theme = useTheme(); - -const customButtonStyles: IButtonStyles = { - rootHovered: { - backgroundColor: theme.semanticColors.primaryButtonBackground, - color: theme.semanticColors.primaryButtonText, - }, -}; - -return ( - - - -); -``` - -### v0 - -In v0, `styles` and `design` prop on components accept javascript objects. Styling and theming is also possible by using `variables` and extending the theme with custom varables. -Flexible system of design variables allowed different consumers to extend their design systems in different ways. In v9, variables API is no longer available as it was one of the reasons for frequent style calculation during runtime. Instead, there was a different approach chosen in order to improve rendering performance - style overrides or CSS variables can be used to achieve similar functionality. - -Due to the high flexibility of variables, it is not possible to provide a straightforward migration plan for them. You can use the v0 debug panel to observe what styles are being applied based on variable change and transform those styles using [style transformation tool](aka.ms/perestroika). - -### v9 - -In v9, styles are created with the `makeStyles` function and combined with the `mergeClasses` function from [`@griffel/react`](https://github.com/microsoft/griffel). -Components apply styles through the `className` property. -The styles are created at build time, but never runtime (requires the use of `griffel`'s build-time optimization plugin). -This allows styles to be deduped, optimized, and bundled for significantly smaller bundles and improved CSS performance. - -There is a new theme provider in v9 named `FluentProvider` that replaces v8's `ThemeProvider`. - -FluentProvider provides a theme using css variables referencing design tokens. -The design tokens provide global colors, fonts, and spacing. -There are alias tokens for general purpose component parts (e.g. background, border). -Components consume the theme, by importing `tokens`, a collection of css var usage, and using them in `makeStyles`. - -FluentProvider can be nested multiple times in the hierarchy to create theme variations and `dir` changes for a scoped set of components. -FluentProvider does **not** have a default theme like ThemeProvider, so you'll need to set the theme at your application's root for the components to be styled correctly. - -For example, the same `Button` customization as before would be done like this. - -```tsx -const useStyles = makeStyles({ - base: { - ':hover': { - backgroundColor: tokens.colorBrandBackground, - color: tokens.colorNeutralForegroundOnBrand, - }, - }, -}); - -const customButtonStyles = useStyles(); -return ; -``` - -## Component Part Customization - -In v8, parts of components were customized through render props callbacks. -Part-specific callbacks were provided by individual components. -Many callbacks included data payloads to allow you to pass data per item into a callback. - -In v9, part customization is done through a slots mechanism. -The props for a component can define slots that allow you to replace the entire part with JSX, -properties to pass to the default slot component style, -or a render function. - -See the [Customizing Components with Slots](/docs/concepts-developer-customizing-components-with-slots--page) topic for detailed information on slots. diff --git a/apps/public-docsite-v9/src/Concepts/Migration/KeepingDesignConsistent.stories.mdx b/apps/public-docsite-v9/src/Concepts/Migration/KeepingDesignConsistent.stories.mdx new file mode 100644 index 0000000000000..1780bffbb179a --- /dev/null +++ b/apps/public-docsite-v9/src/Concepts/Migration/KeepingDesignConsistent.stories.mdx @@ -0,0 +1,147 @@ +import { Meta } from '@storybook/addon-docs'; + + + +# Keeping Design Consistent + +Fluent 2 is the next version of the Fluent design language. +Fluent UI React v9 uses the Fluent 2 design language for layout and style of components. + +The design language defines a set of design tokens. +Themes consist of a property/value pair for each token. +Designers reference these tokens in the design specs detailing the layout and style of components. + +The themes in v0 and v8 were specific to component, component part, and state. +While this allowed for fine-grained control over each component's style, it led to an explosion of theme properties. +Too many theme properties can make defining new themes an arduous chore, can make themes fragile when properties are added or removed, and can leave dead theme properties behind when components stop using them. + +In v9, the theme properties are called design tokens. +They are much more general purpose. +They are partitioned by neutral vs. brand, usage (e.g. foreground, background, stroke), and state. + +This topic covers ways you can maintain a consistent theme and style during migration. + +## You can choose to live with and limit style differences during migration + +The visual style differences between v9 and previous versions are slight. +If your migration effort is small, you can migrate all at once, or if your users are OK with some inconsistency, you might decide to avoid extra effort and live with it. + +For example, you can see differences between v8's and v9's Button components when you put them side-by-side. +However, the design differences between v8's Input and v9's Button are difficult to detect. + +You can reduce the visual friction between Fluent 1 and Fluent 2 designs during migration by migrating all instances of one component type to v9. + +## You can use theme providers side-by-side + +In v0/v8, you pass the `ThemeProvider` component a theme. +This puts the theme object on React's context. +Component style methods then reference the theme properties when building styles. + +In v9, you pass the `FluentProvider` component a theme. +This defines a CSS variable for each design token. +Component CSS styles then reference the CSS variables. + +When migrating to v9, you will have v0/v8 and v9 components side-by-side. +You can wrap both `ThemeProvider` and `FluentProvider` around components. +Both `ThemeProvider` and `FluentProvider` support nesting to define a theme or partial theme at different scopes. + +```tsx +import { ThemeProvider, Button as Buttonv8, webLightTheme} from '@fluentui/react'; +import { FluentProvider, Button as Buttonv9} from '@fluentui/react-components'; + + + + Hello migration + Hello migration + + +``` + +## You can use design token styles in your own components + +Fluent UI React v9 leverages the Griffel CSS-in-JS library. +The `makeStyles` and `mergeClasses` methods are exported by `@fluentui/react-components` package. +Read [Styling Components](/docs/concepts-developer-styling-components--page) for details. + +Because `FluentProvider` defines design token values as CSS variables, you can reference them your own component styles. +Read [Theming](/docs/concepts-developer-theming--page) to see examples. + +## You can extend the theme with new design tokens + +The v9 `FluentProvider` defines CSS variables consumed by components. +You can extend the `Theme` type with your own design tokens, set values when creating an instance of your theme, and then consume them in your own components. + +See _Extending themes with new tokens_ section in [Theming](/docs/concepts-developer-theming--page). + +## You can make v0, v8, v9 components have the same style + +While you have both old and new components together in your application, you may see some differences in the theme and styling of components. +You can choose to live with the minor discrepancies until you have fully migrated to v9. +You can also choose to make everything look like a previous version or like v9. + +> We recommend moving to v9's Fluent 2 design. +> It has improved accessibility and has consistent style across components. + +### You can create custom themes + +By passing a v8 theme to `ThemeProvider` that uses v9 colors, v8 will look more like v9. +Conversely, passing a v9 theme to `FluentProvider` that uses v8 colors will make v9 look more like v8. + +### You can use theme shims + +We have developed some shims (code that helps with migration) that let you create a v9 theme from the default v8 theme, create a v8 theme from the `webLightTheme` or `webDarkTheme` v9 themes. + +One of our key partner teams has developed a Fluent 2 theme for v8 that includes custom component styles to exactly match the Fluent 2 theme of v9. + +Check them out in the _/Migration Shims/Themes_ topics. + +## You can define custom styles with className + +As detailed in the _/Concepts/Developer/Styling Components_ topic, you can create styles with `makeStyles` and `mergeClasses` and then pass the className to any v9 component or component slot.Those styles will be applied last, allowing you to modify the default component style. + +If you do create custom styles, we strongly recommend using design tokens. +This ensures styles update with theme changes. + +## You can recompose components with custom styles + +Fluent v9 has a powerful composition model using React hooks. +Each component is separated into a hook that maps props to state, a hook that uses state to set className styles on each slot, and a render function that outputs each slot with applied props. + +While you can create a wrapper component that renders a v9 component with custom styles applied, this often introduces more virtual DOM elements that may affect performance. + +Instead, you can create a component that reuses the same hooks of the component. +You can substitute your own hooks or call additional hooks. +Because you are leveraging the same infrastructure v9 components use, no additional wrapper virtual DOM elements are created. + +This example defines a new button component. +The props to state hooks and render method from `Button` are reused. +A new style hook is substituted for `useButtonStyle`. + +```tsx +import * as React from 'react'; +import { renderButton_unstable as renderButton, useButton_unstable as useButton } from '@fluentui/react-components'; +import type { ButtonProps, ForwardRefComponent } from '@fluentui/react-components'; + +const useStyles = makeStyles({ + root: { + background: tokens.colorNeutralBackground2, + //... + }, +}); + +// This is an example of a custom style hook +const useCusomButtonStyles = (state: ButtonState): ButtonState => { + const styles = useStyles(); + + state.root.className = styles.root; + //... +}; + +export const MyButton: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useButton(props, ref); + useCustomButtonStyles(state); + return renderButton(state); +}) as ForwardRefComponent; +``` + +This is the most advanced form of customization in Fluent UI React v9, but provides you complete control over components. diff --git a/apps/public-docsite-v9/src/Concepts/Migration/Overview.stories.mdx b/apps/public-docsite-v9/src/Concepts/Migration/Overview.stories.mdx deleted file mode 100644 index 1d814202443f1..0000000000000 --- a/apps/public-docsite-v9/src/Concepts/Migration/Overview.stories.mdx +++ /dev/null @@ -1,66 +0,0 @@ -import { Meta } from '@storybook/addon-docs'; - - - -# Migrating from v8 or v0 to v9 - -If you or your team are currently using version 8 of `@fluentui/react` or version 0.x of `@fluentui/react-northstar` and are thinking of migrating to version 9 -then we would first like to **_thank you_** for making the jump and tell you how excited we are for you to experience all the improvements and features we have been working on. - -There are several things to keep in mind when migrating, so we have created these uprade guide topics explaining: - -- the new concepts you will encounter and how they map to concepts in previous versions -- things to consider when planning migration work -- detailed guidance on migrating components -- examples and helper code to make migrating easier - -We highly recommend reading through the v9 concepts for developers and the component documentation. -Knowing how v9 works will provide needed context for migrating. - -## Why should I migrate from v8 or v0 to v9? - -Fluent UI React v9 provides significant improvements to components over both v8 and v0. - -Some reasons to migrate to v9: - -- New and improved visual styling, rendering performance, and accessibility -- Easier to use and more consistent component props -- Build-time CSS-in-JS -- Component customization using slots -- Design token language with an improved theme provider -- Component composition and re-use leveraging React hooks -- Reduced bundle size with tree shaking - -## Do I have to migrate all at once? - -Absolutely not! **You can migrate incrementally**. - -Fluent UI v9 was built as separate libraries with the intention of support incremental adoption of v9 components alongside v8 and v0 components. - -## What if I'm on v7 right now? - -We recommend first migrating v7 to v8. The migration is mostly fixing a few breaking changes and replacing some deprecated components or props with newer versions. - -## What is available in v9? - -Version 9 is a "converged" library built from the ground-up that addresses many of the concerns and issues that plagued version 8. -However, this approach means that the intial number of version 9 components is fewer than existed in version 8. -Some components have also been renamed and a couple of them have been retired. - -At the time of this writing, v9 has an initial set of components shipped as a release candidate. -There are also some components in preview that are more likely to change than the release candidate components. -However, **all published components are production ready**. - -The v9 RC provides the following v8 equivalents: Avatar (previously Persona), Buttons, Divider, Image, Link, Portal and Popover (previously Layer/Overlay), Text, and Tooltip. -There are also new components: Accordion, Badges, and Menu. - -See the [Component Mapping](/docs/concepts-migrating-from-v8-component-mapping--page) for a complete list. - -The v9 RC provides the following v0 equivalents: Accordion, Avatar, Badge (previously Status), Buttons, Divider, Image, Menu, Portal and Popover (previously Popup), Text, and Tooltip. - -## How much effort is required? - -We won't sugarcoat it; migrating from v8 to v9 is more involved than the previous v7 to v8 migration. -There are breaking changes, component differences, and paradigm shifts. - -The good news is that you can migrate incrementally and take it one step at a time. diff --git a/apps/public-docsite-v9/src/Concepts/Migration/Planning.stories.mdx b/apps/public-docsite-v9/src/Concepts/Migration/Planning.stories.mdx deleted file mode 100644 index f8ff4c9cfbbc0..0000000000000 --- a/apps/public-docsite-v9/src/Concepts/Migration/Planning.stories.mdx +++ /dev/null @@ -1,186 +0,0 @@ -import { Meta } from '@storybook/addon-docs'; - - - -# Planning your journey - -As mentioned before, Fluent UI React v9 was designed to allow you to incrementally migrate. -You have a lot of flexibility on how you approach, plan, and execute moving to v9. - -This part of the guide will help you assess your project, choose your approach, -and plan out an iterative cycle for a successful migration. - -## Assessing your application - -How your application uses Fluent will influence your approach. -Scan over your codebase and try to answer the following questions: - -1. What Fluent components does your application use? -2. For each component, how many times is each component used (i.e. usage instances)? -3. Is most usage basic or advanced? - -Basic usage means you use the component with minimal customization. -You pass typical props and bind data from your components or application state. - -```tsx - -``` - -Advanced usage includes things like passing complex custom styles objects, callbacks for custom rendering, using refs to make imperative calls, and complex data binding. - -## Considerations - -There are lots of ways to migrate. Here are are some different options to consider. - -### Incremental or All-at-once - -_Incremental_: migrate a few components and ship, often by flighting the migrated components to a subset of users. -The benefits of the incremental approach are that you get v9 improvements sooner, find issues earlier, -and can iteratively get faster migrating components. - -Since v9 does not have all the components offered in previous versions yet, incrementally migrating allows you to gradually introduce v9 -side-by-side with v8 or v0. -You can more closely monitor the changes to bundle size and performance improvements with a gradual approach. - -_All-at-once_: migrate every v8/v0 component to their v9 equivalent. -You can still flight the migrated experience to a subset of users. -You get the benefit that you could A/B route to different web application servers when flighting and keep the -previous untouched version running independent of the migrated version. - -You also get the maximum benefits of v9 including a new consistent style, -tree-shaking out v8 components from the bundles, build-time CSS optimizations, and render performance improvements. - -### Horizontal or Vertical - -_Horizontal_: migrating one component across your entire application. -For example, migrating Button from previous version to v9 everywhere. -This has the benefit that your code will end up only depending on v9 Button and the v8 Button won't be included in the downloaded bundle. -Your buttons will look and behave the same across your app. - -_Vertical_: migrating all the components in one part of your application. -For example, migrating Button, Divider, Persona, and Link on a contact status side bar. -This has the benefit that you can migrate one part of your application in isolation leaving the rest of the app unaffected. -You can choose a non-critical part of your application to reduce risk of app-wide issues. -It makes it easier to trace any issues caused by migration. -Vertical may allow you to find integration issues earlier as you are using multiple new components. - -You can also choose to migrate one component in one part of your application. -You lose some of the benefits of each individual approach, but can try things out more slowly. - -### Deep or Shallow - -_Deep_: migrating components that are core to your application and re-used in many places. -For example, migrating a main toolbar to use the v9 Button and Menu components. -You get the benefits of v9 across the entire application. -You will get more usage of the migrated components and can gather feedback earlier. - -_Shallow_: migrating components that appear only in one non-critical place in your application. -For example, migrating an optional edit profile screen. -You get the benefit of limiting risk, but decrease the usage and may not find issues right away. - -### New v9 or Old v8 style - -If you have v8 and v9 components side-by-side, you may want to avoid noticable style differences. -If you need style consistency, apply theming and style customizations to make v8 components look like v9 components, -or make v9 components look like v8 components. - -You may decide you can live with the style differences for a period of time. -Most are small changes that are only noticable when v8 and v9 versions of the same component are next to each other in the UI. - -### New v9 or Old v0 style - -v0 will to some extent gradually converge its appearance. However, you might still need to use style overrides in some cases to achieve consistency. - -### Manual changes, code mod scripts, or shims - -_Manual_: update each usage of Fluent React by hand. -This is the brute force approach to migration. -It may be the best option especially for smaller projects. -You may have a lot of variety in how you use components that preclude a search/replace or automated option. -You may also have an existing wrapper around a component that allows you to migrate at a single code location. -The benefits include you can call v9 components as intended, the opportunity to simplify and improve -how your code uses Fluent, and you can make incremental check-ins ensuring existing tests pass. - -_Code mod_: author a script to update multiple locations in your code at once. -You may be able to leverage existing scripts from previous migrations, from others who have migrated, or from the Fluent React team. -If your codebase is very consistent in how it uses Fluent, this option can save a lot of extra effort over manual migration. -You can have code mods that add flighting logic around usage to have both v8/v0 and v9 available. -The downside is that if your usage is complex or highly varied, authoring a code mod that covers all cases may be impractical. - -_Shims_: author or use a component that takes v8/v0 props and renders a v9 component. -Shims can be a good option to get v9 components in your app if you don't have the time to update all the places you use the component. -You can leave your props creation code alone and pass it to the shim. -It is easy to search/replace your code to update to using the shim. -You can also do your flighting logic within the shim itself. -One downside is that your shim will retain the dependency on v8/v0 and prevent removing it from your bundle. -Also, there are cases with custom renderprops callbacks that cannot be supported by a shim because the rendered -content is not compatible with the v9 component. - -## Recommendations - -### Small projects - -If you have a small project and can commit the effort, we recommend migrating everything and modifying the code directly. - -This gives you the maximum benefit of rendering performance, build time style bundling, and tree-shaking out v8 components that are no longer used. You'll be able to refactor any advanced usage cases in the newer v9 paradigms and end up with cleaner code. - -You should still consider flighting the migrated experience, but you can A/B the entire application rather than if/then flighting per component in the code. - -### Medium or larger with advanced usage - -If you have a medium to large project, significant advanced usage of components, and limited resources or time constraints, we recommend leveraging the shim components. - -You can replace all the usages of a component like Button with ShimButton and get a v9 Button rendered. You get the benefits of v9 components and can crawl over the code to update to use v9 directly at your leisure. - -Warning! Shims aren't free. You'll still need to modify code to migrate custom styles, renderprops callbacks, and ref usage. Shims take a dependency on the v8 types and v9 components, so tree-shaking may be limited. Shims introduce mapping logic (although it shouldn't signficantly impact render performance). - -### Medium or larger apps with basic usage - -If you have a large project with hundreds to thousands of Fluent component usages, we strongly recommend migrating horizontally. The Button component is a typical choice to migrate across the application. - -If your usage is mostly basic, we recommend authoring a code-mod to handle what would be too tedious with search & replace. Consider running code-mods to handle most cases and then do some manual migration work to cover the rest. - -### Large with advanced usage - -If you have a large projects with thousands of Fluent component usages, a lot of advanced usage, and several resource constraints, we recommend creating an application-specific shim and permanent abstraction around the Fluent component. - -A permanent abstraction will give you a place to adapt for compatibility as you move from v8 props to v9 props. It will also be valuable with future migrations. v9 has a new hook-based composition model you can leverage to create a shim without introducing the extra virtual DOM elements of a wrapper. You can also introduce the flighting logic within your shim to be able to toggle the migration on/off. - -You can consider code-mods to migrate the more basic usage, but will likely find too much variance to handle all the cases across your code. - -We recommend you migrate horizontally, but you may want to migrate horizontally within one portion of your application at a time. For example, all the buttons in a toolbar or on a related set of pages in your application. This lets you migrate in stages without destabilizing then entire application. - -If you have a subsystem of your application that is independent and similar to a small/medium application, you may choose to migrate it vertically. You can have a cohesive improvement to one part of the application and flight it independent of the rest of the application. - -## Creating a plan - -We strongly recommend using a work item tracking system or Excel spreadsheet to plan out your migration tasks. - -### A plan for a plan - -You should create and complete a set of planning tasks: - -1. Measure the current bundle size, render performance, and other metrics for later comparison. -2. Determine the mechanism for how you will flight the migrated components to a subset of users. -3. Decide on any pre-migration improvements that you will make first to reduce migration effort. -4. Determine what other constraints you have - maximum bundle size, performance bars, allowed style inconsistencies, etc. -5. Assess the application and choose your approach. -6. Choose a target deadline or milestone date for each phase of migration. - -### Getting started tasks - -You should plan a set of getting started tasks for migrating one component in one location. - -1. Update project to reference Fluent React v9. -2. Add FluentProvider with a theme to the root of the app -3. Add any v9 component to the UI, verify it renders as expected, then remove it. -4. Update a single usage location to use the v9 component. Consider recording how long it takes. - -### Iterative planning - -Plan a task or set of tasks to be able to 'rinse and repeat' each usage migration. - -- The type of tasks and their granularity will vary depending on your approach. -- After migrating some instances, review how long each took and plan out the next set of tasks. diff --git a/apps/public-docsite-v9/src/Concepts/QuickStart.stories.mdx b/apps/public-docsite-v9/src/Concepts/QuickStart.stories.mdx index 1bae31e19eff6..24a1ca1a792c1 100644 --- a/apps/public-docsite-v9/src/Concepts/QuickStart.stories.mdx +++ b/apps/public-docsite-v9/src/Concepts/QuickStart.stories.mdx @@ -44,11 +44,12 @@ export default () => ; ### Strict mode -Strict mode is currently not supported. Plese remove any `React.StrictMode` wrappers from your app. +We are aware of some strict mode bugs when using Fluent UI v9 in React 18. These bugs only show up in strict mode, and they will not stop the rest of your app from running. +You can [track the bugs on Github](https://github.com/microsoft/fluentui/issues?q=is%3Aopen+is%3Aissue+label%3A%22Area%3A+Strict+Mode%22+label%3A%22React+18%22) and learn how they will affect your application. #### SSR with Next.js -To avoid hydration issues, disable strict mode in your app by adding the following configuration to your `next.config.js` file: +To avoid strict mode hydration issues, you can disable strict mode in your Next.js app by adding the following configuration to your `next.config.js` file: ```js module.exports = { diff --git a/apps/public-docsite-v9/src/Concepts/SSR/Nextjs.stories.mdx b/apps/public-docsite-v9/src/Concepts/SSR/Nextjs.stories.mdx new file mode 100644 index 0000000000000..e711ca7a1619b --- /dev/null +++ b/apps/public-docsite-v9/src/Concepts/SSR/Nextjs.stories.mdx @@ -0,0 +1,147 @@ +import { Meta } from '@storybook/addon-docs'; + + + +## Next.js + +For basic instructions on getting Next.js set up, see [Getting Started](https://nextjs.org/docs/getting-started). + +1. Get a basic next.js setup running, rendering a page from the `pages` folder, as guided by the tutorial. +2. Add the Fluent UI dependencies: `@fluentui/react-components`. + +```sh +// yarn +yarn add @fluentui/react-components + +//npm +npm install @fluentui/react-components +``` + +1. Create a `_document.tsx` file under your `pages` folder with the following content: + +```tsx +import { createDOMRenderer, renderToStyleElements } from '@fluentui/react-components'; +import Document, { Html, Head, Main, NextScript, DocumentContext } from 'next/document'; + +class MyDocument extends Document { + static async getInitialProps(ctx: DocumentContext) { + // 👇 creates a renderer that will be used for SSR + const renderer = createDOMRenderer(); + const originalRenderPage = ctx.renderPage; + + ctx.renderPage = () => + originalRenderPage({ + enhanceApp: App => + function EnhancedApp(props) { + const enhancedProps = { + ...props, + // 👇 this is required to provide a proper renderer instance + renderer, + }; + + return ; + }, + }); + + const initialProps = await Document.getInitialProps(ctx); + const styles = renderToStyleElements(renderer); + + return { + ...initialProps, + styles: ( + <> + {initialProps.styles} + {/* 👇 adding Fluent UI styles elements to output */} + {styles} + + ), + }; + } + + render() { + return ( + + + +
+ + + + ); + } +} + +export default MyDocument; +``` + +2. Create or modify a `_app.tsx` file under your `pages` folder with the following content: + +```tsx +import { + createDOMRenderer, + FluentProvider, + GriffelRenderer, + SSRProvider, + RendererProvider, + webLightTheme, +} from '@fluentui/react-components'; +import type { AppProps } from 'next/app'; + +type EnhancedAppProps = AppProps & { renderer?: GriffelRenderer }; + +function MyApp({ Component, pageProps, renderer }: EnhancedAppProps) { + return ( + // 👇 Accepts a renderer from or creates a default one + // Also triggers rehydration a client + + + + + + + + ); +} + +export default MyApp; +``` + +3. You should now be able to server render Fluent UI React components in any of your pages: + +```tsx +import { Button, makeStyles, shorthands, Title1, tokens } from '@fluentui/react-components'; +import type { NextPage } from 'next'; +import Head from 'next/head'; + +const useStyles = makeStyles({ + container: { + display: 'flex', + flexDirection: 'column', + width: '200px', + + ...shorthands.border('2px', 'dashed', tokens.colorPaletteBerryBorder2), + ...shorthands.borderRadius(tokens.borderRadiusMedium), + ...shorthands.gap('5px'), + ...shorthands.padding('10px'), + }, +}); + +const Home: NextPage = () => { + const styles = useStyles(); + + return ( + <> + + My app + + +
+ Hello world! + +
+ + ); +}; + +export default Home; +``` diff --git a/apps/public-docsite-v9/src/Concepts/SSR/Portals.stories.mdx b/apps/public-docsite-v9/src/Concepts/SSR/Portals.stories.mdx new file mode 100644 index 0000000000000..5e6b44d1579b7 --- /dev/null +++ b/apps/public-docsite-v9/src/Concepts/SSR/Portals.stories.mdx @@ -0,0 +1,53 @@ +import { Meta } from '@storybook/addon-docs'; +import { SSRDefaultOpen } from './MenuSSRDefaultOpen.stories'; + + + +## React Portals + +React does not support hydration for portals ([facebook/react#13097](https://github.com/facebook/react/issues/13097)). While Fluent +UI tries to work out of the box without hydration warnings, some workarounds are required in certain edge cases. + +### Default open + +Components like `Menu` or `Popover` have a `defaultOpen` prop that open the positioned surface on mount. These components +are rendered with React portals. In SSR using the `defaultOpen` on server render will cause a hydration error because +React does not support hydration for portals. + +The below example shows how to use the `useIsSSR` hook to implement a `Menu` that is open by default on the first render. +Toggle the checkbox to mount/unmount the component. + + + +```tsx +import * as React from 'react'; +import { Menu, MenuTrigger, MenuList, MenuItem, MenuPopover, useIsSSR, Button } from '@fluentui/react-components'; + +const DefaultOpenMenu = () => { + const [open, setOpen] = React.useState(false); + const isSSR = useIsSSR(); + + React.useEffect(() => { + if (!isSSR) { + setOpen(true); + } + }, [isSSR]); + + return ( + setOpen(data.open)}> + + + + + + + New + New Window + Open File + Open Folder + + + + ); +}; +``` diff --git a/apps/public-docsite-v9/src/Concepts/SSR/SSR.stories.mdx b/apps/public-docsite-v9/src/Concepts/SSR/SSR.stories.mdx index 80298c59e914f..aab9b2bb21530 100644 --- a/apps/public-docsite-v9/src/Concepts/SSR/SSR.stories.mdx +++ b/apps/public-docsite-v9/src/Concepts/SSR/SSR.stories.mdx @@ -1,197 +1,82 @@ import { Meta } from '@storybook/addon-docs'; -import { SSRDefaultOpen } from './MenuSSRDefaultOpen.stories'; - + ## Server-Side Rendering Fluent UI React v9 fully supports Server-Side Rendering. -### Next.js +### Basic setup -For basic instructions on getting Next.js set up, see [Getting Started](https://nextjs.org/docs/getting-started). - -1. Get a basic next.js setup running, rendering a page from the `pages` folder, as guided by the tutorial. -2. Add the Fluent UI dependencies: `@fluentui/react-components`. +Add `@fluentui/react-components` dependency: ```sh +// yarn yarn add @fluentui/react-components -``` - -1. Create a `_document.tsx` file under your `pages` folder with the following content: -```tsx -import { createDOMRenderer, renderToStyleElements } from '@fluentui/react-components'; -import Document, { Html, Head, Main, NextScript, DocumentContext } from 'next/document'; - -class MyDocument extends Document { - static async getInitialProps(ctx: DocumentContext) { - // 👇 creates a renderer that will be used for SSR - const renderer = createDOMRenderer(); - const originalRenderPage = ctx.renderPage; - - ctx.renderPage = () => - originalRenderPage({ - enhanceApp: App => - function EnhancedApp(props) { - const enhancedProps = { - ...props, - // 👇 this is required to provide a proper renderer instance - renderer, - }; - - return ; - }, - }); - - const initialProps = await Document.getInitialProps(ctx); - const styles = renderToStyleElements(renderer); - - return { - ...initialProps, - styles: ( - <> - {initialProps.styles} - {/* 👇 adding Fluent UI styles elements to output */} - {styles} - - ), - }; - } - - render() { - return ( - - - -
- - - - ); - } -} - -export default MyDocument; +//npm +npm install @fluentui/react-components ``` -2. Create or modify a `_app.tsx` file under your `pages` folder with the following content: +For any setup using SSR, you need to provide a `RendererProvider`, `SSRProvider` and `FluentProvider` in the root of your app. If these providers are not added, there will be issues when hydrating. See the following example: ```tsx +import express from 'express'; +import React from 'react'; +import ReactDOMServer from 'react-dom/server'; import { createDOMRenderer, - FluentProvider, - GriffelRenderer, - SSRProvider, RendererProvider, + renderToStyleElements, + FluentProvider, webLightTheme, + SSRProvider, } from '@fluentui/react-components'; -import type { AppProps } from 'next/app'; - -type EnhancedAppProps = AppProps & { renderer?: GriffelRenderer }; - -function MyApp({ Component, pageProps, renderer }: EnhancedAppProps) { - return ( - // 👇 Accepts a renderer from or creates a default one - // Also triggers rehydration a client - - - - - - - - ); -} - -export default MyApp; -``` -3. You should now be able to server render Fluent UI React components in any of your pages: - -```tsx -import { Button, makeStyles, shorthands, Title1, tokens } from '@fluentui/react-components'; -import type { NextPage } from 'next'; -import Head from 'next/head'; - -const useStyles = makeStyles({ - container: { - display: 'flex', - flexDirection: 'column', - width: '200px', - - ...shorthands.border('2px', 'dashed', tokens.colorPaletteBerryBorder2), - ...shorthands.borderRadius(tokens.borderRadiusMedium), - ...shorthands.gap('5px'), - ...shorthands.padding('10px'), +const useExampleStyles = makeStyles({ + root: { + color: 'red', }, }); -const Home: NextPage = () => { - const styles = useStyles(); - - return ( - <> - - My app - +const ExampleComponent: React.FC = () => { + const classes = useExampleStyles(); -
- Hello world! - -
- - ); + return
Hello world
; }; -export default Home; -``` +const server = express(); -### React Portals +server.get('/', (req, res) => { + const renderer = createDOMRenderer(); -React does not support hydration for portals ([facebook/react#13097](https://github.com/facebook/react/issues/13097)). While Fluent -UI tries to work out of the box without hydration warnings, some workarounds are required in certain edge cases. - -#### Default open - -Components like `Menu` or `Popover` have a `defaultOpen` prop that open the positioned surface on mount. These components -are rendered with React portals. In SSR using the `defaultOpen` on server render will cause a hydration error because -React does not support hydration for portals. - -The below example shows how to use the `useIsSSR` hook to implement a `Menu` that is open by default on the first render. -Toggle the checkbox to mount/unmount the component. + const html = ReactDOMServer.renderToString( + + + + + + + , + ); - + // Converting Fluent UI styles to style elements. 👇 + const style = ReactDOMServer.renderToStaticMarkup(<>{renderToStyleElements(renderer)}); + + res.write(` + + + + ${/* 👇 adding Fluent UI styles elements to output */} + ${style} + + +
${html}
+ + + `); + res.end(); +}); -```tsx -import { Menu, MenuTrigger, MenuList, MenuItem, MenuPopover, useIsSSR, Button } from '@fluentui/react-components'; -import * as React from 'react'; - -const DefaultOpenMenu = () => { - const [open, setOpen] = React.useState(false); - const isSSR = useIsSSR(); - - React.useEffect(() => { - if (!isSSR) { - setOpen(true); - } - }, [isSSR]); - - return ( - setOpen(data.open)}> - - - - - - - New - New Window - Open File - Open Folder - - - - ); -}; +server.listen(3000, 'localhost'); ``` diff --git a/apps/public-docsite-v9/src/Concepts/StylingComponents.stories.mdx b/apps/public-docsite-v9/src/Concepts/StylingComponents.stories.mdx index 937d9c0bea2d6..42556c19a19be 100644 --- a/apps/public-docsite-v9/src/Concepts/StylingComponents.stories.mdx +++ b/apps/public-docsite-v9/src/Concepts/StylingComponents.stories.mdx @@ -4,7 +4,7 @@ import { Meta, Source } from '@storybook/addon-docs'; ## Styling components -To style Fluent UI React v9 components `makeStyles` is used. `makeStyles` comes from [`Griffel`](https://griffel.js.org) a homegrown CSS-in-JS implementation which generates atomic CSS classes. +To style Fluent UI React v9 components `makeStyles` is used. `makeStyles` comes from [Griffel](https://griffel.js.org) a homegrown CSS-in-JS implementation which generates atomic CSS classes. Get started by simply importing: @@ -136,9 +136,13 @@ function Component(props) { [Griffel devtools chrome extension](https://chrome.google.com/webstore/detail/griffel-devtools/bejhagjehnpgagkaaeehdpdadmffbigb) can be used to debug style overrides. It shows all griffel styles applied on the currently selected DOM element, including the styles that are overridden in `mergeClasses`. +### Limitations + +Griffel's approach to styling comes with certain [limitations](https://griffel.js.org/react/guides/limitations). One of which is the lack of support for [CSS shorthand properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Shorthand_properties). To work around this, Griffel [provides a collection of shorthand functions](https://griffel.js.org/react/api/shorthands) to write css shorthand. Their usage is demonstrated in the next example. + ## Overriding FUI component styles -To override an appearance of a FUI component, you use the exactly same approach - You call makeStyles/useStyles in your code and pass the resulting classes through `props`. +To override an appearance of a FUI component, you use the exactly same approach - You call `makeStyles`/`useStyles` in your code and pass the resulting classes through `props`. ```jsx import { makeStyles, tokens, shorthands } from '@fluentui/react-components'; diff --git a/apps/public-docsite-v9/src/Concepts/Theming.stories.mdx b/apps/public-docsite-v9/src/Concepts/Theming.stories.mdx index bb17e71cac180..93003cad90de9 100644 --- a/apps/public-docsite-v9/src/Concepts/Theming.stories.mdx +++ b/apps/public-docsite-v9/src/Concepts/Theming.stories.mdx @@ -14,7 +14,7 @@ const exampleTheme = { }; ``` -You can browse all the available tokens in **[Theme](/docs/theme-colors--colors)** section of the docs. +You can browse all the available tokens in **[Theme](/docs/theme-color--page)** section of the docs. ## How theme is applied diff --git a/apps/public-docsite-v9/src/DocsComponents/FluentDocsContainer.stories.tsx b/apps/public-docsite-v9/src/DocsComponents/FluentDocsContainer.stories.tsx index 82050f18dfaaf..e03cbda640bce 100644 --- a/apps/public-docsite-v9/src/DocsComponents/FluentDocsContainer.stories.tsx +++ b/apps/public-docsite-v9/src/DocsComponents/FluentDocsContainer.stories.tsx @@ -1,7 +1,6 @@ import * as React from 'react'; import { DocsContainer, DocsContextProps } from '@storybook/addon-docs'; -import { FluentStoryContext, THEME_ID, themes } from '@fluentui/react-storybook-addon'; -import { FluentDocsHeader } from './FluentDocsHeader.stories'; +import { FluentStoryContext } from '@fluentui/react-storybook-addon'; import { webLightTheme, FluentProvider } from '@fluentui/react-components'; interface IFluentDocsContainerProps { @@ -12,17 +11,8 @@ interface IFluentDocsContainerProps { * A container that wraps storybook's native docs container to add extra components to the docs experience */ export const FluentDocsContainer: React.FC = ({ children, context }) => { - // eslint-disable-next-line deprecation/deprecation - const selectedTheme = themes.find(theme => theme.id === context.globals[THEME_ID]); return ( <> - - - - {/** TODO add table of contents */} {children} diff --git a/apps/public-docsite-v9/src/DocsComponents/FluentDocsHeader.stories.tsx b/apps/public-docsite-v9/src/DocsComponents/FluentDocsHeader.stories.tsx deleted file mode 100644 index 5c554d699bfdb..0000000000000 --- a/apps/public-docsite-v9/src/DocsComponents/FluentDocsHeader.stories.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import * as React from 'react'; -import { FluentGlobals, THEME_ID } from '@fluentui/react-storybook-addon'; -import { shorthands, makeStyles } from '@griffel/react'; -import { ThemePicker } from './ThemePicker.stories'; - -const useStyles = makeStyles({ - root: { - textAlign: 'right', - position: 'relative', - width: 'auto', - ...shorthands.margin('0px', 'auto'), - maxWidth: '1200px', - paddingRight: '15px', - }, -}); - -/** - * Sticky header over the entire docs page - */ -export const FluentDocsHeader: React.FC<{ storybookGlobals: FluentGlobals }> = ({ storybookGlobals }) => { - const styles = useStyles(); - return ( -
- -
- ); -}; diff --git a/apps/public-docsite-v9/src/DocsComponents/FluentDocsPage.stories.tsx b/apps/public-docsite-v9/src/DocsComponents/FluentDocsPage.stories.tsx index de7a8e14626d7..895013317a8c7 100644 --- a/apps/public-docsite-v9/src/DocsComponents/FluentDocsPage.stories.tsx +++ b/apps/public-docsite-v9/src/DocsComponents/FluentDocsPage.stories.tsx @@ -12,6 +12,8 @@ import { } from '@storybook/addon-docs'; import { makeStyles, shorthands } from '@griffel/react'; import { Toc, nameToHash } from './Toc.stories'; +import { THEME_ID, themes } from '@fluentui/react-storybook-addon'; +import { ThemePicker } from './ThemePicker.stories'; const useStyles = makeStyles({ divider: { @@ -40,6 +42,8 @@ const useStyles = makeStyles({ export const FluentDocsPage = () => { const context = React.useContext(DocsContext); + // eslint-disable-next-line deprecation/deprecation + const selectedTheme = themes.find(theme => theme.id === context.globals![THEME_ID]); const stories = context.componentStories(); const primaryStory = stories[0]; const styles = useStyles(); @@ -61,6 +65,7 @@ export const FluentDocsPage = () => {
+
diff --git a/apps/public-docsite-v9/src/DocsComponents/ThemePicker.stories.tsx b/apps/public-docsite-v9/src/DocsComponents/ThemePicker.stories.tsx index 4d545853fb611..8dde44a995a12 100644 --- a/apps/public-docsite-v9/src/DocsComponents/ThemePicker.stories.tsx +++ b/apps/public-docsite-v9/src/DocsComponents/ThemePicker.stories.tsx @@ -32,15 +32,18 @@ const useStyles = makeStyles({ */ export const ThemePicker: React.FC<{ selectedThemeId?: string }> = ({ selectedThemeId }) => { const styles = useStyles(); + const [currentThemeId, setCurrentThemeId] = React.useState(selectedThemeId ?? null); const setGlobalTheme = (themeId: ThemeIds): void => { addons.getChannel().emit('updateGlobals', { globals: { [THEME_ID]: themeId } }); }; const onCheckedValueChange: MenuProps['onCheckedValueChange'] = (e, data) => { - setGlobalTheme(data.checkedItems[0] as ThemeIds); + const newThemeId = data.checkedItems[0] as ThemeIds; + setGlobalTheme(newThemeId); + setCurrentThemeId(newThemeId); }; - const selectedTheme = themes.find(theme => theme.id === selectedThemeId); + const selectedTheme = themes.find(theme => theme.id === currentThemeId); return ( { colorNeutralBackgroundInvertedDisabled: whiteAlpha[10], colorNeutralStencil1: palette.neutralLight, colorNeutralStencil2: palette.neutralLighterAlt, - colorBackgroundOverlay: blackAlpha[10], + colorNeutralStencil1Alpha: inverted ? whiteAlpha[10] : blackAlpha[10], + colorNeutralStencil2Alpha: inverted ? whiteAlpha[5] : blackAlpha[5], + colorBackgroundOverlay: blackAlpha[40], colorScrollbarOverlay: blackAlpha[50], colorBrandBackground: palette.themePrimary, colorBrandBackgroundHover: palette.themeDarkAlt, diff --git a/apps/public-docsite-v9/tsconfig.json b/apps/public-docsite-v9/tsconfig.json index c787b45098766..cc35ba4818249 100644 --- a/apps/public-docsite-v9/tsconfig.json +++ b/apps/public-docsite-v9/tsconfig.json @@ -15,7 +15,7 @@ "moduleResolution": "node", "preserveConstEnums": true, "skipLibCheck": true, - "types": ["webpack-env", "@storybook/react", "screener-storybook"] + "types": ["webpack-env", "@storybook/react"] }, "include": ["src"] } diff --git a/apps/public-docsite/just.config.ts b/apps/public-docsite/just.config.ts index bcc7d9d264037..b10db31a6aca5 100644 --- a/apps/public-docsite/just.config.ts +++ b/apps/public-docsite/just.config.ts @@ -1,3 +1,3 @@ -import { preset } from '@fluentui/scripts'; +import { preset } from '@fluentui/scripts-tasks'; preset(); diff --git a/apps/public-docsite/package.json b/apps/public-docsite/package.json index 94aeffd98d011..9c670a29cd697 100644 --- a/apps/public-docsite/package.json +++ b/apps/public-docsite/package.json @@ -23,27 +23,29 @@ }, "license": "MIT", "devDependencies": { - "@fluentui/common-styles": "^1.2.11", + "@fluentui/common-styles": "^1.2.17", "@fluentui/eslint-plugin": "*", - "@fluentui/react-monaco-editor": "^1.7.18", - "@fluentui/scripts": "^1.0.0", - "write-file-webpack-plugin": "^4.1.0" + "@fluentui/react-monaco-editor": "^1.7.53", + "write-file-webpack-plugin": "^4.1.0", + "@fluentui/scripts-tasks": "*", + "@fluentui/scripts-webpack": "*" }, "dependencies": { - "@fluentui/font-icons-mdl2": "^8.5.2", + "@fluentui/font-icons-mdl2": "^8.5.8", "@fluentui/public-docsite-resources": "^8.1.41", - "@fluentui/public-docsite-setup": "^0.3.12", - "@fluentui/react": "^8.99.0", - "@fluentui/react-docsite-components": "^8.10.18", + "@fluentui/public-docsite-setup": "^0.3.17", + "@fluentui/react": "^8.105.6", + "@fluentui/react-docsite-components": "^8.11.18", "@fluentui/react-examples": "^8.34.4", - "@fluentui/react-experiments": "^8.14.13", - "@fluentui/react-file-type-icons": "^8.8.0", - "@fluentui/react-icons-mdl2": "^1.3.25", - "@fluentui/react-icons-mdl2-branded": "^1.2.26", - "@fluentui/set-version": "^8.2.2", - "@fluentui/theme": "^2.6.17", - "@fluentui/theme-samples": "^8.7.18", - "@fluentui/utilities": "^8.13.2", + "@fluentui/react-experiments": "^8.14.48", + "@fluentui/fluent2-theme": "^8.104.20", + "@fluentui/react-file-type-icons": "^8.8.8", + "@fluentui/react-icons-mdl2": "^1.3.31", + "@fluentui/react-icons-mdl2-branded": "^1.2.32", + "@fluentui/set-version": "^8.2.5", + "@fluentui/theme": "^2.6.22", + "@fluentui/theme-samples": "^8.7.53", + "@fluentui/utilities": "^8.13.6", "@microsoft/load-themed-styles": "^1.10.26", "office-ui-fabric-core": "^11.0.0", "react": "17.0.2", diff --git a/apps/public-docsite/src/SiteDefinition/SiteDefinition.pages/Controls/cross.tsx b/apps/public-docsite/src/SiteDefinition/SiteDefinition.pages/Controls/cross.tsx index f86d6a1ea57c9..a20920e96625b 100644 --- a/apps/public-docsite/src/SiteDefinition/SiteDefinition.pages/Controls/cross.tsx +++ b/apps/public-docsite/src/SiteDefinition/SiteDefinition.pages/Controls/cross.tsx @@ -4,7 +4,7 @@ import { INavPage, LoadingComponent } from '@fluentui/react-docsite-components/l export const controlsPagesCrossPlatform: INavPage[] = [ { title: 'Controls', - url: '#/controls/crossplatform', + url: '#/controls/cross', isHiddenFromMainNav: true, component: () => , getComponent: cb => @@ -18,14 +18,14 @@ export const controlsPagesCrossPlatform: INavPage[] = [ pages: [ { title: 'Button', - url: '#/controls/crossplatform/button', + url: '#/controls/cross/button', component: () => , getComponent: cb => require.ensure([], require => cb(require('../../../pages/Controls/ButtonPage/ButtonPage').ButtonPage)), }, { title: 'Link', - url: '#/controls/crossplatform/link', + url: '#/controls/cross/link', component: () => , getComponent: cb => require.ensure([], require => cb(require('../../../pages/Controls/LinkPage/LinkPage').LinkPage)), @@ -38,7 +38,7 @@ export const controlsPagesCrossPlatform: INavPage[] = [ pages: [ { title: 'Persona', - url: '#/controls/crossplatform/persona', + url: '#/controls/cross/persona', component: () => , getComponent: cb => require.ensure([], require => @@ -53,14 +53,14 @@ export const controlsPagesCrossPlatform: INavPage[] = [ pages: [ { title: 'Text', - url: '#/controls/crossplatform/text', + url: '#/controls/cross/text', component: () => , getComponent: cb => require.ensure([], require => cb(require('../../../pages/Controls/TextPage/TextPage').TextPage)), }, { title: 'Separator', - url: '#/controls/crossplatform/separator', + url: '#/controls/cross/separator', component: () => , getComponent: cb => require.ensure([], require => diff --git a/apps/public-docsite/src/SiteDefinition/SiteDefinition.pages/Controls/web.tsx b/apps/public-docsite/src/SiteDefinition/SiteDefinition.pages/Controls/web.tsx index eb6e827c923ac..43ecb10e92b00 100644 --- a/apps/public-docsite/src/SiteDefinition/SiteDefinition.pages/Controls/web.tsx +++ b/apps/public-docsite/src/SiteDefinition/SiteDefinition.pages/Controls/web.tsx @@ -12,7 +12,7 @@ export interface ICategory { // Exporting this object to be used in generating a TOC (table of content) for docs.microsoft documentation repo. // Any changes to this object need to be communicated to avoid accidental breaking of the documentation // and to allow the appropriate actions to be taken to mitigate this. -export const categories: { Other?: ICategory; [name: string]: ICategory } = { +export const categories: { [name: string]: ICategory } = { 'Basic Inputs': { Button: {}, Checkbox: {}, @@ -58,6 +58,8 @@ export const categories: { Other?: ICategory; [name: string]: ICategory } = { Compact: {}, Grouped: {}, LargeGrouped: { title: 'Large Grouped' }, + GroupedV2: { title: 'Grouped V2' }, + LargeGroupedV2: { title: 'Large Grouped V2' }, CustomColumns: { title: 'Custom Item Columns', url: 'customitemcolumns' }, CustomRows: { title: 'Custom Item Rows', url: 'customitemrows' }, CustomFooter: { title: 'Custom Footer' }, diff --git a/apps/public-docsite/src/SiteDefinition/SiteDefinition.pages/GetStarted/GetStarted.pages.tsx b/apps/public-docsite/src/SiteDefinition/SiteDefinition.pages/GetStarted/GetStarted.pages.tsx index adc8c64b341b2..13b999f220d83 100644 --- a/apps/public-docsite/src/SiteDefinition/SiteDefinition.pages/GetStarted/GetStarted.pages.tsx +++ b/apps/public-docsite/src/SiteDefinition/SiteDefinition.pages/GetStarted/GetStarted.pages.tsx @@ -87,7 +87,7 @@ export const GetStartedPages: INavPage = { cross: [ { title: 'Get started', - url: '#/get-started/crossplatform', + url: '#/get-started/cross', isHiddenFromMainNav: true, component: () => , getComponent: cb => diff --git a/apps/public-docsite/src/SiteDefinition/SiteDefinition.pages/Styles/web.tsx b/apps/public-docsite/src/SiteDefinition/SiteDefinition.pages/Styles/web.tsx index 45431a0609419..6e4743de73a51 100644 --- a/apps/public-docsite/src/SiteDefinition/SiteDefinition.pages/Styles/web.tsx +++ b/apps/public-docsite/src/SiteDefinition/SiteDefinition.pages/Styles/web.tsx @@ -122,12 +122,12 @@ export const stylesPagesWeb: INavPage[] = [ // getComponent: cb => require.ensure([], require => cb(require('../../../pages/Styles/IconsPage/IconsPage').IconsPage)) // }, { - title: 'Office Brand Icons', - url: '#/styles/web/office-brand-icons', - component: () => , + title: 'M365 Product Icons', + url: '#/styles/web/m365-product-icons', + component: () => , getComponent: cb => require.ensure([], require => - cb(require('../../../pages/Styles/OfficeBrandIconsPage/OfficeBrandIconsPage').OfficeBrandIconsPage), + cb(require('../../../pages/Styles/M365ProductIconsPage/M365ProductIconsPage').M365ProductIconsPage), ), }, { diff --git a/apps/public-docsite/src/SiteDefinition/SiteDefinition.tsx b/apps/public-docsite/src/SiteDefinition/SiteDefinition.tsx index b77be715b3bce..3948ae4db1fa8 100644 --- a/apps/public-docsite/src/SiteDefinition/SiteDefinition.tsx +++ b/apps/public-docsite/src/SiteDefinition/SiteDefinition.tsx @@ -3,14 +3,14 @@ import { ISiteDefinition, LoadingComponent } from '@fluentui/react-docsite-compo import { ControlsPages, ResourcesPages, StylesPages, GetStartedPages } from './SiteDefinition.pages/index'; import { Platforms } from '../interfaces/Platforms'; import { platforms } from './SiteDefinition.platforms'; +import { cdnUrl } from '../utilities/cdn'; import { SiteGlobals } from '@fluentui/public-docsite-setup'; declare const window: Window & SiteGlobals; export const SiteDefinition: ISiteDefinition = { siteTitle: 'Fluent UI', - siteLogoSource: - 'https://static2.sharepointonline.com/files/fabric/fabric-website/images/microsoftfluentui-logo-rgb_no-padding.svg', + siteLogoSource: `${cdnUrl}/fabric-website/images/microsoftfluentui-logo-rgb_no-padding.svg`, platforms, pages: [ { @@ -49,7 +49,8 @@ export const SiteDefinition: ISiteDefinition = { { from: '#/examples/announced/', to: '#/controls/web/announced/' }, { from: /#\/components/, to: '#/controls/web' }, { from: '#/styles/animation', to: '#/styles/web/motion' }, - { from: '#/styles/brand-icons', to: '#/styles/web/office-brand-icons' }, + { from: '#/styles/brand-icons', to: '#/styles/web/m365-product-icons' }, + { from: '#/styles/web/office-brand-icons', to: '#/styles/web/m365-product-icons' }, { from: '#/styles/colors', to: '#/styles/web/colors/theme-slots' }, { from: '#/styles/icons', to: '#/styles/web/icons' }, { from: '#/styles/layout', to: '#/styles/web/layout' }, diff --git a/apps/public-docsite/src/components/IconGrid/IconGrid.tsx b/apps/public-docsite/src/components/IconGrid/IconGrid.tsx index fcd3304a39949..d818ecb1637e5 100644 --- a/apps/public-docsite/src/components/IconGrid/IconGrid.tsx +++ b/apps/public-docsite/src/components/IconGrid/IconGrid.tsx @@ -161,7 +161,7 @@ export class IconGrid extends React.Component { private _onSearchQueryChanged: ISearchBoxProps['onChange'] = (ev, newValue) => { this.setState({ - searchQuery: newValue, + searchQuery: newValue!, }); }; } diff --git a/apps/public-docsite/src/components/Nav/Nav.tsx b/apps/public-docsite/src/components/Nav/Nav.tsx index e66290ddd2869..d710cffb1f30e 100644 --- a/apps/public-docsite/src/components/Nav/Nav.tsx +++ b/apps/public-docsite/src/components/Nav/Nav.tsx @@ -155,11 +155,11 @@ export class Nav extends React.Component {
  • {page.title.toLowerCase().indexOf(searchQuery) !== -1 && ( diff --git a/apps/public-docsite/src/components/Site/AppThemes.ts b/apps/public-docsite/src/components/Site/AppThemes.ts index 9ef4a608c42b7..ee1f28c9069c9 100644 --- a/apps/public-docsite/src/components/Site/AppThemes.ts +++ b/apps/public-docsite/src/components/Site/AppThemes.ts @@ -1,9 +1,12 @@ import { DefaultTheme, DarkTheme } from '@fluentui/theme-samples'; +import { Fluent2WebLightTheme, Fluent2WebDarkTheme } from '@fluentui/fluent2-theme'; import { IAppThemes, IExampleCardTheme } from '@fluentui/react-docsite-components'; const exampleCardTheme: IExampleCardTheme[] = [ { title: 'Default', theme: DefaultTheme }, { title: 'Dark', theme: DarkTheme }, + { title: 'Fluent 2 Web Light', theme: Fluent2WebLightTheme }, + { title: 'Fluent 2 Web Dark', theme: Fluent2WebDarkTheme }, ]; export const AppThemes: IAppThemes = { diff --git a/apps/public-docsite/src/components/Site/Site.tsx b/apps/public-docsite/src/components/Site/Site.tsx index 8e38e0ae4b5c5..f26e9c958e7cc 100644 --- a/apps/public-docsite/src/components/Site/Site.tsx +++ b/apps/public-docsite/src/components/Site/Site.tsx @@ -96,7 +96,7 @@ export class Site extends React.Component< let platform = 'default' as TPlatforms; // If current page doesn't have pages for the active platform, switch to its first platform. - if (Object.keys(navData.pagePlatforms).length > 0 && navData.activePages.length === 0) { + if (Object.keys(navData.pagePlatforms!).length > 0 && navData.activePages!.length === 0) { const firstPlatform = getPageFirstPlatform(getSiteArea(siteDefinition.pages), siteDefinition); const currentPage = getSiteArea(siteDefinition.pages); platform = firstPlatform; @@ -142,7 +142,7 @@ export class Site extends React.Component< const { siteDefinition } = this.props; // If current page doesn't have pages for the active platform, switch to its first platform. - if (Object.keys(pagePlatforms).length > 0 && activePages.length === 0) { + if (Object.keys(pagePlatforms!).length > 0 && activePages!.length === 0) { const firstPlatform = getPageFirstPlatform(getSiteArea(siteDefinition.pages), siteDefinition); this._onPlatformChanged(firstPlatform); } @@ -347,22 +347,19 @@ export class Site extends React.Component< return null; }; - private _renderPlatformBar = (): JSX.Element | undefined => { + private _renderPlatformBar = (): JSX.Element | null => { const { siteDefinition } = this.props; const { platform, pagePlatforms, hasPlatformPicker } = this.state; - return ( - hasPlatformPicker && - Object.keys(pagePlatforms).length > 0 && ( - - ) - ); + return hasPlatformPicker && Object.keys(pagePlatforms!).length > 0 ? ( + + ) : null; }; /** @@ -500,7 +497,7 @@ export class Site extends React.Component< document.title = [ siteDefinition.siteTitle, siteArea, - currPlatform && platforms[currPlatform]?.name, + currPlatform && platforms![currPlatform]?.name, activePageName !== siteArea && activePageName, ] .filter(Boolean) @@ -531,7 +528,7 @@ export class Site extends React.Component< this._jumpInterval = this._async.setInterval(() => { const el = document.getElementById(anchor); if (el || Date.now() - start > 1000) { - this._async.clearInterval(this._jumpInterval); + this._async.clearInterval(this._jumpInterval!); this._jumpInterval = undefined; if (el) { jumpToAnchor(anchor); diff --git a/apps/public-docsite/src/components/Table/Table.tsx b/apps/public-docsite/src/components/Table/Table.tsx index f8ce5d148b5a9..4f7b68c822c78 100644 --- a/apps/public-docsite/src/components/Table/Table.tsx +++ b/apps/public-docsite/src/components/Table/Table.tsx @@ -59,7 +59,7 @@ export class Table extends React.Component { ) : ( // eslint-disable-next-line react/no-danger - + ); } diff --git a/apps/public-docsite/src/data/brand-icons-monochrome.json b/apps/public-docsite/src/data/brand-icons-monochrome.json deleted file mode 100644 index 5dceb8bb64703..0000000000000 --- a/apps/public-docsite/src/data/brand-icons-monochrome.json +++ /dev/null @@ -1,38 +0,0 @@ -[ - { "name": "AADLogo" }, - { "name": "AccessLogo" }, - { "name": "ATPLogo" }, - { "name": "AzureLogo" }, - { "name": "BingLogo" }, - { "name": "BookingsLogo" }, - { "name": "ClassroomLogo" }, - { "name": "DelveAnalyticsLogo" }, - { "name": "DelveLogo" }, - { "name": "DynamicSMBLogo" }, - { "name": "EdgeLogo" }, - { "name": "ExcelDocument" }, - { "name": "ExcelLogo" }, - { "name": "ExchangeLogo" }, - { "name": "LyncLogo" }, - { "name": "MSNLogo" }, - { "name": "OfficeAssistantLogo" }, - { "name": "OfficeLogo" }, - { "name": "OfficeStoreLogo" }, - { "name": "OfficeVideoLogo" }, - { "name": "OneDrive" }, - { "name": "OneNoteLogo" }, - { "name": "OutlookLogo" }, - { "name": "PowerBILogo" }, - { "name": "PowerPointDocument" }, - { "name": "PowerPointLogo" }, - { "name": "SharepointLogo" }, - { "name": "SkypeLogo" }, - { "name": "SocialListeningLogo" }, - { "name": "StoreLogo" }, - { "name": "StoreLogoMed" }, - { "name": "VisioLogo" }, - { "name": "WindowsLogo" }, - { "name": "WordDocument" }, - { "name": "WordLogo" }, - { "name": "YammerLogo" } -] diff --git a/apps/public-docsite/src/data/brand-icons-products.json b/apps/public-docsite/src/data/brand-icons-products.json deleted file mode 100644 index 4e60d542186d2..0000000000000 --- a/apps/public-docsite/src/data/brand-icons-products.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { "icon": "outlook", "name": "Outlook" }, - { "icon": "onedrive", "name": "OneDrive" }, - { "icon": "word", "name": "Word" }, - { "icon": "excel", "name": "Excel" }, - { "icon": "powerpoint", "name": "PowerPoint" }, - { "icon": "onenote", "name": "OneNote" }, - { "icon": "sharepoint", "name": "SharePoint" }, - { "icon": "teams", "name": "Microsoft Teams" }, - { "icon": "office", "name": "Office" }, - { "icon": "access", "name": "Access" }, - { "icon": "delve", "name": "Delve" }, - { "icon": "forms", "name": "Microsoft Forms" }, - { "icon": "project", "name": "Project" }, - { "icon": "sway", "name": "Sway" }, - { "icon": "visio", "name": "Visio" } -] diff --git a/apps/public-docsite/src/data/brand-icons-documents.json b/apps/public-docsite/src/data/product-icons-documents.json similarity index 100% rename from apps/public-docsite/src/data/brand-icons-documents.json rename to apps/public-docsite/src/data/product-icons-documents.json diff --git a/apps/public-docsite/src/data/product-icons.json b/apps/public-docsite/src/data/product-icons.json new file mode 100644 index 0000000000000..2e82333585ee7 --- /dev/null +++ b/apps/public-docsite/src/data/product-icons.json @@ -0,0 +1,17 @@ +[ + { "icon": "outlook", "name": "Outlook" }, + { "icon": "onedrive", "name": "OneDrive" }, + { "icon": "word", "name": "Word" }, + { "icon": "excel", "name": "Excel" }, + { "icon": "powerpoint", "name": "PowerPoint" }, + { "icon": "onenote", "name": "OneNote" }, + { "icon": "sharepoint", "name": "SharePoint" }, + { "icon": "teams", "name": "Microsoft Teams" }, + { "icon": "m365", "name": "Microsoft 365" }, + { "icon": "access", "name": "Access" }, + { "icon": "delve", "name": "Delve" }, + { "icon": "forms", "name": "Microsoft Forms" }, + { "icon": "project", "name": "Project" }, + { "icon": "sway", "name": "Sway" }, + { "icon": "visio", "name": "Visio" } +] diff --git a/apps/public-docsite/src/pages/Controls/ActivityItemPage/ActivityItemPage.tsx b/apps/public-docsite/src/pages/Controls/ActivityItemPage/ActivityItemPage.tsx index af00032ebdea6..b7699fe154765 100644 --- a/apps/public-docsite/src/pages/Controls/ActivityItemPage/ActivityItemPage.tsx +++ b/apps/public-docsite/src/pages/Controls/ActivityItemPage/ActivityItemPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { ActivityItemPageProps } from './ActivityItemPage.doc'; export const ActivityItemPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/AnnouncedPage/AnnouncedBulkOperationsPage.tsx b/apps/public-docsite/src/pages/Controls/AnnouncedPage/AnnouncedBulkOperationsPage.tsx index b09f9bd52ab6c..64048b9d3aaf4 100644 --- a/apps/public-docsite/src/pages/Controls/AnnouncedPage/AnnouncedBulkOperationsPage.tsx +++ b/apps/public-docsite/src/pages/Controls/AnnouncedPage/AnnouncedBulkOperationsPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { AnnouncedBulkOperationsPageProps } from './AnnouncedBulkOperationsPage.doc'; export const AnnouncedBulkOperationsPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/AnnouncedPage/AnnouncedLazyLoadingPage.tsx b/apps/public-docsite/src/pages/Controls/AnnouncedPage/AnnouncedLazyLoadingPage.tsx index 370eef01bdcbd..348bb3371334b 100644 --- a/apps/public-docsite/src/pages/Controls/AnnouncedPage/AnnouncedLazyLoadingPage.tsx +++ b/apps/public-docsite/src/pages/Controls/AnnouncedPage/AnnouncedLazyLoadingPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { AnnouncedLazyLoadingPageProps } from './AnnouncedLazyLoadingPage.doc'; export const AnnouncedLazyLoadingPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/AnnouncedPage/AnnouncedPage.tsx b/apps/public-docsite/src/pages/Controls/AnnouncedPage/AnnouncedPage.tsx index b3dbb46e03f69..0d0b5769a2085 100644 --- a/apps/public-docsite/src/pages/Controls/AnnouncedPage/AnnouncedPage.tsx +++ b/apps/public-docsite/src/pages/Controls/AnnouncedPage/AnnouncedPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { AnnouncedPageProps } from './AnnouncedPage.doc'; export const AnnouncedPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/AnnouncedPage/AnnouncedQuickActionsPage.tsx b/apps/public-docsite/src/pages/Controls/AnnouncedPage/AnnouncedQuickActionsPage.tsx index 1209b2617055e..bf2faacbd5be0 100644 --- a/apps/public-docsite/src/pages/Controls/AnnouncedPage/AnnouncedQuickActionsPage.tsx +++ b/apps/public-docsite/src/pages/Controls/AnnouncedPage/AnnouncedQuickActionsPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { AnnouncedQuickActionsPageProps } from './AnnouncedQuickActionsPage.doc'; export const AnnouncedQuickActionsPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/AnnouncedPage/AnnouncedSearchResultsPage.tsx b/apps/public-docsite/src/pages/Controls/AnnouncedPage/AnnouncedSearchResultsPage.tsx index 48a79fc71f5c6..1ef8228e28739 100644 --- a/apps/public-docsite/src/pages/Controls/AnnouncedPage/AnnouncedSearchResultsPage.tsx +++ b/apps/public-docsite/src/pages/Controls/AnnouncedPage/AnnouncedSearchResultsPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { AnnouncedSearchResultsPageProps } from './AnnouncedSearchResultsPage.doc'; export const AnnouncedSearchResultsPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/AvatarPage/AvatarPage.tsx b/apps/public-docsite/src/pages/Controls/AvatarPage/AvatarPage.tsx index d054547095b59..d7fb6a7312417 100644 --- a/apps/public-docsite/src/pages/Controls/AvatarPage/AvatarPage.tsx +++ b/apps/public-docsite/src/pages/Controls/AvatarPage/AvatarPage.tsx @@ -12,13 +12,13 @@ export const AvatarPage: React.FunctionComponent = props => ); }; -function _otherSections(platform: Platforms): IPageSectionProps[] { +function _otherSections(platform: Platforms): IPageSectionProps[] | undefined { switch (platform) { case 'ios': return [ diff --git a/apps/public-docsite/src/pages/Controls/AvatarPage/docs/android/AvatarOverview.md b/apps/public-docsite/src/pages/Controls/AvatarPage/docs/android/AvatarOverview.md index 248759a1a0d24..58d2d745153bd 100644 --- a/apps/public-docsite/src/pages/Controls/AvatarPage/docs/android/AvatarOverview.md +++ b/apps/public-docsite/src/pages/Controls/AvatarPage/docs/android/AvatarOverview.md @@ -3,17 +3,17 @@ ### Initials - - + + ### Profile - - + + ### Group - - + + diff --git a/apps/public-docsite/src/pages/Controls/AvatarPage/docs/ios/AvatarOverview.md b/apps/public-docsite/src/pages/Controls/AvatarPage/docs/ios/AvatarOverview.md index 94f167ef1f30b..8f407ce30c85d 100644 --- a/apps/public-docsite/src/pages/Controls/AvatarPage/docs/ios/AvatarOverview.md +++ b/apps/public-docsite/src/pages/Controls/AvatarPage/docs/ios/AvatarOverview.md @@ -3,17 +3,17 @@ ### Initials - - + + ### Profile - - + + ### Group - - + + diff --git a/apps/public-docsite/src/pages/Controls/AvatarPage/docs/mac/AvatarUsage.md b/apps/public-docsite/src/pages/Controls/AvatarPage/docs/mac/AvatarUsage.md index ab69896b815b0..acbc55449c34f 100644 --- a/apps/public-docsite/src/pages/Controls/AvatarPage/docs/mac/AvatarUsage.md +++ b/apps/public-docsite/src/pages/Controls/AvatarPage/docs/mac/AvatarUsage.md @@ -8,8 +8,8 @@ To determine initials for an avatar, the code initially tries to extract two-let AvatarView(avatarSize: size, contactName: "Amanda Brady", contactEmail: "Amanda.Brady@example.com", contactImage: nil) ``` - - + + ### Profile @@ -18,7 +18,7 @@ AvatarView(avatarSize: size, contactName: "Amanda Brady", contactEmail: "Amanda. AvatarView(avatarSize: size, contactName: "Amanda Brady", contactEmail: "Amanda.Brady@example.com", contactImage: NSImage(named: "Amanda")) ``` - - + + diff --git a/apps/public-docsite/src/pages/Controls/BottomNavigationPage/BottomNavigationPage.tsx b/apps/public-docsite/src/pages/Controls/BottomNavigationPage/BottomNavigationPage.tsx index 6b457f19b2987..0336f1855dc15 100644 --- a/apps/public-docsite/src/pages/Controls/BottomNavigationPage/BottomNavigationPage.tsx +++ b/apps/public-docsite/src/pages/Controls/BottomNavigationPage/BottomNavigationPage.tsx @@ -11,7 +11,7 @@ export const BottomNavigationPage: React.FunctionComponent = return ( ); diff --git a/apps/public-docsite/src/pages/Controls/BottomNavigationPage/docs/android/BottomNavigationOverview.md b/apps/public-docsite/src/pages/Controls/BottomNavigationPage/docs/android/BottomNavigationOverview.md index 7cf0ae6810e19..0758a1a8d327f 100644 --- a/apps/public-docsite/src/pages/Controls/BottomNavigationPage/docs/android/BottomNavigationOverview.md +++ b/apps/public-docsite/src/pages/Controls/BottomNavigationPage/docs/android/BottomNavigationOverview.md @@ -3,6 +3,6 @@ The bottom navigation displays icons and optional text at the bottom of the scre ### Bottom Navigation - - + + diff --git a/apps/public-docsite/src/pages/Controls/BottomNavigationPage/docs/ios/BottomNavigationOverview.md b/apps/public-docsite/src/pages/Controls/BottomNavigationPage/docs/ios/BottomNavigationOverview.md index 918557d9a5e34..05fe0d8641776 100644 --- a/apps/public-docsite/src/pages/Controls/BottomNavigationPage/docs/ios/BottomNavigationOverview.md +++ b/apps/public-docsite/src/pages/Controls/BottomNavigationPage/docs/ios/BottomNavigationOverview.md @@ -5,13 +5,13 @@ The tab bar displays tabs at the bottom of the window for switching between diff ### Portrait - - + + ### Landscape - - + + diff --git a/apps/public-docsite/src/pages/Controls/BottomSheetPage/BottomSheetPage.tsx b/apps/public-docsite/src/pages/Controls/BottomSheetPage/BottomSheetPage.tsx index 783769100cb1a..4a16202d5d81d 100644 --- a/apps/public-docsite/src/pages/Controls/BottomSheetPage/BottomSheetPage.tsx +++ b/apps/public-docsite/src/pages/Controls/BottomSheetPage/BottomSheetPage.tsx @@ -13,13 +13,13 @@ export const BottomSheetPage: React.FunctionComponent = prop ); }; -function _otherSections(platform: Platforms): IPageSectionProps[] { +function _otherSections(platform: Platforms): IPageSectionProps[] | undefined { switch (platform) { case 'android': return [ diff --git a/apps/public-docsite/src/pages/Controls/BottomSheetPage/docs/android/BottomSheetOverview.md b/apps/public-docsite/src/pages/Controls/BottomSheetPage/docs/android/BottomSheetOverview.md index 4f456a188a382..33fb1b83f89a7 100644 --- a/apps/public-docsite/src/pages/Controls/BottomSheetPage/docs/android/BottomSheetOverview.md +++ b/apps/public-docsite/src/pages/Controls/BottomSheetPage/docs/android/BottomSheetOverview.md @@ -3,6 +3,6 @@ ### BottomSheet - - + + diff --git a/apps/public-docsite/src/pages/Controls/BreadcrumbPage/BreadcrumbPage.tsx b/apps/public-docsite/src/pages/Controls/BreadcrumbPage/BreadcrumbPage.tsx index 5146f6ed1481a..c9f6e4a9f561c 100644 --- a/apps/public-docsite/src/pages/Controls/BreadcrumbPage/BreadcrumbPage.tsx +++ b/apps/public-docsite/src/pages/Controls/BreadcrumbPage/BreadcrumbPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { BreadcrumbPageProps } from './BreadcrumbPage.doc'; export const BreadcrumbPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/ButtonPage/ButtonPage.tsx b/apps/public-docsite/src/pages/Controls/ButtonPage/ButtonPage.tsx index 553c49b4cede5..ae23594c4a61b 100644 --- a/apps/public-docsite/src/pages/Controls/ButtonPage/ButtonPage.tsx +++ b/apps/public-docsite/src/pages/Controls/ButtonPage/ButtonPage.tsx @@ -58,14 +58,14 @@ export class ButtonPage extends React.Component< ); } - private _otherSections(platform: Platforms): IPageSectionProps[] { + private _otherSections(platform: Platforms): IPageSectionProps[] | undefined { switch (platform) { case 'ios': return [ diff --git a/apps/public-docsite/src/pages/Controls/ButtonPage/docs/android/ButtonOverview.md b/apps/public-docsite/src/pages/Controls/ButtonPage/docs/android/ButtonOverview.md index 3dbb25424c65b..b7f0cff76daad 100644 --- a/apps/public-docsite/src/pages/Controls/ButtonPage/docs/android/ButtonOverview.md +++ b/apps/public-docsite/src/pages/Controls/ButtonPage/docs/android/ButtonOverview.md @@ -3,12 +3,12 @@ Buttons are one of the core controls that make an app feel native to the platfor ### Primary Filled - - + + ### Borderless Button - - + + diff --git a/apps/public-docsite/src/pages/Controls/ButtonPage/docs/cross/ButtonOverview.md b/apps/public-docsite/src/pages/Controls/ButtonPage/docs/cross/ButtonOverview.md index 18f018d697f2a..066f112fc24c3 100644 --- a/apps/public-docsite/src/pages/Controls/ButtonPage/docs/cross/ButtonOverview.md +++ b/apps/public-docsite/src/pages/Controls/ButtonPage/docs/cross/ButtonOverview.md @@ -1,5 +1,5 @@ Buttons are best used to enable a user to commit a change or complete steps in a task. They are typically found inside forms, dialogs, panels or pages. An example of their usage is confirming the deletion of a file in a confirmation dialog. -When considering their place in a layout, contemplate the order in which a user will flow through the UI. As an example, in a form, the individual will need to read and interact with the form fields before submiting the form. Therefore, as a general rule, the button should be placed at the bottom of the UI container (a dialog, panel, or page) which holds the related UI elements. +When considering their place in a layout, contemplate the order in which a user will flow through the UI. As an example, in a form, the individual will need to read and interact with the form fields before submitting the form. Therefore, as a general rule, the button should be placed at the bottom of the UI container (a dialog, panel, or page) which holds the related UI elements. While buttons can technically be used to navigate a user to another part of the experience, this is not recommended unless that navigation is part of an action or their flow. diff --git a/apps/public-docsite/src/pages/Controls/ButtonPage/docs/cross/ButtonUsage.md b/apps/public-docsite/src/pages/Controls/ButtonPage/docs/cross/ButtonUsage.md index 979ee3d9fef55..3a52ee13ce924 100644 --- a/apps/public-docsite/src/pages/Controls/ButtonPage/docs/cross/ButtonUsage.md +++ b/apps/public-docsite/src/pages/Controls/ButtonPage/docs/cross/ButtonUsage.md @@ -4,19 +4,19 @@ Fluent UI React Native Buttons have default styling based on the Fluent UI Desig #### Default Button (Windows) - + #### Primary Button (Windows) - + #### Default Button (macOS) - + #### Primary Button (macOS) - + #### Example usage (from [ButtonFocusTest.tsx](https://github.com/microsoft/fluentui-react-native/blob/master/apps/fluent-tester/src/FluentTester/TestComponents/Button/ButtonFocusTest.tsx)) diff --git a/apps/public-docsite/src/pages/Controls/ButtonPage/docs/ios/ButtonOverview.md b/apps/public-docsite/src/pages/Controls/ButtonPage/docs/ios/ButtonOverview.md index 3681b7a819517..b6a780b2eef66 100644 --- a/apps/public-docsite/src/pages/Controls/ButtonPage/docs/ios/ButtonOverview.md +++ b/apps/public-docsite/src/pages/Controls/ButtonPage/docs/ios/ButtonOverview.md @@ -3,22 +3,22 @@ Buttons are one of the core controls that make an app feel native to the platfor ### Primary Filled - - + + ### Primary Outlined - - + + ### Secondary Outlined - - + + ### Tertiary Outlined - - + + diff --git a/apps/public-docsite/src/pages/Controls/ButtonPage/docs/mac/ButtonOverview.md b/apps/public-docsite/src/pages/Controls/ButtonPage/docs/mac/ButtonOverview.md index a2d2f65bbc51d..dc4ff10899103 100644 --- a/apps/public-docsite/src/pages/Controls/ButtonPage/docs/mac/ButtonOverview.md +++ b/apps/public-docsite/src/pages/Controls/ButtonPage/docs/mac/ButtonOverview.md @@ -3,17 +3,17 @@ Buttons give people a way to trigger an action. They're typically found in windo ### Primary filled - - + + ### Primary outlined - - + + ### Borderless - - + + diff --git a/apps/public-docsite/src/pages/Controls/ButtonPage/docs/windows/ButtonOverview.md b/apps/public-docsite/src/pages/Controls/ButtonPage/docs/windows/ButtonOverview.md index 18f018d697f2a..066f112fc24c3 100644 --- a/apps/public-docsite/src/pages/Controls/ButtonPage/docs/windows/ButtonOverview.md +++ b/apps/public-docsite/src/pages/Controls/ButtonPage/docs/windows/ButtonOverview.md @@ -1,5 +1,5 @@ Buttons are best used to enable a user to commit a change or complete steps in a task. They are typically found inside forms, dialogs, panels or pages. An example of their usage is confirming the deletion of a file in a confirmation dialog. -When considering their place in a layout, contemplate the order in which a user will flow through the UI. As an example, in a form, the individual will need to read and interact with the form fields before submiting the form. Therefore, as a general rule, the button should be placed at the bottom of the UI container (a dialog, panel, or page) which holds the related UI elements. +When considering their place in a layout, contemplate the order in which a user will flow through the UI. As an example, in a form, the individual will need to read and interact with the form fields before submitting the form. Therefore, as a general rule, the button should be placed at the bottom of the UI container (a dialog, panel, or page) which holds the related UI elements. While buttons can technically be used to navigate a user to another part of the experience, this is not recommended unless that navigation is part of an action or their flow. diff --git a/apps/public-docsite/src/pages/Controls/CalendarPage/CalendarPage.tsx b/apps/public-docsite/src/pages/Controls/CalendarPage/CalendarPage.tsx index 019c578045209..06c3daa7e1b94 100644 --- a/apps/public-docsite/src/pages/Controls/CalendarPage/CalendarPage.tsx +++ b/apps/public-docsite/src/pages/Controls/CalendarPage/CalendarPage.tsx @@ -13,13 +13,13 @@ export const CalendarPage: React.FunctionComponent = props = ); }; -function _otherSections(platform: Platforms): IPageSectionProps[] { +function _otherSections(platform: Platforms): IPageSectionProps[] | undefined { switch (platform) { case 'android': return [ diff --git a/apps/public-docsite/src/pages/Controls/CalendarPage/docs/android/CalendarOverview.md b/apps/public-docsite/src/pages/Controls/CalendarPage/docs/android/CalendarOverview.md index 49a4af4da073d..0b91e54f138f0 100644 --- a/apps/public-docsite/src/pages/Controls/CalendarPage/docs/android/CalendarOverview.md +++ b/apps/public-docsite/src/pages/Controls/CalendarPage/docs/android/CalendarOverview.md @@ -3,7 +3,7 @@ The `CalendarView` is used to display calendar dates and to allow a user to sele ### Calendar - - + + diff --git a/apps/public-docsite/src/pages/Controls/CalloutPage/CalloutPage.tsx b/apps/public-docsite/src/pages/Controls/CalloutPage/CalloutPage.tsx index 701eb549ed441..9565d478a31b8 100644 --- a/apps/public-docsite/src/pages/Controls/CalloutPage/CalloutPage.tsx +++ b/apps/public-docsite/src/pages/Controls/CalloutPage/CalloutPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { CalloutPageProps } from './CalloutPage.doc'; export const CalloutPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/CheckboxPage/CheckboxPage.tsx b/apps/public-docsite/src/pages/Controls/CheckboxPage/CheckboxPage.tsx index d79b3a2e24b8e..6ec99fcb70265 100644 --- a/apps/public-docsite/src/pages/Controls/CheckboxPage/CheckboxPage.tsx +++ b/apps/public-docsite/src/pages/Controls/CheckboxPage/CheckboxPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { CheckboxPageProps } from './CheckboxPage.doc'; export const CheckboxPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/ChipPage/ChipPage.tsx b/apps/public-docsite/src/pages/Controls/ChipPage/ChipPage.tsx index df01399b8b105..0e95a7639a286 100644 --- a/apps/public-docsite/src/pages/Controls/ChipPage/ChipPage.tsx +++ b/apps/public-docsite/src/pages/Controls/ChipPage/ChipPage.tsx @@ -11,13 +11,13 @@ export const ChipPage: React.FunctionComponent = props => { return ( ); }; -function _otherSections(platform: Platforms): IPageSectionProps[] { +function _otherSections(platform: Platforms): IPageSectionProps[] | undefined { switch (platform) { case 'ios': return [ diff --git a/apps/public-docsite/src/pages/Controls/ChipPage/docs/android/ChipOverview.md b/apps/public-docsite/src/pages/Controls/ChipPage/docs/android/ChipOverview.md index be8ff5acd3e5d..e2adc803da8fa 100644 --- a/apps/public-docsite/src/pages/Controls/ChipPage/docs/android/ChipOverview.md +++ b/apps/public-docsite/src/pages/Controls/ChipPage/docs/android/ChipOverview.md @@ -3,7 +3,7 @@ Chips are compact representations of entities (most commonly, people) that can b ### Persona Chips - - + + diff --git a/apps/public-docsite/src/pages/Controls/ChipPage/docs/ios/ChipOverview.md b/apps/public-docsite/src/pages/Controls/ChipPage/docs/ios/ChipOverview.md index 4aac73555c983..74370a88991f1 100644 --- a/apps/public-docsite/src/pages/Controls/ChipPage/docs/ios/ChipOverview.md +++ b/apps/public-docsite/src/pages/Controls/ChipPage/docs/ios/ChipOverview.md @@ -5,17 +5,17 @@ The chip field control handles keyboard input, wrapping and truncation automatic ### Small Chip - - + + ### Medium Chip - - + + ### Badge Field - - + + diff --git a/apps/public-docsite/src/pages/Controls/ChoiceGroupPage/ChoiceGroupPage.tsx b/apps/public-docsite/src/pages/Controls/ChoiceGroupPage/ChoiceGroupPage.tsx index c0f9248324174..6ff5842b76f3d 100644 --- a/apps/public-docsite/src/pages/Controls/ChoiceGroupPage/ChoiceGroupPage.tsx +++ b/apps/public-docsite/src/pages/Controls/ChoiceGroupPage/ChoiceGroupPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { ChoiceGroupPageProps } from './ChoiceGroupPage.doc'; export const ChoiceGroupPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/CoachmarkPage/CoachmarkPage.tsx b/apps/public-docsite/src/pages/Controls/CoachmarkPage/CoachmarkPage.tsx index d09dfe7d2f371..25eb65c1338f2 100644 --- a/apps/public-docsite/src/pages/Controls/CoachmarkPage/CoachmarkPage.tsx +++ b/apps/public-docsite/src/pages/Controls/CoachmarkPage/CoachmarkPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { CoachmarkPageProps } from './CoachmarkPage.doc'; export const CoachmarkPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/ColorPickerPage/ColorPickerPage.tsx b/apps/public-docsite/src/pages/Controls/ColorPickerPage/ColorPickerPage.tsx index 961de49293b03..fb806f6d93de0 100644 --- a/apps/public-docsite/src/pages/Controls/ColorPickerPage/ColorPickerPage.tsx +++ b/apps/public-docsite/src/pages/Controls/ColorPickerPage/ColorPickerPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { ColorPickerPageProps } from './ColorPickerPage.doc'; export const ColorPickerPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/ComboBoxPage/ComboBoxPage.tsx b/apps/public-docsite/src/pages/Controls/ComboBoxPage/ComboBoxPage.tsx index 3dfc7ee4057e2..5662468ecb4d7 100644 --- a/apps/public-docsite/src/pages/Controls/ComboBoxPage/ComboBoxPage.tsx +++ b/apps/public-docsite/src/pages/Controls/ComboBoxPage/ComboBoxPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { ComboBoxPageProps } from './ComboBoxPage.doc'; export const ComboBoxPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/CommandBarPage/CommandBarPage.tsx b/apps/public-docsite/src/pages/Controls/CommandBarPage/CommandBarPage.tsx index 2e2991605a4f8..fb1e3bf17aac6 100644 --- a/apps/public-docsite/src/pages/Controls/CommandBarPage/CommandBarPage.tsx +++ b/apps/public-docsite/src/pages/Controls/CommandBarPage/CommandBarPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { CommandBarPageProps } from './CommandBarPage.doc'; export const CommandBarPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/ContextualMenuPage/ContextualMenuPage.tsx b/apps/public-docsite/src/pages/Controls/ContextualMenuPage/ContextualMenuPage.tsx index 40674363dda45..6c134f0b5917f 100644 --- a/apps/public-docsite/src/pages/Controls/ContextualMenuPage/ContextualMenuPage.tsx +++ b/apps/public-docsite/src/pages/Controls/ContextualMenuPage/ContextualMenuPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { ContextualMenuPageProps } from './ContextualMenuPage.doc'; export const ContextualMenuPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/ControlsAreaPage.tsx b/apps/public-docsite/src/pages/Controls/ControlsAreaPage.tsx index 260d6c0fc3188..25528c11ca408 100644 --- a/apps/public-docsite/src/pages/Controls/ControlsAreaPage.tsx +++ b/apps/public-docsite/src/pages/Controls/ControlsAreaPage.tsx @@ -22,8 +22,8 @@ const ControlsAreaPageBase: React.FunctionComponent = props } return ( = props return ( ); }; -function _otherSections(platform: Platforms): IPageSectionProps[] { +function _otherSections(platform: Platforms): IPageSectionProps[] | undefined { switch (platform) { case 'ios': return [ diff --git a/apps/public-docsite/src/pages/Controls/DatePickerPage/docs/android/DateTimePickerOverview.md b/apps/public-docsite/src/pages/Controls/DatePickerPage/docs/android/DateTimePickerOverview.md index 9e1d0d2bdc224..f2126a86b607f 100644 --- a/apps/public-docsite/src/pages/Controls/DatePickerPage/docs/android/DateTimePickerOverview.md +++ b/apps/public-docsite/src/pages/Controls/DatePickerPage/docs/android/DateTimePickerOverview.md @@ -7,17 +7,17 @@ These pickers let users quickly choose a date or time through a familiar popup a ### Date Picker - - + + ### Time Picker - - + + ### Range Picker for Dates - - + + diff --git a/apps/public-docsite/src/pages/Controls/DatePickerPage/docs/ios/DateTimePickerOverview.md b/apps/public-docsite/src/pages/Controls/DatePickerPage/docs/ios/DateTimePickerOverview.md index 084841ec4c4b6..ed7b989923d1a 100644 --- a/apps/public-docsite/src/pages/Controls/DatePickerPage/docs/ios/DateTimePickerOverview.md +++ b/apps/public-docsite/src/pages/Controls/DatePickerPage/docs/ios/DateTimePickerOverview.md @@ -3,8 +3,8 @@ These pickers let users quickly choose a date or time through a familiar popup a - - + + diff --git a/apps/public-docsite/src/pages/Controls/DatePickerPage/docs/mac/DatePickerUsage.md b/apps/public-docsite/src/pages/Controls/DatePickerPage/docs/mac/DatePickerUsage.md index 3362c5cae0e6a..ca6413881e1b9 100644 --- a/apps/public-docsite/src/pages/Controls/DatePickerPage/docs/mac/DatePickerUsage.md +++ b/apps/public-docsite/src/pages/Controls/DatePickerPage/docs/mac/DatePickerUsage.md @@ -8,8 +8,8 @@ The DatePicker uses the provided [`Calendar`](https://developer.apple.com/docume DatePickerController(date: nil, calendar: nil, style: .date) ``` - - + + ### DatePicker with time text field @@ -18,8 +18,8 @@ DatePickerController(date: nil, calendar: nil, style: .date) DatePickerController(date: nil, calendar: nil, style: .dateTime) ``` - - + + ### Custom initial date @@ -29,8 +29,8 @@ let date = Calendar.current.date(from: DateComponents(year: 2019, month: 1, day: DatePickerController(date: date, calendar: nil, style: .date) ``` - - + + ### Custom calendar @@ -41,8 +41,8 @@ calendar.locale = Locale(identifier: "ar") DatePickerController(date: nil, calendar: calendar, style: .date) ``` - - + + ### Secondary calendar @@ -54,8 +54,8 @@ let controller = DatePickerController(date: nil, calendar: nil, style: .date) controller.secondaryCalendar = calendar ``` - - + + ### No text field @@ -65,7 +65,7 @@ let controller = DatePickerController(date: nil, calendar: nil, style: .date) controller.hasTextField = false ``` - - + + diff --git a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListAdvancedPage.tsx b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListAdvancedPage.tsx index 20f21346c1e14..9fd6a695ec4fb 100644 --- a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListAdvancedPage.tsx +++ b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListAdvancedPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { DetailsListAdvancedPageProps } from './DetailsListAdvancedPage.doc'; export const DetailsListAdvancedPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListAnimationPage.tsx b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListAnimationPage.tsx index ab39d5d383fff..348e11275d972 100644 --- a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListAnimationPage.tsx +++ b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListAnimationPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { DetailsListAnimationPageProps } from './DetailsListAnimationPage.doc'; export const DetailsListAnimationPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListBasicPage.tsx b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListBasicPage.tsx index 1a60271856304..c92832b10e8af 100644 --- a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListBasicPage.tsx +++ b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListBasicPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { DetailsListBasicPageProps } from './DetailsListBasicPage.doc'; export const DetailsListBasicPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListCompactPage.tsx b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListCompactPage.tsx index fb710788b092c..46bc699654805 100644 --- a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListCompactPage.tsx +++ b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListCompactPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { DetailsListCompactPageProps } from './DetailsListCompactPage.doc'; export const DetailsListCompactPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListCustomColumnsPage.tsx b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListCustomColumnsPage.tsx index e37ed3b3d4ed6..acf749957dba9 100644 --- a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListCustomColumnsPage.tsx +++ b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListCustomColumnsPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { DetailsListCustomColumnsPageProps } from './DetailsListCustomColumnsPage.doc'; export const DetailsListCustomColumnsPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListCustomFooterPage.tsx b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListCustomFooterPage.tsx index 48943b15a870c..9ea3d3a95ca0b 100644 --- a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListCustomFooterPage.tsx +++ b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListCustomFooterPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { DetailsListCustomFooterPageProps } from './DetailsListCustomFooterPage.doc'; export const DetailsListCustomFooterPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListCustomGroupHeadersPage.tsx b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListCustomGroupHeadersPage.tsx index 5af9efa5ed2b3..ce7a047971fef 100644 --- a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListCustomGroupHeadersPage.tsx +++ b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListCustomGroupHeadersPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { DetailsListCustomGroupHeadersPageProps } from './DetailsListCustomGroupHeadersPage.doc'; export const DetailsListCustomGroupHeadersPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListCustomRowsPage.tsx b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListCustomRowsPage.tsx index 80a8e48ca8ce1..6088e2b1233a1 100644 --- a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListCustomRowsPage.tsx +++ b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListCustomRowsPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { DetailsListCustomRowsPageProps } from './DetailsListCustomRowsPage.doc'; export const DetailsListCustomRowsPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListDragDropPage.tsx b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListDragDropPage.tsx index c6c5d386d6051..47634e20459f2 100644 --- a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListDragDropPage.tsx +++ b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListDragDropPage.tsx @@ -17,7 +17,7 @@ export const DetailsListDragDropPage: React.FunctionComponent - ; + ;
  • ); }; diff --git a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListGroupedPage.tsx b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListGroupedPage.tsx index a69d2f25604da..b912bbf7ad01f 100644 --- a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListGroupedPage.tsx +++ b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListGroupedPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { DetailsListGroupedPageProps } from './DetailsListGroupedPage.doc'; export const DetailsListGroupedPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListGroupedV2Page.doc.ts b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListGroupedV2Page.doc.ts new file mode 100644 index 0000000000000..10d06bd2c7e8e --- /dev/null +++ b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListGroupedV2Page.doc.ts @@ -0,0 +1,10 @@ +import { TFabricPlatformPageProps } from '../../../interfaces/Platforms'; +import { DetailsListSimpleGroupedV2PageProps as ExternalProps } from '@fluentui/react-examples/lib/react/DetailsList/DetailsList.doc'; + +export const DetailsListGroupedV2PageProps: TFabricPlatformPageProps = { + web: { + ...(ExternalProps as any), + title: 'DetailsList - Grouped V2', + isFeedbackVisible: false, + }, +}; diff --git a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListGroupedV2Page.tsx b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListGroupedV2Page.tsx new file mode 100644 index 0000000000000..6595f9b803ac4 --- /dev/null +++ b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListGroupedV2Page.tsx @@ -0,0 +1,7 @@ +import * as React from 'react'; +import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; +import { DetailsListGroupedV2PageProps } from './DetailsListGroupedV2Page.doc'; + +export const DetailsListGroupedV2Page: React.FunctionComponent = props => { + return ; +}; diff --git a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListKeyboardDragDropPage.tsx b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListKeyboardDragDropPage.tsx index c7b2a4f4c8eb2..11d1d5eb58eec 100644 --- a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListKeyboardDragDropPage.tsx +++ b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListKeyboardDragDropPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { DetailsListKeyboardDragDropPageProps } from './DetailsListKeyboardDragDropPage.doc'; export const DetailsListKeyboardDragDropPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListKeyboardOverridesPage.tsx b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListKeyboardOverridesPage.tsx index dc436ef95f975..33ec4888286cf 100644 --- a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListKeyboardOverridesPage.tsx +++ b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListKeyboardOverridesPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { DetailsListKeyboardOverridesProps } from './DetailsListKeyboardOverrides.doc'; export const DetailsListKeyboardOverridesPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListLargeGroupedPage.tsx b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListLargeGroupedPage.tsx index 0945a61721f80..3c97c96749f1d 100644 --- a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListLargeGroupedPage.tsx +++ b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListLargeGroupedPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { DetailsListLargeGroupedPageProps } from './DetailsListLargeGroupedPage.doc'; export const DetailsListLargeGroupedPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListLargeGroupedV2Page.doc.ts b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListLargeGroupedV2Page.doc.ts new file mode 100644 index 0000000000000..e21b2a1d08fe4 --- /dev/null +++ b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListLargeGroupedV2Page.doc.ts @@ -0,0 +1,10 @@ +import { TFabricPlatformPageProps } from '../../../interfaces/Platforms'; +import { DetailsListLargeGroupedPageProps as ExternalProps } from '@fluentui/react-examples/lib/react/DetailsList/DetailsList.doc'; + +export const DetailsListLargeGroupedV2PageProps: TFabricPlatformPageProps = { + web: { + ...(ExternalProps as any), + title: 'DetailsList - Large Grouped V2', + isFeedbackVisible: false, + }, +}; diff --git a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListLargeGroupedV2Page.tsx b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListLargeGroupedV2Page.tsx new file mode 100644 index 0000000000000..2d04890dffd02 --- /dev/null +++ b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListLargeGroupedV2Page.tsx @@ -0,0 +1,7 @@ +import * as React from 'react'; +import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; +import { DetailsListLargeGroupedV2PageProps } from './DetailsListLargeGroupedV2Page.doc'; + +export const DetailsListLargeGroupedV2Page: React.FunctionComponent = props => { + return ; +}; diff --git a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListNavigatingFocusPage.tsx b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListNavigatingFocusPage.tsx index f9b06299b772c..5ca279fc08273 100644 --- a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListNavigatingFocusPage.tsx +++ b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListNavigatingFocusPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { DetailsListNavigatingFocusPageProps } from './DetailsListNavigatingFocusPage.doc'; export const DetailsListNavigatingFocusPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListPage.tsx b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListPage.tsx index 6d70f8b4437e2..f62edd373b9bc 100644 --- a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListPage.tsx +++ b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { DetailsListPageProps } from './DetailsListPage.doc'; export const DetailsListPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListProportionalColumnsPage.tsx b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListProportionalColumnsPage.tsx index 74cf427410f67..1b8b88fea244b 100644 --- a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListProportionalColumnsPage.tsx +++ b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListProportionalColumnsPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { DetailsListProportionalColumnsPageProps } from './DetailsListProportionalColumnsPage.doc'; export const DetailsListProportionalColumnsPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListShimmerPage.tsx b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListShimmerPage.tsx index d47778f5eb5ea..7b37f39a8ef87 100644 --- a/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListShimmerPage.tsx +++ b/apps/public-docsite/src/pages/Controls/DetailsListPage/DetailsListShimmerPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { DetailsListShimmerPageProps } from './DetailsListShimmerPage.doc'; export const DetailsListShimmerPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/DialogPage/DialogPage.tsx b/apps/public-docsite/src/pages/Controls/DialogPage/DialogPage.tsx index c27c154abe7ac..f43c1df563e2f 100644 --- a/apps/public-docsite/src/pages/Controls/DialogPage/DialogPage.tsx +++ b/apps/public-docsite/src/pages/Controls/DialogPage/DialogPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { DialogPageProps } from './DialogPage.doc'; export const DialogPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/DocumentCardPage/DocumentCardPage.tsx b/apps/public-docsite/src/pages/Controls/DocumentCardPage/DocumentCardPage.tsx index fde3b5cd47405..a335ee1fa4fd2 100644 --- a/apps/public-docsite/src/pages/Controls/DocumentCardPage/DocumentCardPage.tsx +++ b/apps/public-docsite/src/pages/Controls/DocumentCardPage/DocumentCardPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { DocumentCardPageProps } from './DocumentCardPage.doc'; export const DocumentCardPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/DrawerPage/DrawerPage.tsx b/apps/public-docsite/src/pages/Controls/DrawerPage/DrawerPage.tsx index 41d3eccce35fa..3ddf28f5f4e05 100644 --- a/apps/public-docsite/src/pages/Controls/DrawerPage/DrawerPage.tsx +++ b/apps/public-docsite/src/pages/Controls/DrawerPage/DrawerPage.tsx @@ -12,13 +12,13 @@ export const DrawerPage: React.FunctionComponent = props => ); }; -function _otherSections(platform: Platforms): IPageSectionProps[] { +function _otherSections(platform: Platforms): IPageSectionProps[] | undefined { switch (platform) { case 'ios': return [ diff --git a/apps/public-docsite/src/pages/Controls/DrawerPage/docs/android/DrawerOverview.md b/apps/public-docsite/src/pages/Controls/DrawerPage/docs/android/DrawerOverview.md index 28bb1805477c5..d41a166d3cc2c 100644 --- a/apps/public-docsite/src/pages/Controls/DrawerPage/docs/android/DrawerOverview.md +++ b/apps/public-docsite/src/pages/Controls/DrawerPage/docs/android/DrawerOverview.md @@ -2,7 +2,7 @@ - - + + diff --git a/apps/public-docsite/src/pages/Controls/DrawerPage/docs/ios/DrawerOverview.md b/apps/public-docsite/src/pages/Controls/DrawerPage/docs/ios/DrawerOverview.md index 9a63dd6479c8f..18b0ec809f684 100644 --- a/apps/public-docsite/src/pages/Controls/DrawerPage/docs/ios/DrawerOverview.md +++ b/apps/public-docsite/src/pages/Controls/DrawerPage/docs/ios/DrawerOverview.md @@ -1,14 +1,14 @@ Drawers let you reveal lightweight views inside your application without being a full-screen view that takes over the navigation hierarchy. They are easy to dismiss & resize, and may leave space on-screen that shows the content behind them. -### Veritcal +### Vertical - - + + ### Horizontal - - + + diff --git a/apps/public-docsite/src/pages/Controls/DropdownPage/DropdownPage.tsx b/apps/public-docsite/src/pages/Controls/DropdownPage/DropdownPage.tsx index 352318b9b4338..9eba28f7bdbd9 100644 --- a/apps/public-docsite/src/pages/Controls/DropdownPage/DropdownPage.tsx +++ b/apps/public-docsite/src/pages/Controls/DropdownPage/DropdownPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { DropdownPageProps } from './DropdownPage.doc'; export const DropdownPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/FacepilePage/FacepilePage.tsx b/apps/public-docsite/src/pages/Controls/FacepilePage/FacepilePage.tsx index bd0690c400f75..d45d1a2c985b7 100644 --- a/apps/public-docsite/src/pages/Controls/FacepilePage/FacepilePage.tsx +++ b/apps/public-docsite/src/pages/Controls/FacepilePage/FacepilePage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { FacepilePageProps } from './FacepilePage.doc'; export const FacepilePage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/FocusTrapZonePage/FocusTrapZonePage.tsx b/apps/public-docsite/src/pages/Controls/FocusTrapZonePage/FocusTrapZonePage.tsx index 9333e2a018d1e..9753b0e1da6d9 100644 --- a/apps/public-docsite/src/pages/Controls/FocusTrapZonePage/FocusTrapZonePage.tsx +++ b/apps/public-docsite/src/pages/Controls/FocusTrapZonePage/FocusTrapZonePage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { FocusTrapZonePageProps } from './FocusTrapZonePage.doc'; export const FocusTrapZonePage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/FocusZonePage/FocusZonePage.tsx b/apps/public-docsite/src/pages/Controls/FocusZonePage/FocusZonePage.tsx index ef8c9d4a85c66..7b258dcbe380f 100644 --- a/apps/public-docsite/src/pages/Controls/FocusZonePage/FocusZonePage.tsx +++ b/apps/public-docsite/src/pages/Controls/FocusZonePage/FocusZonePage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { FocusZonePageProps } from './FocusZonePage.doc'; export const FocusZonePage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/GroupedListPage/GroupedListPage.tsx b/apps/public-docsite/src/pages/Controls/GroupedListPage/GroupedListPage.tsx index 1348ad5db488a..03c50d35c1262 100644 --- a/apps/public-docsite/src/pages/Controls/GroupedListPage/GroupedListPage.tsx +++ b/apps/public-docsite/src/pages/Controls/GroupedListPage/GroupedListPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { GroupedListPageProps } from './GroupedListPage.doc'; export const GroupedListPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/HoverCardPage/HoverCardPage.tsx b/apps/public-docsite/src/pages/Controls/HoverCardPage/HoverCardPage.tsx index 54acd69bedd9d..6b18b0696b1f4 100644 --- a/apps/public-docsite/src/pages/Controls/HoverCardPage/HoverCardPage.tsx +++ b/apps/public-docsite/src/pages/Controls/HoverCardPage/HoverCardPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { HoverCardPageProps } from './HoverCardPage.doc'; export const HoverCardPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/IconPage/IconPage.tsx b/apps/public-docsite/src/pages/Controls/IconPage/IconPage.tsx index cefd251d4262f..59d9cf53f44d7 100644 --- a/apps/public-docsite/src/pages/Controls/IconPage/IconPage.tsx +++ b/apps/public-docsite/src/pages/Controls/IconPage/IconPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { IconPageProps } from './IconPage.doc'; export const IconPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/ImagePage/ImagePage.tsx b/apps/public-docsite/src/pages/Controls/ImagePage/ImagePage.tsx index 4a159c51c127b..7dca1e58b935c 100644 --- a/apps/public-docsite/src/pages/Controls/ImagePage/ImagePage.tsx +++ b/apps/public-docsite/src/pages/Controls/ImagePage/ImagePage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { ImagePageProps } from './ImagePage.doc'; export const ImagePage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/KeytipsPage/KeytipsPage.tsx b/apps/public-docsite/src/pages/Controls/KeytipsPage/KeytipsPage.tsx index a0de154172595..d5bb47786465c 100644 --- a/apps/public-docsite/src/pages/Controls/KeytipsPage/KeytipsPage.tsx +++ b/apps/public-docsite/src/pages/Controls/KeytipsPage/KeytipsPage.tsx @@ -6,7 +6,7 @@ import { KeytipLayer } from '@fluentui/react/lib/KeytipLayer'; export const KeytipsPage: React.FunctionComponent = props => { return (
    - +
    ); diff --git a/apps/public-docsite/src/pages/Controls/LabelPage/LabelPage.tsx b/apps/public-docsite/src/pages/Controls/LabelPage/LabelPage.tsx index 84750f1883078..1ac37fc69b930 100644 --- a/apps/public-docsite/src/pages/Controls/LabelPage/LabelPage.tsx +++ b/apps/public-docsite/src/pages/Controls/LabelPage/LabelPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { LabelPageProps } from './LabelPage.doc'; export const LabelPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/LayerPage/LayerPage.tsx b/apps/public-docsite/src/pages/Controls/LayerPage/LayerPage.tsx index 08c87c96f05f4..7af0a8cb4c932 100644 --- a/apps/public-docsite/src/pages/Controls/LayerPage/LayerPage.tsx +++ b/apps/public-docsite/src/pages/Controls/LayerPage/LayerPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { LayerPageProps } from './LayerPage.doc'; export const LayerPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/LinkPage/LinkPage.tsx b/apps/public-docsite/src/pages/Controls/LinkPage/LinkPage.tsx index dfd24cdd2ef36..752b62010146e 100644 --- a/apps/public-docsite/src/pages/Controls/LinkPage/LinkPage.tsx +++ b/apps/public-docsite/src/pages/Controls/LinkPage/LinkPage.tsx @@ -15,13 +15,13 @@ export const LinkPage: React.FunctionComponent = props => { return ( ); }; -function _otherSections(platform: Platforms): IPageSectionProps[] { +function _otherSections(platform: Platforms): IPageSectionProps[] | undefined { switch (platform) { case 'mac': return [ diff --git a/apps/public-docsite/src/pages/Controls/LinkPage/docs/cross/LinkUsage.md b/apps/public-docsite/src/pages/Controls/LinkPage/docs/cross/LinkUsage.md index 5f85b3d56af17..ec7042efa57bf 100644 --- a/apps/public-docsite/src/pages/Controls/LinkPage/docs/cross/LinkUsage.md +++ b/apps/public-docsite/src/pages/Controls/LinkPage/docs/cross/LinkUsage.md @@ -2,7 +2,7 @@ Fluent UI React Native Link has default styling based on the Fluent Design Langu ### Link example - + #### Example usage (from [LinkTest.tsx](https://github.com/microsoft/fluentui-react-native/blob/master/apps/fluent-tester/src/FluentTester/TestComponents/Link/LinkTest.tsx)) diff --git a/apps/public-docsite/src/pages/Controls/LinkPage/docs/mac/LinkUsage.md b/apps/public-docsite/src/pages/Controls/LinkPage/docs/mac/LinkUsage.md index 4bcf18dbd406c..695e86b18c87d 100644 --- a/apps/public-docsite/src/pages/Controls/LinkPage/docs/mac/LinkUsage.md +++ b/apps/public-docsite/src/pages/Controls/LinkPage/docs/mac/LinkUsage.md @@ -2,8 +2,8 @@ The Link control is implemented as a stylized NSButton, and thus inherits all of - - + + ### Default configuration diff --git a/apps/public-docsite/src/pages/Controls/ListCellsPage/ListCellsPage.tsx b/apps/public-docsite/src/pages/Controls/ListCellsPage/ListCellsPage.tsx index 9216302bb0953..b35b86b4d341a 100644 --- a/apps/public-docsite/src/pages/Controls/ListCellsPage/ListCellsPage.tsx +++ b/apps/public-docsite/src/pages/Controls/ListCellsPage/ListCellsPage.tsx @@ -13,13 +13,13 @@ export const ListCellsPage: React.FunctionComponent = props ); }; -function _otherSections(platform: Platforms): IPageSectionProps[] { +function _otherSections(platform: Platforms): IPageSectionProps[] | undefined { switch (platform) { case 'ios': return [ diff --git a/apps/public-docsite/src/pages/Controls/ListCellsPage/docs/android/ListCellsOverview.md b/apps/public-docsite/src/pages/Controls/ListCellsPage/docs/android/ListCellsOverview.md index dca070c6de499..a968b1b3c49a8 100644 --- a/apps/public-docsite/src/pages/Controls/ListCellsPage/docs/android/ListCellsOverview.md +++ b/apps/public-docsite/src/pages/Controls/ListCellsPage/docs/android/ListCellsOverview.md @@ -3,17 +3,17 @@ When displaying fundamental content types like files or people, it's important t ### One line - - + + ### Two line - - + + ### Three line - - + + diff --git a/apps/public-docsite/src/pages/Controls/ListCellsPage/docs/ios/ListCellsOverview.md b/apps/public-docsite/src/pages/Controls/ListCellsPage/docs/ios/ListCellsOverview.md index cb7363929fa8d..70797919bb582 100644 --- a/apps/public-docsite/src/pages/Controls/ListCellsPage/docs/ios/ListCellsOverview.md +++ b/apps/public-docsite/src/pages/Controls/ListCellsPage/docs/ios/ListCellsOverview.md @@ -3,32 +3,32 @@ When displaying fundamental content types like files or people, it's important t ### One line - - + + ### Two line - - + + ### Three line - - + + ### Center line - - + + ### Selection - - + + ### Description - - + + diff --git a/apps/public-docsite/src/pages/Controls/ListPage/ListPage.tsx b/apps/public-docsite/src/pages/Controls/ListPage/ListPage.tsx index d9dd9c0d68f59..1ddd04e0ab472 100644 --- a/apps/public-docsite/src/pages/Controls/ListPage/ListPage.tsx +++ b/apps/public-docsite/src/pages/Controls/ListPage/ListPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { ListPageProps } from './ListPage.doc'; export const ListPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/MarqueeSelectionPage/MarqueeSelectionPage.tsx b/apps/public-docsite/src/pages/Controls/MarqueeSelectionPage/MarqueeSelectionPage.tsx index 06998feefdd54..11e66cb507e9b 100644 --- a/apps/public-docsite/src/pages/Controls/MarqueeSelectionPage/MarqueeSelectionPage.tsx +++ b/apps/public-docsite/src/pages/Controls/MarqueeSelectionPage/MarqueeSelectionPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { MarqueeSelectionPageProps } from './MarqueeSelectionPage.doc'; export const MarqueeSelectionPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/MessageBarPage/MessageBarPage.tsx b/apps/public-docsite/src/pages/Controls/MessageBarPage/MessageBarPage.tsx index 762d08c24788f..c5217553e42cd 100644 --- a/apps/public-docsite/src/pages/Controls/MessageBarPage/MessageBarPage.tsx +++ b/apps/public-docsite/src/pages/Controls/MessageBarPage/MessageBarPage.tsx @@ -11,7 +11,7 @@ export const MessageBarPage: React.FunctionComponent = props return ( ); diff --git a/apps/public-docsite/src/pages/Controls/MessageBarPage/docs/ios/MessageBarOverview.md b/apps/public-docsite/src/pages/Controls/MessageBarPage/docs/ios/MessageBarOverview.md index 0cb5d555eb0d9..34013457e6abe 100644 --- a/apps/public-docsite/src/pages/Controls/MessageBarPage/docs/ios/MessageBarOverview.md +++ b/apps/public-docsite/src/pages/Controls/MessageBarPage/docs/ios/MessageBarOverview.md @@ -3,12 +3,12 @@ ### Toast - - + + ### Bar - - + + diff --git a/apps/public-docsite/src/pages/Controls/ModalPage/ModalPage.tsx b/apps/public-docsite/src/pages/Controls/ModalPage/ModalPage.tsx index e4e95aef14a8e..20449c4bca94f 100644 --- a/apps/public-docsite/src/pages/Controls/ModalPage/ModalPage.tsx +++ b/apps/public-docsite/src/pages/Controls/ModalPage/ModalPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { ModalPageProps } from './ModalPage.doc'; export const ModalPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/NavBarPage/NavBarPage.tsx b/apps/public-docsite/src/pages/Controls/NavBarPage/NavBarPage.tsx index 1e0f758a05c26..0915e66a9deff 100644 --- a/apps/public-docsite/src/pages/Controls/NavBarPage/NavBarPage.tsx +++ b/apps/public-docsite/src/pages/Controls/NavBarPage/NavBarPage.tsx @@ -11,13 +11,13 @@ export const NavBarPage: React.FunctionComponent = props => return ( ); }; -function _otherSections(platform: Platforms): IPageSectionProps[] { +function _otherSections(platform: Platforms): IPageSectionProps[] | undefined { switch (platform) { case 'ios': return [ diff --git a/apps/public-docsite/src/pages/Controls/NavBarPage/docs/android/NavBarOverview.md b/apps/public-docsite/src/pages/Controls/NavBarPage/docs/android/NavBarOverview.md index deb27e1b4dc84..1ce884ca8464b 100644 --- a/apps/public-docsite/src/pages/Controls/NavBarPage/docs/android/NavBarOverview.md +++ b/apps/public-docsite/src/pages/Controls/NavBarPage/docs/android/NavBarOverview.md @@ -3,11 +3,11 @@ ### Top App bar - - + + ### Top App bar with Search - - + + diff --git a/apps/public-docsite/src/pages/Controls/NavBarPage/docs/ios/NavBarOverview.md b/apps/public-docsite/src/pages/Controls/NavBarPage/docs/ios/NavBarOverview.md index af54e421ff11b..a17d0c732b4da 100644 --- a/apps/public-docsite/src/pages/Controls/NavBarPage/docs/ios/NavBarOverview.md +++ b/apps/public-docsite/src/pages/Controls/NavBarPage/docs/ios/NavBarOverview.md @@ -4,13 +4,13 @@ This navigation controller provides supports the Large Title presentation and an ### Portrait - - + + ### Landscape - - + + diff --git a/apps/public-docsite/src/pages/Controls/NavPage/NavPage.tsx b/apps/public-docsite/src/pages/Controls/NavPage/NavPage.tsx index c302aebbbc367..ceb5f38bcff08 100644 --- a/apps/public-docsite/src/pages/Controls/NavPage/NavPage.tsx +++ b/apps/public-docsite/src/pages/Controls/NavPage/NavPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { NavPageProps } from './NavPage.doc'; export const NavPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/OverflowSetPage/OverflowSetPage.tsx b/apps/public-docsite/src/pages/Controls/OverflowSetPage/OverflowSetPage.tsx index 4bdf45e892c0a..54f22b71289df 100644 --- a/apps/public-docsite/src/pages/Controls/OverflowSetPage/OverflowSetPage.tsx +++ b/apps/public-docsite/src/pages/Controls/OverflowSetPage/OverflowSetPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { OverflowSetPageProps } from './OverflowSetPage.doc'; export const OverflowSetPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/OverlayPage/OverlayPage.tsx b/apps/public-docsite/src/pages/Controls/OverlayPage/OverlayPage.tsx index d4456338c405a..3e9dbb89860fe 100644 --- a/apps/public-docsite/src/pages/Controls/OverlayPage/OverlayPage.tsx +++ b/apps/public-docsite/src/pages/Controls/OverlayPage/OverlayPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { OverlayPageProps } from './OverlayPage.doc'; export const OverlayPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/PanelPage/PanelPage.tsx b/apps/public-docsite/src/pages/Controls/PanelPage/PanelPage.tsx index eb51bcaae1954..a7197c0076995 100644 --- a/apps/public-docsite/src/pages/Controls/PanelPage/PanelPage.tsx +++ b/apps/public-docsite/src/pages/Controls/PanelPage/PanelPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { PanelPageProps } from './PanelPage.doc'; export const PanelPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/PeoplePickerPage/PeoplePickerPage.tsx b/apps/public-docsite/src/pages/Controls/PeoplePickerPage/PeoplePickerPage.tsx index 69cd4574c9ffd..b78ca997ee7de 100644 --- a/apps/public-docsite/src/pages/Controls/PeoplePickerPage/PeoplePickerPage.tsx +++ b/apps/public-docsite/src/pages/Controls/PeoplePickerPage/PeoplePickerPage.tsx @@ -13,13 +13,13 @@ export const PeoplePickerPage: React.FunctionComponent = pro ); }; -function _otherSections(platform: Platforms): IPageSectionProps[] { +function _otherSections(platform: Platforms): IPageSectionProps[] | undefined { switch (platform) { case 'android': return [ diff --git a/apps/public-docsite/src/pages/Controls/PeoplePickerPage/docs/android/PeoplePickerOverview.md b/apps/public-docsite/src/pages/Controls/PeoplePickerPage/docs/android/PeoplePickerOverview.md index f341dc5672c1a..10ece252db11a 100644 --- a/apps/public-docsite/src/pages/Controls/PeoplePickerPage/docs/android/PeoplePickerOverview.md +++ b/apps/public-docsite/src/pages/Controls/PeoplePickerPage/docs/android/PeoplePickerOverview.md @@ -5,7 +5,7 @@ The `PeoplePicker` control handles keyboard input, field expanding and collapsin ### People Picker - - + + diff --git a/apps/public-docsite/src/pages/Controls/PersonaPage/PersonaPage.doc.ts b/apps/public-docsite/src/pages/Controls/PersonaPage/PersonaPage.doc.ts index 230f4e9652f75..577f9af37965f 100644 --- a/apps/public-docsite/src/pages/Controls/PersonaPage/PersonaPage.doc.ts +++ b/apps/public-docsite/src/pages/Controls/PersonaPage/PersonaPage.doc.ts @@ -7,7 +7,7 @@ const related: ISideRailLink[] = [ { text: 'iOS Persona', url: '#/controls/ios/persona' }, { text: 'Android Persona', url: '#/controls/android/persona' }, { text: 'macOS Avatar', url: '#/controls/mac/avatar' }, - { text: 'Cross-platform Persona', url: '#/controls/crossplatform/persona' }, + { text: 'Cross-platform Persona', url: '#/controls/cross/persona' }, ]; const componentUrl = 'https://github.com/microsoft/fluentui/tree/master/apps/public-docsite/src/pages/Controls/PersonaPage'; diff --git a/apps/public-docsite/src/pages/Controls/PersonaPage/PersonaPage.tsx b/apps/public-docsite/src/pages/Controls/PersonaPage/PersonaPage.tsx index eb0dcf666bc0c..2d9f2b3420252 100644 --- a/apps/public-docsite/src/pages/Controls/PersonaPage/PersonaPage.tsx +++ b/apps/public-docsite/src/pages/Controls/PersonaPage/PersonaPage.tsx @@ -16,13 +16,13 @@ export const PersonaPage: React.FunctionComponent = props => ); }; -function _otherSections(platform: Platforms): IPageSectionProps[] { +function _otherSections(platform: Platforms): IPageSectionProps[] | undefined { switch (platform) { case 'ios': return [ diff --git a/apps/public-docsite/src/pages/Controls/PersonaPage/docs/android/PersonaOverview.md b/apps/public-docsite/src/pages/Controls/PersonaPage/docs/android/PersonaOverview.md index 6675efc26d340..922c8c31c6f10 100644 --- a/apps/public-docsite/src/pages/Controls/PersonaPage/docs/android/PersonaOverview.md +++ b/apps/public-docsite/src/pages/Controls/PersonaPage/docs/android/PersonaOverview.md @@ -8,7 +8,7 @@ Persona controls are also available as a performant list view. The `PersonaListV - - + + diff --git a/apps/public-docsite/src/pages/Controls/PersonaPage/docs/cross/PersonaUsage.md b/apps/public-docsite/src/pages/Controls/PersonaPage/docs/cross/PersonaUsage.md index d156be2ab8823..d1897ca4aba4c 100644 --- a/apps/public-docsite/src/pages/Controls/PersonaPage/docs/cross/PersonaUsage.md +++ b/apps/public-docsite/src/pages/Controls/PersonaPage/docs/cross/PersonaUsage.md @@ -1,6 +1,6 @@ ### Persona in various sizes - + #### Example usage (from [PersonaCoinTest.tsx](https://github.com/microsoft/fluentui-react-native/tree/master/apps/fluent-tester/src/FluentTester/TestComponents/PersonaCoin)) diff --git a/apps/public-docsite/src/pages/Controls/PersonaPage/docs/ios/PersonaOverview.md b/apps/public-docsite/src/pages/Controls/PersonaPage/docs/ios/PersonaOverview.md index d8542a337ce36..87e3234d2fb83 100644 --- a/apps/public-docsite/src/pages/Controls/PersonaPage/docs/ios/PersonaOverview.md +++ b/apps/public-docsite/src/pages/Controls/PersonaPage/docs/ios/PersonaOverview.md @@ -8,7 +8,7 @@ Persona controls are also available as a performant list view. The `PersonaListV - - + + diff --git a/apps/public-docsite/src/pages/Controls/PickersPage/PickersPage.tsx b/apps/public-docsite/src/pages/Controls/PickersPage/PickersPage.tsx index 213b1c4d8b1d4..13f1479a3a7df 100644 --- a/apps/public-docsite/src/pages/Controls/PickersPage/PickersPage.tsx +++ b/apps/public-docsite/src/pages/Controls/PickersPage/PickersPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { PickersPageProps } from './PickersPage.doc'; export const PickersPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/PillButtonBarPage/PillButtonBarPage.tsx b/apps/public-docsite/src/pages/Controls/PillButtonBarPage/PillButtonBarPage.tsx index 311ef48215fbd..271eca93a9fd7 100644 --- a/apps/public-docsite/src/pages/Controls/PillButtonBarPage/PillButtonBarPage.tsx +++ b/apps/public-docsite/src/pages/Controls/PillButtonBarPage/PillButtonBarPage.tsx @@ -11,7 +11,7 @@ export const PillButtonBarPage: React.FunctionComponent = pr return ( ); diff --git a/apps/public-docsite/src/pages/Controls/PillButtonBarPage/docs/ios/PillButtonBarOverview.md b/apps/public-docsite/src/pages/Controls/PillButtonBarPage/docs/ios/PillButtonBarOverview.md index 1cc350c4091ea..b58fc669aae4f 100644 --- a/apps/public-docsite/src/pages/Controls/PillButtonBarPage/docs/ios/PillButtonBarOverview.md +++ b/apps/public-docsite/src/pages/Controls/PillButtonBarPage/docs/ios/PillButtonBarOverview.md @@ -3,8 +3,8 @@ - - + + diff --git a/apps/public-docsite/src/pages/Controls/PivotPage/PivotPage.tsx b/apps/public-docsite/src/pages/Controls/PivotPage/PivotPage.tsx index 17804b6e4cdd2..0a3b3fd57f9f7 100644 --- a/apps/public-docsite/src/pages/Controls/PivotPage/PivotPage.tsx +++ b/apps/public-docsite/src/pages/Controls/PivotPage/PivotPage.tsx @@ -10,7 +10,7 @@ export const PivotPage: React.FunctionComponent = props => { return ( ); diff --git a/apps/public-docsite/src/pages/Controls/PivotPage/docs/ios/PivotOverview.md b/apps/public-docsite/src/pages/Controls/PivotPage/docs/ios/PivotOverview.md index 6dafbc6732f70..d82ed65c7e951 100644 --- a/apps/public-docsite/src/pages/Controls/PivotPage/docs/ios/PivotOverview.md +++ b/apps/public-docsite/src/pages/Controls/PivotPage/docs/ios/PivotOverview.md @@ -3,17 +3,17 @@ Pivots are used for switching between sub-views or different pre-defined filteri ### Two - - + + ### Three - - + + ### Four - - + + diff --git a/apps/public-docsite/src/pages/Controls/PopupMenuPage/PopupMenuPage.tsx b/apps/public-docsite/src/pages/Controls/PopupMenuPage/PopupMenuPage.tsx index 43cf41619da1a..7645a2903f6a4 100644 --- a/apps/public-docsite/src/pages/Controls/PopupMenuPage/PopupMenuPage.tsx +++ b/apps/public-docsite/src/pages/Controls/PopupMenuPage/PopupMenuPage.tsx @@ -13,13 +13,13 @@ export const PopupMenuPage: React.FunctionComponent = props ); }; -function _otherSections(platform: Platforms): IPageSectionProps[] { +function _otherSections(platform: Platforms): IPageSectionProps[] | undefined { switch (platform) { case 'ios': return [ diff --git a/apps/public-docsite/src/pages/Controls/PopupMenuPage/docs/android/PopupMenuOverview.md b/apps/public-docsite/src/pages/Controls/PopupMenuPage/docs/android/PopupMenuOverview.md index 4a87eb306b5bf..6ff45f8e4de9c 100644 --- a/apps/public-docsite/src/pages/Controls/PopupMenuPage/docs/android/PopupMenuOverview.md +++ b/apps/public-docsite/src/pages/Controls/PopupMenuPage/docs/android/PopupMenuOverview.md @@ -3,16 +3,16 @@ ### Popup Menu with icons - - + + ### Popup Menu with Radio Buttons - - + + ### Popup Menu with Check Boxes - - + + diff --git a/apps/public-docsite/src/pages/Controls/PopupMenuPage/docs/ios/PopupMenuOverview.md b/apps/public-docsite/src/pages/Controls/PopupMenuPage/docs/ios/PopupMenuOverview.md index 577387d53254a..e26470e6a90b7 100644 --- a/apps/public-docsite/src/pages/Controls/PopupMenuPage/docs/ios/PopupMenuOverview.md +++ b/apps/public-docsite/src/pages/Controls/PopupMenuPage/docs/ios/PopupMenuOverview.md @@ -4,13 +4,13 @@ PopupMenus provide a set of commands or options inside of a drawer. Two types of ### Top down - - + + ### Bottom up - - + + diff --git a/apps/public-docsite/src/pages/Controls/PopupPage/PopupPage.tsx b/apps/public-docsite/src/pages/Controls/PopupPage/PopupPage.tsx index ad7dca94b2228..7ddf0a381266b 100644 --- a/apps/public-docsite/src/pages/Controls/PopupPage/PopupPage.tsx +++ b/apps/public-docsite/src/pages/Controls/PopupPage/PopupPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { PopupPageProps } from './PopupPage.doc'; export const PopupPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/ProgressIndicatorPage/ProgressIndicatorPage.tsx b/apps/public-docsite/src/pages/Controls/ProgressIndicatorPage/ProgressIndicatorPage.tsx index 5c3232c386e05..eac3d618aa91b 100644 --- a/apps/public-docsite/src/pages/Controls/ProgressIndicatorPage/ProgressIndicatorPage.tsx +++ b/apps/public-docsite/src/pages/Controls/ProgressIndicatorPage/ProgressIndicatorPage.tsx @@ -5,5 +5,5 @@ import { ProgressIndicatorPageProps } from './ProgressIndicatorPage.doc'; export const ProgressIndicatorPage: React.FunctionComponent = props => { const { platform } = props; - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/RatingPage/RatingPage.tsx b/apps/public-docsite/src/pages/Controls/RatingPage/RatingPage.tsx index 9ec5920fd9a5c..0bd52c9714cb0 100644 --- a/apps/public-docsite/src/pages/Controls/RatingPage/RatingPage.tsx +++ b/apps/public-docsite/src/pages/Controls/RatingPage/RatingPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { RatingPageProps } from './RatingPage.doc'; export const RatingPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/ResizeGroupPage/ResizeGroupPage.tsx b/apps/public-docsite/src/pages/Controls/ResizeGroupPage/ResizeGroupPage.tsx index abc71f8f6af8c..a8a46a19456ee 100644 --- a/apps/public-docsite/src/pages/Controls/ResizeGroupPage/ResizeGroupPage.tsx +++ b/apps/public-docsite/src/pages/Controls/ResizeGroupPage/ResizeGroupPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { ResizeGroupPageProps } from './ResizeGroupPage.doc'; export const ResizeGroupPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/ScrollablePanePage/ScrollablePanePage.tsx b/apps/public-docsite/src/pages/Controls/ScrollablePanePage/ScrollablePanePage.tsx index 6af27a4998986..470488aa46cae 100644 --- a/apps/public-docsite/src/pages/Controls/ScrollablePanePage/ScrollablePanePage.tsx +++ b/apps/public-docsite/src/pages/Controls/ScrollablePanePage/ScrollablePanePage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { ScrollablePanePageProps } from './ScrollablePanePage.doc'; export const ScrollablePanePage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/SearchBoxPage/SearchBoxPage.tsx b/apps/public-docsite/src/pages/Controls/SearchBoxPage/SearchBoxPage.tsx index 1c877fe2ba068..a03d133eaa8b4 100644 --- a/apps/public-docsite/src/pages/Controls/SearchBoxPage/SearchBoxPage.tsx +++ b/apps/public-docsite/src/pages/Controls/SearchBoxPage/SearchBoxPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { SearchBoxPageProps } from './SearchBoxPage.doc'; export const SearchBoxPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/SelectionPage/SelectionPage.tsx b/apps/public-docsite/src/pages/Controls/SelectionPage/SelectionPage.tsx index 0419f2041c16d..315c614a71f69 100644 --- a/apps/public-docsite/src/pages/Controls/SelectionPage/SelectionPage.tsx +++ b/apps/public-docsite/src/pages/Controls/SelectionPage/SelectionPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { SelectionPageProps } from './SelectionPage.doc'; export const SelectionPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/SeparatorPage/SeparatorPage.doc.ts b/apps/public-docsite/src/pages/Controls/SeparatorPage/SeparatorPage.doc.ts index 929639b7a3c6c..06dfce758ff70 100644 --- a/apps/public-docsite/src/pages/Controls/SeparatorPage/SeparatorPage.doc.ts +++ b/apps/public-docsite/src/pages/Controls/SeparatorPage/SeparatorPage.doc.ts @@ -8,7 +8,7 @@ const related: ISideRailLink[] = [ { text: 'Android Separator', url: '#/controls/android/separator' }, { text: 'Android ListItemDivider', url: '#/controls/android/listcells' }, { text: 'macOS Separator', url: '#/controls/mac/separator' }, - { text: 'Cross-platform Separator', url: '#/controls/crossplatform/separator' }, + { text: 'Cross-platform Separator', url: '#/controls/cross/separator' }, ]; const componentUrl = 'https://github.com/microsoft/fluentui/tree/master/apps/public-docsite/src/pages/Controls/SeparatorPage'; diff --git a/apps/public-docsite/src/pages/Controls/SeparatorPage/SeparatorPage.tsx b/apps/public-docsite/src/pages/Controls/SeparatorPage/SeparatorPage.tsx index 553cf260ed6f7..583e7947c1aa3 100644 --- a/apps/public-docsite/src/pages/Controls/SeparatorPage/SeparatorPage.tsx +++ b/apps/public-docsite/src/pages/Controls/SeparatorPage/SeparatorPage.tsx @@ -17,13 +17,13 @@ export const SeparatorPage: React.FunctionComponent = props ); }; -function _otherSections(platform: Platforms): IPageSectionProps[] { +function _otherSections(platform: Platforms): IPageSectionProps[] | undefined { switch (platform) { case 'ios': return [ diff --git a/apps/public-docsite/src/pages/Controls/SeparatorPage/docs/android/SeparatorOverview.md b/apps/public-docsite/src/pages/Controls/SeparatorPage/docs/android/SeparatorOverview.md index edb5791c124e5..a00e61ae37004 100644 --- a/apps/public-docsite/src/pages/Controls/SeparatorPage/docs/android/SeparatorOverview.md +++ b/apps/public-docsite/src/pages/Controls/SeparatorPage/docs/android/SeparatorOverview.md @@ -2,7 +2,7 @@ A separator visually separates content into groups. - - + + diff --git a/apps/public-docsite/src/pages/Controls/SeparatorPage/docs/cross/SeparatorUsage.md b/apps/public-docsite/src/pages/Controls/SeparatorPage/docs/cross/SeparatorUsage.md index 86efaac24ad08..3a5492852e472 100644 --- a/apps/public-docsite/src/pages/Controls/SeparatorPage/docs/cross/SeparatorUsage.md +++ b/apps/public-docsite/src/pages/Controls/SeparatorPage/docs/cross/SeparatorUsage.md @@ -1,6 +1,6 @@ ### Link example - + #### Example usage (from [SeparatorTest.tsx](https://github.com/microsoft/fluentui-react-native/blob/master/apps/fluent-tester/src/FluentTester/TestComponents/Separator/SeparatorTest.tsx)) diff --git a/apps/public-docsite/src/pages/Controls/SeparatorPage/docs/ios/SeparatorOverview.md b/apps/public-docsite/src/pages/Controls/SeparatorPage/docs/ios/SeparatorOverview.md index afa8f0d2562f6..9937664ed24d8 100644 --- a/apps/public-docsite/src/pages/Controls/SeparatorPage/docs/ios/SeparatorOverview.md +++ b/apps/public-docsite/src/pages/Controls/SeparatorPage/docs/ios/SeparatorOverview.md @@ -2,7 +2,7 @@ A separator visually separates content into groups. - - + + diff --git a/apps/public-docsite/src/pages/Controls/SeparatorPage/docs/mac/SeparatorOverview.md b/apps/public-docsite/src/pages/Controls/SeparatorPage/docs/mac/SeparatorOverview.md index a21e752ba76f7..8e1bc0b07f469 100644 --- a/apps/public-docsite/src/pages/Controls/SeparatorPage/docs/mac/SeparatorOverview.md +++ b/apps/public-docsite/src/pages/Controls/SeparatorPage/docs/mac/SeparatorOverview.md @@ -2,7 +2,7 @@ A separator visually separates content into groups. - - + + diff --git a/apps/public-docsite/src/pages/Controls/ShimmerPage/ShimmerPage.tsx b/apps/public-docsite/src/pages/Controls/ShimmerPage/ShimmerPage.tsx index 8958377648df8..162ab6df92250 100644 --- a/apps/public-docsite/src/pages/Controls/ShimmerPage/ShimmerPage.tsx +++ b/apps/public-docsite/src/pages/Controls/ShimmerPage/ShimmerPage.tsx @@ -12,13 +12,13 @@ export const ShimmerPage: React.FunctionComponent = props => ); }; -function _otherSections(platform: Platforms): IPageSectionProps[] { +function _otherSections(platform: Platforms): IPageSectionProps[] | undefined { switch (platform) { case 'ios': return [ diff --git a/apps/public-docsite/src/pages/Controls/ShimmerPage/docs/ios/ShimmerOverview.md b/apps/public-docsite/src/pages/Controls/ShimmerPage/docs/ios/ShimmerOverview.md index 5d42ebb4883ee..fc6db4f581691 100644 --- a/apps/public-docsite/src/pages/Controls/ShimmerPage/docs/ios/ShimmerOverview.md +++ b/apps/public-docsite/src/pages/Controls/ShimmerPage/docs/ios/ShimmerOverview.md @@ -2,7 +2,7 @@ Shimmer is a temporary animation placeholder for when a service call takes time - - + + diff --git a/apps/public-docsite/src/pages/Controls/SliderPage/SliderPage.tsx b/apps/public-docsite/src/pages/Controls/SliderPage/SliderPage.tsx index f728de0296229..53f9beeb789d4 100644 --- a/apps/public-docsite/src/pages/Controls/SliderPage/SliderPage.tsx +++ b/apps/public-docsite/src/pages/Controls/SliderPage/SliderPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { SliderPageProps } from './SliderPage.doc'; export const SliderPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/SnackbarPage/SnackbarPage.tsx b/apps/public-docsite/src/pages/Controls/SnackbarPage/SnackbarPage.tsx index 231136bf95079..0b956b8154789 100644 --- a/apps/public-docsite/src/pages/Controls/SnackbarPage/SnackbarPage.tsx +++ b/apps/public-docsite/src/pages/Controls/SnackbarPage/SnackbarPage.tsx @@ -12,13 +12,13 @@ export const SnackbarPage: React.FunctionComponent = props = return ( ); }; -function _otherSections(platform: Platforms): IPageSectionProps[] { +function _otherSections(platform: Platforms): IPageSectionProps[] | undefined { switch (platform) { case 'android': return [ diff --git a/apps/public-docsite/src/pages/Controls/SnackbarPage/docs/android/SnackbarOverview.md b/apps/public-docsite/src/pages/Controls/SnackbarPage/docs/android/SnackbarOverview.md index 68ad973f6df0b..43f534dc5523c 100644 --- a/apps/public-docsite/src/pages/Controls/SnackbarPage/docs/android/SnackbarOverview.md +++ b/apps/public-docsite/src/pages/Controls/SnackbarPage/docs/android/SnackbarOverview.md @@ -3,11 +3,11 @@ Snackbars provide a brief message about an operation at the bottom of the screen ### Snackbar - - + + ### Announcement Snackbar - - + + diff --git a/apps/public-docsite/src/pages/Controls/SpinButtonPage/SpinButtonPage.tsx b/apps/public-docsite/src/pages/Controls/SpinButtonPage/SpinButtonPage.tsx index 488a04c913a25..5777afcb7e01f 100644 --- a/apps/public-docsite/src/pages/Controls/SpinButtonPage/SpinButtonPage.tsx +++ b/apps/public-docsite/src/pages/Controls/SpinButtonPage/SpinButtonPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { SpinButtonPageProps } from './SpinButtonPage.doc'; export const SpinButtonPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/SpinnerPage/SpinnerPage.tsx b/apps/public-docsite/src/pages/Controls/SpinnerPage/SpinnerPage.tsx index 909c4a6d5a3e7..00873435772e5 100644 --- a/apps/public-docsite/src/pages/Controls/SpinnerPage/SpinnerPage.tsx +++ b/apps/public-docsite/src/pages/Controls/SpinnerPage/SpinnerPage.tsx @@ -10,13 +10,13 @@ export const SpinnerPage: React.FunctionComponent = props => ); }; -function _otherSections(platform: Platforms): IPageSectionProps[] { +function _otherSections(platform: Platforms): IPageSectionProps[] | undefined { switch (platform) { case 'ios': return [ diff --git a/apps/public-docsite/src/pages/Controls/SpinnerPage/docs/android/SpinnerOverview.md b/apps/public-docsite/src/pages/Controls/SpinnerPage/docs/android/SpinnerOverview.md index 3e084dfabcd54..384baa4ff1a7f 100644 --- a/apps/public-docsite/src/pages/Controls/SpinnerPage/docs/android/SpinnerOverview.md +++ b/apps/public-docsite/src/pages/Controls/SpinnerPage/docs/android/SpinnerOverview.md @@ -7,6 +7,6 @@ Use a standalone spinner when you need a progress indicator on an existing surfa ### Spinner - - + + diff --git a/apps/public-docsite/src/pages/Controls/SpinnerPage/docs/ios/SpinnerOverview.md b/apps/public-docsite/src/pages/Controls/SpinnerPage/docs/ios/SpinnerOverview.md index 9c83d0a77ceb1..3c102d10d5ecd 100644 --- a/apps/public-docsite/src/pages/Controls/SpinnerPage/docs/ios/SpinnerOverview.md +++ b/apps/public-docsite/src/pages/Controls/SpinnerPage/docs/ios/SpinnerOverview.md @@ -9,12 +9,12 @@ For actions that happen "between views", you can use the progress indicator that ### Activity Indicator - - + + ### HUD - - + + diff --git a/apps/public-docsite/src/pages/Controls/StackPage/StackPage.tsx b/apps/public-docsite/src/pages/Controls/StackPage/StackPage.tsx index 129f316dc4527..e3e72c7a7bad2 100644 --- a/apps/public-docsite/src/pages/Controls/StackPage/StackPage.tsx +++ b/apps/public-docsite/src/pages/Controls/StackPage/StackPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { StackPageProps } from './StackPage.doc'; export const StackPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/SwatchColorPickerPage/SwatchColorPickerPage.tsx b/apps/public-docsite/src/pages/Controls/SwatchColorPickerPage/SwatchColorPickerPage.tsx index b9b1afe27a44a..7f3faab52e61b 100644 --- a/apps/public-docsite/src/pages/Controls/SwatchColorPickerPage/SwatchColorPickerPage.tsx +++ b/apps/public-docsite/src/pages/Controls/SwatchColorPickerPage/SwatchColorPickerPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { SwatchColorPickerPageProps } from './SwatchColorPickerPage.doc'; export const SwatchColorPickerPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/TeachingBubblePage/TeachingBubblePage.tsx b/apps/public-docsite/src/pages/Controls/TeachingBubblePage/TeachingBubblePage.tsx index 19ea54594b547..d4fc9b248a915 100644 --- a/apps/public-docsite/src/pages/Controls/TeachingBubblePage/TeachingBubblePage.tsx +++ b/apps/public-docsite/src/pages/Controls/TeachingBubblePage/TeachingBubblePage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { TeachingBubblePageProps } from './TeachingBubblePage.doc'; export const TeachingBubblePage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/TextFieldPage/TextFieldPage.tsx b/apps/public-docsite/src/pages/Controls/TextFieldPage/TextFieldPage.tsx index 0046f279c1fdb..42f0433a2a04b 100644 --- a/apps/public-docsite/src/pages/Controls/TextFieldPage/TextFieldPage.tsx +++ b/apps/public-docsite/src/pages/Controls/TextFieldPage/TextFieldPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { TextFieldPageProps } from './TextFieldPage.doc'; export const TextFieldPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/TextPage/TextPage.doc.ts b/apps/public-docsite/src/pages/Controls/TextPage/TextPage.doc.ts index a2878d5d784c3..530b3ade2eef0 100644 --- a/apps/public-docsite/src/pages/Controls/TextPage/TextPage.doc.ts +++ b/apps/public-docsite/src/pages/Controls/TextPage/TextPage.doc.ts @@ -6,7 +6,7 @@ const related: ISideRailLink[] = [ { text: 'Web Text', url: '#/controls/web/text' }, { text: 'iOS Text', url: '#/controls/ios/text' }, { text: 'Android Text', url: '#/controls/android/text' }, - { text: 'Cross-platform Text', url: '#/controls/crossplatform/text' }, + { text: 'Cross-platform Text', url: '#/controls/cross/text' }, ]; const componentUrl = 'https://github.com/microsoft/fluentui/tree/master/apps/public-docsite/src/pages/Controls/TextPage'; diff --git a/apps/public-docsite/src/pages/Controls/TextPage/TextPage.tsx b/apps/public-docsite/src/pages/Controls/TextPage/TextPage.tsx index 0f61532f142fd..4ed8005229fa9 100644 --- a/apps/public-docsite/src/pages/Controls/TextPage/TextPage.tsx +++ b/apps/public-docsite/src/pages/Controls/TextPage/TextPage.tsx @@ -15,13 +15,13 @@ export const TextPage: React.FunctionComponent = props => { ); }; -function _otherSections(platform: Platforms): IPageSectionProps[] { +function _otherSections(platform: Platforms): IPageSectionProps[] | undefined { switch (platform) { case 'ios': return [ diff --git a/apps/public-docsite/src/pages/Controls/TextPage/docs/android/TextOverview.md b/apps/public-docsite/src/pages/Controls/TextPage/docs/android/TextOverview.md index be6f19edae754..c971c5dd59021 100644 --- a/apps/public-docsite/src/pages/Controls/TextPage/docs/android/TextOverview.md +++ b/apps/public-docsite/src/pages/Controls/TextPage/docs/android/TextOverview.md @@ -2,7 +2,7 @@ Use these typography styles to standardize text across your app. - - + + diff --git a/apps/public-docsite/src/pages/Controls/TextPage/docs/cross/TextUsage.md b/apps/public-docsite/src/pages/Controls/TextPage/docs/cross/TextUsage.md index ed63574634a20..81f836cca21ff 100644 --- a/apps/public-docsite/src/pages/Controls/TextPage/docs/cross/TextUsage.md +++ b/apps/public-docsite/src/pages/Controls/TextPage/docs/cross/TextUsage.md @@ -5,15 +5,15 @@ If you need to customize the fontFamily, fontSize, or fontWeight of your Text, y ### Text example On Windows, Text uses the Segoe UI font family. - + On macOS, Text uses the San Francisco font family. - + ### Text ramp example You can specify the `variant` prop to apply font styles to Text. Examples of `variant` values are shown below. - + #### Example usage (from [TextTest.tsx](https://github.com/microsoft/fluentui-react-native/tree/master/apps/fluent-tester/src/FluentTester/TestComponents/Text)) diff --git a/apps/public-docsite/src/pages/Controls/TextPage/docs/ios/TextOverview.md b/apps/public-docsite/src/pages/Controls/TextPage/docs/ios/TextOverview.md index c18e1869ee77d..a070472fc8d3e 100644 --- a/apps/public-docsite/src/pages/Controls/TextPage/docs/ios/TextOverview.md +++ b/apps/public-docsite/src/pages/Controls/TextPage/docs/ios/TextOverview.md @@ -2,7 +2,7 @@ Use `Label` to standardize text across your app. - - + + diff --git a/apps/public-docsite/src/pages/Controls/ThemeProviderPage/ThemeProviderPage.tsx b/apps/public-docsite/src/pages/Controls/ThemeProviderPage/ThemeProviderPage.tsx index 1827fad21dc3c..dc09c5dff30b6 100644 --- a/apps/public-docsite/src/pages/Controls/ThemeProviderPage/ThemeProviderPage.tsx +++ b/apps/public-docsite/src/pages/Controls/ThemeProviderPage/ThemeProviderPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { ThemeProviderProps } from './ThemeProviderPage.doc'; export const ThemeProviderPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/ThemesPage/ThemesPage.tsx b/apps/public-docsite/src/pages/Controls/ThemesPage/ThemesPage.tsx index e4e247d16fd7d..17d1365337950 100644 --- a/apps/public-docsite/src/pages/Controls/ThemesPage/ThemesPage.tsx +++ b/apps/public-docsite/src/pages/Controls/ThemesPage/ThemesPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { ThemesPageProps } from './ThemesPage.doc'; export const ThemesPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/TimePickerPage/TimePickerPage.tsx b/apps/public-docsite/src/pages/Controls/TimePickerPage/TimePickerPage.tsx index 9d603c42e4e73..bca13e85b9c5b 100644 --- a/apps/public-docsite/src/pages/Controls/TimePickerPage/TimePickerPage.tsx +++ b/apps/public-docsite/src/pages/Controls/TimePickerPage/TimePickerPage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { TimePickerPageProps } from './TimePickerPage.doc'; export const TimePickerPage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/TogglePage/TogglePage.tsx b/apps/public-docsite/src/pages/Controls/TogglePage/TogglePage.tsx index bfd707d9e4916..f9dcc8adab8b9 100644 --- a/apps/public-docsite/src/pages/Controls/TogglePage/TogglePage.tsx +++ b/apps/public-docsite/src/pages/Controls/TogglePage/TogglePage.tsx @@ -3,5 +3,5 @@ import { ControlsAreaPage, IControlsPageProps } from '../ControlsAreaPage'; import { TogglePageProps } from './TogglePage.doc'; export const TogglePage: React.FunctionComponent = props => { - return ; + return ; }; diff --git a/apps/public-docsite/src/pages/Controls/TooltipPage/TooltipPage.tsx b/apps/public-docsite/src/pages/Controls/TooltipPage/TooltipPage.tsx index 292440b8c4ddc..39abb5b6f531c 100644 --- a/apps/public-docsite/src/pages/Controls/TooltipPage/TooltipPage.tsx +++ b/apps/public-docsite/src/pages/Controls/TooltipPage/TooltipPage.tsx @@ -11,7 +11,7 @@ export const TooltipPage: React.FunctionComponent = props => ); diff --git a/apps/public-docsite/src/pages/Controls/TooltipPage/docs/android/TooltipOverview.md b/apps/public-docsite/src/pages/Controls/TooltipPage/docs/android/TooltipOverview.md index 6f3b81fb32218..a73919b8d435c 100644 --- a/apps/public-docsite/src/pages/Controls/TooltipPage/docs/android/TooltipOverview.md +++ b/apps/public-docsite/src/pages/Controls/TooltipPage/docs/android/TooltipOverview.md @@ -3,12 +3,12 @@ Use tooltips to show small unobtrusive hints on top of your app's UI. These can ### One line - - + + ### Two line - - + + diff --git a/apps/public-docsite/src/pages/Controls/TooltipPage/docs/ios/TooltipOverview.md b/apps/public-docsite/src/pages/Controls/TooltipPage/docs/ios/TooltipOverview.md index 657a19a40c5f2..7ba2daa0ebb60 100644 --- a/apps/public-docsite/src/pages/Controls/TooltipPage/docs/ios/TooltipOverview.md +++ b/apps/public-docsite/src/pages/Controls/TooltipPage/docs/ios/TooltipOverview.md @@ -3,12 +3,12 @@ Use tooltips to show small unobtrusive hints on top of your app's UI. These can ### One line - - + + ### Two line - - + + diff --git a/apps/public-docsite/src/pages/HomePage/HomePage.base.tsx b/apps/public-docsite/src/pages/HomePage/HomePage.base.tsx index f2ff28c099056..b5b7066fdf0a0 100644 --- a/apps/public-docsite/src/pages/HomePage/HomePage.base.tsx +++ b/apps/public-docsite/src/pages/HomePage/HomePage.base.tsx @@ -23,6 +23,7 @@ import { windowsLogoColor, macLogoColor, crossPlatformLogoColor, + cdnUrl, } from '../../utilities/index'; import { SiteDefinition } from '../../SiteDefinition/SiteDefinition'; import { IHomePageProps, IHomePageStyles, IHomePageStyleProps } from './HomePage.types'; @@ -41,7 +42,7 @@ registerIcons({ }, }); -const fabricUsageIconBaseUrl = 'https://static2.sharepointonline.com/files/fabric/assets/brand-icons/product/svg/'; +const fabricUsageIconBaseUrl = `${cdnUrl}/assets/brand-icons/product/svg/`; /** * List of App/Brand icon names that use Fluent UI. @@ -105,7 +106,7 @@ export class HomePageBase extends React.Component @@ -315,10 +316,10 @@ export class HomePageBase extends React.Component
    • - {this._renderLink('#/controls/crossplatform', 'Controls', { ariaLabel: 'Controls: Cross-platform' })} + {this._renderLink('#/controls/cross', 'Controls', { ariaLabel: 'Controls: Cross-platform' })}
    • - {this._renderLink('#/get-started/crossplatform', 'Get started', { + {this._renderLink('#/get-started/cross', 'Get started', { ariaLabel: 'Get started: Cross-platform', })}
    • @@ -335,7 +336,7 @@ export class HomePageBase extends React.Component
      Resources illustration diff --git a/apps/public-docsite/src/pages/NotFoundPage/NotFoundPage.tsx b/apps/public-docsite/src/pages/NotFoundPage/NotFoundPage.tsx index edfd441990db2..28fd52d07ca34 100644 --- a/apps/public-docsite/src/pages/NotFoundPage/NotFoundPage.tsx +++ b/apps/public-docsite/src/pages/NotFoundPage/NotFoundPage.tsx @@ -12,11 +12,12 @@ import { } from '@fluentui/react-docsite-components/lib/index2'; import { SiteDefinition } from '../../SiteDefinition/index'; import { topNavHeight, mediaQuery } from '../../styles/constants'; +import { cdnUrl } from '../../utilities/cdn'; const illustrations = [ - 'https://static2.sharepointonline.com/files/fabric/office-ui-fabric-react-assets/images/error/error1.svg', - 'https://static2.sharepointonline.com/files/fabric/office-ui-fabric-react-assets/images/error/error2.svg', - 'https://static2.sharepointonline.com/files/fabric/office-ui-fabric-react-assets/images/error/error3.svg', + `${cdnUrl}/office-ui-fabric-react-assets/images/error/error1.svg`, + `${cdnUrl}/office-ui-fabric-react-assets/images/error/error2.svg`, + `${cdnUrl}/office-ui-fabric-react-assets/images/error/error3.svg`, ]; const rootClass = mergeStyles({ @@ -70,7 +71,7 @@ export class NotFoundPage extends React.Component { ]; /** Gets the top level page from the current URL and returns a link to it. */ - private _getAreaLink = (): JSX.Element => { + private _getAreaLink = (): JSX.Element | undefined => { const area = getSiteArea(SiteDefinition.pages); const pageForArea = SiteDefinition.pages.filter(page => page.title === area)[0]; if (pageForArea) { @@ -78,7 +79,7 @@ export class NotFoundPage extends React.Component { return (
    • - this._onInternalLinkClick(ev, url)} underline> + this._onInternalLinkClick(ev, url!)} underline> {title}
    • @@ -87,7 +88,7 @@ export class NotFoundPage extends React.Component { }; /** Renders a button to go back in the browser history only if there is a page to go back to. */ - private _renderBackButton = (): JSX.Element => { + private _renderBackButton = (): JSX.Element | undefined => { if (window.history.length > 1) { return (

      diff --git a/apps/public-docsite/src/pages/Overviews/ControlsPage/ControlsPage.tsx b/apps/public-docsite/src/pages/Overviews/ControlsPage/ControlsPage.tsx index 7ac76ae74d14f..43022905623d6 100644 --- a/apps/public-docsite/src/pages/Overviews/ControlsPage/ControlsPage.tsx +++ b/apps/public-docsite/src/pages/Overviews/ControlsPage/ControlsPage.tsx @@ -20,21 +20,21 @@ const ControlsPageBase: React.FunctionComponent> = props = {...props} title="Controls" platform={platform} - subTitle={getSubTitle(platform)} - otherSections={_otherSections(platform) as IPageSectionProps[]} + subTitle={getSubTitle(platform!)} + otherSections={_otherSections(platform!) as IPageSectionProps[]} showSideRail={false} versionSwitcherDefinition={platform === Platforms.web ? SiteDefinition.versionSwitcherDefinition : undefined} - {...ControlsPageProps[platform]} + {...ControlsPageProps[platform!]} /> ); }; -function _otherSections(platform: Platforms): IPageSectionProps[] { +function _otherSections(platform: Platforms): IPageSectionProps[] | undefined { const controls = SiteDefinition.pages.filter(page => page.title === 'Controls')[0].platforms; - const platformControls: INavPage[] = controls[platform]; + const platformControls: INavPage[] | undefined = controls![platform]; if (platformControls) { - let sections: IPageSectionProps[] = platformControls + let sections = platformControls .filter(page => !page.isHiddenFromMainNav && page.isCategory) .map( category => @@ -55,14 +55,16 @@ function _otherSections(platform: Platforms): IPageSectionProps[] {

    ), }, - ); + ) as IPageSectionProps[]; - _otherControlsRequestSections(platform) !== undefined && sections.push(_otherControlsRequestSections(platform)); + const _otherControlsRequestSectionsValue = _otherControlsRequestSections(platform); + + _otherControlsRequestSectionsValue !== undefined && sections.push(_otherControlsRequestSectionsValue); return sections; } } -function _otherControlsRequestSections(platform: Platforms): IPageSectionProps { +function _otherControlsRequestSections(platform: Platforms): IPageSectionProps | undefined { switch (platform) { case 'web': return { diff --git a/apps/public-docsite/src/pages/Overviews/GetStartedPage/GetStartedPage.tsx b/apps/public-docsite/src/pages/Overviews/GetStartedPage/GetStartedPage.tsx index bfb0a1491df3f..bc481cac223a8 100644 --- a/apps/public-docsite/src/pages/Overviews/GetStartedPage/GetStartedPage.tsx +++ b/apps/public-docsite/src/pages/Overviews/GetStartedPage/GetStartedPage.tsx @@ -16,10 +16,10 @@ const GetStartedPageBase: React.FunctionComponent = props return ( ); }; diff --git a/apps/public-docsite/src/pages/Overviews/GetStartedPage/docs/web/GetStartedDesign.md b/apps/public-docsite/src/pages/Overviews/GetStartedPage/docs/web/GetStartedDesign.md index c4df274def486..868d86ffc4ab4 100644 --- a/apps/public-docsite/src/pages/Overviews/GetStartedPage/docs/web/GetStartedDesign.md +++ b/apps/public-docsite/src/pages/Overviews/GetStartedPage/docs/web/GetStartedDesign.md @@ -4,7 +4,7 @@ Fluent UI gives you access to Segoe, Microsoft’s official typeface, along with ### Icons -Fluent UI includes Office’s official product icons. Fluent UI also provides a suite of product and document symbols, so you can use the same metaphors we use. [Learn more](#/styles/web/icons) +Fluent UI includes Microsoft 365's official product icons. Fluent UI also provides a suite of product and document symbols, so you can use the same metaphors we use. [Learn more](#/styles/web/icons) ### Controls diff --git a/apps/public-docsite/src/pages/Overviews/GetStartedPage/docs/web/GetStartedDevelopCore.md b/apps/public-docsite/src/pages/Overviews/GetStartedPage/docs/web/GetStartedDevelopCore.md index cc6294b3462b0..0c254b08a7e06 100644 --- a/apps/public-docsite/src/pages/Overviews/GetStartedPage/docs/web/GetStartedDevelopCore.md +++ b/apps/public-docsite/src/pages/Overviews/GetStartedPage/docs/web/GetStartedDevelopCore.md @@ -8,12 +8,12 @@ If you're using Fluent UI React, you may not need Fabric Core. Most of the style ### Adding Fabric Core to your site -To add the latest version of Fabric Core to your site, link to this CSS file in the `` of your webpage. (For the MDL2 styles used in Fabric 6, replace `11.0.0` with `9.6.1` in the `href`.) +To add the latest version of Fabric Core to your site, link to this CSS file in the `` of your webpage. (For the MDL2 styles used in Fabric 6, replace `11.1.0` with `9.6.1` in the `href`.) ```html ``` diff --git a/apps/public-docsite/src/pages/Overviews/ResourcesPage/docs/default/ResourcesDesignResources.md b/apps/public-docsite/src/pages/Overviews/ResourcesPage/docs/default/ResourcesDesignResources.md index 935baaad273b8..55e65d245cd57 100644 --- a/apps/public-docsite/src/pages/Overviews/ResourcesPage/docs/default/ResourcesDesignResources.md +++ b/apps/public-docsite/src/pages/Overviews/ResourcesPage/docs/default/ResourcesDesignResources.md @@ -22,16 +22,6 @@ These SharePoint design resources provide everything you need to design your web
  • [SharePoint Toolkit (Figma)](https://aka.ms/SharePointToolkits/Web/Figma)
  • -

    Office Add-ins

    - -The Add-ins design toolkit provides layouts for interface elements and commonly used patterns in Word, Excel, and PowerPoint. Use it in addition to the Microsoft design toolkits to create an add-in that fits within Office. - -
      -
    • [Add-ins Toolkit (Sketch)](https://aka.ms/addins_sketch_toolkit)
    • -
    • [Designing Office Add-ins](https://docs.microsoft.com/en-us/office/dev/add-ins/design/add-in-design)
    • -
    • [Add-ins Toolkit (XD)](https://aka.ms/addins_toolkit)
    • -
    - ### Fonts
      diff --git a/apps/public-docsite/src/pages/Overviews/ResourcesPage/docs/default/ResourcesDeveloperResources.md b/apps/public-docsite/src/pages/Overviews/ResourcesPage/docs/default/ResourcesDeveloperResources.md index abce5f2d41a72..4237577575722 100644 --- a/apps/public-docsite/src/pages/Overviews/ResourcesPage/docs/default/ResourcesDeveloperResources.md +++ b/apps/public-docsite/src/pages/Overviews/ResourcesPage/docs/default/ResourcesDeveloperResources.md @@ -41,12 +41,3 @@ SharePoint uses Fluent UI, so if you’re building on top of or within a SharePo
    • [Theme Designer](https://aka.ms/themedesigner)
    • [Get started with building client-side web parts](https://aka.ms/spfx-tutorials)
    - -

    Office Add-ins

    - -Fluent UI is the official UI toolkit for creating Office Add-ins. Check out some of these resources to learn more about how to use Fluent UI in your next Add-in. - -
      -
    • [Add-ins overview](https://docs.microsoft.com/office/dev/add-ins/)
    • -
    • [Using Fluent UI React in your Add-ins](https://docs.microsoft.com/office/dev/add-ins/design/add-in-design)
    • -
    diff --git a/apps/public-docsite/src/pages/Overviews/StylesPage/StylesPage.tsx b/apps/public-docsite/src/pages/Overviews/StylesPage/StylesPage.tsx index b5f5a172c6ec4..daa8b625567f4 100644 --- a/apps/public-docsite/src/pages/Overviews/StylesPage/StylesPage.tsx +++ b/apps/public-docsite/src/pages/Overviews/StylesPage/StylesPage.tsx @@ -17,8 +17,8 @@ const StylesPageBase: React.FunctionComponent> = props => diff --git a/apps/public-docsite/src/pages/PageTemplates/TemplatePage/TemplatePage.tsx b/apps/public-docsite/src/pages/PageTemplates/TemplatePage/TemplatePage.tsx index f0d515a18e5e3..f8580f42723e9 100644 --- a/apps/public-docsite/src/pages/PageTemplates/TemplatePage/TemplatePage.tsx +++ b/apps/public-docsite/src/pages/PageTemplates/TemplatePage/TemplatePage.tsx @@ -34,12 +34,12 @@ const TemplatePageBase: React.FunctionComponent = props => { // Pass all the props to the Page component. {...props} // Use the platform specific props from the doc.ts file. - {...TemplatePageProps[platform]} + {...TemplatePageProps[platform!]} // Use the getSubTitle helper function to get the page header subtitle from the active platform. - subTitle={getSubTitle(platform)} + subTitle={getSubTitle(platform!)} // You can define custom sections using the `otherSections` prop. // Here it is using a method that takes the platform as an argument to return the correct array of section props. - otherSections={_otherSections(platform) as IPageSectionProps[]} + otherSections={_otherSections(platform!) as IPageSectionProps[]} // You can hide the side rail by setting `showSideRail` to false. // showSideRail={false} diff --git a/apps/public-docsite/src/pages/Styles/Colors/MessagingPage.tsx b/apps/public-docsite/src/pages/Styles/Colors/MessagingPage.tsx index 7711d13d78948..b14c8c3fc6a55 100644 --- a/apps/public-docsite/src/pages/Styles/Colors/MessagingPage.tsx +++ b/apps/public-docsite/src/pages/Styles/Colors/MessagingPage.tsx @@ -11,8 +11,8 @@ export const ColorsMessagingPage: React.FunctionComponent = pr return ( ); }; diff --git a/apps/public-docsite/src/pages/Styles/Colors/NeutralsPage.tsx b/apps/public-docsite/src/pages/Styles/Colors/NeutralsPage.tsx index 9d71ed59584b2..a276563856547 100644 --- a/apps/public-docsite/src/pages/Styles/Colors/NeutralsPage.tsx +++ b/apps/public-docsite/src/pages/Styles/Colors/NeutralsPage.tsx @@ -14,8 +14,8 @@ export const ColorsNeutralsPage: React.FunctionComponent = pro return ( ); }; diff --git a/apps/public-docsite/src/pages/Styles/Colors/PersonasPage.tsx b/apps/public-docsite/src/pages/Styles/Colors/PersonasPage.tsx index 438f349aae407..82e49838efafc 100644 --- a/apps/public-docsite/src/pages/Styles/Colors/PersonasPage.tsx +++ b/apps/public-docsite/src/pages/Styles/Colors/PersonasPage.tsx @@ -16,8 +16,8 @@ export const ColorsPersonasPage: React.FunctionComponent = pro return ( ); }; diff --git a/apps/public-docsite/src/pages/Styles/Colors/PresencePage.tsx b/apps/public-docsite/src/pages/Styles/Colors/PresencePage.tsx index 2954269b8c0ed..a575dc5d1e854 100644 --- a/apps/public-docsite/src/pages/Styles/Colors/PresencePage.tsx +++ b/apps/public-docsite/src/pages/Styles/Colors/PresencePage.tsx @@ -11,8 +11,8 @@ export const ColorsPresencePage: React.FunctionComponent = pro return ( ); }; diff --git a/apps/public-docsite/src/pages/Styles/Colors/ProductsPage.tsx b/apps/public-docsite/src/pages/Styles/Colors/ProductsPage.tsx index 6c5f12fe30a13..65c8c5952b627 100644 --- a/apps/public-docsite/src/pages/Styles/Colors/ProductsPage.tsx +++ b/apps/public-docsite/src/pages/Styles/Colors/ProductsPage.tsx @@ -34,16 +34,16 @@ export interface IColorsProductsPageState { export class ColorsProductsPage extends React.Component { public readonly state = { - activeAppColorPalette: null, - activeAppDetails: null, - }; + activeAppColorPalette: undefined, + activeAppDetails: undefined, + } as IColorsProductsPageState; public render() { return ( ); } @@ -67,6 +67,7 @@ export class ColorsProductsPage extends React.Component {activeAppColorPalette.name} + {/* @ts-expect-error - FIXME: notes property doesn't exist within IColorPaletteTheme */}

    {activeAppColorPalette.notes}

    @@ -98,7 +99,7 @@ export class ColorsProductsPage extends React.Component = props return ( ); }; diff --git a/apps/public-docsite/src/pages/Styles/Colors/docs/web/ColorsNeutrals.md b/apps/public-docsite/src/pages/Styles/Colors/docs/web/ColorsNeutrals.md index 451406bc4ec60..2521dea7b385f 100644 --- a/apps/public-docsite/src/pages/Styles/Colors/docs/web/ColorsNeutrals.md +++ b/apps/public-docsite/src/pages/Styles/Colors/docs/web/ColorsNeutrals.md @@ -1,5 +1,5 @@ These are commonly used for backgrounds, strokes, and interactive states within controls. -This palette can be used to customize your `theme.palette`. See how our default `theme.palette` maps to new Fluent colors with this [web color conversion table](https://static2.sharepointonline.com/files/fabric/fabric-website/files/fabric-neutrals-web-color-conversion.pdf).​​ +This palette can be used to customize your `theme.palette`. See how our default `theme.palette` maps to new Fluent colors with this [web color conversion table](https://res-1.cdn.office.net/files/fabric-cdn-prod_20221209.001/fabric-website/files/fabric-neutrals-web-color-conversion.pdf).​​ In case you have a need to create a custom neutral theme palette to use in your application, you can use the [Theme Designer](https://aka.ms/themedesigner).​ diff --git a/apps/public-docsite/src/pages/Styles/Colors/palettes/Excel.tsx b/apps/public-docsite/src/pages/Styles/Colors/palettes/Excel.tsx index 0cb9d3e78f367..3447f5e32932a 100644 --- a/apps/public-docsite/src/pages/Styles/Colors/palettes/Excel.tsx +++ b/apps/public-docsite/src/pages/Styles/Colors/palettes/Excel.tsx @@ -9,37 +9,37 @@ export const Excel = () => { Excel diff --git a/apps/public-docsite/src/pages/Styles/Colors/palettes/SharePoint.tsx b/apps/public-docsite/src/pages/Styles/Colors/palettes/SharePoint.tsx index adec3ed0913ac..389ff018c3750 100644 --- a/apps/public-docsite/src/pages/Styles/Colors/palettes/SharePoint.tsx +++ b/apps/public-docsite/src/pages/Styles/Colors/palettes/SharePoint.tsx @@ -2,10 +2,11 @@ import * as React from 'react'; import { ColorPalette, IColorSwatch, MarkdownHeader } from '@fluentui/react-docsite-components/lib/index2'; import { SharePointNeutrals, SharePointThemes } from './sharePointThemes'; -export class SharePoint extends React.Component<{}, { activeThemeName?: string }> { +type SharePointState = { activeThemeName?: string }; +export class SharePoint extends React.Component<{}, SharePointState> { public readonly state = { - activeThemeName: null, - }; + activeThemeName: undefined, + } as SharePointState; public render() { const { activeThemeName } = this.state; @@ -45,11 +46,12 @@ export class SharePoint extends React.Component<{}, { activeThemeName?: string } } private _changeTheme = (theme: IColorSwatch) => { - this.setState( - prevState => - prevState.activeThemeName !== theme.name && { - activeThemeName: theme.name, - }, + this.setState(prevState => + prevState.activeThemeName !== theme.name + ? { + activeThemeName: theme.name, + } + : {}, ); }; } diff --git a/apps/public-docsite/src/pages/Styles/ElevationPage/ElevationPage.tsx b/apps/public-docsite/src/pages/Styles/ElevationPage/ElevationPage.tsx index 912c1c209ada7..6e998bd834b1e 100644 --- a/apps/public-docsite/src/pages/Styles/ElevationPage/ElevationPage.tsx +++ b/apps/public-docsite/src/pages/Styles/ElevationPage/ElevationPage.tsx @@ -14,8 +14,8 @@ export const ElevationPage: React.FunctionComponent = props => return ( ); }; @@ -124,7 +124,7 @@ function _renderDepthsTable() {
    ); default: - return row[column.rowProperty]; + return row[column.rowProperty!]; } }} /> diff --git a/apps/public-docsite/src/pages/Styles/FabricIconsPage/FabricIconsPage.tsx b/apps/public-docsite/src/pages/Styles/FabricIconsPage/FabricIconsPage.tsx index dc6a39ed79787..c3e0a6534abda 100644 --- a/apps/public-docsite/src/pages/Styles/FabricIconsPage/FabricIconsPage.tsx +++ b/apps/public-docsite/src/pages/Styles/FabricIconsPage/FabricIconsPage.tsx @@ -19,8 +19,8 @@ export const FabricIconsPage: React.FunctionComponent = props return ( ); }; @@ -52,7 +52,7 @@ function _otherSections(platform: Platforms): IPageSectionProps[] { content: ( { - setSelectedItem(item.props.itemKey); + setSelectedItem(item!.props.itemKey!); }} > @@ -69,7 +69,7 @@ function _otherSections(platform: Platforms): IPageSectionProps[] { ) } - + {selectedItem === 'svg-branded' && ( )} diff --git a/apps/public-docsite/src/pages/Styles/FabricIconsPage/docs/web/FabricIconsOverview.md b/apps/public-docsite/src/pages/Styles/FabricIconsPage/docs/web/FabricIconsOverview.md index 6dc50f29d7446..2a5ff87cf81d6 100644 --- a/apps/public-docsite/src/pages/Styles/FabricIconsPage/docs/web/FabricIconsOverview.md +++ b/apps/public-docsite/src/pages/Styles/FabricIconsPage/docs/web/FabricIconsOverview.md @@ -1,7 +1,7 @@ Fluent UI primarily uses a custom font for its iconography, released under the [Microsoft Fabric Assets License](https://aka.ms/fluentui-assets-license). As of Fluent UI React version 8, an SVG-based version of the same icon set is available under the MIT license. -**This page is about the general-use monoline icons. See the [brand icons page](#/styles/web/office-brand-icons) for multi-color product icons and the [file type icons page](#/styles/web/file-type-icons) for document icons.** +**This page is about the general-use monoline icons. See the [product icons page](#/styles/web/m365-product-icons) for multi-color product icons and the [file type icons page](#/styles/web/file-type-icons) for document icons.** ### When should I use Fluent UI icons? -It is recommended to use Fluent UI icons for command bars, navigation or status indicators. If you need icons to represent Office apps, see the [Office brand icons page](#/styles/web/office-brand-icons). If you are representing files or digital content, see the [file type icons page](#/styles/web/file-type-icons). +It is recommended to use Fluent UI icons for command bars, navigation or status indicators. If you need icons to represent Microsoft 365 apps, see the [Microsoft 365 product icons page](#/styles/web/m365-product-icons). If you are representing files or digital content, see the [file type icons page](#/styles/web/file-type-icons). diff --git a/apps/public-docsite/src/pages/Styles/FabricIconsPage/docs/web/FabricIconsSvgUsage.md b/apps/public-docsite/src/pages/Styles/FabricIconsPage/docs/web/FabricIconsSvgUsage.md index 0a95e5f84fe42..9c797e71929da 100644 --- a/apps/public-docsite/src/pages/Styles/FabricIconsPage/docs/web/FabricIconsSvgUsage.md +++ b/apps/public-docsite/src/pages/Styles/FabricIconsPage/docs/web/FabricIconsSvgUsage.md @@ -1,6 +1,6 @@ -An SVG-based version of Fluent UI's icon set is available from `@fluentui/react-icons-mdl2` and is released under the MIT license. This is the same MDL2 icon set used in the font icons, excluding any branded icons. +An SVG-based version of Fluent UI's icon set is available from `@fluentui/react-icons-mdl2` and is released under the MIT license. This is the same MDL2 icon set used in the font icons, excluding any product icons. -Branded SVG icons are available from `@fluentui/react-icons-mdl2-branded` and are still subject to the [Microsoft Fabric Assets License](https://aka.ms/fluentui-assets-license). +Product SVG icons are available from `@fluentui/react-icons-mdl2-branded` and are still subject to the [Microsoft Fabric Assets License](https://aka.ms/fluentui-assets-license). Both packages contain SVG icons wrapped in React components. This allows you to import and bundle only the icons you need, resulting in smaller download sizes compared to the font-based approach with `initializeIcons`, which downloads all icons by default. diff --git a/apps/public-docsite/src/pages/Styles/FileTypeIconsPage/FileTypeIconsPage.module.scss b/apps/public-docsite/src/pages/Styles/FileTypeIconsPage/FileTypeIconsPage.module.scss index c13274d71e0dd..3450cf0da0ee7 100644 --- a/apps/public-docsite/src/pages/Styles/FileTypeIconsPage/FileTypeIconsPage.module.scss +++ b/apps/public-docsite/src/pages/Styles/FileTypeIconsPage/FileTypeIconsPage.module.scss @@ -62,7 +62,7 @@ } } -.brandIconsPage .brandIconsPageLink { +.productIconsPage .productIconsPageLink { color: $ms-color-themePrimary; } diff --git a/apps/public-docsite/src/pages/Styles/FileTypeIconsPage/FileTypeIconsPage.tsx b/apps/public-docsite/src/pages/Styles/FileTypeIconsPage/FileTypeIconsPage.tsx index d38bce567ed11..0036be34cb055 100644 --- a/apps/public-docsite/src/pages/Styles/FileTypeIconsPage/FileTypeIconsPage.tsx +++ b/apps/public-docsite/src/pages/Styles/FileTypeIconsPage/FileTypeIconsPage.tsx @@ -11,15 +11,15 @@ const baseUrl = 'https://github.com/microsoft/fluentui/tree/master/apps/public-docsite/src/pages/Styles/FileTypeIconsPage/docs'; // eslint-disable-next-line import/no-extraneous-dependencies -const documentIcons = require<{ name: string }[]>('@fluentui/public-docsite/lib/data/brand-icons-documents.json'); +const documentIcons = require<{ name: string }[]>('@fluentui/public-docsite/lib/data/product-icons-documents.json'); export const FileTypeIconsPage: React.FunctionComponent = props => { const { platform } = props; return ( ); }; @@ -47,7 +47,7 @@ function _otherSections(platform: Platforms): IPageSectionProps[] { Use file type icons to indicate to users that they are creating a new file of that type. Make sure that a file of the type that the icon represents loads when the user selects the icon. For example, do not use a Word .docx icon to open a .txt file. File type icons should always represent - Microsoft Office files. + Microsoft 365 files.

    If you're looking for icons for command bars, navigation, status indicators, or similar, check out @@ -55,10 +55,10 @@ function _otherSections(platform: Platforms): IPageSectionProps[] { Fluent UI icons page - . {/* comment to prevent eslint/prettier conflict */}Alternatively, if you're looking for brand + . {/* comment to prevent eslint/prettier conflict */}Alternatively, if you're looking for product logos, or the icons of apps themselves, check out the{' '} - - Fluent UI brand icons page + + Fluent UI product icons page .

    diff --git a/apps/public-docsite/src/pages/Styles/FileTypeIconsPage/docs/web/FileTypeIconsOverview.md b/apps/public-docsite/src/pages/Styles/FileTypeIconsPage/docs/web/FileTypeIconsOverview.md index 6ce6e06097917..c726149e7b07c 100644 --- a/apps/public-docsite/src/pages/Styles/FileTypeIconsPage/docs/web/FileTypeIconsOverview.md +++ b/apps/public-docsite/src/pages/Styles/FileTypeIconsPage/docs/web/FileTypeIconsOverview.md @@ -2,4 +2,4 @@ Fluent UI includes document icons that you can use to connect your experience to File type icons represent user content, typically "files" in the classical sense, but also many "digital objects" like SharePoint pages or Sway stories. These icons are usually bigger and more detailed than command icons, and they're replaced with an actual thumbnail preview when possible. -Usage of these icons is subject to the [assets license agreement (PDF)](https://aka.ms/fluentui-assets-license). Please read this document and the resolution/size guidance carefully to ensure that you use our branded icons correctly to create the best experience. +Usage of these icons is subject to the [assets license agreement (PDF)](https://aka.ms/fluentui-assets-license). Please read this document and the resolution/size guidance carefully to ensure that you use our product icons correctly to create the best experience. diff --git a/apps/public-docsite/src/pages/Styles/LayoutPage/LayoutPage.tsx b/apps/public-docsite/src/pages/Styles/LayoutPage/LayoutPage.tsx index 57b51419b984d..edccced77d1be 100644 --- a/apps/public-docsite/src/pages/Styles/LayoutPage/LayoutPage.tsx +++ b/apps/public-docsite/src/pages/Styles/LayoutPage/LayoutPage.tsx @@ -20,13 +20,13 @@ export const LayoutPage: React.FunctionComponent = props => { return ( ); }; -function _otherSections(platform: Platforms): IPageSectionProps[] { +function _otherSections(platform: Platforms): IPageSectionProps[] | undefined { switch (platform) { case 'web': return [ diff --git a/apps/public-docsite/src/pages/Styles/LocalizationPage/LocalizationPage.tsx b/apps/public-docsite/src/pages/Styles/LocalizationPage/LocalizationPage.tsx index 28a62be45fab1..4700c6ec12c90 100644 --- a/apps/public-docsite/src/pages/Styles/LocalizationPage/LocalizationPage.tsx +++ b/apps/public-docsite/src/pages/Styles/LocalizationPage/LocalizationPage.tsx @@ -17,13 +17,13 @@ export const LocalizationPage: React.FunctionComponent = props return ( ); }; -function _otherSections(platform: Platforms): IPageSectionProps[] { +function _otherSections(platform: Platforms): IPageSectionProps[] | undefined { switch (platform) { case 'web': return [ diff --git a/apps/public-docsite/src/pages/Styles/M365ProductIconsPage/M365ProductIconsPage.doc.ts b/apps/public-docsite/src/pages/Styles/M365ProductIconsPage/M365ProductIconsPage.doc.ts new file mode 100644 index 0000000000000..f0346f84a6538 --- /dev/null +++ b/apps/public-docsite/src/pages/Styles/M365ProductIconsPage/M365ProductIconsPage.doc.ts @@ -0,0 +1,12 @@ +import { TFabricPlatformPageProps } from '../../../interfaces/Platforms'; + +const title = 'Microsoft 365 Product Icons'; +const componentUrl = + 'https://github.com/microsoft/fluentui/tree/master/apps/public-docsite/src/pages/Styles/M365ProductIconsPage'; + +export const M365ProductIconsPageProps: TFabricPlatformPageProps = { + web: { + title, + componentUrl, + }, +}; diff --git a/apps/public-docsite/src/pages/Styles/M365ProductIconsPage/M365ProductIconsPage.module.scss b/apps/public-docsite/src/pages/Styles/M365ProductIconsPage/M365ProductIconsPage.module.scss new file mode 100644 index 0000000000000..99ae5cc31ead9 --- /dev/null +++ b/apps/public-docsite/src/pages/Styles/M365ProductIconsPage/M365ProductIconsPage.module.scss @@ -0,0 +1,80 @@ +@import '../../../styles/common'; + +.paragraphInGrid { + @include ms-padding-left($contentInGrid); +} + +.exampleIcons { + align-items: flex-end; + display: flex; + justify-content: space-around; + + li { + align-items: flex-start; + display: flex; + flex-direction: column; + flex: 1; + + span { + display: block; + font-size: $ms-font-size-s; + margin-top: 20px; + } + } +} + +.exampleIcons + .exampleIcons { + margin-top: 60px; +} + +.productIcon { + width: 100%; + max-width: 96px; + height: 96px; + @include ms-padding-right(8px); +} + +.iconList { + display: flex; + flex-wrap: wrap; + + li { + align-items: center; + display: flex; + height: 60px; + margin-bottom: 20px; + width: 100%; + } + + .icon { + height: auto; + margin-right: 20px; + max-width: 48px; + } + + .iconName { + font-size: $ms-font-size-l; + font-weight: $ms-font-weight-semibold; + color: $ms-color-gray150; + } +} + +.productIconsPage .productIconsPageLink { + color: $ms-color-themePrimary; +} + +@media screen and (min-width: $uhf-screen-min-mobile) { + .iconList { + li { + width: 50%; + } + } +} + +@media screen and (min-width: $ms-screen-min-xl) { + .iconList { + li { + width: 33%; + } + } +} diff --git a/apps/public-docsite/src/pages/Styles/M365ProductIconsPage/M365ProductIconsPage.tsx b/apps/public-docsite/src/pages/Styles/M365ProductIconsPage/M365ProductIconsPage.tsx new file mode 100644 index 0000000000000..a1febd7bdb35d --- /dev/null +++ b/apps/public-docsite/src/pages/Styles/M365ProductIconsPage/M365ProductIconsPage.tsx @@ -0,0 +1,204 @@ +import * as React from 'react'; +import { Image, Link } from '@fluentui/react'; +import { Markdown, MarkdownHeader, IPageSectionProps } from '@fluentui/react-docsite-components/lib/index2'; +import { IStylesPageProps, StylesAreaPage } from '../StylesAreaPage'; +import { M365ProductIconsPageProps } from './M365ProductIconsPage.doc'; +import { Platforms } from '../../../interfaces/Platforms'; +import { cdnUrl } from '../../../utilities/cdn'; +import * as styles from './M365ProductIconsPage.module.scss'; + +const baseUrl = + 'https://github.com/microsoft/fluentui/tree/master/apps/public-docsite/src/pages/Styles/M365ProductIconsPage/docs'; +const fabricCDN = `${cdnUrl}/assets`; + +const productIcons = require< + { icon: string; name: string }[] + // eslint-disable-next-line import/no-extraneous-dependencies +>('@fluentui/public-docsite/lib/data/product-icons.json'); + +export const M365ProductIconsPage: React.FunctionComponent = props => { + const { platform } = props; + return ( + + ); +}; + +function _otherSections(platform: Platforms): IPageSectionProps[] { + switch (platform) { + case 'web': + return [ + { + sectionName: 'Overview', + editUrl: `${baseUrl}/web/M365ProductIconsOverview.md`, + content: ( + <> + + { + require('!raw-loader?esModule=false!@fluentui/public-docsite/src/pages/Styles/M365ProductIconsPage/docs/web/M365ProductIconsOverview.md') as string + } + + When should I use Microsoft 365 Product icons? +
    +
    +
    +

    + Use Microsoft 365 product icons to help your users transition between Microsoft products. Product + icons should only be used when the behavior of the command (app icon) is to launch the + application. Do not use a product icon to create a new file of that type. For example, do not use + the Word app icon for the menu option that allows users create a new Word document. +

    +

    + If you're looking for icons for command bars, navigation, status indicators, or similar, check out + the{' '} + + Fluent UI icons page + + . Alternatively, if you're looking for file type icons to represent digital content or to indicate + to users that they are creating a new file of that type, check out the{' '} + + Fluent UI file type icons page + + . +

    +
    +
    +
      +
    • + Word logo +
    • +
    • + Excel logo +
    • +
    • + PowerPoint logo +
    • +
    +
    +
    +
    + + ), + }, + { + sectionName: 'Format and sizes', + editUrl: `${baseUrl}/web/M365ProductIconsFormat.md`, + content: ( +
    +
    +
    + + { + require('!raw-loader?esModule=false!@fluentui/public-docsite/src/pages/Styles/M365ProductIconsPage/docs/web/M365ProductIconsFormat.md') as string + } + +
    +
    +
      +
    • + Outlook 16x1 PNG product icon + 16px +
    • +
    • + Outlook 32x1 PNG product icon + 32px +
    • +
    • + Outlook 48x1 PNG product icon + 48px +
    • +
    • + Outlook 96x1 PNG product icon + 96px +
    • +
    +
    +
    +
    + ), + }, + { + sectionName: 'Resolutions', + editUrl: `${baseUrl}/web/M365ProductIconsResolutions.md`, + content: ( + + { + require('!raw-loader?esModule=false!@fluentui/public-docsite/src/pages/Styles/M365ProductIconsPage/docs/web/M365ProductIconsResolutions.md') as string + } + + ), + }, + { + sectionName: 'Implementation', + editUrl: `${baseUrl}/web/M365ProductIconsImplementation.md`, + content: ( + + { + require('!raw-loader?esModule=false!@fluentui/public-docsite/src/pages/Styles/M365ProductIconsPage/docs/web/M365ProductIconsImplementation.md') as string + } + + ), + }, + + { + sectionName: 'Product icon library', + content: ( + <> +
      + {productIcons.map((icon, iconIndex) => ( +
    • + {icon.name + {icon.name} +
    • + ))} +
    + + ), + }, + ]; + + default: + return []; + } +} diff --git a/apps/public-docsite/src/pages/Styles/M365ProductIconsPage/docs/web/M365ProductIconsFormat.md b/apps/public-docsite/src/pages/Styles/M365ProductIconsPage/docs/web/M365ProductIconsFormat.md new file mode 100644 index 0000000000000..02a1a3413de58 --- /dev/null +++ b/apps/public-docsite/src/pages/Styles/M365ProductIconsPage/docs/web/M365ProductIconsFormat.md @@ -0,0 +1,5 @@ +Microsoft 365 product icons look best at 16x16, 48x48, and 96x96 pixel sizes in the UI of Microsoft products. Fluent UI provides these icons in both SVG and PNG formats. SVGs are more versatile, and can be resized more easily since they are vectors, but are not supported by all browsers. PNGs are supported by most browsers, but require many sizes to remain visually crisp. + +Both PNGs and SVGs are available in predefined dimensions at 16x16, 20x20, 32x32, 40x40, 48x48, 64x64 and 96x96 pixel sizes. Where possible, use the default sizes to prevent artifacts and blurry subpixel rendering for PNGs. Otherwise, use the size that most closely maps to what you need for your experience for the best quality. + +Monochrome product icons that are included in the icon font are subject to the branding guidelines, but you can reference them just like other icons noted in the [icons section](#/styles/web/icons). diff --git a/apps/public-docsite/src/pages/Styles/M365ProductIconsPage/docs/web/M365ProductIconsImplementation.md b/apps/public-docsite/src/pages/Styles/M365ProductIconsPage/docs/web/M365ProductIconsImplementation.md new file mode 100644 index 0000000000000..dcad916ece372 --- /dev/null +++ b/apps/public-docsite/src/pages/Styles/M365ProductIconsPage/docs/web/M365ProductIconsImplementation.md @@ -0,0 +1,24 @@ +To use the Microsoft 365 multicolor product icons, select the format and size that best meets your needs. Fluent UI includes a media query that automatically selects the right image file for the pixel density of the screen you’re targeting. + +The following code shows you how to specify a 96px product icon by brand using the [office-ui-fabric-core](https://github.com/OfficeDev/office-ui-fabric-core) CSS and a `
    ` element: + +```jsx +// Sample code for using office-ui-fabric-core version 11.1.0 to display an Word 96x96px Icon + + +
    +``` + +This following code shows you how to specify a 48px product icon by brand using the [office-ui-fabric-core](https://github.com/OfficeDev/office-ui-fabric-core) SVG and an `` element: + +```jsx +Word product icon +``` diff --git a/apps/public-docsite/src/pages/Styles/M365ProductIconsPage/docs/web/M365ProductIconsOverview.md b/apps/public-docsite/src/pages/Styles/M365ProductIconsPage/docs/web/M365ProductIconsOverview.md new file mode 100644 index 0000000000000..b1eae5decca4b --- /dev/null +++ b/apps/public-docsite/src/pages/Styles/M365ProductIconsPage/docs/web/M365ProductIconsOverview.md @@ -0,0 +1,3 @@ +Fluent UI includes product icons that you can use to connect your experience to other Microsoft 365 endpoints. The icons come in three formats: SVG and PNG for multicolor, and the [icon font for single-color](#/styles/web/icons#available-icons). All three formats come in a variety of sizes and resolutions. + +Usage of these icons is subject to the [assets license agreement (PDF)](https://aka.ms/fluentui-assets-license). Please read this document and the resolution/size guidance carefully to ensure that you use our product icons correctly to create the best experience. diff --git a/apps/public-docsite/src/pages/Styles/OfficeBrandIconsPage/docs/web/OfficeBrandIconsResolutions.md b/apps/public-docsite/src/pages/Styles/M365ProductIconsPage/docs/web/M365ProductIconsResolutions.md similarity index 100% rename from apps/public-docsite/src/pages/Styles/OfficeBrandIconsPage/docs/web/OfficeBrandIconsResolutions.md rename to apps/public-docsite/src/pages/Styles/M365ProductIconsPage/docs/web/M365ProductIconsResolutions.md diff --git a/apps/public-docsite/src/pages/Styles/OfficeBrandIconsPage/docs/web/OfficeBrandIconsSingleColor.md b/apps/public-docsite/src/pages/Styles/M365ProductIconsPage/docs/web/M365ProductIconsSingleColor.md similarity index 100% rename from apps/public-docsite/src/pages/Styles/OfficeBrandIconsPage/docs/web/OfficeBrandIconsSingleColor.md rename to apps/public-docsite/src/pages/Styles/M365ProductIconsPage/docs/web/M365ProductIconsSingleColor.md diff --git a/apps/public-docsite/src/pages/Styles/MotionPage/MotionPage.tsx b/apps/public-docsite/src/pages/Styles/MotionPage/MotionPage.tsx index c2b5266f5dfcf..13499acd65f5a 100644 --- a/apps/public-docsite/src/pages/Styles/MotionPage/MotionPage.tsx +++ b/apps/public-docsite/src/pages/Styles/MotionPage/MotionPage.tsx @@ -8,15 +8,17 @@ import { Table, Video, MarkdownCode, + ITableRowProps, } from '@fluentui/react-docsite-components/lib/index2'; import { IStylesPageProps, StylesAreaPage } from '../StylesAreaPage'; import { MotionPageProps } from './MotionPage.doc'; import { Platforms } from '../../../interfaces/Platforms'; +import { cdnUrl } from '../../../utilities/cdn'; const baseUrl = 'https://github.com/microsoft/fluentui/tree/master/apps/public-docsite/src/pages/Styles/MotionPage/docs'; -const PatternTable = ({ rows }) => ( +const PatternTable = ({ rows }: { rows: ITableRowProps[] }) => ( ( { title: 'Delay', data: 'delay' }, ]} rows={rows} - formatter={(column, row) => row[column.data]} + formatter={(column, row) => row[column.data!]} /> ); @@ -35,8 +37,8 @@ export const MotionPage: React.FunctionComponent = props => { return ( ); }; @@ -58,7 +60,7 @@ function _otherSections(platform: Platforms): IPageSectionProps[] { Delete & Slide

    This pattern for deleting an object from the view and how the remaining objects realign themselves.

    -
    @@ -87,7 +87,7 @@ export const FabricPalette: React.FunctionComponent = (prop directionalHint={DirectionalHint.leftCenter} /> - {themeRules[FabricSlots[FabricSlots.themeDark]].color.str} + {themeRules[FabricSlots[FabricSlots.themeDark]].color!.str} = (prop directionalHint={DirectionalHint.leftCenter} /> - {themeRules[FabricSlots[FabricSlots.neutralDark]].color.str} + {themeRules[FabricSlots[FabricSlots.neutralDark]].color!.str} = (prop directionalHint={DirectionalHint.leftCenter} /> - {themeRules[FabricSlots[FabricSlots.neutralDark]].color.str} + {themeRules[FabricSlots[FabricSlots.neutralDark]].color!.str} @@ -116,7 +116,7 @@ export const FabricPalette: React.FunctionComponent = (prop directionalHint={DirectionalHint.leftCenter} /> - {themeRules[FabricSlots[FabricSlots.themeDarkAlt]].color.str} + {themeRules[FabricSlots[FabricSlots.themeDarkAlt]].color!.str} = (prop directionalHint={DirectionalHint.leftCenter} /> - {themeRules[FabricSlots[FabricSlots.neutralPrimary]].color.str} + {themeRules[FabricSlots[FabricSlots.neutralPrimary]].color!.str} = (prop directionalHint={DirectionalHint.leftCenter} /> - {themeRules[FabricSlots[FabricSlots.neutralQuaternaryAlt]].color.str} + {themeRules[FabricSlots[FabricSlots.neutralQuaternaryAlt]].color!.str} @@ -145,7 +145,7 @@ export const FabricPalette: React.FunctionComponent = (prop directionalHint={DirectionalHint.leftCenter} /> - {themeRules[FabricSlots[FabricSlots.themePrimary]].color.str} + {themeRules[FabricSlots[FabricSlots.themePrimary]].color!.str} = (prop directionalHint={DirectionalHint.leftCenter} /> - {themeRules[FabricSlots[FabricSlots.neutralPrimaryAlt]].color.str} + {themeRules[FabricSlots[FabricSlots.neutralPrimaryAlt]].color!.str} = (prop directionalHint={DirectionalHint.leftCenter} /> - {themeRules[FabricSlots[FabricSlots.neutralLight]].color.str} + {themeRules[FabricSlots[FabricSlots.neutralLight]].color!.str} @@ -174,7 +174,7 @@ export const FabricPalette: React.FunctionComponent = (prop directionalHint={DirectionalHint.leftCenter} /> - {themeRules[FabricSlots[FabricSlots.themeSecondary]].color.str} + {themeRules[FabricSlots[FabricSlots.themeSecondary]].color!.str} = (prop directionalHint={DirectionalHint.leftCenter} /> - {themeRules[FabricSlots[FabricSlots.neutralSecondary]].color.str} + {themeRules[FabricSlots[FabricSlots.neutralSecondary]].color!.str} = (prop directionalHint={DirectionalHint.leftCenter} /> - {themeRules[FabricSlots[FabricSlots.neutralLighter]].color.str} + {themeRules[FabricSlots[FabricSlots.neutralLighter]].color!.str} @@ -203,7 +203,7 @@ export const FabricPalette: React.FunctionComponent = (prop directionalHint={DirectionalHint.leftCenter} /> - {themeRules[FabricSlots[FabricSlots.themeTertiary]].color.str} + {themeRules[FabricSlots[FabricSlots.themeTertiary]].color!.str} = (prop directionalHint={DirectionalHint.leftCenter} /> - {themeRules[FabricSlots[FabricSlots.neutralTertiary]].color.str} + {themeRules[FabricSlots[FabricSlots.neutralTertiary]].color!.str} = (prop directionalHint={DirectionalHint.leftCenter} /> - {themeRules[FabricSlots[FabricSlots.neutralLighterAlt]].color.str} + {themeRules[FabricSlots[FabricSlots.neutralLighterAlt]].color!.str} @@ -232,7 +232,7 @@ export const FabricPalette: React.FunctionComponent = (prop directionalHint={DirectionalHint.leftCenter} /> - {themeRules[FabricSlots[FabricSlots.themeLight]].color.str} + {themeRules[FabricSlots[FabricSlots.themeLight]].color!.str} = (prop directionalHint={DirectionalHint.leftCenter} /> - {themeRules[FabricSlots[FabricSlots.neutralSecondaryAlt]].color.str} + {themeRules[FabricSlots[FabricSlots.neutralSecondaryAlt]].color!.str} @@ -253,7 +253,7 @@ export const FabricPalette: React.FunctionComponent = (prop directionalHint={DirectionalHint.leftCenter} /> - {themeRules[FabricSlots[FabricSlots.themeLighter]].color.str} + {themeRules[FabricSlots[FabricSlots.themeLighter]].color!.str} = (prop directionalHint={DirectionalHint.leftCenter} /> - {themeRules[FabricSlots[FabricSlots.white]].color.str} + {themeRules[FabricSlots[FabricSlots.white]].color!.str} @@ -273,7 +273,7 @@ export const FabricPalette: React.FunctionComponent = (prop directionalHint={DirectionalHint.leftCenter} /> - {themeRules[FabricSlots[FabricSlots.themeLighterAlt]].color.str} + {themeRules[FabricSlots[FabricSlots.themeLighterAlt]].color!.str}
    diff --git a/apps/theming-designer/src/components/FabricSlotWidget.tsx b/apps/theming-designer/src/components/FabricSlotWidget.tsx index 030b69c02c2da..a76fa14597e51 100644 --- a/apps/theming-designer/src/components/FabricSlotWidget.tsx +++ b/apps/theming-designer/src/components/FabricSlotWidget.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { IThemeRules, FabricSlots, IThemeSlotRule } from '@fluentui/react/lib/ThemeGenerator'; +import { FabricSlots, IThemeSlotRule } from '@fluentui/react/lib/ThemeGenerator'; import { IColor } from '@fluentui/react/lib/Color'; import { Stack, IStackStyles } from '@fluentui/react/lib/Stack'; import { mergeStyles } from '@fluentui/merge-styles'; @@ -9,7 +9,7 @@ import { Callout, DirectionalHint } from '@fluentui/react/lib/Callout'; export interface IFabricSlotWidgetProps { slot: FabricSlots; onFabricPaletteColorChange: (newColor: IColor, fabricSlot: FabricSlots) => void; - slotRule?: IThemeSlotRule; + slotRule: IThemeSlotRule; directionalHint?: DirectionalHint; } @@ -58,7 +58,7 @@ export class FabricSlotWidget extends React.Component
    {slotRule.name}
    @@ -71,7 +71,7 @@ export class FabricSlotWidget extends React.Component - + )}
    diff --git a/apps/theming-designer/src/components/SemanticSlots.tsx b/apps/theming-designer/src/components/SemanticSlots.tsx index 60b1defc10067..f744744618041 100644 --- a/apps/theming-designer/src/components/SemanticSlots.tsx +++ b/apps/theming-designer/src/components/SemanticSlots.tsx @@ -166,7 +166,7 @@ export const SemanticSlots: React.FunctionComponent = (prop } }; - let semanticSlotsNone = props.theme.semanticColors; + let semanticSlotsNone = props.theme!.semanticColors; slotNames = trimSemanticSlotsOrNames(Object.keys(semanticSlotsNone)) as ISlotNames; noneSlots = fillVariantSlotsList(VariantThemeType.None); neutralSlots = fillVariantSlotsList(VariantThemeType.Neutral); diff --git a/apps/theming-designer/src/components/ThemeSlots.tsx b/apps/theming-designer/src/components/ThemeSlots.tsx index 37f1edff608ab..159fd890e15a2 100644 --- a/apps/theming-designer/src/components/ThemeSlots.tsx +++ b/apps/theming-designer/src/components/ThemeSlots.tsx @@ -9,7 +9,7 @@ import { IColor } from '@fluentui/react/lib/Color'; export interface IThemeSlotsProps { theme?: ITheme; - themeRules?: IThemeRules; + themeRules: IThemeRules; onFabricPaletteColorChange: (newColor: IColor | undefined, fabricSlot: FabricSlots) => void; } diff --git a/apps/theming-designer/src/components/ThemingDesigner.tsx b/apps/theming-designer/src/components/ThemingDesigner.tsx index 12671673555ba..bd3d7169f6591 100644 --- a/apps/theming-designer/src/components/ThemingDesigner.tsx +++ b/apps/theming-designer/src/components/ThemingDesigner.tsx @@ -133,7 +133,7 @@ export class ThemingDesigner extends React.Component<{}, IThemingDesignerState>
    @@ -142,7 +142,7 @@ export class ThemingDesigner extends React.Component<{}, IThemingDesignerState> ); } - private _onFabricPaletteColorChange = (newColor: IColor | undefined, fabricSlot: FabricSlots) => { + private _onFabricPaletteColorChange = (newColor: IColor, fabricSlot: FabricSlots) => { if (this._fabricPaletteColorChangeTimeout) { this._async.clearTimeout(this._fabricPaletteColorChangeTimeout); } @@ -159,7 +159,7 @@ export class ThemingDesigner extends React.Component<{}, IThemingDesignerState> ThemeGenerator.insureSlots(themeRules, currentIsDark); } } - this.setState({ themeRules: themeRules }, this._makeNewTheme); + this.setState({ themeRules }, this._makeNewTheme); }, 20); }; @@ -213,7 +213,7 @@ export class ThemingDesigner extends React.Component<{}, IThemingDesignerState> ThemeGenerator.insureSlots(themeRules, currentIsDark); } } - this.setState({ themeRules: themeRules }, this._makeNewTheme); + this.setState({ themeRules }, this._makeNewTheme); }, 20); // 20ms is low enough that you can slowly drag to change color and see that theme, // but high enough that quick changes don't get bogged down by a million changes inbetween @@ -250,7 +250,7 @@ export class ThemingDesigner extends React.Component<{}, IThemingDesignerState> const state = { ...colors, theme: finalTheme, - themeRules: themeRules, + themeRules, }; return state; diff --git a/apps/theming-designer/tsconfig.json b/apps/theming-designer/tsconfig.json index 2474846337f20..78c5173940ff7 100644 --- a/apps/theming-designer/tsconfig.json +++ b/apps/theming-designer/tsconfig.json @@ -1,4 +1,5 @@ { + "extends": "../../tsconfig.base.v8.json", "compilerOptions": { "target": "es5", "outDir": "lib", @@ -7,14 +8,9 @@ "declaration": true, "sourceMap": true, "experimentalDecorators": true, - "forceConsistentCasingInFileNames": true, - "moduleResolution": "node", "preserveConstEnums": true, - "strict": false, - "lib": ["es6", "dom"], - "types": [], - "skipLibCheck": true, - "noImplicitAny": true + "lib": ["ES2015", "DOM"], + "types": ["jest", "custom-global", "webpack-env", "node"] }, "include": ["src"] } diff --git a/apps/theming-designer/webpack.config.js b/apps/theming-designer/webpack.config.js index 46c31b76b0656..48631ab55cc89 100644 --- a/apps/theming-designer/webpack.config.js +++ b/apps/theming-designer/webpack.config.js @@ -1,4 +1,4 @@ -const resources = require('../../scripts/webpack/webpack-resources'); +const { resources } = require('@fluentui/scripts-webpack'); const BUNDLE_NAME = 'theming-designer'; const IS_PRODUCTION = process.argv.indexOf('--production') > -1; diff --git a/apps/theming-designer/webpack.serve.config.js b/apps/theming-designer/webpack.serve.config.js index 22b2cc4f95981..fdbcd7a657096 100644 --- a/apps/theming-designer/webpack.serve.config.js +++ b/apps/theming-designer/webpack.serve.config.js @@ -1,5 +1,4 @@ -const resources = require('../../scripts/webpack/webpack-resources'); -const getResolveAlias = require('../../scripts/webpack/getResolveAlias'); +const { getResolveAlias, resources } = require('@fluentui/scripts-webpack'); module.exports = resources.createServeConfig( { diff --git a/apps/ts-minbar-test-react-components/README.md b/apps/ts-minbar-test-react-components/README.md index 09270c4f69be6..57fc6f0070e12 100644 --- a/apps/ts-minbar-test-react-components/README.md +++ b/apps/ts-minbar-test-react-components/README.md @@ -1 +1,3 @@ -This test package was created to ensure that `@fluentui/react-components` remains compatible with Typescript 3.9 and no non TS 3.9 compatible code are introduced. +# ts-minbar-test-react-components + +This test app ensures that `@fluentui/react-components` is compatible back to Typescript 3.9. diff --git a/apps/ts-minbar-test-react-components/babel.config.js b/apps/ts-minbar-test-react-components/babel.config.js deleted file mode 100644 index 8745a9acea9a4..0000000000000 --- a/apps/ts-minbar-test-react-components/babel.config.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = api => ({ - ...require('@fluentui/scripts/babel')(api), - babelrcRoots: ['../../*'], -}); diff --git a/apps/ts-minbar-test-react-components/assets/index.tsx b/apps/ts-minbar-test-react-components/files/src/index.tsx similarity index 100% rename from apps/ts-minbar-test-react-components/assets/index.tsx rename to apps/ts-minbar-test-react-components/files/src/index.tsx diff --git a/apps/ts-minbar-test-react-components/assets/tsconfig.json b/apps/ts-minbar-test-react-components/files/tsconfig.json similarity index 100% rename from apps/ts-minbar-test-react-components/assets/tsconfig.json rename to apps/ts-minbar-test-react-components/files/tsconfig.json diff --git a/apps/ts-minbar-test-react-components/just.config.ts b/apps/ts-minbar-test-react-components/just.config.ts index ab644d198e0d4..bff7e48d69e59 100644 --- a/apps/ts-minbar-test-react-components/just.config.ts +++ b/apps/ts-minbar-test-react-components/just.config.ts @@ -1,4 +1,4 @@ -import { preset, task } from '@fluentui/scripts'; +import { preset, task } from '@fluentui/scripts-tasks'; preset(); -task('build', 'build:node-lib').cached(); +task('build', 'build:node-lib').cached!(); diff --git a/apps/ts-minbar-test-react-components/package.json b/apps/ts-minbar-test-react-components/package.json index 1ee18a144c16a..b5c8bdf6a7f35 100644 --- a/apps/ts-minbar-test-react-components/package.json +++ b/apps/ts-minbar-test-react-components/package.json @@ -1,16 +1,18 @@ { "name": "@fluentui/ts-minbar-test-react-components", - "version": "9.0.0-rc.0", + "version": "9.0.0", "private": true, "description": "Testing Fluent UI React Components compatibility with Typescript 3.9", "license": "MIT", "dependencies": { - "@fluentui/react-components": "^9.6.1" + "@fluentui/react-components": "^9.15.0" }, "scripts": { - "build": "just-scripts build", - "clean": "just-scripts clean", - "lint": "just-scripts lint", - "test": "node -r @fluentui/scripts/babel/register src/index.ts" + "type-check": "tsc -p .", + "test": "ts-node --swc ./src/index.ts" + }, + "devDependencies": { + "@fluentui/scripts-tasks": "*", + "@fluentui/scripts-projects-test": "*" } } diff --git a/apps/ts-minbar-test-react-components/src/index.ts b/apps/ts-minbar-test-react-components/src/index.ts index c2249c1dd9062..e7582ba1c0ddd 100644 --- a/apps/ts-minbar-test-react-components/src/index.ts +++ b/apps/ts-minbar-test-react-components/src/index.ts @@ -1,11 +1,14 @@ -import config from '@fluentui/scripts/config'; -import * as fs from 'fs-extra'; import * as path from 'path'; import { + prepareTempDirs, + log, + shEcho, + TempPaths, + workspaceRoot, + generateFiles, addResolutionPathsForProjectPackages, packProjectPackages, -} from '@fluentui/scripts/projects-test/packPackages'; -import { prepareTempDirs, log, shEcho, TempPaths } from '@fluentui/scripts/projects-test/utils'; +} from '@fluentui/scripts-projects-test'; const tsVersion = '3.9'; const testName = 'ts-minbar-react-components'; @@ -15,7 +18,7 @@ async function performTest() { const logger = log(`test:${testName}`); try { - const scaffoldPath = config.paths.withRootAt(path.resolve(__dirname, '../assets/')); + const scaffoldPathRoot = path.resolve(__dirname, '../files'); tempPaths = prepareTempDirs(`${testName}-`); logger(`✔️ Temporary directories created under ${tempPaths.root}`); @@ -31,16 +34,14 @@ async function performTest() { await shEcho(`yarn add ${dependencies}`, tempPaths.testApp); logger(`✔️ Dependencies were installed`); - const lernaRoot = config.paths.allPackages(); + const lernaRoot = workspaceRoot; const packedPackages = await packProjectPackages(logger, lernaRoot, ['@fluentui/react-components']); await addResolutionPathsForProjectPackages(tempPaths.testApp); await shEcho(`yarn add ${packedPackages['@fluentui/react-components']}`, tempPaths.testApp); logger(`✔️ Fluent UI packages were added to dependencies`); - fs.mkdirSync(path.join(tempPaths.testApp, 'src')); - fs.copyFileSync(scaffoldPath('index.tsx'), path.join(tempPaths.testApp, 'src/index.tsx')); - fs.copyFileSync(scaffoldPath('tsconfig.json'), path.join(tempPaths.testApp, 'tsconfig.json')); + generateFiles(scaffoldPathRoot, tempPaths.testApp); logger(`✔️ Source and configs were copied`); await shEcho(`npx npm-which yarn`); diff --git a/apps/ts-minbar-test-react-components/tsconfig.json b/apps/ts-minbar-test-react-components/tsconfig.json index 2e24a7c63ca34..d3111e7d16f28 100644 --- a/apps/ts-minbar-test-react-components/tsconfig.json +++ b/apps/ts-minbar-test-react-components/tsconfig.json @@ -1,10 +1,10 @@ { "compilerOptions": { "noEmit": true, - "lib": ["es2018"], - "target": "es2018", - "module": "commonjs", - "moduleResolution": "node", + "lib": ["ES2019"], + "target": "ES2019", + "module": "CommonJS", + "moduleResolution": "Node", "strict": true, "esModuleInterop": true, "skipLibCheck": true, diff --git a/apps/ts-minbar-test-react/README.md b/apps/ts-minbar-test-react/README.md index 5a82486a92d00..d7239a359fb09 100644 --- a/apps/ts-minbar-test-react/README.md +++ b/apps/ts-minbar-test-react/README.md @@ -1 +1,3 @@ -This test package was created to ensure that `@fluentui/react` remains compatible with Typescript 3.9 and no non TS 3.9 compatible code are introduced. +# ts-minbar-test-react + +This test app ensures that `@fluentui/react` is compatible back to Typescript 3.9. diff --git a/apps/ts-minbar-test-react/babel.config.js b/apps/ts-minbar-test-react/babel.config.js deleted file mode 100644 index 8745a9acea9a4..0000000000000 --- a/apps/ts-minbar-test-react/babel.config.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = api => ({ - ...require('@fluentui/scripts/babel')(api), - babelrcRoots: ['../../*'], -}); diff --git a/apps/ts-minbar-test-react/assets/index.tsx b/apps/ts-minbar-test-react/files/src/index.tsx similarity index 100% rename from apps/ts-minbar-test-react/assets/index.tsx rename to apps/ts-minbar-test-react/files/src/index.tsx diff --git a/apps/ts-minbar-test-react/assets/tsconfig.json b/apps/ts-minbar-test-react/files/tsconfig.json similarity index 100% rename from apps/ts-minbar-test-react/assets/tsconfig.json rename to apps/ts-minbar-test-react/files/tsconfig.json diff --git a/apps/ts-minbar-test-react/just.config.ts b/apps/ts-minbar-test-react/just.config.ts index ab644d198e0d4..bff7e48d69e59 100644 --- a/apps/ts-minbar-test-react/just.config.ts +++ b/apps/ts-minbar-test-react/just.config.ts @@ -1,4 +1,4 @@ -import { preset, task } from '@fluentui/scripts'; +import { preset, task } from '@fluentui/scripts-tasks'; preset(); -task('build', 'build:node-lib').cached(); +task('build', 'build:node-lib').cached!(); diff --git a/apps/ts-minbar-test-react/package.json b/apps/ts-minbar-test-react/package.json index 209f460d92d57..984828ac39982 100644 --- a/apps/ts-minbar-test-react/package.json +++ b/apps/ts-minbar-test-react/package.json @@ -1,14 +1,18 @@ { "name": "@fluentui/ts-minbar-test-react", - "version": "1.0.0", + "version": "8.0.0", "private": true, "description": "Testing Fluent UI React compatibility with Typescript 3.9", "license": "MIT", "dependencies": { - "@fluentui/react": "^8.99.0" + "@fluentui/react": "^8.105.6" }, "scripts": { - "build": "just-scripts build", - "test": "node -r @fluentui/scripts/babel/register src/index.ts" + "type-check": "tsc -p .", + "test": "ts-node --swc ./src/index.ts" + }, + "devDependencies": { + "@fluentui/scripts-tasks": "*", + "@fluentui/scripts-projects-test": "*" } } diff --git a/apps/ts-minbar-test-react/src/index.ts b/apps/ts-minbar-test-react/src/index.ts index 0e9615a608115..056cc3ddf15b7 100644 --- a/apps/ts-minbar-test-react/src/index.ts +++ b/apps/ts-minbar-test-react/src/index.ts @@ -1,11 +1,15 @@ -import config from '@fluentui/scripts/config'; -import * as fs from 'fs-extra'; import * as path from 'path'; + import { addResolutionPathsForProjectPackages, packProjectPackages, -} from '@fluentui/scripts/projects-test/packPackages'; -import { prepareTempDirs, log, shEcho, TempPaths } from '@fluentui/scripts/projects-test/utils'; + prepareTempDirs, + log, + shEcho, + TempPaths, + workspaceRoot, + generateFiles, +} from '@fluentui/scripts-projects-test'; const tsVersion = '3.9'; const testName = 'ts-minbar-react'; @@ -15,14 +19,14 @@ async function performTest() { const logger = log(`test:${testName}`); try { - const scaffoldPath = config.paths.withRootAt(path.resolve(__dirname, '../assets/')); + const scaffoldPathRoot = path.resolve(__dirname, '../files'); tempPaths = prepareTempDirs(`${testName}-`); logger(`✔️ Temporary directories created under ${tempPaths.root}`); // Install dependencies, using the minimum TS version supported for consumers const dependencies = [ - '@types/node', + '@types/node@14', '@types/react@17', '@types/react-dom@17', 'react@17', @@ -32,16 +36,14 @@ async function performTest() { await shEcho(`yarn add ${dependencies}`, tempPaths.testApp); logger(`✔️ Dependencies were installed`); - const lernaRoot = config.paths.allPackages(); + const lernaRoot = workspaceRoot; const packedPackages = await packProjectPackages(logger, lernaRoot, ['@fluentui/react']); await addResolutionPathsForProjectPackages(tempPaths.testApp); await shEcho(`yarn add ${packedPackages['@fluentui/react']}`, tempPaths.testApp); logger(`✔️ Fluent UI packages were added to dependencies`); - fs.mkdirSync(path.join(tempPaths.testApp, 'src')); - fs.copyFileSync(scaffoldPath('index.tsx'), path.join(tempPaths.testApp, 'src/index.tsx')); - fs.copyFileSync(scaffoldPath('tsconfig.json'), path.join(tempPaths.testApp, 'tsconfig.json')); + generateFiles(scaffoldPathRoot, tempPaths.testApp); logger(`✔️ Source and configs were copied`); await shEcho(`npx npm-which yarn`); diff --git a/apps/ts-minbar-test-react/tsconfig.json b/apps/ts-minbar-test-react/tsconfig.json index 2e24a7c63ca34..d3111e7d16f28 100644 --- a/apps/ts-minbar-test-react/tsconfig.json +++ b/apps/ts-minbar-test-react/tsconfig.json @@ -1,10 +1,10 @@ { "compilerOptions": { "noEmit": true, - "lib": ["es2018"], - "target": "es2018", - "module": "commonjs", - "moduleResolution": "node", + "lib": ["ES2019"], + "target": "ES2019", + "module": "CommonJS", + "moduleResolution": "Node", "strict": true, "esModuleInterop": true, "skipLibCheck": true, diff --git a/apps/vr-tests-react-components/.storybook/main.js b/apps/vr-tests-react-components/.storybook/main.js index 66d036830a218..b8a83b5919fa8 100644 --- a/apps/vr-tests-react-components/.storybook/main.js +++ b/apps/vr-tests-react-components/.storybook/main.js @@ -2,9 +2,12 @@ const path = require('path'); const { TsconfigPathsPlugin } = require('tsconfig-paths-webpack-plugin'); module.exports = /** @type {import('../../../.storybook/main').StorybookBaseConfig} */ ({ + addons: ['@fluentui/react-storybook-addon'], + stories: ['../src/**/*.stories.tsx'], core: { builder: 'webpack5', + disableTelemetry: true, }, babel: {}, typescript: { diff --git a/apps/vr-tests-react-components/.storybook/preview.js b/apps/vr-tests-react-components/.storybook/preview.js index 760cf508fdf2c..50e39889ee309 100644 --- a/apps/vr-tests-react-components/.storybook/preview.js +++ b/apps/vr-tests-react-components/.storybook/preview.js @@ -25,12 +25,16 @@ setAddon({ */ addStory(storyName, storyFn, config = {}) { this.add(storyName, (/** @type {import('../src/utilities/types').StoryContext} */ context) => { - return {storyFn(context)}; + return ( + + {storyFn(context)} + + ); }); if (config.includeRtl) { this.add(storyName + ' - RTL', (/** @type {import('../src/utilities/types').StoryContext} */ context) => { return ( - + {storyFn(context)} ); @@ -38,14 +42,22 @@ setAddon({ } if (config.includeDarkMode) { this.add(storyName + ' - Dark Mode', (/** @type {import('../src/utilities/types').StoryContext} */ context) => { - return {storyFn(context)}; + return ( + + {storyFn(context)} + + ); }); } if (config.includeHighContrast) { this.add(storyName + ' - High Contrast', ( /** @type {import('../src/utilities/types').StoryContext} */ context, ) => { - return {storyFn(context)}; + return ( + + {storyFn(context)} + + ); }); } @@ -53,9 +65,5 @@ setAddon({ }, }); -export const parameters = { layout: 'none' }; - -// For static storybook per https://github.com/screener-io/screener-storybook#testing-with-static-storybook-app -if (typeof window === 'object') { - /** @type {*} */ (window).__screener_storybook__ = require('@storybook/react').getStorybook; -} +/** @type {import("@fluentui/react-storybook-addon").FluentParameters} */ +export const parameters = { layout: 'none', mode: 'vr-test' }; diff --git a/apps/vr-tests-react-components/jest.config.js b/apps/vr-tests-react-components/jest.config.js new file mode 100644 index 0000000000000..30ea9c1e51275 --- /dev/null +++ b/apps/vr-tests-react-components/jest.config.js @@ -0,0 +1,18 @@ +// @ts-check + +/** + * @type {import('@jest/types').Config.InitialOptions} + */ +module.exports = { + displayName: 'vr-tests-react-components', + preset: '../../jest.preset.js', + globals: { + 'ts-jest': { + tsConfig: '/tsconfig.json', + diagnostics: false, + }, + }, + transform: { + '^.+\\.tsx?$': 'ts-jest', + }, +}; diff --git a/apps/vr-tests-react-components/just.config.ts b/apps/vr-tests-react-components/just.config.ts index bcc7d9d264037..b10db31a6aca5 100644 --- a/apps/vr-tests-react-components/just.config.ts +++ b/apps/vr-tests-react-components/just.config.ts @@ -1,3 +1,3 @@ -import { preset } from '@fluentui/scripts'; +import { preset } from '@fluentui/scripts-tasks'; preset(); diff --git a/apps/vr-tests-react-components/package.json b/apps/vr-tests-react-components/package.json index fbf47998f437c..ebbb54d1a99d8 100644 --- a/apps/vr-tests-react-components/package.json +++ b/apps/vr-tests-react-components/package.json @@ -8,54 +8,59 @@ "clean": "just-scripts clean", "format": "prettier . -w --ignore-path ../../.prettierignore", "lint": "just-scripts lint", - "screener": "just-scripts screener", - "screener:build": "yarn build", "start": "start-storybook", - "type-check": "tsc" + "test": "just-scripts test", + "type-check": "tsc", + "vr:build": "yarn build", + "vr:test": "storywright --browsers chromium --url dist/storybook --destpath dist/screenshots --waitTimeScreenshot 500 --concurrency 4 --headless true" }, "devDependencies": { - "@fluentui/eslint-plugin": "*" + "@fluentui/eslint-plugin": "*", + "@fluentui/scripts-tasks": "*" }, "dependencies": { - "@fluentui/react-accordion": "^9.0.9", - "@fluentui/react-avatar": "^9.2.4", - "@fluentui/react-badge": "^9.0.10", - "@fluentui/react-button": "^9.1.6", - "@fluentui/react-card": "9.0.0-beta.30", - "@fluentui/react-checkbox": "^9.0.10", - "@fluentui/react-dialog": "^9.0.3", - "@fluentui/react-divider": "^9.1.2", - "@fluentui/react-field": "9.0.0-alpha.6", + "@fluentui/react-accordion": "^9.0.23", + "@fluentui/react-avatar": "^9.3.3", + "@fluentui/react-badge": "^9.0.24", + "@fluentui/react-button": "^9.2.3", + "@fluentui/react-card": "9.0.0-beta.44", + "@fluentui/react-checkbox": "^9.0.26", + "@fluentui/react-combobox": "^9.1.1", + "@fluentui/react-dialog": "^9.1.14", + "@fluentui/react-divider": "^9.1.14", + "@fluentui/react-field": "9.0.0-alpha.19", "@fluentui/react-icons": "^2.0.175", - "@fluentui/react-image": "^9.0.9", - "@fluentui/react-input": "^9.2.3", - "@fluentui/react-label": "^9.0.8", - "@fluentui/react-link": "^9.0.9", - "@fluentui/react-menu": "^9.3.1", - "@fluentui/react-persona": "9.1.0-beta.1", - "@fluentui/react-popover": "^9.2.1", - "@fluentui/react-positioning": "^9.2.2", - "@fluentui/react-progress": "9.0.0-alpha.3", - "@fluentui/react-provider": "^9.1.5", - "@fluentui/react-radio": "^9.0.9", - "@fluentui/react-select": "9.0.0-beta.12", - "@fluentui/react-shared-contexts": "^9.0.2", - "@fluentui/react-slider": "^9.0.8", - "@fluentui/react-spinner": "^9.0.8", - "@fluentui/react-spinbutton": "^9.0.6", - "@fluentui/react-switch": "^9.0.9", - "@fluentui/react-tabs": "^9.0.9", - "@fluentui/react-table": "9.0.0-alpha.8", - "@fluentui/react-text": "^9.1.4", - "@fluentui/react-textarea": "^9.1.3", - "@fluentui/react-theme": "^9.1.1", - "@fluentui/react-tooltip": "^9.0.9", - "@fluentui/react-utilities": "^9.1.2", - "@fluentui/scripts": "^1.0.0", - "@griffel/react": "^1.4.1", + "@fluentui/react-image": "^9.0.21", + "@fluentui/react-infobutton": "9.0.0-beta.13", + "@fluentui/react-input": "^9.3.2", + "@fluentui/react-label": "^9.0.20", + "@fluentui/react-link": "^9.0.23", + "@fluentui/react-menu": "^9.6.8", + "@fluentui/react-persona": "^9.1.9", + "@fluentui/react-popover": "^9.4.7", + "@fluentui/react-portal": "^9.1.7", + "@fluentui/react-positioning": "^9.4.0", + "@fluentui/react-progress": "9.0.0-alpha.16", + "@fluentui/react-provider": "^9.3.3", + "@fluentui/react-radio": "^9.0.24", + "@fluentui/react-select": "^9.0.1", + "@fluentui/react-shared-contexts": "^9.2.0", + "@fluentui/react-slider": "^9.0.23", + "@fluentui/react-spinner": "^9.0.20", + "@fluentui/react-spinbutton": "^9.1.2", + "@fluentui/react-storybook-addon": "9.0.0-rc.1", + "@fluentui/react-switch": "^9.0.24", + "@fluentui/react-tabs": "^9.2.2", + "@fluentui/react-table": "^9.0.0", + "@fluentui/react-text": "^9.2.1", + "@fluentui/react-textarea": "^9.2.2", + "@fluentui/react-theme": "^9.1.5", + "@fluentui/react-tooltip": "^9.1.14", + "@fluentui/react-toolbar": "^9.0.5", + "@fluentui/react-utilities": "^9.5.2", + "@griffel/react": "^1.5.2", "react": "17.0.2", "react-dom": "17.0.2", - "screener-storybook": "0.23.0", "tslib": "^2.1.0" } } diff --git a/apps/vr-tests-react-components/screener.config.js b/apps/vr-tests-react-components/screener.config.js deleted file mode 100644 index 0e229136d99d1..0000000000000 --- a/apps/vr-tests-react-components/screener.config.js +++ /dev/null @@ -1,49 +0,0 @@ -const cp = require('child_process'); - -function getCurrentHash() { - try { - const buffer = cp.execSync('git rev-list --parents -n 1 HEAD', { - stdio: ['pipe', 'pipe', process.stderr], - }); - - if (buffer) { - // The command returns a list of hashes, the last one is the one we want - return buffer.toString().trim().split(' ').pop(); - } - } catch (e) { - console.error('Cannot get current git hash'); - process.exit(1); - } - - return ''; -} -/** - * - * @param {Object} options - * @param {string} options.screenerApiKey - * @param {string} options.sourceBranchName - * @param {string} options.deployUrl - * @param {string} options.targetBranch - * @returns {import('@fluentui/scripts/screener/screener.types').ScreenerRunnerConfig} - */ -function getConfig({ screenerApiKey, sourceBranchName, deployUrl, targetBranch }) { - const baseBranch = targetBranch ? targetBranch.replace(/^refs\/heads\//, '') : 'master'; - // https://github.com/screener-io/screener-storybook#additional-configuration-options - const config = { - projectRepo: 'microsoft/fluentui/react-components', - storybookStaticBuildDir: 'dist/storybook', - storybookConfigDir: '.storybook', - apiKey: screenerApiKey, - resolution: '1024x768', - baseBranch, - failureExitCode: 0, - alwaysAcceptBaseBranch: true, - states: [], - ...(sourceBranchName !== 'master' ? { commit: getCurrentHash() } : null), - baseUrl: `${deployUrl}/react-components-screener/iframe.html`, - }; - console.log('Screener config: ' + JSON.stringify({ ...config, apiKey: '...' }, null, 2)); - return config; -} - -module.exports = getConfig; diff --git a/apps/vr-tests-react-components/src/stories/Accordion.stories.tsx b/apps/vr-tests-react-components/src/stories/Accordion.stories.tsx deleted file mode 100644 index 4fee9cf87f3a8..0000000000000 --- a/apps/vr-tests-react-components/src/stories/Accordion.stories.tsx +++ /dev/null @@ -1,161 +0,0 @@ -import { storiesOf } from '@storybook/react'; -import * as React from 'react'; -import Screener from 'screener-storybook/src/screener'; -import { Accordion, AccordionItem, AccordionHeader, AccordionPanel } from '@fluentui/react-accordion'; -import { CircleRegular } from '@fluentui/react-icons'; - -storiesOf('Accordion Converged', module) - .addDecorator(story => ( - -
    - {story()} -
    -
    - )) - - .addStory( - 'visibility+focus', - () => ( - - - Opened - Opened Panel - - - Closed - Closed Panel - - - ), - { includeRtl: true, includeHighContrast: true, includeDarkMode: true }, - ); - -storiesOf('Accordion Converged', module) - .addDecorator(story => ( - -
    - {story()} -
    -
    - )) - - .addStory( - 'size', - () => ( - - - Small - Small Panel - - - Medium - Medium Panel - - - Large - Large Panel - - - Extra Large - Extra Large Panel - - - ), - { includeRtl: true }, - ) - .addStory( - 'expandIconPosition="end"', - () => ( - - - Opened - Visible Panel - - - Closed - Hidden Panel - - - ), - { includeRtl: true }, - ) - .addStory( - 'expandIcon=""', - () => ( - - - } expandIconPosition="start"> - Expand Icon Start - - Expand Icon Start Panel - - - } expandIconPosition="end"> - Expand Icon End - - Expand Icon End Panel - - - } expandIconPosition="end"> - Expand Icon Inline End - - Expand Icon Inline End Panel - - - ), - { includeRtl: true, includeHighContrast: true, includeDarkMode: true }, - ) - .addStory( - 'icon=""', - () => ( - - - } expandIconPosition="start"> - Icon Start - - Icon Start Panel - - - } expandIconPosition="end"> - Icon End - - Icon End Panel - - - } expandIconPosition="end"> - Icon Inline End - - Icon Inline End Panel - - - ), - { includeRtl: true }, - ) - .addStory( - 'disabled', - () => ( - - - Disabled Item Opened - Disabled Item Opened Panel - - - Disabled Item Closed - Disabled Item Closed Panel - - - Disabled Item ClosedInline - Disabled Item ClosedInline Panel - - - ), - { includeHighContrast: true, includeDarkMode: true }, - ); diff --git a/apps/vr-tests-react-components/src/stories/Accordion/Accordion.stories.tsx b/apps/vr-tests-react-components/src/stories/Accordion/Accordion.stories.tsx new file mode 100644 index 0000000000000..08c1e884d4430 --- /dev/null +++ b/apps/vr-tests-react-components/src/stories/Accordion/Accordion.stories.tsx @@ -0,0 +1,140 @@ +import * as React from 'react'; +import { Steps, StoryWright } from 'storywright'; +import { Accordion, AccordionItem, AccordionHeader, AccordionPanel } from '@fluentui/react-accordion'; +import { CircleRegular } from '@fluentui/react-icons'; +import { ComponentMeta } from '@storybook/react'; +import { getStoryVariant, DARK_MODE, HIGH_CONTRAST, RTL } from '../../utilities'; + +export default { + title: 'Accordion Converged', + + decorators: [ + story => ( + +
    + {story()} +
    +
    + ), + ], +} as ComponentMeta; + +export const Size = () => ( + + + Small + Small Panel + + + Medium + Medium Panel + + + Large + Large Panel + + + Extra Large + Extra Large Panel + + +); + +Size.storyName = 'size'; + +export const SizeRTL = getStoryVariant(Size, RTL); + +export const ExpandIconPositionEnd = () => ( + + + Opened + Visible Panel + + + Closed + Hidden Panel + + +); + +ExpandIconPositionEnd.storyName = 'expandIconPosition="end"'; + +export const ExpandIconPositionEndRTL = getStoryVariant(ExpandIconPositionEnd, RTL); + +export const ExpandIconIcon = () => ( + + + } expandIconPosition="start"> + Expand Icon Start + + Expand Icon Start Panel + + + } expandIconPosition="end"> + Expand Icon End + + Expand Icon End Panel + + + } expandIconPosition="end"> + Expand Icon Inline End + + Expand Icon Inline End Panel + + +); + +ExpandIconIcon.storyName = 'expandIcon=""'; + +export const ExpandIconIconDarkMode = getStoryVariant(ExpandIconIcon, DARK_MODE); +export const ExpandIconIconHighContrast = getStoryVariant(ExpandIconIcon, HIGH_CONTRAST); +export const ExpandIconIconRTL = getStoryVariant(ExpandIconIcon, RTL); + +export const IconIcon = () => ( + + + } expandIconPosition="start"> + Icon Start + + Icon Start Panel + + + } expandIconPosition="end"> + Icon End + + Icon End Panel + + + } expandIconPosition="end"> + Icon Inline End + + Icon Inline End Panel + + +); + +IconIcon.storyName = 'icon=""'; + +export const IconIconRTL = getStoryVariant(IconIcon, RTL); + +export const Disabled = () => ( + + + Disabled Item Opened + Disabled Item Opened Panel + + + Disabled Item Closed + Disabled Item Closed Panel + + + Disabled Item ClosedInline + Disabled Item ClosedInline Panel + + +); + +Disabled.storyName = 'disabled'; + +export const DisabledDarkMode = getStoryVariant(Disabled, DARK_MODE); +export const DisabledHighContrast = getStoryVariant(Disabled, HIGH_CONTRAST); diff --git a/apps/vr-tests-react-components/src/stories/Accordion/AccordionFocusInteractions.stories.tsx b/apps/vr-tests-react-components/src/stories/Accordion/AccordionFocusInteractions.stories.tsx new file mode 100644 index 0000000000000..450dcd268df27 --- /dev/null +++ b/apps/vr-tests-react-components/src/stories/Accordion/AccordionFocusInteractions.stories.tsx @@ -0,0 +1,46 @@ +import * as React from 'react'; +import { Steps, StoryWright } from 'storywright'; +import { Accordion, AccordionItem, AccordionHeader, AccordionPanel } from '@fluentui/react-accordion'; +import { ComponentMeta } from '@storybook/react'; +import { getStoryVariant, DARK_MODE, HIGH_CONTRAST, RTL } from '../../utilities'; + +export default { + title: 'Accordion Converged', + + decorators: [ + story => ( + +
    + {story()} +
    +
    + ), + ], +} as ComponentMeta; + +export const VisibilityFocus = () => ( + + + Opened + Opened Panel + + + Closed + Closed Panel + + +); + +VisibilityFocus.storyName = 'visibility+focus'; + +export const VisibilityFocusDarkMode = getStoryVariant(VisibilityFocus, DARK_MODE); +export const VisibilityFocusHighContrast = getStoryVariant(VisibilityFocus, HIGH_CONTRAST); +export const VisibilityFocusRTL = getStoryVariant(VisibilityFocus, RTL); diff --git a/apps/vr-tests-react-components/src/stories/Avatar.stories.tsx b/apps/vr-tests-react-components/src/stories/Avatar.stories.tsx index f19cc9bb55fae..282b0674b386e 100644 --- a/apps/vr-tests-react-components/src/stories/Avatar.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Avatar.stories.tsx @@ -1,6 +1,6 @@ import { storiesOf } from '@storybook/react'; import * as React from 'react'; -import Screener from 'screener-storybook/src/screener'; +import { Steps, StoryWright } from 'storywright'; import { Avatar, AvatarProps } from '@fluentui/react-avatar'; import { PeopleRegular, PersonCallRegular } from '@fluentui/react-icons'; @@ -42,7 +42,7 @@ const nameAndImage = [ /** Arrays of example values for each Avatar prop */ const examples = { size: [16, 20, 24, 28, 32, 36, 40, 48, 56, 64, 72, 96, 120, 128], - nameAndImage: nameAndImage, + nameAndImage, name: nameAndImage.map(p => p.name), image: nameAndImage.map(p => p.image), badge: [ @@ -161,6 +161,29 @@ const AvatarCustomSizeList: React.FC< ); }; +const AvatarColors: React.FC> = props => { + const rowStyles = { display: 'flex', flexDirection: 'row', flexWrap: 'wrap', gap: '12px', padding: '12px' } as const; + + return ( +
    +
    + + +
    +
    + {examples.name.map(name => ( + + ))} +
    +
    + {examples.namedColors.map(color => ( + + ))} +
    +
    + ); +}; + storiesOf('Avatar Converged', module) .addDecorator(story => (
    @@ -170,7 +193,7 @@ storiesOf('Avatar Converged', module)
    )) .addDecorator(story => ( - {story()} + {story()} )) .addStory( 'basic', @@ -195,6 +218,9 @@ storiesOf('Avatar Converged', module) .addStory('size+inactive+badge', () => ( )) + + /* Temporarily disable these stories as these cause noise with storywright + The issue is raised against playwright. Till it gets fixed we disabled these. https://github.com/microsoft/playwright/issues/18373 .addStory('size+active+badge', () => ( )) @@ -203,36 +229,19 @@ storiesOf('Avatar Converged', module) )) .addStory('size+active+ring-shadow', () => ( - )) + ))*/ .addStory('customSize+image', () => ) .addStory('customSize+name+badge', () => ( )) .addStory('customSize+icon+active', () => ) - .addStory( - 'color', - () => { - const rowStyles: React.CSSProperties = { display: 'flex', flexWrap: 'wrap', gap: '8px' }; - - return ( -
    -
    - - -
    -
    - {examples.name.map(name => ( - - ))} -
    -
    - {examples.namedColors.map(color => ( - - ))} -
    -
    - ); - }, - { includeHighContrast: true, includeDarkMode: true }, - ) - .addStory('image-bad-url', () => ); + .addStory('color', () => , { + includeHighContrast: true, + includeDarkMode: true, + }) + .addStory('color+active', () => , { + includeHighContrast: true, + includeDarkMode: true, + }) + .addStory('image-bad-url', () => ) + .addStory('image-bad-url+icon', () => ); diff --git a/apps/vr-tests-react-components/src/stories/AvatarGroup.stories.tsx b/apps/vr-tests-react-components/src/stories/AvatarGroup.stories.tsx index 940e110f44195..6bd674763f1cb 100644 --- a/apps/vr-tests-react-components/src/stories/AvatarGroup.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/AvatarGroup.stories.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { storiesOf } from '@storybook/react'; -import Screener from 'screener-storybook/src/screener'; +import { Steps, StoryWright } from 'storywright'; import { AvatarGroup, AvatarGroupItem, @@ -74,7 +74,7 @@ const AvatarGroupList: React.FC< storiesOf('AvatarGroup Converged', module) .addDecorator(TestWrapperDecorator) .addDecorator(story => ( - {story()} + {story()} )) .addStory('basic', () => , { includeHighContrast: true, @@ -99,6 +99,7 @@ storiesOf('AvatarGroup Converged', module) { includeHighContrast: true, includeDarkMode: true, + includeRtl: true, }, ) .addStory( @@ -118,11 +119,13 @@ storiesOf('AvatarGroup Converged', module) { includeHighContrast: true, includeDarkMode: true, + includeRtl: true, }, ) .addStory('layoutPie', () => , { includeHighContrast: true, includeDarkMode: true, + includeRtl: true, }) .addStory('overflowIndicator', () => , { includeHighContrast: true, @@ -133,9 +136,9 @@ storiesOf('AvatarGroup Converged', module) storiesOf('AvatarGroup Converged', module) .addDecorator(TestWrapperDecorator) .addDecorator(story => ( - + {story()} - + )) .addStory( 'overflowContent', diff --git a/apps/vr-tests-react-components/src/stories/Badge.stories.tsx b/apps/vr-tests-react-components/src/stories/Badge.stories.tsx deleted file mode 100644 index ead15d05920ad..0000000000000 --- a/apps/vr-tests-react-components/src/stories/Badge.stories.tsx +++ /dev/null @@ -1,196 +0,0 @@ -import { storiesOf } from '@storybook/react'; -import * as React from 'react'; -import { Badge, BadgeProps } from '@fluentui/react-badge'; -import { CircleRegular } from '@fluentui/react-icons'; -import { mergeClasses, makeStyles, shorthands } from '@griffel/react'; -import { tokens, typographyStyles } from '@fluentui/react-theme'; - -type ValueArrays = { - [K in keyof T]: T[K][]; -}; - -const propValues: ValueArrays, 'size' | 'color' | 'appearance' | 'shape'>> = { - size: ['tiny', 'extra-small', 'small', 'medium', 'large', 'extra-large'], - color: ['brand', 'danger', 'severe', 'warning', 'success', 'important', 'informative', 'subtle'], - appearance: ['filled', 'outline', 'tint', 'ghost'], - shape: ['circular', 'rounded', 'square'], -}; - -const useStyles = makeStyles({ - container: { - display: 'flex', - alignItems: 'center', - }, - - badgeContainer: { - display: 'flex', - alignItems: 'center', - ...shorthands.gap('5px'), - ...shorthands.padding('5px'), - }, - - label: { - marginLeft: '10px', - }, - - brandContainer: { - backgroundColor: tokens.colorBrandBackgroundStatic, - }, - - groupSet: { - display: 'inline-flex', - flexDirection: 'column', - ...shorthands.padding(0, tokens.spacingHorizontalL), - rowGap: tokens.spacingVerticalL, - }, - - group: { - display: 'inline-flex', - flexDirection: 'column', - alignItems: 'start', - rowGap: tokens.spacingVerticalS, - }, - - groupLabel: { - ...typographyStyles.subtitle2Stronger, - }, - - row: { - display: 'inline-flex', - alignItems: 'center', - columnGap: tokens.spacingHorizontalS, - }, -}); - -const BadgeAppearanceTemplate: React.FC<{ appearance: Required['appearance'] }> = ({ appearance }) => { - const styles = useStyles(); - - const badges = new Map(); - badges.set('brand', []); - badges.set('danger', []); - badges.set('severe', []); - badges.set('warning', []); - badges.set('success', []); - badges.set('important', []); - badges.set('informative', []); - badges.set('subtle', []); - - propValues.color.forEach(color => { - const circularWithText = ( - - 1 - - ); - const circularWithIcon = } />; - const roundedWithIcon = } />; - const roundedWithText = ( - - {appearance.toUpperCase()} - - ); - const roundedWithTextAndIconBefore = ( - } iconPosition="before"> - {appearance.toUpperCase()} - - ); - const roundedWithTextAndIconAfter = ( - } iconPosition="after"> - {appearance.toUpperCase()} - - ); - - badges - .get(color)! - .push( - circularWithText, - circularWithIcon, - roundedWithIcon, - roundedWithText, - roundedWithTextAndIconAfter, - roundedWithTextAndIconBefore, - ); - }); - - return ( -
    - {Array.from(badges.keys()).map((color: BadgeProps['color'], i) => ( -
    -
    - {badges.get(color)} -
    -
    {color}
    -
    - ))} -
    - ); -}; - -const BadgeSampleRow: React.FC = props => { - const styles = useStyles(); - - // Text content is not supported for tiny and extra-small - if (props.size === 'tiny' || props.size === 'extra-small') { - return ( -
    - } /> -
    - ); - } - - return ( -
    - 1 - } /> - BADGE - }> - BADGE - - } iconPosition="after"> - BADGE - - {props.children} -
    - ); -}; - -const badgeStories = storiesOf('Badge Converged', module); - -// appearance stories -propValues.appearance.forEach(appearance => { - badgeStories.addStory(appearance, () => , { - includeHighContrast: true, - includeDarkMode: true, - }); -}); - -// size stories -propValues.size.forEach(size => - badgeStories.addStory( - `size: ${size}`, - () => { - const styles = useStyles(); - return ( -
    - {propValues.appearance.map(appearance => - // tiny + ghost is not supported - size === 'tiny' && appearance === 'ghost' ? null : ( -
    - appearance: {appearance} - {propValues.shape.map(shape => ( - - ))} -
    - ), - )} -
    - ); - }, - { includeRtl: true }, - ), -); diff --git a/apps/vr-tests-react-components/src/stories/Badge/BadgeAppearance.stories.tsx b/apps/vr-tests-react-components/src/stories/Badge/BadgeAppearance.stories.tsx new file mode 100644 index 0000000000000..e782b07cce547 --- /dev/null +++ b/apps/vr-tests-react-components/src/stories/Badge/BadgeAppearance.stories.tsx @@ -0,0 +1,108 @@ +import * as React from 'react'; +import { Badge, BadgeProps } from '@fluentui/react-badge'; +import { CircleRegular } from '@fluentui/react-icons'; +import { mergeClasses } from '@griffel/react'; +import { propValues, useStyles } from './utils'; +import { ComponentMeta } from '@storybook/react'; +import { getStoryVariant, DARK_MODE, HIGH_CONTRAST } from '../../utilities'; + +const BadgeAppearanceTemplate: React.FC<{ appearance: Required['appearance'] }> = ({ appearance }) => { + const styles = useStyles(); + + const badges = new Map(); + badges.set('brand', []); + badges.set('danger', []); + badges.set('severe', []); + badges.set('warning', []); + badges.set('success', []); + badges.set('important', []); + badges.set('informative', []); + badges.set('subtle', []); + + propValues.color.forEach(color => { + const circularWithText = ( + + 1 + + ); + const circularWithIcon = } />; + const roundedWithIcon = } />; + const roundedWithText = ( + + {appearance.toUpperCase()} + + ); + const roundedWithTextAndIconBefore = ( + } iconPosition="before"> + {appearance.toUpperCase()} + + ); + const roundedWithTextAndIconAfter = ( + } iconPosition="after"> + {appearance.toUpperCase()} + + ); + + badges + .get(color)! + .push( + circularWithText, + circularWithIcon, + roundedWithIcon, + roundedWithText, + roundedWithTextAndIconAfter, + roundedWithTextAndIconBefore, + ); + }); + + return ( +
    + {Array.from(badges.keys()).map((color: BadgeProps['color'], i) => ( +
    +
    + {badges.get(color)} +
    +
    {color}
    +
    + ))} +
    + ); +}; + +export default { + title: 'Badge Converged', +} as ComponentMeta; + +export const Filled = () => ; + +Filled.storyName = 'filled'; + +export const FilledDarkMode = getStoryVariant(Filled, DARK_MODE); +export const FilledHighContrast = getStoryVariant(Filled, HIGH_CONTRAST); + +export const Outline = () => ; + +Outline.storyName = 'outline'; + +export const OutlineDarkMode = getStoryVariant(Outline, DARK_MODE); +export const OutlineHighContrast = getStoryVariant(Outline, HIGH_CONTRAST); + +export const Tint = () => ; + +Tint.storyName = 'tint'; + +export const TintDarkMode = getStoryVariant(Tint, DARK_MODE); +export const TintHighContrast = getStoryVariant(Tint, HIGH_CONTRAST); + +export const Ghost = () => ; + +Ghost.storyName = 'ghost'; + +export const GhostDarkMode = getStoryVariant(Ghost, DARK_MODE); +export const GhostHighContrast = getStoryVariant(Ghost, HIGH_CONTRAST); diff --git a/apps/vr-tests-react-components/src/stories/Badge/BadgeSize.stories.tsx b/apps/vr-tests-react-components/src/stories/Badge/BadgeSize.stories.tsx new file mode 100644 index 0000000000000..5813d5e96acf9 --- /dev/null +++ b/apps/vr-tests-react-components/src/stories/Badge/BadgeSize.stories.tsx @@ -0,0 +1,161 @@ +import * as React from 'react'; +import { Badge, BadgeProps } from '@fluentui/react-badge'; +import { CircleRegular } from '@fluentui/react-icons'; +import { propValues, useStyles } from './utils'; +import { ComponentMeta } from '@storybook/react'; +import { getStoryVariant, RTL } from '../../utilities'; + +const BadgeSampleRow: React.FC = props => { + const styles = useStyles(); + + // Text content is not supported for tiny and extra-small + if (props.size === 'tiny' || props.size === 'extra-small') { + return ( +
    + } /> +
    + ); + } + + return ( +
    + 1 + } /> + BADGE + }> + BADGE + + } iconPosition="after"> + BADGE + + {props.children} +
    + ); +}; + +export default { + title: 'Badge Converged', +} as ComponentMeta; + +export const SizeTiny = () => { + const styles = useStyles(); + return ( +
    + {propValues.appearance.map(appearance => + // tiny + ghost is not supported + appearance === 'ghost' ? null : ( +
    + appearance: {appearance} + {propValues.shape.map(shape => ( + + ))} +
    + ), + )} +
    + ); +}; + +SizeTiny.storyName = 'size: tiny'; + +export const SizeTinyRTL = getStoryVariant(SizeTiny, RTL); + +export const SizeExtraSmall = () => { + const styles = useStyles(); + return ( +
    + {propValues.appearance.map(appearance => ( +
    + appearance: {appearance} + {propValues.shape.map(shape => ( + + ))} +
    + ))} +
    + ); +}; + +SizeExtraSmall.storyName = 'size: extra-small'; + +export const SizeExtraSmallRTL = getStoryVariant(SizeExtraSmall, RTL); + +export const SizeSmall = () => { + const styles = useStyles(); + return ( +
    + {propValues.appearance.map(appearance => ( +
    + appearance: {appearance} + {propValues.shape.map(shape => ( + + ))} +
    + ))} +
    + ); +}; + +SizeSmall.storyName = 'size: small'; + +export const SizeSmallRTL = getStoryVariant(SizeSmall, RTL); + +export const SizeMedium = () => { + const styles = useStyles(); + return ( +
    + {propValues.appearance.map(appearance => ( +
    + appearance: {appearance} + {propValues.shape.map(shape => ( + + ))} +
    + ))} +
    + ); +}; + +SizeMedium.storyName = 'size: medium'; + +export const SizeMediumRTL = getStoryVariant(SizeMedium, RTL); + +export const SizeLarge = () => { + const styles = useStyles(); + return ( +
    + {propValues.appearance.map(appearance => ( +
    + appearance: {appearance} + {propValues.shape.map(shape => ( + + ))} +
    + ))} +
    + ); +}; + +SizeLarge.storyName = 'size: large'; + +export const SizeLargeRTL = getStoryVariant(SizeLarge, RTL); + +export const SizeExtraLarge = () => { + const styles = useStyles(); + return ( +
    + {propValues.appearance.map(appearance => ( +
    + appearance: {appearance} + {propValues.shape.map(shape => ( + + ))} +
    + ))} +
    + ); +}; + +SizeExtraLarge.storyName = 'size: extra-large'; + +export const SizeExtraLargeRTL = getStoryVariant(SizeExtraLarge, RTL); diff --git a/apps/vr-tests-react-components/src/stories/Badge/utils.ts b/apps/vr-tests-react-components/src/stories/Badge/utils.ts new file mode 100644 index 0000000000000..a5423654ead19 --- /dev/null +++ b/apps/vr-tests-react-components/src/stories/Badge/utils.ts @@ -0,0 +1,60 @@ +import { BadgeProps } from '@fluentui/react-badge'; +import { makeStyles, shorthands } from '@griffel/react'; +import { tokens, typographyStyles } from '@fluentui/react-theme'; + +type ValueArrays = { + [K in keyof T]: T[K][]; +}; + +export const propValues: ValueArrays, 'size' | 'color' | 'appearance' | 'shape'>> = { + size: ['tiny', 'extra-small', 'small', 'medium', 'large', 'extra-large'], + color: ['brand', 'danger', 'severe', 'warning', 'success', 'important', 'informative', 'subtle'], + appearance: ['filled', 'outline', 'tint', 'ghost'], + shape: ['circular', 'rounded', 'square'], +}; + +export const useStyles = makeStyles({ + container: { + display: 'flex', + alignItems: 'center', + }, + + badgeContainer: { + display: 'flex', + alignItems: 'center', + ...shorthands.gap('5px'), + ...shorthands.padding('5px'), + }, + + label: { + marginLeft: '10px', + }, + + brandContainer: { + backgroundColor: tokens.colorBrandBackgroundStatic, + }, + + groupSet: { + display: 'inline-flex', + flexDirection: 'column', + ...shorthands.padding(0, tokens.spacingHorizontalL), + rowGap: tokens.spacingVerticalL, + }, + + group: { + display: 'inline-flex', + flexDirection: 'column', + alignItems: 'start', + rowGap: tokens.spacingVerticalS, + }, + + groupLabel: { + ...typographyStyles.subtitle2Stronger, + }, + + row: { + display: 'inline-flex', + alignItems: 'center', + columnGap: tokens.spacingHorizontalS, + }, +}); diff --git a/apps/vr-tests-react-components/src/stories/Button.stories.tsx b/apps/vr-tests-react-components/src/stories/Button.stories.tsx deleted file mode 100644 index bb064b192f7b4..0000000000000 --- a/apps/vr-tests-react-components/src/stories/Button.stories.tsx +++ /dev/null @@ -1,574 +0,0 @@ -import { storiesOf } from '@storybook/react'; -import * as React from 'react'; -import Screener from 'screener-storybook/src/screener'; -import { Button, CompoundButton, ToggleButton, MenuButton } from '@fluentui/react-button'; -import { bundleIcon, CalendarMonthFilled, CalendarMonthRegular } from '@fluentui/react-icons'; -import { makeStyles } from '@griffel/react'; - -const CalendarMonth = bundleIcon(CalendarMonthFilled, CalendarMonthRegular); - -const steps = new Screener.Steps() - .snapshot('default', { cropTo: '.testWrapper' }) - .hover('#button-id') - .snapshot('hover', { cropTo: '.testWrapper' }) - .mouseDown('#button-id') - .snapshot('pressed', { cropTo: '.testWrapper' }) - .end(); - -const buttonId = 'button-id'; - -const useStyles = makeStyles({ - longText: { - width: '280px', - }, -}); - -storiesOf('Button Converged', module) - .addDecorator(story => {story()}) - .addStory('Default', () => , { - includeRtl: true, - includeHighContrast: true, - includeDarkMode: true, - }) - .addStory('As an anchor', () => ( - - )) - .addStory('Circular', () => ( - - )) - .addStory('Outline', () => ( - - )) - .addStory( - 'Primary', - () => ( - - ), - { - includeHighContrast: true, - includeDarkMode: true, - }, - ) - .addStory( - 'Subtle', - () => ( - - ), - { - includeHighContrast: true, - includeDarkMode: true, - }, - ) - .addStory( - 'Transparent', - () => ( - - ), - { - includeHighContrast: true, - includeDarkMode: true, - }, - ) - .addStory( - 'Disabled', - () => ( - - ), - { - includeHighContrast: true, - includeDarkMode: true, - }, - ) - .addStory( - 'Outline Disabled', - () => ( - - ), - { - includeHighContrast: true, - includeDarkMode: true, - }, - ) - .addStory( - 'Primary Disabled', - () => ( - - ), - { includeHighContrast: true, includeDarkMode: true }, - ) - .addStory( - 'Subtle Disabled', - () => ( - - ), - { includeHighContrast: true, includeDarkMode: true }, - ) - .addStory( - 'Transparent Disabled', - () => ( - - ), - { includeHighContrast: true, includeDarkMode: true }, - ) - .addStory('Size small', () => ( - - )) - .addStory('Size large', () => ( - - )) - .addStory('Size small - with long text wrapping', () => { - const styles = useStyles(); - return ( - - ); - }) - .addStory('Size medium - with long text wrapping', () => { - const styles = useStyles(); - return ( - - ); - }) - .addStory('Size large - with long text wrapping', () => { - const styles = useStyles(); - return ( - - ); - }) - .addStory( - 'With icon before content', - () => ( - - ), - { - includeRtl: true, - }, - ) - .addStory( - 'With icon after content', - () => ( - - ), - { includeRtl: true }, - ) - .addStory('Icon only', () => ; + +export const DefaultRTL = getStoryVariant(Default, RTL); +export const DefaultDarkMode = getStoryVariant(Default, DARK_MODE); +export const DefaultHighContrast = getStoryVariant(Default, HIGH_CONTRAST); + +export const AsAnAnchor = () => ( + +); + +AsAnAnchor.storyName = 'As an anchor'; + +export const Circular = () => ( + +); + +export const Outline = () => ( + +); + +export const Primary = () => ( + +); + +export const PrimaryHighContrast = getStoryVariant(Primary, HIGH_CONTRAST); +export const PrimaryDarkMode = getStoryVariant(Primary, DARK_MODE); + +export const Subtle = () => ( + +); + +export const SubtleHighContrast = getStoryVariant(Subtle, HIGH_CONTRAST); +export const SubtleDarkMode = getStoryVariant(Subtle, DARK_MODE); + +export const Transparent = () => ( + +); + +export const TransparentHighContrast = getStoryVariant(Transparent, HIGH_CONTRAST); +export const TransparentDarkMode = getStoryVariant(Transparent, DARK_MODE); + +export const Disabled = () => ( + +); + +export const DisabledHighContrast = getStoryVariant(Disabled, HIGH_CONTRAST); +export const DisabledDarkMode = getStoryVariant(Disabled, DARK_MODE); + +export const OutlineDisabled = () => ( + +); + +export const OutlineDisabledHighContrast = getStoryVariant(OutlineDisabled, HIGH_CONTRAST); +export const OutlineDisabledDarkMode = getStoryVariant(OutlineDisabled, DARK_MODE); + +export const PrimaryDisabled = () => ( + +); + +export const PrimaryDisabledHighContrast = getStoryVariant(PrimaryDisabled, HIGH_CONTRAST); +export const PrimaryDisabledDarkMode = getStoryVariant(PrimaryDisabled, DARK_MODE); + +export const SubtleDisabled = () => ( + +); + +export const SubtleDisabledHighContrast = getStoryVariant(SubtleDisabled, HIGH_CONTRAST); +export const SubtleDisabledDarkMode = getStoryVariant(SubtleDisabled, DARK_MODE); + +export const TransparentDisabled = () => ( + +); + +export const TransparentDisabledHighContrast = getStoryVariant(TransparentDisabled, HIGH_CONTRAST); +export const TransparentDisabledDarkMode = getStoryVariant(TransparentDisabled, DARK_MODE); + +export const SizeSmall = () => ( + +); + +SizeSmall.storyName = 'Size small'; + +export const SizeLarge = () => ( + +); + +SizeLarge.storyName = 'Size large'; + +export const SizeSmallWithLongTextWrapping = () => { + const styles = useStyles(); + return ( + + ); +}; + +SizeSmallWithLongTextWrapping.storyName = 'Size small - with long text wrapping'; + +export const SizeMediumWithLongTextWrapping = () => { + const styles = useStyles(); + return ( + + ); +}; + +SizeMediumWithLongTextWrapping.storyName = 'Size medium - with long text wrapping'; + +export const SizeLargeWithLongTextWrapping = () => { + const styles = useStyles(); + return ( + + ); +}; + +SizeLargeWithLongTextWrapping.storyName = 'Size large - with long text wrapping'; + +export const WithIconBeforeContent = () => ( + +); + +WithIconBeforeContent.storyName = 'With icon before content'; + +export const WithIconBeforeContentRTL = getStoryVariant(WithIconBeforeContent, RTL); + +export const WithIconAfterContent = () => ( + +); + +WithIconAfterContent.storyName = 'With icon after content'; + +export const WithIconAfterContentRTL = getStoryVariant(WithIconAfterContent, RTL); + +export const IconOnly = () => - - - -); - -storiesOf('Card Converged', module) - .addDecorator(story => ( - -
    - {story()} -
    -
    - )) - .addStory('card templates', () => ( -
    - - - sales presentation preview - - - Sales analysis 2019 presentation - - } - description={Folder > Presentations} - /> - -
    - )) - .addStory( - 'appearance', - () => ( -
    -
    -

    Filled

    - - - -
    -
    -

    Filled alternative

    - - - -
    -
    -

    Outline

    - - - -
    -
    -

    Subtle

    - - - -
    -
    - ), - { - includeRtl: true, - includeHighContrast: true, - includeDarkMode: true, - }, - ) - .addStory('size', () => ( -
    - - - - - - - - - -
    - )) - .addStory('orientation', () => ( -
    -
    -

    Vertical

    - - - -
    -
    -

    Horizontal

    - - - -
    -
    - )) - .addStory('CardHeader', () => ( - - - App Name - - } - description={Developer} - action={ + + + +); diff --git a/apps/vr-tests-react-components/src/stories/Checkbox.stories.tsx b/apps/vr-tests-react-components/src/stories/Checkbox.stories.tsx index ec456a60d55a0..375a23d90e89b 100644 --- a/apps/vr-tests-react-components/src/stories/Checkbox.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Checkbox.stories.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import Screener, { Steps } from 'screener-storybook/src/screener'; +import { Steps, StoryWright } from 'storywright'; import { storiesOf } from '@storybook/react'; import { Checkbox } from '@fluentui/react-checkbox'; import { TestWrapperDecoratorFixedWidth } from '../utilities/TestWrapperDecorator'; @@ -7,7 +7,7 @@ import { TestWrapperDecoratorFixedWidth } from '../utilities/TestWrapperDecorato storiesOf('Checkbox Converged', module) .addDecorator(TestWrapperDecoratorFixedWidth) .addDecorator(story => ( - {story()} - + )) .addStory('unchecked', () => , { includeRtl: true }) .addStory('checked', () => ) @@ -27,7 +27,7 @@ storiesOf('Checkbox Converged', module) storiesOf('Checkbox Converged', module) .addDecorator(TestWrapperDecoratorFixedWidth) .addDecorator(story => ( - {story()} + {story()} )) .addStory('disabled+checked', () => ) .addStory('disabled+mixed', () => ) diff --git a/apps/vr-tests-react-components/src/stories/Combobox.stories.tsx b/apps/vr-tests-react-components/src/stories/Combobox.stories.tsx new file mode 100644 index 0000000000000..0b237f2954af6 --- /dev/null +++ b/apps/vr-tests-react-components/src/stories/Combobox.stories.tsx @@ -0,0 +1,190 @@ +import * as React from 'react'; +import { Steps, StoryWright } from 'storywright'; +import { storiesOf } from '@storybook/react'; +import { Combobox, Option, OptionGroup } from '@fluentui/react-combobox'; +import { TestWrapperDecoratorFixedWidth } from '../utilities/TestWrapperDecorator'; + +storiesOf('Combobox Converged', module) + .addDecorator(TestWrapperDecoratorFixedWidth) + .addDecorator(story => ( + + {story()} + + )) + .addStory('Appearance: outline (default)', () => ( + + + + )) + .addStory('Appearance: underline', () => ( + + + + )) + .addStory('Appearance: filled-darker', () => ( +
    + + + +
    + )) + .addStory('Appearance: filled-lighter', () => ( +
    + + + +
    + )) + .addStory('Disabled', () => ( + + + + )) + .addStory('Disabled with value', () => ( + + + + )) + .addStory('Invalid: outline', () => ( + + + + )) + .addStory('Invalid: underline', () => ( + + + + )) + .addStory('Invalid: filled-darker', () => ( +
    + + + +
    + )) + .addStory('Invalid: filled-lighter', () => ( +
    + + + +
    + )) + .addStory('With placeholder', () => ( + + + + )) + .addStory('With value', () => ( + + + + )) + .addStory('Size: small', () => ( + + + + )) + .addStory('Size: large', () => ( + + + + )); + +// Option interaction stories +storiesOf('Combobox Converged', module) + .addDecorator(TestWrapperDecoratorFixedWidth) + .addDecorator(story => ( + + {story()} + + )) + .addStory('Open', () => ( +
    + + + + + +
    + )) + .addStory('Open with inlinePopup', () => ( +
    + + + + + +
    + )) + .addStory('Option with long content', () => ( +
    + + + + + +
    + )) + .addStory('With selection', () => ( +
    + + + + + +
    + )) + .addStory('With multiselect selection', () => ( +
    + + + + + +
    + )) + .addStory('Disabled option', () => ( +
    + + + + + +
    + )) + .addStory('Open with grouped options', () => ( +
    + + + + + + + + + + + + +
    + )); diff --git a/apps/vr-tests-react-components/src/stories/CounterBadge.stories.tsx b/apps/vr-tests-react-components/src/stories/CounterBadge.stories.tsx deleted file mode 100644 index c9d1360f34a21..0000000000000 --- a/apps/vr-tests-react-components/src/stories/CounterBadge.stories.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { storiesOf } from '@storybook/react'; -import * as React from 'react'; -import { CounterBadge } from '@fluentui/react-badge'; - -storiesOf('CounterBadge Converged - colors', module).addStory( - 'default', - () => ( -
    - {(['brand', 'danger', 'important', 'informative'] as const).map(color => ( - - ))} -
    - ), - { includeRtl: true }, -); diff --git a/apps/vr-tests-react-components/src/stories/CounterBadge/CounterBadge.stories.tsx b/apps/vr-tests-react-components/src/stories/CounterBadge/CounterBadge.stories.tsx new file mode 100644 index 0000000000000..9af7b16afc253 --- /dev/null +++ b/apps/vr-tests-react-components/src/stories/CounterBadge/CounterBadge.stories.tsx @@ -0,0 +1,20 @@ +import * as React from 'react'; +import { CounterBadge } from '@fluentui/react-badge'; +import { ComponentMeta } from '@storybook/react'; +import { getStoryVariant, RTL } from '../../utilities'; + +export default { + title: 'CounterBadge Converged - colors', +} as ComponentMeta; + +export const Default = () => ( +
    + {(['brand', 'danger', 'important', 'informative'] as const).map(color => ( + + ))} +
    +); + +Default.storyName = 'default'; + +export const DefaultRTL = getStoryVariant(Default, RTL); diff --git a/apps/vr-tests-react-components/src/stories/Dialog.stories.tsx b/apps/vr-tests-react-components/src/stories/Dialog.stories.tsx deleted file mode 100644 index 98ccf2836eb63..0000000000000 --- a/apps/vr-tests-react-components/src/stories/Dialog.stories.tsx +++ /dev/null @@ -1,411 +0,0 @@ -import * as React from 'react'; -import { storiesOf } from '@storybook/react'; -import { - Dialog, - DialogActions, - DialogBody, - DialogContent, - DialogSurface, - DialogTitle, - DialogTrigger, -} from '@fluentui/react-dialog'; -import { Button } from '@fluentui/react-button'; -import { Rocket24Regular } from '@fluentui/react-icons'; - -storiesOf('Dialog', module) - .addStory( - 'default', - () => ( - - - - - - - Dialog title - - Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam exercitationem cumque repellendus eaque - est dolor eius expedita nulla ullam? Tenetur reprehenderit aut voluptatum impedit voluptates in natus iure - cumque eaque? - - - - - - - - - - - ), - { includeDarkMode: true, includeHighContrast: true, includeRtl: true }, - ) - .addStory( - 'non-modal', - () => ( - - - - - - - Dialog title - - Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam exercitationem cumque repellendus eaque - est dolor eius expedita nulla ullam? Tenetur reprehenderit aut voluptatum impedit voluptates in natus iure - cumque eaque? - - - - - - - - - - - ), - { includeDarkMode: true, includeHighContrast: true, includeRtl: true }, - ) - .addStory( - 'alert', - () => ( - - - - - - - Dialog title - - Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam exercitationem cumque repellendus eaque - est dolor eius expedita nulla ullam? Tenetur reprehenderit aut voluptatum impedit voluptates in natus iure - cumque eaque? - - - - - - - - - - - ), - { includeDarkMode: true, includeHighContrast: true, includeRtl: true }, - ) - .addStory( - 'actions position start', - () => ( - - - - - - - Dialog title - - Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam exercitationem cumque repellendus eaque - est dolor eius expedita nulla ullam? Tenetur reprehenderit aut voluptatum impedit voluptates in natus iure - cumque eaque? - - - - - - - - - - - ), - { includeDarkMode: true, includeHighContrast: true, includeRtl: true }, - ) - .addStory( - 'actions position start & position end', - () => ( - - - - - - - Dialog title - - Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam exercitationem cumque repellendus eaque - est dolor eius expedita nulla ullam? Tenetur reprehenderit aut voluptatum impedit voluptates in natus iure - cumque eaque? - - - - - - - - - - - - - - - - ), - { includeDarkMode: true, includeHighContrast: true, includeRtl: true }, - ) - .addStory( - 'no actions', - () => ( - - - - - - - Dialog title - - Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam exercitationem cumque repellendus eaque - est dolor eius expedita nulla ullam? Tenetur reprehenderit aut voluptatum impedit voluptates in natus iure - cumque eaque? - - - - - ), - { includeDarkMode: true, includeHighContrast: true, includeRtl: true }, - ) - .addStory( - 'no title', - () => ( - - - - - - - - Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam exercitationem cumque repellendus eaque - est dolor eius expedita nulla ullam? Tenetur reprehenderit aut voluptatum impedit voluptates in natus iure - cumque eaque? - - - - - - - - - - - ), - { includeDarkMode: true, includeHighContrast: true, includeRtl: true }, - ) - .addStory( - 'no title & no actions', - () => ( - - - - - - - - Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam exercitationem cumque repellendus eaque - est dolor eius expedita nulla ullam? Tenetur reprehenderit aut voluptatum impedit voluptates in natus iure - cumque eaque? - - - - - ), - { includeDarkMode: true, includeHighContrast: true, includeRtl: true }, - ) - .addStory( - 'title custom action', - () => ( - - - - - - - } />}> - Dialog title - - - Lorem, ipsum dolor sit amet consectetur adipisicing elit. Aliquid, explicabo repudiandae impedit doloribus - laborum quidem maxime dolores perspiciatis non ipsam, nostrum commodi quis autem sequi, incidunt cum? - Consequuntur, repellendus nostrum? - - - - - ), - { includeDarkMode: true, includeHighContrast: true, includeRtl: true }, - ) - .addStory( - 'nested', - () => ( - - - - - - - Dialog title - - - - - - - - Inner dialog title - - ⛔️ just because you can doesn't mean you should have nested dialogs ⛔️ - - - - - - - - - - - - - - ), - { includeDarkMode: true, includeHighContrast: true, includeRtl: true }, - ) - .addStory( - 'scroll long content', - () => ( - - - - - - - Dialog title - -

    - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et - dolore magna aliqua. Nisl pretium fusce id velit ut tortor. Leo vel fringilla est ullamcorper. Eget est - lorem ipsum dolor sit amet consectetur adipiscing elit. In mollis nunc sed id semper risus in hendrerit - gravida. Ullamcorper sit amet risus nullam eget felis eget. Dolor sed viverra ipsum nunc aliquet - bibendum. Facilisi morbi tempus iaculis urna id volutpat. Porta non pulvinar neque laoreet suspendisse. - Nunc id cursus metus aliquam eleifend mi in. A iaculis at erat pellentesque adipiscing commodo. Proin - nibh nisl condimentum id. In hac habitasse platea dictumst vestibulum rhoncus est. Non tellus orci ac - auctor augue mauris augue neque. Enim nulla aliquet porttitor lacus luctus accumsan tortor. Nascetur - ridiculus mus mauris vitae ultricies leo integer. Ullamcorper eget nulla facilisi etiam dignissim. Leo - in vitae turpis massa sed elementum tempus egestas sed. -

    -

    - Ut enim blandit volutpat maecenas volutpat. Venenatis urna cursus eget nunc scelerisque viverra mauris. - Neque aliquam vestibulum morbi blandit. Porttitor eget dolor morbi non. Nisi quis eleifend quam - adipiscing vitae. Aliquam ultrices sagittis orci a scelerisque purus semper. Interdum varius sit amet - mattis vulputate enim nulla aliquet. Ut sem viverra aliquet eget sit amet tellus cras. Sit amet tellus - cras adipiscing enim eu turpis egestas. Amet cursus sit amet dictum sit amet justo donec enim. Neque - gravida in fermentum et sollicitudin ac. Arcu cursus euismod quis viverra nibh cras pulvinar mattis - nunc. Ultrices eros in cursus turpis massa tincidunt dui. Nisl rhoncus mattis rhoncus urna neque viverra - justo. Odio pellentesque diam volutpat commodo sed egestas. Nunc mi ipsum faucibus vitae aliquet nec - ullamcorper. Ipsum nunc aliquet bibendum enim. Faucibus ornare suspendisse sed nisi lacus sed. Sapien - nec sagittis aliquam malesuada bibendum arcu vitae elementum. Metus vulputate eu scelerisque felis - imperdiet. -

    -

    - Consequat interdum varius sit amet mattis vulputate enim. Amet cursus sit amet dictum sit amet justo. - Eget aliquet nibh praesent tristique magna sit. Ut consequat semper viverra nam libero justo. Pharetra - massa massa ultricies mi. Sem viverra aliquet eget sit amet. Pulvinar mattis nunc sed blandit libero - volutpat sed. Pharetra diam sit amet nisl suscipit adipiscing bibendum. Consectetur adipiscing elit ut - aliquam. Volutpat diam ut venenatis tellus in metus vulputate. Scelerisque in dictum non consectetur a - erat. Venenatis lectus magna fringilla urna porttitor rhoncus. Vitae congue mauris rhoncus aenean vel - elit. Neque laoreet suspendisse interdum consectetur. Ultrices gravida dictum fusce ut placerat orci. - Bibendum ut tristique et egestas quis ipsum suspendisse. Mattis rhoncus urna neque viverra justo nec - ultrices dui. Elit duis tristique sollicitudin nibh sit amet. -

    -

    - At risus viverra adipiscing at. Interdum posuere lorem ipsum dolor sit amet consectetur adipiscing elit. - Nunc vel risus commodo viverra maecenas. Sit amet est placerat in egestas erat imperdiet sed euismod. - Turpis egestas maecenas pharetra convallis posuere. Egestas tellus rutrum tellus pellentesque eu - tincidunt tortor aliquam. Dolor sit amet consectetur adipiscing elit. Aliquam purus sit amet luctus - venenatis lectus magna fringilla. Scelerisque fermentum dui faucibus in ornare quam viverra. Egestas - maecenas pharetra convallis posuere morbi leo urna. A diam sollicitudin tempor id eu nisl nunc. Lectus - sit amet est placerat. -

    -

    - Mattis ullamcorper velit sed ullamcorper morbi tincidunt ornare massa eget. At tellus at urna - condimentum mattis pellentesque id nibh. Dui faucibus in ornare quam. Tincidunt id aliquet risus feugiat - in ante metus dictum. Adipiscing commodo elit at imperdiet dui. Dolor sed viverra ipsum nunc. Sodales - neque sodales ut etiam sit amet nisl. Hendrerit dolor magna eget est lorem ipsum dolor sit amet. Mattis - molestie a iaculis at erat pellentesque adipiscing. Adipiscing elit duis tristique sollicitudin nibh sit - amet commodo nulla. Fringilla urna porttitor rhoncus dolor purus. -

    -

    - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et - dolore magna aliqua. Nisl pretium fusce id velit ut tortor. Leo vel fringilla est ullamcorper. Eget est - lorem ipsum dolor sit amet consectetur adipiscing elit. In mollis nunc sed id semper risus in hendrerit - gravida. Ullamcorper sit amet risus nullam eget felis eget. Dolor sed viverra ipsum nunc aliquet - bibendum. Facilisi morbi tempus iaculis urna id volutpat. Porta non pulvinar neque laoreet suspendisse. - Nunc id cursus metus aliquam eleifend mi in. A iaculis at erat pellentesque adipiscing commodo. Proin - nibh nisl condimentum id. In hac habitasse platea dictumst vestibulum rhoncus est. Non tellus orci ac - auctor augue mauris augue neque. Enim nulla aliquet porttitor lacus luctus accumsan tortor. Nascetur - ridiculus mus mauris vitae ultricies leo integer. Ullamcorper eget nulla facilisi etiam dignissim. Leo - in vitae turpis massa sed elementum tempus egestas sed. -

    -

    - Ut enim blandit volutpat maecenas volutpat. Venenatis urna cursus eget nunc scelerisque viverra mauris. - Neque aliquam vestibulum morbi blandit. Porttitor eget dolor morbi non. Nisi quis eleifend quam - adipiscing vitae. Aliquam ultrices sagittis orci a scelerisque purus semper. Interdum varius sit amet - mattis vulputate enim nulla aliquet. Ut sem viverra aliquet eget sit amet tellus cras. Sit amet tellus - cras adipiscing enim eu turpis egestas. Amet cursus sit amet dictum sit amet justo donec enim. Neque - gravida in fermentum et sollicitudin ac. Arcu cursus euismod quis viverra nibh cras pulvinar mattis - nunc. Ultrices eros in cursus turpis massa tincidunt dui. Nisl rhoncus mattis rhoncus urna neque viverra - justo. Odio pellentesque diam volutpat commodo sed egestas. Nunc mi ipsum faucibus vitae aliquet nec - ullamcorper. Ipsum nunc aliquet bibendum enim. Faucibus ornare suspendisse sed nisi lacus sed. Sapien - nec sagittis aliquam malesuada bibendum arcu vitae elementum. Metus vulputate eu scelerisque felis - imperdiet. -

    -

    - Consequat interdum varius sit amet mattis vulputate enim. Amet cursus sit amet dictum sit amet justo. - Eget aliquet nibh praesent tristique magna sit. Ut consequat semper viverra nam libero justo. Pharetra - massa massa ultricies mi. Sem viverra aliquet eget sit amet. Pulvinar mattis nunc sed blandit libero - volutpat sed. Pharetra diam sit amet nisl suscipit adipiscing bibendum. Consectetur adipiscing elit ut - aliquam. Volutpat diam ut venenatis tellus in metus vulputate. Scelerisque in dictum non consectetur a - erat. Venenatis lectus magna fringilla urna porttitor rhoncus. Vitae congue mauris rhoncus aenean vel - elit. Neque laoreet suspendisse interdum consectetur. Ultrices gravida dictum fusce ut placerat orci. - Bibendum ut tristique et egestas quis ipsum suspendisse. Mattis rhoncus urna neque viverra justo nec - ultrices dui. Elit duis tristique sollicitudin nibh sit amet. -

    -

    - At risus viverra adipiscing at. Interdum posuere lorem ipsum dolor sit amet consectetur adipiscing elit. - Nunc vel risus commodo viverra maecenas. Sit amet est placerat in egestas erat imperdiet sed euismod. - Turpis egestas maecenas pharetra convallis posuere. Egestas tellus rutrum tellus pellentesque eu - tincidunt tortor aliquam. Dolor sit amet consectetur adipiscing elit. Aliquam purus sit amet luctus - venenatis lectus magna fringilla. Scelerisque fermentum dui faucibus in ornare quam viverra. Egestas - maecenas pharetra convallis posuere morbi leo urna. A diam sollicitudin tempor id eu nisl nunc. Lectus - sit amet est placerat. -

    -

    - Mattis ullamcorper velit sed ullamcorper morbi tincidunt ornare massa eget. At tellus at urna - condimentum mattis pellentesque id nibh. Dui faucibus in ornare quam. Tincidunt id aliquet risus feugiat - in ante metus dictum. Adipiscing commodo elit at imperdiet dui. Dolor sed viverra ipsum nunc. Sodales - neque sodales ut etiam sit amet nisl. Hendrerit dolor magna eget est lorem ipsum dolor sit amet. Mattis - molestie a iaculis at erat pellentesque adipiscing. Adipiscing elit duis tristique sollicitudin nibh sit - amet commodo nulla. Fringilla urna porttitor rhoncus dolor purus. -

    -
    - - - - - - -
    -
    -
    - ), - { includeDarkMode: true, includeHighContrast: true, includeRtl: true }, - ); diff --git a/apps/vr-tests-react-components/src/stories/Dialog/Dialog.stories.tsx b/apps/vr-tests-react-components/src/stories/Dialog/Dialog.stories.tsx new file mode 100644 index 0000000000000..5061f52be2d9c --- /dev/null +++ b/apps/vr-tests-react-components/src/stories/Dialog/Dialog.stories.tsx @@ -0,0 +1,444 @@ +import * as React from 'react'; +import { + Dialog, + DialogActions, + DialogBody, + DialogContent, + DialogSurface, + DialogTitle, + DialogTrigger, +} from '@fluentui/react-dialog'; +import { Button } from '@fluentui/react-button'; +import { Rocket24Regular } from '@fluentui/react-icons'; +import { ComponentMeta } from '@storybook/react'; +import { getStoryVariant, DARK_MODE, HIGH_CONTRAST, RTL } from '../../utilities'; + +export default { + title: 'Dialog', +} as ComponentMeta; + +export const Default = () => ( + + + + + + + Dialog title + + Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam exercitationem cumque repellendus eaque est + dolor eius expedita nulla ullam? Tenetur reprehenderit aut voluptatum impedit voluptates in natus iure cumque + eaque? + + + + + + + + + + +); + +Default.storyName = 'default'; + +export const DefaultDarkMode = getStoryVariant(Default, DARK_MODE); +export const DefaultHighContrast = getStoryVariant(Default, HIGH_CONTRAST); +export const DefaultRTL = getStoryVariant(Default, RTL); + +export const NonModal = () => ( + + + + + + + Dialog title + + Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam exercitationem cumque repellendus eaque est + dolor eius expedita nulla ullam? Tenetur reprehenderit aut voluptatum impedit voluptates in natus iure cumque + eaque? + + + + + + + + + + +); + +NonModal.storyName = 'non-modal'; + +export const NonModalDarkMode = getStoryVariant(NonModal, DARK_MODE); +export const NonModalHighContrast = getStoryVariant(NonModal, HIGH_CONTRAST); +export const NonModalRTL = getStoryVariant(NonModal, RTL); + +export const Alert = () => ( + + + + + + + Dialog title + + Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam exercitationem cumque repellendus eaque est + dolor eius expedita nulla ullam? Tenetur reprehenderit aut voluptatum impedit voluptates in natus iure cumque + eaque? + + + + + + + + + + +); + +Alert.storyName = 'alert'; + +export const AlertDarkMode = getStoryVariant(Alert, DARK_MODE); +export const AlertHighContrast = getStoryVariant(Alert, HIGH_CONTRAST); +export const AlertRTL = getStoryVariant(Alert, RTL); + +export const ActionsPositionStart = () => ( + + + + + + + Dialog title + + Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam exercitationem cumque repellendus eaque est + dolor eius expedita nulla ullam? Tenetur reprehenderit aut voluptatum impedit voluptates in natus iure cumque + eaque? + + + + + + + + + + +); + +ActionsPositionStart.storyName = 'actions position start'; + +export const ActionsPositionStartDarkMode = getStoryVariant(ActionsPositionStart, DARK_MODE); +export const ActionsPositionStartHighContrast = getStoryVariant(ActionsPositionStart, HIGH_CONTRAST); +export const ActionsPositionStartRTL = getStoryVariant(ActionsPositionStart, RTL); + +export const ActionsPositionStartPositionEnd = () => ( + + + + + + + Dialog title + + Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam exercitationem cumque repellendus eaque est + dolor eius expedita nulla ullam? Tenetur reprehenderit aut voluptatum impedit voluptates in natus iure cumque + eaque? + + + + + + + + + + + + + + + +); + +ActionsPositionStartPositionEnd.storyName = 'actions position start & position end'; + +export const ActionsPositionStartPositionEndDarkMode = getStoryVariant(ActionsPositionStartPositionEnd, DARK_MODE); +export const ActionsPositionStartPositionEndHighContrast = getStoryVariant( + ActionsPositionStartPositionEnd, + HIGH_CONTRAST, +); +export const ActionsPositionStartPositionEndRTL = getStoryVariant(ActionsPositionStartPositionEnd, RTL); + +export const NoActions = () => ( + + + + + + + Dialog title + + Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam exercitationem cumque repellendus eaque est + dolor eius expedita nulla ullam? Tenetur reprehenderit aut voluptatum impedit voluptates in natus iure cumque + eaque? + + + + +); + +NoActions.storyName = 'no actions'; + +export const NoActionsDarkMode = getStoryVariant(NoActions, DARK_MODE); +export const NoActionsHighContrast = getStoryVariant(NoActions, HIGH_CONTRAST); +export const NoActionsRTL = getStoryVariant(NoActions, RTL); + +export const NoTitle = () => ( + + + + + + + + Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam exercitationem cumque repellendus eaque est + dolor eius expedita nulla ullam? Tenetur reprehenderit aut voluptatum impedit voluptates in natus iure cumque + eaque? + + + + + + + + + + +); + +NoTitle.storyName = 'no title'; + +export const NoTitleDarkMode = getStoryVariant(NoTitle, DARK_MODE); +export const NoTitleHighContrast = getStoryVariant(NoTitle, HIGH_CONTRAST); +export const NoTitleRTL = getStoryVariant(NoTitle, RTL); + +export const NoTitleNoActions = () => ( + + + + + + + + Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam exercitationem cumque repellendus eaque est + dolor eius expedita nulla ullam? Tenetur reprehenderit aut voluptatum impedit voluptates in natus iure cumque + eaque? + + + + +); + +NoTitleNoActions.storyName = 'no title & no actions'; + +export const NoTitleNoActionsDarkMode = getStoryVariant(NoTitleNoActions, DARK_MODE); +export const NoTitleNoActionsHighContrast = getStoryVariant(NoTitleNoActions, HIGH_CONTRAST); +export const NoTitleNoActionsRTL = getStoryVariant(NoTitleNoActions, RTL); + +export const TitleCustomAction = () => ( + + + + + + + } />}> + Dialog title + + + Lorem, ipsum dolor sit amet consectetur adipisicing elit. Aliquid, explicabo repudiandae impedit doloribus + laborum quidem maxime dolores perspiciatis non ipsam, nostrum commodi quis autem sequi, incidunt cum? + Consequuntur, repellendus nostrum? + + + + +); + +TitleCustomAction.storyName = 'title custom action'; + +export const TitleCustomActionDarkMode = getStoryVariant(TitleCustomAction, DARK_MODE); +export const TitleCustomActionHighContrast = getStoryVariant(TitleCustomAction, HIGH_CONTRAST); +export const TitleCustomActionRTL = getStoryVariant(TitleCustomAction, RTL); + +export const Nested = () => ( + + + + + + + Dialog title + + + + + + + + Inner dialog title + ⛔️ just because you can doesn't mean you should have nested dialogs ⛔️ + + + + + + + + + + + + +); + +Nested.storyName = 'nested'; + +export const NestedDarkMode = getStoryVariant(Nested, DARK_MODE); +export const NestedHighContrast = getStoryVariant(Nested, HIGH_CONTRAST); +export const NestedRTL = getStoryVariant(Nested, RTL); + +export const ScrollLongContent = () => ( + + + + + + + Dialog title + +

    + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et + dolore magna aliqua. Nisl pretium fusce id velit ut tortor. Leo vel fringilla est ullamcorper. Eget est + lorem ipsum dolor sit amet consectetur adipiscing elit. In mollis nunc sed id semper risus in hendrerit + gravida. Ullamcorper sit amet risus nullam eget felis eget. Dolor sed viverra ipsum nunc aliquet bibendum. + Facilisi morbi tempus iaculis urna id volutpat. Porta non pulvinar neque laoreet suspendisse. Nunc id cursus + metus aliquam eleifend mi in. A iaculis at erat pellentesque adipiscing commodo. Proin nibh nisl condimentum + id. In hac habitasse platea dictumst vestibulum rhoncus est. Non tellus orci ac auctor augue mauris augue + neque. Enim nulla aliquet porttitor lacus luctus accumsan tortor. Nascetur ridiculus mus mauris vitae + ultricies leo integer. Ullamcorper eget nulla facilisi etiam dignissim. Leo in vitae turpis massa sed + elementum tempus egestas sed. +

    +

    + Ut enim blandit volutpat maecenas volutpat. Venenatis urna cursus eget nunc scelerisque viverra mauris. + Neque aliquam vestibulum morbi blandit. Porttitor eget dolor morbi non. Nisi quis eleifend quam adipiscing + vitae. Aliquam ultrices sagittis orci a scelerisque purus semper. Interdum varius sit amet mattis vulputate + enim nulla aliquet. Ut sem viverra aliquet eget sit amet tellus cras. Sit amet tellus cras adipiscing enim + eu turpis egestas. Amet cursus sit amet dictum sit amet justo donec enim. Neque gravida in fermentum et + sollicitudin ac. Arcu cursus euismod quis viverra nibh cras pulvinar mattis nunc. Ultrices eros in cursus + turpis massa tincidunt dui. Nisl rhoncus mattis rhoncus urna neque viverra justo. Odio pellentesque diam + volutpat commodo sed egestas. Nunc mi ipsum faucibus vitae aliquet nec ullamcorper. Ipsum nunc aliquet + bibendum enim. Faucibus ornare suspendisse sed nisi lacus sed. Sapien nec sagittis aliquam malesuada + bibendum arcu vitae elementum. Metus vulputate eu scelerisque felis imperdiet. +

    +

    + Consequat interdum varius sit amet mattis vulputate enim. Amet cursus sit amet dictum sit amet justo. Eget + aliquet nibh praesent tristique magna sit. Ut consequat semper viverra nam libero justo. Pharetra massa + massa ultricies mi. Sem viverra aliquet eget sit amet. Pulvinar mattis nunc sed blandit libero volutpat sed. + Pharetra diam sit amet nisl suscipit adipiscing bibendum. Consectetur adipiscing elit ut aliquam. Volutpat + diam ut venenatis tellus in metus vulputate. Scelerisque in dictum non consectetur a erat. Venenatis lectus + magna fringilla urna porttitor rhoncus. Vitae congue mauris rhoncus aenean vel elit. Neque laoreet + suspendisse interdum consectetur. Ultrices gravida dictum fusce ut placerat orci. Bibendum ut tristique et + egestas quis ipsum suspendisse. Mattis rhoncus urna neque viverra justo nec ultrices dui. Elit duis + tristique sollicitudin nibh sit amet. +

    +

    + At risus viverra adipiscing at. Interdum posuere lorem ipsum dolor sit amet consectetur adipiscing elit. + Nunc vel risus commodo viverra maecenas. Sit amet est placerat in egestas erat imperdiet sed euismod. Turpis + egestas maecenas pharetra convallis posuere. Egestas tellus rutrum tellus pellentesque eu tincidunt tortor + aliquam. Dolor sit amet consectetur adipiscing elit. Aliquam purus sit amet luctus venenatis lectus magna + fringilla. Scelerisque fermentum dui faucibus in ornare quam viverra. Egestas maecenas pharetra convallis + posuere morbi leo urna. A diam sollicitudin tempor id eu nisl nunc. Lectus sit amet est placerat. +

    +

    + Mattis ullamcorper velit sed ullamcorper morbi tincidunt ornare massa eget. At tellus at urna condimentum + mattis pellentesque id nibh. Dui faucibus in ornare quam. Tincidunt id aliquet risus feugiat in ante metus + dictum. Adipiscing commodo elit at imperdiet dui. Dolor sed viverra ipsum nunc. Sodales neque sodales ut + etiam sit amet nisl. Hendrerit dolor magna eget est lorem ipsum dolor sit amet. Mattis molestie a iaculis at + erat pellentesque adipiscing. Adipiscing elit duis tristique sollicitudin nibh sit amet commodo nulla. + Fringilla urna porttitor rhoncus dolor purus. +

    +

    + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et + dolore magna aliqua. Nisl pretium fusce id velit ut tortor. Leo vel fringilla est ullamcorper. Eget est + lorem ipsum dolor sit amet consectetur adipiscing elit. In mollis nunc sed id semper risus in hendrerit + gravida. Ullamcorper sit amet risus nullam eget felis eget. Dolor sed viverra ipsum nunc aliquet bibendum. + Facilisi morbi tempus iaculis urna id volutpat. Porta non pulvinar neque laoreet suspendisse. Nunc id cursus + metus aliquam eleifend mi in. A iaculis at erat pellentesque adipiscing commodo. Proin nibh nisl condimentum + id. In hac habitasse platea dictumst vestibulum rhoncus est. Non tellus orci ac auctor augue mauris augue + neque. Enim nulla aliquet porttitor lacus luctus accumsan tortor. Nascetur ridiculus mus mauris vitae + ultricies leo integer. Ullamcorper eget nulla facilisi etiam dignissim. Leo in vitae turpis massa sed + elementum tempus egestas sed. +

    +

    + Ut enim blandit volutpat maecenas volutpat. Venenatis urna cursus eget nunc scelerisque viverra mauris. + Neque aliquam vestibulum morbi blandit. Porttitor eget dolor morbi non. Nisi quis eleifend quam adipiscing + vitae. Aliquam ultrices sagittis orci a scelerisque purus semper. Interdum varius sit amet mattis vulputate + enim nulla aliquet. Ut sem viverra aliquet eget sit amet tellus cras. Sit amet tellus cras adipiscing enim + eu turpis egestas. Amet cursus sit amet dictum sit amet justo donec enim. Neque gravida in fermentum et + sollicitudin ac. Arcu cursus euismod quis viverra nibh cras pulvinar mattis nunc. Ultrices eros in cursus + turpis massa tincidunt dui. Nisl rhoncus mattis rhoncus urna neque viverra justo. Odio pellentesque diam + volutpat commodo sed egestas. Nunc mi ipsum faucibus vitae aliquet nec ullamcorper. Ipsum nunc aliquet + bibendum enim. Faucibus ornare suspendisse sed nisi lacus sed. Sapien nec sagittis aliquam malesuada + bibendum arcu vitae elementum. Metus vulputate eu scelerisque felis imperdiet. +

    +

    + Consequat interdum varius sit amet mattis vulputate enim. Amet cursus sit amet dictum sit amet justo. Eget + aliquet nibh praesent tristique magna sit. Ut consequat semper viverra nam libero justo. Pharetra massa + massa ultricies mi. Sem viverra aliquet eget sit amet. Pulvinar mattis nunc sed blandit libero volutpat sed. + Pharetra diam sit amet nisl suscipit adipiscing bibendum. Consectetur adipiscing elit ut aliquam. Volutpat + diam ut venenatis tellus in metus vulputate. Scelerisque in dictum non consectetur a erat. Venenatis lectus + magna fringilla urna porttitor rhoncus. Vitae congue mauris rhoncus aenean vel elit. Neque laoreet + suspendisse interdum consectetur. Ultrices gravida dictum fusce ut placerat orci. Bibendum ut tristique et + egestas quis ipsum suspendisse. Mattis rhoncus urna neque viverra justo nec ultrices dui. Elit duis + tristique sollicitudin nibh sit amet. +

    +

    + At risus viverra adipiscing at. Interdum posuere lorem ipsum dolor sit amet consectetur adipiscing elit. + Nunc vel risus commodo viverra maecenas. Sit amet est placerat in egestas erat imperdiet sed euismod. Turpis + egestas maecenas pharetra convallis posuere. Egestas tellus rutrum tellus pellentesque eu tincidunt tortor + aliquam. Dolor sit amet consectetur adipiscing elit. Aliquam purus sit amet luctus venenatis lectus magna + fringilla. Scelerisque fermentum dui faucibus in ornare quam viverra. Egestas maecenas pharetra convallis + posuere morbi leo urna. A diam sollicitudin tempor id eu nisl nunc. Lectus sit amet est placerat. +

    +

    + Mattis ullamcorper velit sed ullamcorper morbi tincidunt ornare massa eget. At tellus at urna condimentum + mattis pellentesque id nibh. Dui faucibus in ornare quam. Tincidunt id aliquet risus feugiat in ante metus + dictum. Adipiscing commodo elit at imperdiet dui. Dolor sed viverra ipsum nunc. Sodales neque sodales ut + etiam sit amet nisl. Hendrerit dolor magna eget est lorem ipsum dolor sit amet. Mattis molestie a iaculis at + erat pellentesque adipiscing. Adipiscing elit duis tristique sollicitudin nibh sit amet commodo nulla. + Fringilla urna porttitor rhoncus dolor purus. +

    +
    + + + + + + +
    +
    +
    +); + +ScrollLongContent.storyName = 'scroll long content'; + +export const ScrollLongContentDarkMode = getStoryVariant(ScrollLongContent, DARK_MODE); +export const ScrollLongContentHighContrast = getStoryVariant(ScrollLongContent, HIGH_CONTRAST); +export const ScrollLongContentRTL = getStoryVariant(ScrollLongContent, RTL); diff --git a/apps/vr-tests-react-components/src/stories/Divider.stories.tsx b/apps/vr-tests-react-components/src/stories/Divider.stories.tsx index 3c07d6fd9b943..28cbc16ac0efb 100644 --- a/apps/vr-tests-react-components/src/stories/Divider.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Divider.stories.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import Screener, { Steps } from 'screener-storybook/src/screener'; +import { Steps, StoryWright } from 'storywright'; import { storiesOf } from '@storybook/react'; import { Divider } from '@fluentui/react-divider'; import { TestWrapperDecorator, TestWrapperDecoratorFixedWidth } from '../utilities/index'; @@ -7,7 +7,7 @@ import { TestWrapperDecorator, TestWrapperDecoratorFixedWidth } from '../utiliti storiesOf('Divider Converged - Horizontal', module) .addDecorator(TestWrapperDecoratorFixedWidth) .addDecorator(story => ( - {story()} + {story()} )) .addStory('without content', () => , { includeRtl: true }) .addStory('with content', () => Today, { @@ -37,7 +37,7 @@ storiesOf('Divider Converged - Vertical', module) .addDecorator(TestWrapperDecorator) .addDecorator(story => (
    - {story()} + {story()}
    )) .addStory('Center Aligned', () => Today) diff --git a/apps/vr-tests-react-components/src/stories/Dropdown.stories.tsx b/apps/vr-tests-react-components/src/stories/Dropdown.stories.tsx new file mode 100644 index 0000000000000..9140191c9fd33 --- /dev/null +++ b/apps/vr-tests-react-components/src/stories/Dropdown.stories.tsx @@ -0,0 +1,185 @@ +import * as React from 'react'; +import { Steps, StoryWright } from 'storywright'; +import { storiesOf } from '@storybook/react'; +import { Dropdown, Option, OptionGroup } from '@fluentui/react-combobox'; +import { TestWrapperDecoratorFixedWidth } from '../utilities/TestWrapperDecorator'; + +storiesOf('Dropdown Converged', module) + .addDecorator(TestWrapperDecoratorFixedWidth) + .addDecorator(story => ( + + {story()} + + )) + .addStory('Appearance: outline (default)', () => ( + + + + )) + .addStory('Appearance: underline', () => ( + + + + )) + .addStory('Appearance: filled-darker', () => ( +
    + + + +
    + )) + .addStory('Appearance: filled-lighter', () => ( +
    + + + +
    + )) + .addStory('Disabled', () => ( + + + + )) + .addStory('Disabled with value', () => ( + + + + )) + .addStory('Invalid: outline', () => ( + + + + )) + .addStory('Invalid: underline', () => ( + + + + )) + .addStory('Invalid: filled-darker', () => ( +
    + + + +
    + )) + .addStory('Invalid: filled-lighter', () => ( +
    + + + +
    + )) + .addStory('With placeholder', () => ( + + + + + + )) + .addStory('With value', () => ( + + + + )) + .addStory('With multiselect value', () => ( + + + + + + )) + .addStory('Size: small', () => ( + + + + )) + .addStory('Size: large', () => ( + + + + )); + +// Option interaction stories +storiesOf('Dropdown Converged', module) + .addDecorator(TestWrapperDecoratorFixedWidth) + .addDecorator(story => ( + + {story()} + + )) + .addStory('Open', () => ( + + + + + + )) + .addStory('Open with inlinePopup', () => ( + + + + + + )) + .addStory('Option with long content', () => ( + + + + + + )) + .addStory('With selection', () => ( + + + + + + )) + .addStory('With multiselect selection', () => ( + + + + + + )) + .addStory('Disabled option', () => ( + + + + + + )) + .addStory('Open with grouped options', () => ( + + + + + + + + + + + + + )); diff --git a/apps/vr-tests-react-components/src/stories/Field.stories.tsx b/apps/vr-tests-react-components/src/stories/Field.stories.tsx index 663edb6328523..7c2137b4e9b3d 100644 --- a/apps/vr-tests-react-components/src/stories/Field.stories.tsx +++ b/apps/vr-tests-react-components/src/stories/Field.stories.tsx @@ -1,134 +1,165 @@ import * as React from 'react'; -import Screener, { Steps } from 'screener-storybook/src/screener'; -import { storiesOf } from '@storybook/react'; -import { Radio } from '@fluentui/react-radio'; -import { - CheckboxField, - ComboboxField, - InputField, - ProgressField, - RadioGroupField, - SelectField, - SliderField, - SpinButtonField, - SwitchField, - TextareaField, -} from '@fluentui/react-field'; -import { SparkleFilled } from '@fluentui/react-icons'; -import { FieldComponent, FieldPropsWithOptionalComponentProps } from '@fluentui/react-field/src/Field'; - -type FieldComponentProps = Pick< - FieldPropsWithOptionalComponentProps, - 'orientation' | 'required' | 'label' | 'validationState' | 'validationMessage' | 'validationMessageIcon' | 'hint' ->; - -/** - * Common VR tests for all field components. Pass the given Field component (or a wrapper around it). - */ -const storiesOfField = (name: string, Field: React.VoidFunctionComponent) => - storiesOf(name, module) - .addDecorator(story => {story()}) - .addDecorator(story => ( -
    -
    - {story()} -
    -
    - )) - .addStory('base', () => ) - .addStory('required', () => ) - .addStory('validation', () => ( -
    - - - - } - validationMessage="Custom message" - /> -
    - )) - .addStory('hint', () => ) - .addStory('horizontal', () => ( - - )); - -/** - * Same as storiesOfField, but with extra stories for Field components that support the size prop. - */ -const storiesOfFieldWithSize = ( - name: string, - Field: React.VoidFunctionComponent, -) => - storiesOfField(name, Field) - .addStory('size:small', () => ) - .addStory('size:large', () => ); - -// -// CheckboxField -// -storiesOfField('CheckboxField converged', CheckboxField) - .addStory('size:large', () => ) - .addStory('fieldLabel', () => ); - -// -// ComboboxField -// -storiesOfFieldWithSize('ComboboxField converged', ComboboxField); - -// -// InputField -// -storiesOfFieldWithSize('InputField converged', InputField); -// -// ProgressField -// -storiesOfField('ProgressField converged', props => ); - -// -// RadioGroupField -// -storiesOfField('RadioGroupField converged', props => ( - - - - - -)); - -// -// SelectField -// -storiesOfFieldWithSize('SelectField converged', props => ( - - - -)); - -// -// SliderField -// -storiesOfField('SliderField converged', SliderField); - -// -// SpinButtonField -// -storiesOfField('SpinButtonField converged', SpinButtonField); - -// -// SwitchField -// -storiesOfField('SwitchField converged', SwitchField); +import { Checkbox } from '@fluentui/react-checkbox'; +import { Combobox, Dropdown } from '@fluentui/react-combobox'; +import { Field } from '@fluentui/react-field'; +import { Dismiss12Filled } from '@fluentui/react-icons'; +import { Input } from '@fluentui/react-input'; +import { ProgressBar } from '@fluentui/react-progress'; +import { Radio, RadioGroup } from '@fluentui/react-radio'; +import { Select } from '@fluentui/react-select'; +import { Slider } from '@fluentui/react-slider'; +import { SpinButton } from '@fluentui/react-spinbutton'; +import { Switch } from '@fluentui/react-switch'; +import { Textarea } from '@fluentui/react-textarea'; +import { storiesOf } from '@storybook/react'; +import { Steps, StoryWright } from 'storywright'; -// -// TextareaField -// -storiesOfFieldWithSize('TextareaField converged', TextareaField); +storiesOf('Field', module) + .addDecorator(story => ( +
    + {story()} +
    + )) + .addStory('base', () => ( + + + + )) + .addStory('required', () => ( + + + + )) + .addStory('size:small', () => ( + + + + )) + .addStory('size:large', () => ( + + + + )) + .addStory('validation:error', () => ( + + + + )) + .addStory('validation:warning', () => ( + + + + )) + .addStory('validation:success', () => ( + + + + )) + .addStory('validation:none', () => ( + + + + )) + .addStory('validationMessageIcon', () => ( + } + > + + + )) + .addStory('hint', () => ( + + + + )) + .addStory('horizontal', () => ( + + + + )) + .addStory('horizontal+longLabel', () => ( + + + + )) + .addStory('horizontal+noLabel', () => ( + + + + )) + .addStory('Checkbox:error', () => ( + + + + )) + .addStory('Combobox:error', () => ( + + + + )) + .addStory('Dropdown:error', () => ( + + + + )) + .addStory('ProgressBar:error', () => ( + + + + )) + .addStory('RadioGroup:error', () => ( + + + + + + + + )) + .addStory('Select:error', () => ( + +