diff --git a/.devops/templates/cleanup.yml b/.devops/templates/cleanup.yml index dd967838ff6cc9..5e6fb5430aa570 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 00000000000000..28575d15929bdd --- /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 ba27a4691dba71..80e036d32da0df 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 ca5b1b2522ffe9..a5eb943d41d509 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 390a0a4303eb35..7edd4678498993 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 875957b38b1a37..32a67668aeeae3 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 ad38254db1f9a8..f34c3719932e1f 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 2369a9478b3038..fc8ef562d8eba7 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 fa9e24a32e5143..f358f4ce03052a 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 6464862d7e3315..8abcb77c26b3f4 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 6a1909aca67a45..7af9503414458f 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 f4ddf2e6633f10..00000000000000 --- 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 6ddd0a26c50bef..00000000000000 --- 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 92421f5eba985f..e75f16fd1a21e0 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 a3930f814d2d57..7aa372589e0d72 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 e1f8fe7f8d97f1..556379d237f3db 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 cce2e61868cd33..4d7988a2c5447e 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 4d5b76dfc83a87..4000008cd53fa4 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 743eeae1d54bdd..db3efb7177c52a 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 4662d73f44d707..5e375cbe8493e9 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 5929fd3ee0fc5c..be016c1495657e 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 55c092e105bb7d..5fc65f6964bd30 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 830d33392c04f7..00000000000000 --- 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 00000000000000..aa2482f34f6cbc --- /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 982cd8fe1b9a6e..00000000000000 --- 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 00000000000000..7bb7aa2c2d28d6 --- /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 8868c41f361e7f..00000000000000 --- 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 00000000000000..e72be02dacf713 --- /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 00000000000000..dc19a247fade23 --- /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 00000000000000..51fd802f21bb51 --- /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 00000000000000..bc0dbd40b4bcdb --- /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 80ed1801149c2e..794ed65e9b1ce0 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 f3c612b74211c1..399abe363dcada 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 f066ba3fe9eef0..545d23fe7806e5 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 5929fd3ee0fc5c..be016c1495657e 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 3fe0d492ca0c60..885f3d9df2d559 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 1e81dfe7943cbc..00000000000000 --- 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 00000000000000..e04633b61ae235 --- /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 e9bdcd6b11db34..00000000000000 --- 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 00000000000000..4a2dd120f69fa5 --- /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 e30c3c4aaff06a..00000000000000 --- 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 00000000000000..58018e5e5df72f --- /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 d11a357df84a30..ffe9d0c3364731 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 74a7815df7fd51..1ad60241b65c29 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 f066ba3fe9eef0..545d23fe7806e5 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 b353f9ec833e75..87fe6ecdd5bf6b 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 0c14cc1bdc51e3..dd5086c2e3e46c 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 be6e56c8715f97..e398612f0585cb 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 1358952b5e2e3e..27d5253cdb438f 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 1600436c62b075..17fba636fddf4d 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 164cfd41d215f7..86a30cc955bed6 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 bf324b5371c9d1..b3041f7ac06d9e 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 e690e4c847eab7..4e67a31a4ac52e 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 cdf52607e80de9..88271cdbdd9310 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 59faae6dc58f6a..15242005deed6b 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 00dfb3f33ec9c1..e0af52225d409c 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 a9ba66ecd41ff7..a460739ddccc70 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 3dd9fe4e367b92..00000000000000 --- 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 b1df0f4d1aa5fa..00000000000000 --- 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 93c8712239c741..90cd58429aa7bc 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 00000000000000..7427bec5facac5 --- /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 6ba74c8de1f030..242d94f1f02109 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 b0177f01b787b4..1587975e0a6c05 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 00000000000000..b81cda6dc04b8f --- /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 ec77bd58cc644d..00000000000000 --- 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 00000000000000..9f48013a060432 --- /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 00000000000000..fabc5c78b04f23 --- /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 00000000000000..a2424498a07644 --- /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 00000000000000..186602ac8c0cb2 --- /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 00000000000000..2d4766c606c4a6 --- /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 00000000000000..c6eb2c09fbf7ae --- /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 21cc1be52f89dd..4388c80a1423ad 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 00000000000000..0902bbe6cc889e --- /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 00000000000000..2c0874400df788 --- /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 bba2de6cb427a7..00000000000000 --- 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 00000000000000..1780bffbb179a2 --- /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 1d814202443f10..00000000000000 --- 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 f8ff4c9cfbbc08..00000000000000 --- 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 1bae31e19eff68..24a1ca1a792c1e 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 00000000000000..e711ca7a1619b5 --- /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 00000000000000..5e6b44d1579b75 --- /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 80298c59e914f6..aab9b2bb21530a 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 937d9c0bea2d6f..42556c19a19be6 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 bb17e71cac180e..93003cad90de96 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 82050f18dfaaf4..e03cbda640bce2 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 5c554d699bfdbe..00000000000000 --- 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 de7a8e14626d79..895013317a8c7c 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 4d545853fb611c..8dde44a995a123 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 c787b450987660..cc35ba4818249e 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 bcc7d9d264037c..b10db31a6aca51 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 94aeffd98d011e..9c670a29cd697e 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 f86d6a1ea57c9f..a20920e96625b9 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 eb6e827c923ac1..43ecb10e92b001 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 adc8c64b341b26..13b999f220d83a 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 45431a06094190..6e4743de73a518 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 b77be715b3bce0..3948ae4db1fa84 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 fcd3304a399498..d818ecb1637e51 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 e66290ddd28697..d710cffb1f30eb 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 9ef4a608c42b72..ee1f28c9069c9b 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 8e38e0ae4b5c50..f26e9c958e7cce 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 f8ce5d148b5a94..4f7b68c822c787 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 5dceb8bb64703c..00000000000000 --- 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 4e60d542186d29..00000000000000 --- 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 00000000000000..2e82333585ee7d --- /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 af00032ebdea68..b7699fe1547659 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 b09f9bd52ab6c6..64048b9d3aaf4b 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 370eef01bdcbd9..348bb3371334b5 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 b3dbb46e03f69d..0d0b5769a20852 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 1209b2617055e9..bf2faacbd5be0a 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 48a79fc71f5c64..1ef8228e28739b 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 d054547095b59e..d7fb6a7312417e 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 248759a1a0d240..58d2d745153bd2 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 94f167ef1f30bd..8f407ce30c85d0 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 ab69896b815b04..acbc55449c34fe 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 6b457f19b29873..0336f1855dc15a 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 7cf0ae6810e197..0758a1a8d327ff 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 918557d9a5e348..05fe0d8641776e 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 783769100cb1a4..4a16202d5d81dc 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 4f456a188a382c..33fb1b83f89a71 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 5146f6ed1481a1..c9f6e4a9f561c4 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 553c49b4cede5e..ae23594c4a61b1 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 3dbb25424c65b8..b7f0cff76daade 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 18f018d697f2ac..066f112fc24c33 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 979ee3d9fef555..3a52ee13ce924b 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 3681b7a819517f..b6a780b2eef667 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 a2d2f65bbc51dd..dc4ff10899103d 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 18f018d697f2ac..066f112fc24c33 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 019c578045209c..06c3daa7e1b941 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 49a4af4da073d0..0b91e54f138f0f 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 701eb549ed4414..9565d478a31b83 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 d79b3a2e24b8eb..6ec99fcb702650 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 df01399b8b105c..0e95a7639a2864 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 be8ff5acd3e5d0..e2adc803da8fab 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 4aac73555c9838..74370a88991f1b 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 c0f92483241748..6ff5842b76f3d9 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 d09dfe7d2f371a..25eb65c1338f2d 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 961de49293b039..fb806f6d93de0f 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 3dfc7ee4057e29..5662468ecb4d7f 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 2e2991605a4f8e..fb1e3bf17aac65 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 40674363dda456..6c134f0b5917f5 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 260d6c0fc31889..25528c11ca408b 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 9e1d0d2bdc2247..f2126a86b607f7 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 084841ec4c4b6d..ed7b989923d1ad 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 3362c5cae0e6a1..ca6413881e1b9e 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 20f21346c1e14d..9fd6a695ec4fb8 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 ab39d5d383fffa..348e11275d9727 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 1a602718563041..c92832b10e8af4 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 fb710788b092ca..46bc6996548056 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 e37ed3b3d4ed60..acf749957dba9c 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 48943b15a870ca..9ea3d3a95ca0bb 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 5af9efa5ed2b33..ce7a047971feff 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 80a8e48ca8ce12..6088e2b1233a1e 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 c6c5d386d6051a..47634e20459f2a 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 a69d2f25604da2..b912bbf7ad01ff 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 00000000000000..10d06bd2c7e8ee --- /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 00000000000000..6595f9b803ac41 --- /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 c7b2a4f4c8eb21..11d1d5eb58eec8 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 dc436ef95f975a..33ec4888286cf2 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 0945a61721f80d..3c97c96749f1d2 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 00000000000000..e21b2a1d08fe4d --- /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 00000000000000..2d04890dffd02c --- /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 f9b06299b772ca..5ca279fc082731 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 6d70f8b4437e24..f62edd373b9bcd 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 74cf427410f671..1b8b88fea244be 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 d47778f5eb5ea7..7b37f39a8ef874 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 c27c154abe7ac0..f43c1df563e2f7 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 fde3b5cd47405f..a335ee1fa4fd28 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 41d3eccce35faa..3ddf28f5f4e05a 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 28bb1805477c5d..d41a166d3cc2cc 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 9a63dd6479c8f1..18b0ec809f6845 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 352318b9b43385..9eba28f7bdbd9f 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 bd0690c400f75b..d45d1a2c985b7f 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 9333e2a018d1e4..9753b0e1da6d9e 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 ef8c9d4a85c669..7b258dcbe380fa 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 1348ad5db488aa..03c50d35c1262c 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 54acd69bedd9d0..6b18b0696b1f42 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 cefd251d4262fd..59d9cf53f44d76 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 4a159c51c127bf..7dca1e58b935ca 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 a0de154172595d..d5bb47786465ca 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 84750f1883078d..1ac37fc69b9303 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 08c87c96f05f41..7af0a8cb4c9328 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 dfd24cdd2ef36e..752b62010146e6 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 5f85b3d56af17c..ec7042efa57bfd 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 4bcf18dbd406c7..695e86b18c87db 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 9216302bb0953c..b35b86b4d341aa 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 dca070c6de4994..a968b1b3c49a84 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 cb7363929fa8d4..70797919bb582c 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 d9dd9c0d68f595..1ddd04e0ab4722 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 06998feefdd544..11e66cb507e9b5 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 762d08c24788f8..c5217553e42cdc 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 0cb5d555eb0d91..34013457e6abe0 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 e4e95aef14a8eb..20449c4bca94f9 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 1e0f758a05c26b..0915e66a9deff0 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 deb27e1b4dc84c..1ce884ca8464bd 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 af54e421ff11b4..a17d0c732b4dad 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 c302aebbbc3673..ceb5f38bcff08d 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 4bdf45e892c0a9..54f22b71289df5 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 d4456338c405a4..3e9dbb89860fee 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 eb51bcaae19546..a7197c00769954 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 69cd4574c9ffd9..b78ca997ee7de9 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 f341dc5672c1a1..10ece252db11a2 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 230f4e9652f757..577f9af37965ff 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 eb0dcf666bc0cb..2d9f2b34202524 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 6675efc26d340b..922c8c31c6f10d 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 d156be2ab88239..d1897ca4aba4c0 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 d8542a337ce362..87e3234d2fb83f 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 213b1c4d8b1d43..13f1479a3a7dfe 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 311ef48215fbd3..271eca93a9fd7b 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 1cc350c4091ea6..b58fc669aae4f7 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 17804b6e4cdd24..0a3b3fd57f9f7a 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 6dafbc6732f704..d82ed65c7e9514 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 43cf41619da1a5..7645a2903f6a4a 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 4a87eb306b5bf1..6ff45f8e4de9c7 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 577387d53254ab..e26470e6a90b76 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 ad7dca94b2228b..7ddf0a381266b9 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 5c3232c386e059..eac3d618aa91b8 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 9ec5920fd9a5c5..0bd52c9714cb05 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 abc71f8f6af8c3..a8a46a19456eeb 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 6af27a4998986e..470488aa46caee 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 1c877fe2ba068a..a03d133eaa8b44 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 0419f2041c16d6..315c614a71f696 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 929639b7a3c6c9..06dfce758ff70d 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 553cf260ed6f7b..583e7947c1aa32 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 edb5791c124e54..a00e61ae370040 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 86efaac24ad080..3a5492852e472b 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 afa8f0d2562f64..9937664ed24d8e 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 a21e752ba76f73..8e1bc0b07f4690 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 8958377648df8c..162ab6df922506 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 5d42ebb4883eeb..fc6db4f5816910 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 f728de02962299..53f9beeb789d4a 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 231136bf950796..0b956b81547899 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 68ad973f6df0b5..43f534dc5523cc 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 488a04c913a253..5777afcb7e01fa 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 909c4a6d5a3e7b..00873435772e59 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 3e084dfabcd541..384baa4ff1a7fd 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 9c83d0a77ceb1d..3c102d10d5ecda 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 129f316dc4527c..e3e72c7a7bad29 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 b9b1afe27a44ad..7f3faab52e61bf 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 19ea54594b547b..d4fc9b248a915d 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 0046f279c1fdbd..42f0433a2a04b9 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 a2878d5d784c31..530b3ade2eef0b 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 0f61532f142fde..4ed8005229fa93 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 be6f19edae7543..c971c5dd590216 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 ed63574634a209..81f836cca21ff9 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 c18e1869ee77d4..a070472fc8d3ee 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 1827fad21dc3c8..dc09c5dff30b69 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 e4e247d16fd7da..17d13653379509 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 9d603c42e4e735..bca13e85b9c5b9 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 bfd707d9e49169..f9dcc8adab8b90 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 292440b8c4ddcb..39abb5b6f531cb 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 6f3b81fb322181..a73919b8d435cc 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 657a19a40c5f21..7ba2daa0ebb60c 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 f2ff28c0990563..b5b7066fdf0a08 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 edfd441990db2d..28fd52d07ca344 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 7ac76ae74d14f6..43022905623d67 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 bfb0a1491df3f2..bc481cac223a86 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 c4df274def4861..868d86ffc4ab40 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 cc6294b3462b08..0c254b08a7e06d 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 935baaad273b80..55e65d245cd573 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 abce5f2d41a72a..4237577575722a 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 b5f5a172c6ec45..daa8b625567f41 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 f0d515a18e5e33..f8580f42723e93 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 7711d13d789482..b14c8c3fc6a55e 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 9d71ed59584b2f..a276563856547d 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 438f349aae407f..82e49838efafc3 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 2954269b8c0ed1..a575dc5d1e854a 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 6c5f12fe30a135..65c8c5952b627a 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 451406bc4ec603..2521dea7b385f8 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 0cb9d3e78f3679..3447f5e32932a1 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 adec3ed0913acb..389ff018c3750d 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 912c1c209ada76..6e998bd834b1e6 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 dc6a39ed797879..c3e0a6534abda3 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 6dc50f29d74462..2a5ff87cf81d62 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 0a95e5f84fe425..9c797e71929da5 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 c13274d71e0dd9..3450cf0da0ee78 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 d38bce567ed11a..0036be34cb055e 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 6ce6e06097917e..c726149e7b07c8 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 57b51419b984dd..edccced77d1be2 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 28a62be45fab1c..4700c6ec12c908 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 00000000000000..f0346f84a6538c --- /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 00000000000000..99ae5cc31ead96 --- /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 00000000000000..a1febd7bdb35d9 --- /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 00000000000000..02a1a3413de584 --- /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 00000000000000..dcad916ece372f --- /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 00000000000000..b1eae5decca4b3 --- /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 c2b5266f5dfcf2..13499acd65f5af 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 030b69c02c2daa..a76fa14597e517 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 60b1defc10067c..f7447446180419 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 37f1edff608abe..159fd890e15a2f 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 12671673555bae..bd3d7169f65911 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 2474846337f204..78c5173940ff73 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 46c31b76b0656f..48631ab55cc893 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 22b2cc4f95981d..fdbcd7a6570964 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 09270c4f69be6b..57fc6f0070e12c 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 8745a9acea9a47..00000000000000 --- 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 ab644d198e0d42..bff7e48d69e59c 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 1ee18a144c16a2..b5c8bdf6a7f35b 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 c2249c1dd90625..e7582ba1c0ddd6 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 2e24a7c63ca341..d3111e7d16f286 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 5a82486a92d002..d7239a359fb097 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 8745a9acea9a47..00000000000000 --- 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 ab644d198e0d42..bff7e48d69e59c 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 209f460d92d570..984828ac399825 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 0e9615a6081150..056cc3ddf15b71 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 2e24a7c63ca341..d3111e7d16f286 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 66d036830a2187..b8a83b5919fa87 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 760cf508fdf2ca..50e39889ee309f 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 00000000000000..30ea9c1e512750 --- /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 bcc7d9d264037c..b10db31a6aca51 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 fbf47998f437c6..ebbb54d1a99d84 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 0e229136d99d10..00000000000000 --- 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 4fee9cf87f3a8b..00000000000000 --- 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 00000000000000..08c1e884d44309 --- /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 00000000000000..450dcd268df27d --- /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 f19cc9bb55faea..282b0674b386ed 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 940e110f441951..6bd674763f1cb4 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 ead15d05920ad4..00000000000000 --- 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 00000000000000..e782b07cce5478 --- /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 00000000000000..5813d5e96acf92 --- /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 00000000000000..a5423654ead193 --- /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 bb064b192f7b49..00000000000000 --- 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 ec456a60d55a09..375a23d90e89b4 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 00000000000000..0b237f2954af68 --- /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 c9d1360f34a21b..00000000000000 --- 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 00000000000000..9af7b16afc2538 --- /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 98ccf2836eb637..00000000000000 --- 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 00000000000000..5061f52be2d9c5 --- /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 3c07d6fd9b943d..28cbc16ac0efb6 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 00000000000000..9140191c9fd338 --- /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 663edb63285237..7c2137b4e9b3d0 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', () => ( + +