diff --git a/.eslintignore b/.eslintignore index 8d16fa50d70..f7b19a782f3 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,5 +1,19 @@ node_modules +# carbon-web-components +packages/carbon-web-components/coverage +packages/carbon-web-components/dist +packages/carbon-web-components/es +packages/carbon-web-components/examples +packages/carbon-web-components/umd +packages/carbon-web-components/lib +packages/carbon-web-components/node_modules +packages/carbon-web-components/storybook-static +packages/carbon-web-components/src/internal/vendor +packages/carbon-web-components/tests/e2e/dist +packages/carbon-web-components/tests/e2e/cypress +packages/carbon-web-components/tests/e2e-storybook/cypress + # react packages/react/coverage packages/react/es diff --git a/.eslintrc b/.eslintrc index 380e7edaf20..79537c1b1d1 100644 --- a/.eslintrc +++ b/.eslintrc @@ -99,7 +99,7 @@ "sourceType": "module" }, "rules": { - "import/no-unresolved": 0 + // "import/no-unresolved": 0 } }, { diff --git a/.github/ISSUE_TEMPLATE/design_kit_bug b/.github/ISSUE_TEMPLATE/design_kit_bug new file mode 100644 index 00000000000..2d9c01d808d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/design_kit_bug @@ -0,0 +1,68 @@ +name: Design kit ๐Ÿ› +description: + Something isn't working as expected in the Carbon for IBM.com design kit? Here is the right place to report. +title: '[YOUR TITLE]: Brief description' +assignees: + - oliviaflory,RichKummer +labels: ['bug','design kit', 'design'] +body: + - type: markdown + attributes: + value: '## Design kit ๐Ÿ›' + - type: markdown + attributes: + value: 'Use the form below to report any bugs you find in the Carbon for IBM.com design kit. Feel free to leave blank any sections that arenโ€™t relevant but try to include as much detail as possible. The more details we have, the faster we can respond.' + - type: textarea + id: components + attributes: + label: Component(s) impacted + description: "Is this issue related to a specific component? If so please give the component name, breakpoint, and variables." + validations: + required: true + - type: textarea + id: description + attributes: + label: Description + description: "What did you expect to happen? What happened instead? Is this issue being filed based on a discrepancy between the website and/or code and the kit? If so what is the inconsistency?" + validations: + required: true + - type: textarea + id: kit + attributes: + label: Design kit + description: "What version of the Carbon for IBM.com design kit are you using" + validations: + required: true + - type: textarea + id: reproduce + attributes: + label: "Steps to reproduce the issue (if applicable)" + validations: + required: true + - type: input + id: application + attributes: + label: Application/website + description: "What application/website do you work on?" + validations: + required: true + - type: textarea + id: release-date + attributes: + label: "Any pressing ship or release date we should be aware of (if applicable)?" + validations: + required: false + - type: checkboxes + id: terms + attributes: + label: Code of Conduct + description: Please confirm the following + options: + - label: + I agree to follow this project's [Code of + Conduct](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/blob/main/.github/CODE_OF_CONDUCT.md) + required: true + - label: + I checked the [current + issues](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/issues) for + duplicate issues diff --git a/.github/workflows/automerge-cwc-v2.yml b/.github/workflows/automerge-cwc-v2.yml new file mode 100644 index 00000000000..0f522e4a588 --- /dev/null +++ b/.github/workflows/automerge-cwc-v2.yml @@ -0,0 +1,29 @@ +name: automerge-cwc-v2 +on: + push: + branches: + - 'main' + +concurrency: + group: automerge-cwc-v2-${{ github.ref }} + cancel-in-progress: true + +jobs: + automerge-mastheadv2: + if: github.repository == 'carbon-design-system/carbon-for-ibm-dotcom' + runs-on: ubuntu-20.04 + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + steps: + - uses: actions/checkout@v2 + - name: Merge to feat/cwc-v2 + uses: devmasx/merge-branch@1.4.0 + with: + type: now + target_branch: 'feat/cwc-v2' + env: + GITHUB_TOKEN: ${{secrets.MERGE_ACTION}} + - uses: act10ns/slack@v1 + with: + status: ${{ job.status }} + if: failure() diff --git a/.github/workflows/automerge-import-cwc-repo.yml b/.github/workflows/automerge-import-cwc-repo.yml deleted file mode 100644 index 39a00b97fa4..00000000000 --- a/.github/workflows/automerge-import-cwc-repo.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: automerge-import-cwc-repo -on: - push: - branches: - - 'main' - -concurrency: - group: automerge-import-cwc-repo-${{ github.ref }} - cancel-in-progress: true - -jobs: - automerge-import-cwc-repo: - if: github.repository == 'carbon-design-system/carbon-for-ibm-dotcom' - runs-on: ubuntu-20.04 - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - steps: - - uses: actions/checkout@v2 - - name: Merge to chore/import-cwc-repo - uses: devmasx/merge-branch@1.4.0 - with: - type: now - target_branch: 'chore/import-cwc-repo' - env: - GITHUB_TOKEN: ${{secrets.MERGE_ACTION}} - - uses: act10ns/slack@v1 - with: - status: ${{ job.status }} - if: failure() diff --git a/.github/workflows/ci-check.yml b/.github/workflows/ci-check.yml index acf2f8c6d18..2b79ba5da6f 100644 --- a/.github/workflows/ci-check.yml +++ b/.github/workflows/ci-check.yml @@ -2,9 +2,9 @@ name: ci-check on: push: - branches: [ main, release/* ] + branches: [ main, release/*, feat/cwc-v2 ] pull_request: - branches: [ main, release/* ] + branches: [ main, release/*, feat/cwc-v2 ] concurrency: group: ci-check-${{ github.ref }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index dccbc6766dd..f4e366bf2f5 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -13,7 +13,7 @@ name: "CodeQL" on: push: - branches: [ main, release/* ] + branches: [ main, release/*, feat/cwc-v2 ] pull_request: # The branches below must be a subset of the branches above branches: [ main ] diff --git a/.github/workflows/deploy-canary.yml b/.github/workflows/deploy-canary.yml index 5657818c907..536034a1b77 100644 --- a/.github/workflows/deploy-canary.yml +++ b/.github/workflows/deploy-canary.yml @@ -10,6 +10,63 @@ concurrency: cancel-in-progress: true jobs: + carbon-web-components: + if: github.repository == 'carbon-design-system/carbon-for-ibm-dotcom' + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + with: + token: ${{secrets.MERGE_ACTION}} + - name: Use Node.js 14.x + uses: actions/setup-node@v2 + with: + node-version: '14.x' + cache: 'yarn' + - name: Install dependencies + run: yarn install --offline + - name: Build project + run: yarn lerna run --scope @carbon/web-components build + + - name: Set env vars + uses: ./.github/actions/set-dotenv + with: + env-file: packages/carbon-web-components/.env + env: + KALTURA_PARTNER_ID: ${{ secrets.KALTURA_PARTNER_ID }} + KALTURA_UICONF_ID: ${{ secrets.KALTURA_UICONF_ID }} + PROFILE_HOST: ${{ secrets.PROFILE_HOST }} + - name: Building @carbon/web-components storybook + run: yarn build-storybook + working-directory: packages/carbon-web-components + - name: Move storybook to build folder + run: | + rm packages/carbon-web-components/.env + mkdir -p builds + mv packages/carbon-web-components/storybook-static builds/carbon-web-components + + - name: Deploying @carbon/web-components storybook to Github Pages + run: | + git config --global user.email ${{ secrets.BOT_EMAIL }} + git config --global user.name ${{ secrets.BOT_NAME }} + + git fetch origin gh-pages + git checkout -b gh-pages origin/gh-pages + git update-ref -d refs/remotes/origin/gh-pages + git pull origin gh-pages + + rm -rf canary/carbon-web-components + mkdir -p canary + mv builds/carbon-web-components canary/carbon-web-components + + git add canary/carbon-web-components + git commit -m "chore(deploy): deploy Carbon web components canary to GitHub Pages" + git push origin gh-pages + - uses: act10ns/slack@v1 + if: failure() + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + with: + status: ${{ job.status }} react: if: github.repository == 'carbon-design-system/carbon-for-ibm-dotcom' runs-on: ubuntu-20.04 @@ -25,7 +82,7 @@ jobs: - name: Install dependencies run: yarn install --offline - name: Build project - run: yarn lerna run --stream --ignore @carbon/ibmdotcom-web-components --ignore @carbon/ibmdotcom-services-store build + run: yarn lerna run build - name: Set env vars uses: ./.github/actions/set-dotenv @@ -121,7 +178,7 @@ jobs: - name: Install dependencies run: yarn install --offline - name: Build project - run: yarn lerna run --stream --ignore @carbon/ibmdotcom-react build + run: yarn lerna run --ignore @carbon/ibmdotcom-react build - name: Set env vars uses: ./.github/actions/set-dotenv @@ -236,7 +293,7 @@ jobs: - name: Install dependencies run: yarn install --offline - name: Build project - run: yarn lerna run --stream --ignore @carbon/ibmdotcom-react --ignore @carbon/ibmdotcom-web-components --ignore @carbon/ibmdotcom-services-store build + run: yarn lerna run --ignore @carbon/ibmdotcom-react --ignore @carbon/ibmdotcom-web-components --ignore @carbon/web-components build - name: Set env vars uses: ./.github/actions/set-dotenv with: diff --git a/.github/workflows/deploy-next.yml b/.github/workflows/deploy-next.yml index 5a43512f2f7..12fa82016bd 100644 --- a/.github/workflows/deploy-next.yml +++ b/.github/workflows/deploy-next.yml @@ -10,6 +10,63 @@ concurrency: cancel-in-progress: true jobs: + carbon-web-components: + if: github.repository == 'carbon-design-system/carbon-for-ibm-dotcom' + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + with: + token: ${{secrets.MERGE_ACTION}} + - name: Use Node.js 14.x + uses: actions/setup-node@v2 + with: + node-version: '14.x' + cache: 'yarn' + - name: Install dependencies + run: yarn install --offline + - name: Build project + run: yarn lerna run --scope @carbon/web-components build + + - name: Set env vars + uses: ./.github/actions/set-dotenv + with: + env-file: packages/carbon-web-components/.env + env: + KALTURA_PARTNER_ID: ${{ secrets.KALTURA_PARTNER_ID }} + KALTURA_UICONF_ID: ${{ secrets.KALTURA_UICONF_ID }} + PROFILE_HOST: ${{ secrets.PROFILE_HOST }} + - name: Building @carbon/web-components (next) storybook + run: yarn build-storybook + working-directory: packages/carbon-web-components + - name: Move storybook to build folder + run: | + rm packages/carbon-web-components/.env + mkdir -p builds + mv packages/carbon-web-components/storybook-static builds/carbon-web-components + + - name: Deploying @carbon/web-components (next) storybook to Github Pages + run: | + git config --global user.email ${{ secrets.BOT_EMAIL }} + git config --global user.name ${{ secrets.BOT_NAME }} + + git fetch origin gh-pages + git checkout -b gh-pages origin/gh-pages + git update-ref -d refs/remotes/origin/gh-pages + git pull origin gh-pages + + rm -rf next/carbon-web-components + mkdir -p next + mv builds/carbon-web-components next/carbon-web-components + + git add next/carbon-web-components + git commit -m "chore(deploy): deploy Carbon web components next to GitHub Pages" + git push origin gh-pages + - uses: act10ns/slack@v1 + if: failure() + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + with: + status: ${{ job.status }} react: if: github.repository == 'carbon-design-system/carbon-for-ibm-dotcom' runs-on: ubuntu-20.04 @@ -25,7 +82,7 @@ jobs: - name: Install dependencies run: yarn install --offline - name: Build project - run: yarn lerna run --stream --ignore @carbon/ibmdotcom-web-components --ignore @carbon/ibmdotcom-services-store build + run: yarn lerna run build - name: Set env vars uses: ./.github/actions/set-dotenv @@ -101,7 +158,7 @@ jobs: - name: Install dependencies run: yarn install --offline - name: Build project - run: yarn lerna run --stream --ignore @carbon/ibmdotcom-react build + run: yarn lerna run --ignore @carbon/ibmdotcom-react build - name: Set env vars uses: ./.github/actions/set-dotenv diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 56eedf04cf6..a5a31be62c3 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -2,9 +2,9 @@ name: e2e-tests on: push: - branches: [ main, release/* ] + branches: [ main, release/*, feat/cwc-v2 ] pull_request: - branches: [ main, release/* ] + branches: [ main, release/*, feat/cwc-v2 ] concurrency: group: e2e-tests-${{ github.ref }} diff --git a/.github/workflows/percy-update-base.yml b/.github/workflows/percy-update-base.yml index 94f47e04a98..5ff7aa412cf 100644 --- a/.github/workflows/percy-update-base.yml +++ b/.github/workflows/percy-update-base.yml @@ -2,7 +2,7 @@ name: percy-update-base on: push: - branches: [ main, release/* ] + branches: [ main, release/*, feat/cwc-v2 ] concurrency: group: percy-update-base-${{ github.ref }} @@ -37,7 +37,7 @@ jobs: KALTURA_UICONF_ID: ${{ secrets.KALTURA_UICONF_ID }} PERCY_TOKEN: ${{ secrets.PERCY_TOKEN_REACT }} - name: Run percy storybook - run: yarn build-storybook && yarn visual-snapshot + run: yarn visual-snapshot working-directory: packages/react react-storybook-e2e: if: github.repository == 'carbon-design-system/carbon-for-ibm-dotcom' @@ -95,5 +95,35 @@ jobs: KALTURA_UICONF_ID: ${{ secrets.KALTURA_UICONF_ID }} PERCY_TOKEN: ${{ secrets.PERCY_TOKEN_WEBCOMPONENTS }} - name: Run percy storybook - run: yarn build-storybook && yarn visual-snapshot + run: yarn visual-snapshot working-directory: packages/web-components + carbon-web-components: + if: github.repository == 'carbon-design-system/carbon-for-ibm-dotcom' + runs-on: ubuntu-20.04 + strategy: + matrix: + node-version: ['14.x'] + steps: + - uses: actions/checkout@v2 + - name: Use Node.js 14.x + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + cache: 'yarn' + - name: Install dependencies + run: yarn install + - name: Install xvfb + run: sudo apt-get install xvfb + - name: Build + run: yarn lerna run --stream --ignore @carbon/ibmdotcom-react --stream --ignore @carbon/ibmdotcom-web-components --ignore @carbon/ibmdotcom-styles --ignore @carbon/ibmdotcom-services-store --ignore @carbon/ibmdotcom-utilities --ignore @carbon/ibmdotcom-services build + - name: Set env vars + uses: ./.github/actions/set-dotenv + with: + env-file: packages/carbon-web-components/.env + env: + KALTURA_PARTNER_ID: ${{ secrets.KALTURA_PARTNER_ID }} + KALTURA_UICONF_ID: ${{ secrets.KALTURA_UICONF_ID }} + PERCY_TOKEN: ${{ secrets.PERCY_TOKEN_CARBONWEBCOMPONENTS }} + - name: Run percy storybook + run: yarn visual-snapshot + working-directory: packages/carbon-web-components diff --git a/.prettierignore b/.prettierignore index 00571b5e2f9..daa0241470c 100644 --- a/.prettierignore +++ b/.prettierignore @@ -3,11 +3,12 @@ lib es umd build -dist +**/dist/** docs coverage -storybook-static -storybook-static-react +snapshots +fixtures +storybook-static* .github jsdocs examples @@ -19,6 +20,4 @@ CHANGELOG.md packages/**/src/internal/vendor packages/**/tests/e2e/cypress packages/**/tests/e2e-storybook/cypress -packages/web-components/tests/snapshots -packages/web-components/tests/e2e/build/examples-scaffold -packages/web-components/tests/e2e/dist +custom-elements.json diff --git a/.prettierrc b/.prettierrc index 9eae89852ff..452d9790fa5 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,5 +1,5 @@ { - "jsxBracketSameLine": true, + "bracketSameLine": true, "printWidth": 80, "singleQuote": true, "trailingComma": "es5", diff --git a/.yarn/offline-mirror/@babel-core-7.19.3.tgz b/.yarn/offline-mirror/@babel-core-7.19.3.tgz deleted file mode 100644 index 836411008f0..00000000000 Binary files a/.yarn/offline-mirror/@babel-core-7.19.3.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@babel-core-7.19.6.tgz b/.yarn/offline-mirror/@babel-core-7.19.6.tgz new file mode 100644 index 00000000000..49ca681ffff Binary files /dev/null and b/.yarn/offline-mirror/@babel-core-7.19.6.tgz differ diff --git a/.yarn/offline-mirror/@babel-generator-7.19.5.tgz b/.yarn/offline-mirror/@babel-generator-7.19.5.tgz deleted file mode 100644 index 6b2e33bb3df..00000000000 Binary files a/.yarn/offline-mirror/@babel-generator-7.19.5.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@babel-generator-7.19.6.tgz b/.yarn/offline-mirror/@babel-generator-7.19.6.tgz new file mode 100644 index 00000000000..eb95d0ec35a Binary files /dev/null and b/.yarn/offline-mirror/@babel-generator-7.19.6.tgz differ diff --git a/.yarn/offline-mirror/@babel-helper-module-transforms-7.19.0.tgz b/.yarn/offline-mirror/@babel-helper-module-transforms-7.19.0.tgz deleted file mode 100644 index d8bc7453c39..00000000000 Binary files a/.yarn/offline-mirror/@babel-helper-module-transforms-7.19.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@babel-helper-module-transforms-7.19.6.tgz b/.yarn/offline-mirror/@babel-helper-module-transforms-7.19.6.tgz new file mode 100644 index 00000000000..cbf1780edc7 Binary files /dev/null and b/.yarn/offline-mirror/@babel-helper-module-transforms-7.19.6.tgz differ diff --git a/.yarn/offline-mirror/@babel-parser-7.19.4.tgz b/.yarn/offline-mirror/@babel-parser-7.19.4.tgz deleted file mode 100644 index 9a74621a21a..00000000000 Binary files a/.yarn/offline-mirror/@babel-parser-7.19.4.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@babel-parser-7.19.6.tgz b/.yarn/offline-mirror/@babel-parser-7.19.6.tgz new file mode 100644 index 00000000000..6133a04deb0 Binary files /dev/null and b/.yarn/offline-mirror/@babel-parser-7.19.6.tgz differ diff --git a/.yarn/offline-mirror/@babel-plugin-proposal-decorators-7.19.3.tgz b/.yarn/offline-mirror/@babel-plugin-proposal-decorators-7.19.3.tgz deleted file mode 100644 index 02ac238a5da..00000000000 Binary files a/.yarn/offline-mirror/@babel-plugin-proposal-decorators-7.19.3.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@babel-plugin-proposal-decorators-7.19.6.tgz b/.yarn/offline-mirror/@babel-plugin-proposal-decorators-7.19.6.tgz new file mode 100644 index 00000000000..d0ce237e284 Binary files /dev/null and b/.yarn/offline-mirror/@babel-plugin-proposal-decorators-7.19.6.tgz differ diff --git a/.yarn/offline-mirror/@babel-plugin-transform-modules-amd-7.18.6.tgz b/.yarn/offline-mirror/@babel-plugin-transform-modules-amd-7.18.6.tgz deleted file mode 100644 index 2b57265d86d..00000000000 Binary files a/.yarn/offline-mirror/@babel-plugin-transform-modules-amd-7.18.6.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@babel-plugin-transform-modules-amd-7.19.6.tgz b/.yarn/offline-mirror/@babel-plugin-transform-modules-amd-7.19.6.tgz new file mode 100644 index 00000000000..0f68efa003c Binary files /dev/null and b/.yarn/offline-mirror/@babel-plugin-transform-modules-amd-7.19.6.tgz differ diff --git a/.yarn/offline-mirror/@babel-plugin-transform-modules-commonjs-7.18.6.tgz b/.yarn/offline-mirror/@babel-plugin-transform-modules-commonjs-7.18.6.tgz deleted file mode 100644 index acb97dd6bca..00000000000 Binary files a/.yarn/offline-mirror/@babel-plugin-transform-modules-commonjs-7.18.6.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@babel-plugin-transform-modules-commonjs-7.19.6.tgz b/.yarn/offline-mirror/@babel-plugin-transform-modules-commonjs-7.19.6.tgz new file mode 100644 index 00000000000..85102cf4513 Binary files /dev/null and b/.yarn/offline-mirror/@babel-plugin-transform-modules-commonjs-7.19.6.tgz differ diff --git a/.yarn/offline-mirror/@babel-plugin-transform-modules-systemjs-7.19.0.tgz b/.yarn/offline-mirror/@babel-plugin-transform-modules-systemjs-7.19.0.tgz deleted file mode 100644 index d2cd3fb425f..00000000000 Binary files a/.yarn/offline-mirror/@babel-plugin-transform-modules-systemjs-7.19.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@babel-plugin-transform-modules-systemjs-7.19.6.tgz b/.yarn/offline-mirror/@babel-plugin-transform-modules-systemjs-7.19.6.tgz new file mode 100644 index 00000000000..e8169fa1eb7 Binary files /dev/null and b/.yarn/offline-mirror/@babel-plugin-transform-modules-systemjs-7.19.6.tgz differ diff --git a/.yarn/offline-mirror/@babel-plugin-transform-runtime-7.19.1.tgz b/.yarn/offline-mirror/@babel-plugin-transform-runtime-7.19.1.tgz deleted file mode 100644 index 28489a5df91..00000000000 Binary files a/.yarn/offline-mirror/@babel-plugin-transform-runtime-7.19.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@babel-plugin-transform-runtime-7.19.6.tgz b/.yarn/offline-mirror/@babel-plugin-transform-runtime-7.19.6.tgz new file mode 100644 index 00000000000..4a1cb1254e4 Binary files /dev/null and b/.yarn/offline-mirror/@babel-plugin-transform-runtime-7.19.6.tgz differ diff --git a/.yarn/offline-mirror/@babel-runtime-7.20.6.tgz b/.yarn/offline-mirror/@babel-runtime-7.20.6.tgz new file mode 100644 index 00000000000..334ab9e0a02 Binary files /dev/null and b/.yarn/offline-mirror/@babel-runtime-7.20.6.tgz differ diff --git a/.yarn/offline-mirror/@babel-runtime-corejs3-7.19.4.tgz b/.yarn/offline-mirror/@babel-runtime-corejs3-7.19.4.tgz deleted file mode 100644 index 3e661e02fb9..00000000000 Binary files a/.yarn/offline-mirror/@babel-runtime-corejs3-7.19.4.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@babel-runtime-corejs3-7.19.6.tgz b/.yarn/offline-mirror/@babel-runtime-corejs3-7.19.6.tgz new file mode 100644 index 00000000000..7597c6b2c2a Binary files /dev/null and b/.yarn/offline-mirror/@babel-runtime-corejs3-7.19.6.tgz differ diff --git a/.yarn/offline-mirror/@babel-traverse-7.19.4.tgz b/.yarn/offline-mirror/@babel-traverse-7.19.4.tgz deleted file mode 100644 index 09edac9d2c9..00000000000 Binary files a/.yarn/offline-mirror/@babel-traverse-7.19.4.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@babel-traverse-7.19.6.tgz b/.yarn/offline-mirror/@babel-traverse-7.19.6.tgz new file mode 100644 index 00000000000..4ac72125e1a Binary files /dev/null and b/.yarn/offline-mirror/@babel-traverse-7.19.6.tgz differ diff --git a/.yarn/offline-mirror/@carbon-icon-helpers-10.37.0.tgz b/.yarn/offline-mirror/@carbon-icon-helpers-10.37.0.tgz new file mode 100644 index 00000000000..979508ec41c Binary files /dev/null and b/.yarn/offline-mirror/@carbon-icon-helpers-10.37.0.tgz differ diff --git a/.yarn/offline-mirror/@carbon-layout-10.37.0.tgz b/.yarn/offline-mirror/@carbon-layout-10.37.0.tgz deleted file mode 100644 index db19fc3d1c5..00000000000 Binary files a/.yarn/offline-mirror/@carbon-layout-10.37.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@carbon-pictograms-react-11.33.0.tgz b/.yarn/offline-mirror/@carbon-pictograms-react-11.33.0.tgz deleted file mode 100644 index 2a5c75277bc..00000000000 Binary files a/.yarn/offline-mirror/@carbon-pictograms-react-11.33.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@carbon-pictograms-react-11.37.0.tgz b/.yarn/offline-mirror/@carbon-pictograms-react-11.37.0.tgz new file mode 100644 index 00000000000..ae6180d3fa1 Binary files /dev/null and b/.yarn/offline-mirror/@carbon-pictograms-react-11.37.0.tgz differ diff --git a/.yarn/offline-mirror/@carbon-telemetry-0.0.0-alpha.6.tgz b/.yarn/offline-mirror/@carbon-telemetry-0.0.0-alpha.6.tgz deleted file mode 100644 index 7ab8b604eae..00000000000 Binary files a/.yarn/offline-mirror/@carbon-telemetry-0.0.0-alpha.6.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@dabh-diagnostics-2.0.3.tgz b/.yarn/offline-mirror/@dabh-diagnostics-2.0.3.tgz deleted file mode 100644 index abcbc52d3fd..00000000000 Binary files a/.yarn/offline-mirror/@dabh-diagnostics-2.0.3.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@es-joy-jsdoccomment-0.36.0.tgz b/.yarn/offline-mirror/@es-joy-jsdoccomment-0.36.0.tgz new file mode 100644 index 00000000000..cc56dafe189 Binary files /dev/null and b/.yarn/offline-mirror/@es-joy-jsdoccomment-0.36.0.tgz differ diff --git a/.yarn/offline-mirror/@gulp-sourcemaps-identity-map-2.0.1.tgz b/.yarn/offline-mirror/@gulp-sourcemaps-identity-map-2.0.1.tgz new file mode 100644 index 00000000000..aea7a70490b Binary files /dev/null and b/.yarn/offline-mirror/@gulp-sourcemaps-identity-map-2.0.1.tgz differ diff --git a/.yarn/offline-mirror/@hapi-address-2.1.4.tgz b/.yarn/offline-mirror/@hapi-address-2.1.4.tgz new file mode 100644 index 00000000000..6c093884bb8 Binary files /dev/null and b/.yarn/offline-mirror/@hapi-address-2.1.4.tgz differ diff --git a/.yarn/offline-mirror/@hapi-bourne-1.3.2.tgz b/.yarn/offline-mirror/@hapi-bourne-1.3.2.tgz new file mode 100644 index 00000000000..ed8995de0dc Binary files /dev/null and b/.yarn/offline-mirror/@hapi-bourne-1.3.2.tgz differ diff --git a/.yarn/offline-mirror/@hapi-hoek-8.5.1.tgz b/.yarn/offline-mirror/@hapi-hoek-8.5.1.tgz new file mode 100644 index 00000000000..344c8b1daba Binary files /dev/null and b/.yarn/offline-mirror/@hapi-hoek-8.5.1.tgz differ diff --git a/.yarn/offline-mirror/@hapi-joi-15.1.1.tgz b/.yarn/offline-mirror/@hapi-joi-15.1.1.tgz new file mode 100644 index 00000000000..e700951cb3a Binary files /dev/null and b/.yarn/offline-mirror/@hapi-joi-15.1.1.tgz differ diff --git a/.yarn/offline-mirror/@hapi-topo-3.1.6.tgz b/.yarn/offline-mirror/@hapi-topo-3.1.6.tgz new file mode 100644 index 00000000000..1fb8738afbd Binary files /dev/null and b/.yarn/offline-mirror/@hapi-topo-3.1.6.tgz differ diff --git a/.yarn/offline-mirror/@jest-console-26.6.2.tgz b/.yarn/offline-mirror/@jest-console-26.6.2.tgz new file mode 100644 index 00000000000..84b2751ead6 Binary files /dev/null and b/.yarn/offline-mirror/@jest-console-26.6.2.tgz differ diff --git a/.yarn/offline-mirror/@jest-environment-26.6.2.tgz b/.yarn/offline-mirror/@jest-environment-26.6.2.tgz new file mode 100644 index 00000000000..e35db6093ea Binary files /dev/null and b/.yarn/offline-mirror/@jest-environment-26.6.2.tgz differ diff --git a/.yarn/offline-mirror/@jest-environment-27.5.1.tgz b/.yarn/offline-mirror/@jest-environment-27.5.1.tgz new file mode 100644 index 00000000000..2196ace625f Binary files /dev/null and b/.yarn/offline-mirror/@jest-environment-27.5.1.tgz differ diff --git a/.yarn/offline-mirror/@jest-expect-utils-29.2.0.tgz b/.yarn/offline-mirror/@jest-expect-utils-29.2.0.tgz deleted file mode 100644 index b353e7ba130..00000000000 Binary files a/.yarn/offline-mirror/@jest-expect-utils-29.2.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@jest-expect-utils-29.2.1.tgz b/.yarn/offline-mirror/@jest-expect-utils-29.2.1.tgz new file mode 100644 index 00000000000..97692ff67eb Binary files /dev/null and b/.yarn/offline-mirror/@jest-expect-utils-29.2.1.tgz differ diff --git a/.yarn/offline-mirror/@jest-fake-timers-26.6.2.tgz b/.yarn/offline-mirror/@jest-fake-timers-26.6.2.tgz new file mode 100644 index 00000000000..57b740a6cc4 Binary files /dev/null and b/.yarn/offline-mirror/@jest-fake-timers-26.6.2.tgz differ diff --git a/.yarn/offline-mirror/@jest-fake-timers-27.5.1.tgz b/.yarn/offline-mirror/@jest-fake-timers-27.5.1.tgz new file mode 100644 index 00000000000..7af052326a3 Binary files /dev/null and b/.yarn/offline-mirror/@jest-fake-timers-27.5.1.tgz differ diff --git a/.yarn/offline-mirror/@jest-globals-26.6.2.tgz b/.yarn/offline-mirror/@jest-globals-26.6.2.tgz new file mode 100644 index 00000000000..1262b9dc7f5 Binary files /dev/null and b/.yarn/offline-mirror/@jest-globals-26.6.2.tgz differ diff --git a/.yarn/offline-mirror/@jest-source-map-26.6.2.tgz b/.yarn/offline-mirror/@jest-source-map-26.6.2.tgz new file mode 100644 index 00000000000..d6682ef7bc5 Binary files /dev/null and b/.yarn/offline-mirror/@jest-source-map-26.6.2.tgz differ diff --git a/.yarn/offline-mirror/@jest-test-result-26.6.2.tgz b/.yarn/offline-mirror/@jest-test-result-26.6.2.tgz new file mode 100644 index 00000000000..ef0daba9b2b Binary files /dev/null and b/.yarn/offline-mirror/@jest-test-result-26.6.2.tgz differ diff --git a/.yarn/offline-mirror/@jest-test-sequencer-26.6.3.tgz b/.yarn/offline-mirror/@jest-test-sequencer-26.6.3.tgz new file mode 100644 index 00000000000..a0fb96bfdfb Binary files /dev/null and b/.yarn/offline-mirror/@jest-test-sequencer-26.6.3.tgz differ diff --git a/.yarn/offline-mirror/@jest-types-27.5.1.tgz b/.yarn/offline-mirror/@jest-types-27.5.1.tgz new file mode 100644 index 00000000000..c4b9ade8068 Binary files /dev/null and b/.yarn/offline-mirror/@jest-types-27.5.1.tgz differ diff --git a/.yarn/offline-mirror/@jest-types-29.2.0.tgz b/.yarn/offline-mirror/@jest-types-29.2.0.tgz deleted file mode 100644 index c50d22b0ebb..00000000000 Binary files a/.yarn/offline-mirror/@jest-types-29.2.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@jest-types-29.2.1.tgz b/.yarn/offline-mirror/@jest-types-29.2.1.tgz new file mode 100644 index 00000000000..a39fe1864f1 Binary files /dev/null and b/.yarn/offline-mirror/@jest-types-29.2.1.tgz differ diff --git a/.yarn/offline-mirror/@leichtgewicht-ip-codec-2.0.4.tgz b/.yarn/offline-mirror/@leichtgewicht-ip-codec-2.0.4.tgz new file mode 100644 index 00000000000..23e6ca021b5 Binary files /dev/null and b/.yarn/offline-mirror/@leichtgewicht-ip-codec-2.0.4.tgz differ diff --git a/.yarn/offline-mirror/@open-wc-semantic-dom-diff-0.18.0.tgz b/.yarn/offline-mirror/@open-wc-semantic-dom-diff-0.18.0.tgz new file mode 100644 index 00000000000..d98c716f975 Binary files /dev/null and b/.yarn/offline-mirror/@open-wc-semantic-dom-diff-0.18.0.tgz differ diff --git a/.yarn/offline-mirror/@percy-cli-1.11.0.tgz b/.yarn/offline-mirror/@percy-cli-1.11.0.tgz deleted file mode 100644 index 4e4ab1ebcfc..00000000000 Binary files a/.yarn/offline-mirror/@percy-cli-1.11.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@percy-cli-1.12.0.tgz b/.yarn/offline-mirror/@percy-cli-1.12.0.tgz new file mode 100644 index 00000000000..949a7fa67e9 Binary files /dev/null and b/.yarn/offline-mirror/@percy-cli-1.12.0.tgz differ diff --git a/.yarn/offline-mirror/@percy-cli-app-1.11.0.tgz b/.yarn/offline-mirror/@percy-cli-app-1.11.0.tgz deleted file mode 100644 index 52a87c67a29..00000000000 Binary files a/.yarn/offline-mirror/@percy-cli-app-1.11.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@percy-cli-app-1.12.0.tgz b/.yarn/offline-mirror/@percy-cli-app-1.12.0.tgz new file mode 100644 index 00000000000..51f403cf56c Binary files /dev/null and b/.yarn/offline-mirror/@percy-cli-app-1.12.0.tgz differ diff --git a/.yarn/offline-mirror/@percy-cli-build-1.11.0.tgz b/.yarn/offline-mirror/@percy-cli-build-1.11.0.tgz deleted file mode 100644 index 995e43a5548..00000000000 Binary files a/.yarn/offline-mirror/@percy-cli-build-1.11.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@percy-cli-build-1.12.0.tgz b/.yarn/offline-mirror/@percy-cli-build-1.12.0.tgz new file mode 100644 index 00000000000..cf06cb7c165 Binary files /dev/null and b/.yarn/offline-mirror/@percy-cli-build-1.12.0.tgz differ diff --git a/.yarn/offline-mirror/@percy-cli-command-1.11.0.tgz b/.yarn/offline-mirror/@percy-cli-command-1.11.0.tgz deleted file mode 100644 index b03c724f8ec..00000000000 Binary files a/.yarn/offline-mirror/@percy-cli-command-1.11.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@percy-cli-command-1.12.0.tgz b/.yarn/offline-mirror/@percy-cli-command-1.12.0.tgz new file mode 100644 index 00000000000..7f825ce4063 Binary files /dev/null and b/.yarn/offline-mirror/@percy-cli-command-1.12.0.tgz differ diff --git a/.yarn/offline-mirror/@percy-cli-config-1.11.0.tgz b/.yarn/offline-mirror/@percy-cli-config-1.11.0.tgz deleted file mode 100644 index c0442b99c86..00000000000 Binary files a/.yarn/offline-mirror/@percy-cli-config-1.11.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@percy-cli-config-1.12.0.tgz b/.yarn/offline-mirror/@percy-cli-config-1.12.0.tgz new file mode 100644 index 00000000000..1d90c24ee00 Binary files /dev/null and b/.yarn/offline-mirror/@percy-cli-config-1.12.0.tgz differ diff --git a/.yarn/offline-mirror/@percy-cli-exec-1.11.0.tgz b/.yarn/offline-mirror/@percy-cli-exec-1.11.0.tgz deleted file mode 100644 index 8e7851e3af9..00000000000 Binary files a/.yarn/offline-mirror/@percy-cli-exec-1.11.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@percy-cli-exec-1.12.0.tgz b/.yarn/offline-mirror/@percy-cli-exec-1.12.0.tgz new file mode 100644 index 00000000000..52aefb046f1 Binary files /dev/null and b/.yarn/offline-mirror/@percy-cli-exec-1.12.0.tgz differ diff --git a/.yarn/offline-mirror/@percy-cli-snapshot-1.11.0.tgz b/.yarn/offline-mirror/@percy-cli-snapshot-1.11.0.tgz deleted file mode 100644 index 3a4f367f229..00000000000 Binary files a/.yarn/offline-mirror/@percy-cli-snapshot-1.11.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@percy-cli-snapshot-1.12.0.tgz b/.yarn/offline-mirror/@percy-cli-snapshot-1.12.0.tgz new file mode 100644 index 00000000000..62325c8b76b Binary files /dev/null and b/.yarn/offline-mirror/@percy-cli-snapshot-1.12.0.tgz differ diff --git a/.yarn/offline-mirror/@percy-cli-upload-1.11.0.tgz b/.yarn/offline-mirror/@percy-cli-upload-1.11.0.tgz deleted file mode 100644 index b752a6f84c6..00000000000 Binary files a/.yarn/offline-mirror/@percy-cli-upload-1.11.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@percy-cli-upload-1.12.0.tgz b/.yarn/offline-mirror/@percy-cli-upload-1.12.0.tgz new file mode 100644 index 00000000000..397918e51fa Binary files /dev/null and b/.yarn/offline-mirror/@percy-cli-upload-1.12.0.tgz differ diff --git a/.yarn/offline-mirror/@percy-client-1.11.0.tgz b/.yarn/offline-mirror/@percy-client-1.11.0.tgz deleted file mode 100644 index 0096fdeac40..00000000000 Binary files a/.yarn/offline-mirror/@percy-client-1.11.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@percy-client-1.12.0.tgz b/.yarn/offline-mirror/@percy-client-1.12.0.tgz new file mode 100644 index 00000000000..376e84e3ed9 Binary files /dev/null and b/.yarn/offline-mirror/@percy-client-1.12.0.tgz differ diff --git a/.yarn/offline-mirror/@percy-config-1.11.0.tgz b/.yarn/offline-mirror/@percy-config-1.11.0.tgz deleted file mode 100644 index 65016dacd12..00000000000 Binary files a/.yarn/offline-mirror/@percy-config-1.11.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@percy-config-1.12.0.tgz b/.yarn/offline-mirror/@percy-config-1.12.0.tgz new file mode 100644 index 00000000000..fa7f49c5160 Binary files /dev/null and b/.yarn/offline-mirror/@percy-config-1.12.0.tgz differ diff --git a/.yarn/offline-mirror/@percy-core-1.11.0.tgz b/.yarn/offline-mirror/@percy-core-1.11.0.tgz deleted file mode 100644 index b9e6ea1c813..00000000000 Binary files a/.yarn/offline-mirror/@percy-core-1.11.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@percy-core-1.12.0.tgz b/.yarn/offline-mirror/@percy-core-1.12.0.tgz new file mode 100644 index 00000000000..3b70dc8b784 Binary files /dev/null and b/.yarn/offline-mirror/@percy-core-1.12.0.tgz differ diff --git a/.yarn/offline-mirror/@percy-dom-1.11.0.tgz b/.yarn/offline-mirror/@percy-dom-1.11.0.tgz deleted file mode 100644 index 10adacf4d2d..00000000000 Binary files a/.yarn/offline-mirror/@percy-dom-1.11.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@percy-dom-1.12.0.tgz b/.yarn/offline-mirror/@percy-dom-1.12.0.tgz new file mode 100644 index 00000000000..cf02b5cac04 Binary files /dev/null and b/.yarn/offline-mirror/@percy-dom-1.12.0.tgz differ diff --git a/.yarn/offline-mirror/@percy-env-1.11.0.tgz b/.yarn/offline-mirror/@percy-env-1.11.0.tgz deleted file mode 100644 index 133d1faa4c4..00000000000 Binary files a/.yarn/offline-mirror/@percy-env-1.11.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@percy-env-1.12.0.tgz b/.yarn/offline-mirror/@percy-env-1.12.0.tgz new file mode 100644 index 00000000000..31f3e25ba63 Binary files /dev/null and b/.yarn/offline-mirror/@percy-env-1.12.0.tgz differ diff --git a/.yarn/offline-mirror/@percy-logger-1.11.0.tgz b/.yarn/offline-mirror/@percy-logger-1.11.0.tgz deleted file mode 100644 index d90a8d1bec3..00000000000 Binary files a/.yarn/offline-mirror/@percy-logger-1.11.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@percy-logger-1.12.0.tgz b/.yarn/offline-mirror/@percy-logger-1.12.0.tgz new file mode 100644 index 00000000000..76d37fd5003 Binary files /dev/null and b/.yarn/offline-mirror/@percy-logger-1.12.0.tgz differ diff --git a/.yarn/offline-mirror/@percy-sdk-utils-1.11.0.tgz b/.yarn/offline-mirror/@percy-sdk-utils-1.11.0.tgz deleted file mode 100644 index 96988dbf0d0..00000000000 Binary files a/.yarn/offline-mirror/@percy-sdk-utils-1.11.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@percy-sdk-utils-1.12.0.tgz b/.yarn/offline-mirror/@percy-sdk-utils-1.12.0.tgz new file mode 100644 index 00000000000..ab7bf81e18c Binary files /dev/null and b/.yarn/offline-mirror/@percy-sdk-utils-1.12.0.tgz differ diff --git a/.yarn/offline-mirror/@sinclair-typebox-0.24.46.tgz b/.yarn/offline-mirror/@sinclair-typebox-0.24.46.tgz deleted file mode 100644 index 4e21ac1008a..00000000000 Binary files a/.yarn/offline-mirror/@sinclair-typebox-0.24.46.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@sinclair-typebox-0.24.50.tgz b/.yarn/offline-mirror/@sinclair-typebox-0.24.50.tgz new file mode 100644 index 00000000000..b340e084cb0 Binary files /dev/null and b/.yarn/offline-mirror/@sinclair-typebox-0.24.50.tgz differ diff --git a/.yarn/offline-mirror/@sindresorhus-is-4.6.0.tgz b/.yarn/offline-mirror/@sindresorhus-is-4.6.0.tgz deleted file mode 100644 index e6f051eec6e..00000000000 Binary files a/.yarn/offline-mirror/@sindresorhus-is-4.6.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@sinonjs-fake-timers-6.0.1.tgz b/.yarn/offline-mirror/@sinonjs-fake-timers-6.0.1.tgz new file mode 100644 index 00000000000..3d871deee1d Binary files /dev/null and b/.yarn/offline-mirror/@sinonjs-fake-timers-6.0.1.tgz differ diff --git a/.yarn/offline-mirror/@sinonjs-fake-timers-8.1.0.tgz b/.yarn/offline-mirror/@sinonjs-fake-timers-8.1.0.tgz new file mode 100644 index 00000000000..1b0dfd0fa90 Binary files /dev/null and b/.yarn/offline-mirror/@sinonjs-fake-timers-8.1.0.tgz differ diff --git a/.yarn/offline-mirror/@storybook-addon-a11y-6.5.13.tgz b/.yarn/offline-mirror/@storybook-addon-a11y-6.5.13.tgz deleted file mode 100644 index 7a45b70eed1..00000000000 Binary files a/.yarn/offline-mirror/@storybook-addon-a11y-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-addon-a11y-6.5.15.tgz b/.yarn/offline-mirror/@storybook-addon-a11y-6.5.15.tgz new file mode 100644 index 00000000000..a54e5f80d93 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-addon-a11y-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-addon-actions-6.5.13.tgz b/.yarn/offline-mirror/@storybook-addon-actions-6.5.13.tgz deleted file mode 100644 index 7b02578f231..00000000000 Binary files a/.yarn/offline-mirror/@storybook-addon-actions-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-addon-actions-6.5.15.tgz b/.yarn/offline-mirror/@storybook-addon-actions-6.5.15.tgz new file mode 100644 index 00000000000..5e3962a6643 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-addon-actions-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-addon-backgrounds-6.5.13.tgz b/.yarn/offline-mirror/@storybook-addon-backgrounds-6.5.13.tgz deleted file mode 100644 index ffaeea6f2c0..00000000000 Binary files a/.yarn/offline-mirror/@storybook-addon-backgrounds-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-addon-backgrounds-6.5.15.tgz b/.yarn/offline-mirror/@storybook-addon-backgrounds-6.5.15.tgz new file mode 100644 index 00000000000..787721a2e27 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-addon-backgrounds-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-addon-controls-6.5.13.tgz b/.yarn/offline-mirror/@storybook-addon-controls-6.5.13.tgz deleted file mode 100644 index cd820108c8f..00000000000 Binary files a/.yarn/offline-mirror/@storybook-addon-controls-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-addon-controls-6.5.15.tgz b/.yarn/offline-mirror/@storybook-addon-controls-6.5.15.tgz new file mode 100644 index 00000000000..2597b4af021 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-addon-controls-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-addon-docs-6.5.13.tgz b/.yarn/offline-mirror/@storybook-addon-docs-6.5.13.tgz deleted file mode 100644 index 4381c655eab..00000000000 Binary files a/.yarn/offline-mirror/@storybook-addon-docs-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-addon-docs-6.5.15.tgz b/.yarn/offline-mirror/@storybook-addon-docs-6.5.15.tgz new file mode 100644 index 00000000000..28f5e793321 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-addon-docs-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-addon-essentials-6.5.13.tgz b/.yarn/offline-mirror/@storybook-addon-essentials-6.5.13.tgz deleted file mode 100644 index 8410c4692a9..00000000000 Binary files a/.yarn/offline-mirror/@storybook-addon-essentials-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-addon-essentials-6.5.15.tgz b/.yarn/offline-mirror/@storybook-addon-essentials-6.5.15.tgz new file mode 100644 index 00000000000..c2f67902575 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-addon-essentials-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-addon-links-6.5.13.tgz b/.yarn/offline-mirror/@storybook-addon-links-6.5.13.tgz deleted file mode 100644 index 8461af2d2ac..00000000000 Binary files a/.yarn/offline-mirror/@storybook-addon-links-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-addon-links-6.5.15.tgz b/.yarn/offline-mirror/@storybook-addon-links-6.5.15.tgz new file mode 100644 index 00000000000..8162aaf9b95 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-addon-links-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-addon-measure-6.5.13.tgz b/.yarn/offline-mirror/@storybook-addon-measure-6.5.13.tgz deleted file mode 100644 index 984cbef4c0c..00000000000 Binary files a/.yarn/offline-mirror/@storybook-addon-measure-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-addon-measure-6.5.15.tgz b/.yarn/offline-mirror/@storybook-addon-measure-6.5.15.tgz new file mode 100644 index 00000000000..4e8fc112c17 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-addon-measure-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-addon-outline-6.5.13.tgz b/.yarn/offline-mirror/@storybook-addon-outline-6.5.13.tgz deleted file mode 100644 index c1053c134b0..00000000000 Binary files a/.yarn/offline-mirror/@storybook-addon-outline-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-addon-outline-6.5.15.tgz b/.yarn/offline-mirror/@storybook-addon-outline-6.5.15.tgz new file mode 100644 index 00000000000..c0abf0a2097 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-addon-outline-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-addon-storyshots-6.5.13.tgz b/.yarn/offline-mirror/@storybook-addon-storyshots-6.5.13.tgz deleted file mode 100644 index 5e84a68c8db..00000000000 Binary files a/.yarn/offline-mirror/@storybook-addon-storyshots-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-addon-storyshots-6.5.15.tgz b/.yarn/offline-mirror/@storybook-addon-storyshots-6.5.15.tgz new file mode 100644 index 00000000000..be200b11c95 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-addon-storyshots-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-addon-storysource-6.5.13.tgz b/.yarn/offline-mirror/@storybook-addon-storysource-6.5.13.tgz deleted file mode 100644 index 0c1ef85eed8..00000000000 Binary files a/.yarn/offline-mirror/@storybook-addon-storysource-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-addon-storysource-6.5.15.tgz b/.yarn/offline-mirror/@storybook-addon-storysource-6.5.15.tgz new file mode 100644 index 00000000000..df1cb109fcc Binary files /dev/null and b/.yarn/offline-mirror/@storybook-addon-storysource-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-addon-toolbars-6.5.13.tgz b/.yarn/offline-mirror/@storybook-addon-toolbars-6.5.13.tgz deleted file mode 100644 index e6076f2a1e3..00000000000 Binary files a/.yarn/offline-mirror/@storybook-addon-toolbars-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-addon-toolbars-6.5.15.tgz b/.yarn/offline-mirror/@storybook-addon-toolbars-6.5.15.tgz new file mode 100644 index 00000000000..20fa3783ee8 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-addon-toolbars-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-addon-viewport-6.5.13.tgz b/.yarn/offline-mirror/@storybook-addon-viewport-6.5.13.tgz deleted file mode 100644 index 2868cf1d773..00000000000 Binary files a/.yarn/offline-mirror/@storybook-addon-viewport-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-addon-viewport-6.5.15.tgz b/.yarn/offline-mirror/@storybook-addon-viewport-6.5.15.tgz new file mode 100644 index 00000000000..1b59ec86f3a Binary files /dev/null and b/.yarn/offline-mirror/@storybook-addon-viewport-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-addons-6.5.13.tgz b/.yarn/offline-mirror/@storybook-addons-6.5.13.tgz deleted file mode 100644 index a0eb21a5552..00000000000 Binary files a/.yarn/offline-mirror/@storybook-addons-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-addons-6.5.15.tgz b/.yarn/offline-mirror/@storybook-addons-6.5.15.tgz new file mode 100644 index 00000000000..2ab0b259582 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-addons-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-api-6.5.13.tgz b/.yarn/offline-mirror/@storybook-api-6.5.13.tgz deleted file mode 100644 index dd36562b9e6..00000000000 Binary files a/.yarn/offline-mirror/@storybook-api-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-api-6.5.15.tgz b/.yarn/offline-mirror/@storybook-api-6.5.15.tgz new file mode 100644 index 00000000000..881f465de44 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-api-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-builder-webpack4-6.5.13.tgz b/.yarn/offline-mirror/@storybook-builder-webpack4-6.5.13.tgz deleted file mode 100644 index 13c0b0187d8..00000000000 Binary files a/.yarn/offline-mirror/@storybook-builder-webpack4-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-builder-webpack4-6.5.15.tgz b/.yarn/offline-mirror/@storybook-builder-webpack4-6.5.15.tgz new file mode 100644 index 00000000000..1a735f12fbd Binary files /dev/null and b/.yarn/offline-mirror/@storybook-builder-webpack4-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-builder-webpack5-6.5.13.tgz b/.yarn/offline-mirror/@storybook-builder-webpack5-6.5.13.tgz deleted file mode 100644 index 370bd31b4a8..00000000000 Binary files a/.yarn/offline-mirror/@storybook-builder-webpack5-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-builder-webpack5-6.5.15.tgz b/.yarn/offline-mirror/@storybook-builder-webpack5-6.5.15.tgz new file mode 100644 index 00000000000..85c4de0b13e Binary files /dev/null and b/.yarn/offline-mirror/@storybook-builder-webpack5-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-channel-postmessage-6.5.13.tgz b/.yarn/offline-mirror/@storybook-channel-postmessage-6.5.13.tgz deleted file mode 100644 index 2e69bff1a41..00000000000 Binary files a/.yarn/offline-mirror/@storybook-channel-postmessage-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-channel-postmessage-6.5.15.tgz b/.yarn/offline-mirror/@storybook-channel-postmessage-6.5.15.tgz new file mode 100644 index 00000000000..780c869786d Binary files /dev/null and b/.yarn/offline-mirror/@storybook-channel-postmessage-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-channel-websocket-6.5.13.tgz b/.yarn/offline-mirror/@storybook-channel-websocket-6.5.13.tgz deleted file mode 100644 index b2eada924b0..00000000000 Binary files a/.yarn/offline-mirror/@storybook-channel-websocket-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-channel-websocket-6.5.15.tgz b/.yarn/offline-mirror/@storybook-channel-websocket-6.5.15.tgz new file mode 100644 index 00000000000..1b455dd7255 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-channel-websocket-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-channels-6.5.13.tgz b/.yarn/offline-mirror/@storybook-channels-6.5.13.tgz deleted file mode 100644 index 27314a97b9f..00000000000 Binary files a/.yarn/offline-mirror/@storybook-channels-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-channels-6.5.15.tgz b/.yarn/offline-mirror/@storybook-channels-6.5.15.tgz new file mode 100644 index 00000000000..629dfa39857 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-channels-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-client-api-6.5.13.tgz b/.yarn/offline-mirror/@storybook-client-api-6.5.13.tgz deleted file mode 100644 index efe7b46dabd..00000000000 Binary files a/.yarn/offline-mirror/@storybook-client-api-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-client-api-6.5.15.tgz b/.yarn/offline-mirror/@storybook-client-api-6.5.15.tgz new file mode 100644 index 00000000000..69bfdfb5571 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-client-api-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-client-logger-6.5.13.tgz b/.yarn/offline-mirror/@storybook-client-logger-6.5.13.tgz deleted file mode 100644 index 988f94835bb..00000000000 Binary files a/.yarn/offline-mirror/@storybook-client-logger-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-client-logger-6.5.15.tgz b/.yarn/offline-mirror/@storybook-client-logger-6.5.15.tgz new file mode 100644 index 00000000000..c6879d29394 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-client-logger-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-components-6.5.13.tgz b/.yarn/offline-mirror/@storybook-components-6.5.13.tgz deleted file mode 100644 index a949bd031cc..00000000000 Binary files a/.yarn/offline-mirror/@storybook-components-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-components-6.5.15.tgz b/.yarn/offline-mirror/@storybook-components-6.5.15.tgz new file mode 100644 index 00000000000..3ebace52004 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-components-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-core-6.5.13.tgz b/.yarn/offline-mirror/@storybook-core-6.5.13.tgz deleted file mode 100644 index c16b159c02d..00000000000 Binary files a/.yarn/offline-mirror/@storybook-core-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-core-6.5.15.tgz b/.yarn/offline-mirror/@storybook-core-6.5.15.tgz new file mode 100644 index 00000000000..a8833ff1f1b Binary files /dev/null and b/.yarn/offline-mirror/@storybook-core-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-core-client-6.5.13.tgz b/.yarn/offline-mirror/@storybook-core-client-6.5.13.tgz deleted file mode 100644 index 9ff52e049ac..00000000000 Binary files a/.yarn/offline-mirror/@storybook-core-client-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-core-client-6.5.15.tgz b/.yarn/offline-mirror/@storybook-core-client-6.5.15.tgz new file mode 100644 index 00000000000..e5a7ff65f2e Binary files /dev/null and b/.yarn/offline-mirror/@storybook-core-client-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-core-common-6.5.13.tgz b/.yarn/offline-mirror/@storybook-core-common-6.5.13.tgz deleted file mode 100644 index 54141d56ffe..00000000000 Binary files a/.yarn/offline-mirror/@storybook-core-common-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-core-common-6.5.15.tgz b/.yarn/offline-mirror/@storybook-core-common-6.5.15.tgz new file mode 100644 index 00000000000..996e73fc2b3 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-core-common-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-core-events-6.5.13.tgz b/.yarn/offline-mirror/@storybook-core-events-6.5.13.tgz deleted file mode 100644 index 31ba794906f..00000000000 Binary files a/.yarn/offline-mirror/@storybook-core-events-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-core-events-6.5.15.tgz b/.yarn/offline-mirror/@storybook-core-events-6.5.15.tgz new file mode 100644 index 00000000000..9dd5028d0ff Binary files /dev/null and b/.yarn/offline-mirror/@storybook-core-events-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-core-server-6.5.13.tgz b/.yarn/offline-mirror/@storybook-core-server-6.5.13.tgz deleted file mode 100644 index 110f7edb6ac..00000000000 Binary files a/.yarn/offline-mirror/@storybook-core-server-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-core-server-6.5.15.tgz b/.yarn/offline-mirror/@storybook-core-server-6.5.15.tgz new file mode 100644 index 00000000000..6a7a8cdeefe Binary files /dev/null and b/.yarn/offline-mirror/@storybook-core-server-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-csf-tools-6.5.13.tgz b/.yarn/offline-mirror/@storybook-csf-tools-6.5.13.tgz deleted file mode 100644 index cc8494f44ea..00000000000 Binary files a/.yarn/offline-mirror/@storybook-csf-tools-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-csf-tools-6.5.15.tgz b/.yarn/offline-mirror/@storybook-csf-tools-6.5.15.tgz new file mode 100644 index 00000000000..eb0627586df Binary files /dev/null and b/.yarn/offline-mirror/@storybook-csf-tools-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-docs-tools-6.5.13.tgz b/.yarn/offline-mirror/@storybook-docs-tools-6.5.13.tgz deleted file mode 100644 index 0263b1f8a56..00000000000 Binary files a/.yarn/offline-mirror/@storybook-docs-tools-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-docs-tools-6.5.15.tgz b/.yarn/offline-mirror/@storybook-docs-tools-6.5.15.tgz new file mode 100644 index 00000000000..955a4d2beea Binary files /dev/null and b/.yarn/offline-mirror/@storybook-docs-tools-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-manager-webpack4-6.5.13.tgz b/.yarn/offline-mirror/@storybook-manager-webpack4-6.5.13.tgz deleted file mode 100644 index 10a0380bd26..00000000000 Binary files a/.yarn/offline-mirror/@storybook-manager-webpack4-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-manager-webpack4-6.5.15.tgz b/.yarn/offline-mirror/@storybook-manager-webpack4-6.5.15.tgz new file mode 100644 index 00000000000..6f6ce5e02e7 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-manager-webpack4-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-manager-webpack5-6.5.13.tgz b/.yarn/offline-mirror/@storybook-manager-webpack5-6.5.13.tgz deleted file mode 100644 index e039a242db5..00000000000 Binary files a/.yarn/offline-mirror/@storybook-manager-webpack5-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-manager-webpack5-6.5.15.tgz b/.yarn/offline-mirror/@storybook-manager-webpack5-6.5.15.tgz new file mode 100644 index 00000000000..dcf8a83f2db Binary files /dev/null and b/.yarn/offline-mirror/@storybook-manager-webpack5-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-node-logger-6.5.13.tgz b/.yarn/offline-mirror/@storybook-node-logger-6.5.13.tgz deleted file mode 100644 index 4eebd06ae1c..00000000000 Binary files a/.yarn/offline-mirror/@storybook-node-logger-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-node-logger-6.5.15.tgz b/.yarn/offline-mirror/@storybook-node-logger-6.5.15.tgz new file mode 100644 index 00000000000..3d934290776 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-node-logger-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-postinstall-6.5.13.tgz b/.yarn/offline-mirror/@storybook-postinstall-6.5.13.tgz deleted file mode 100644 index b202174a434..00000000000 Binary files a/.yarn/offline-mirror/@storybook-postinstall-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-postinstall-6.5.15.tgz b/.yarn/offline-mirror/@storybook-postinstall-6.5.15.tgz new file mode 100644 index 00000000000..f453b0573a5 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-postinstall-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-preview-web-6.5.13.tgz b/.yarn/offline-mirror/@storybook-preview-web-6.5.13.tgz deleted file mode 100644 index 616c0fd806b..00000000000 Binary files a/.yarn/offline-mirror/@storybook-preview-web-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-preview-web-6.5.15.tgz b/.yarn/offline-mirror/@storybook-preview-web-6.5.15.tgz new file mode 100644 index 00000000000..e95bd0eb7c8 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-preview-web-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-react-6.5.13.tgz b/.yarn/offline-mirror/@storybook-react-6.5.13.tgz deleted file mode 100644 index be425d7bb6a..00000000000 Binary files a/.yarn/offline-mirror/@storybook-react-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-react-6.5.15.tgz b/.yarn/offline-mirror/@storybook-react-6.5.15.tgz new file mode 100644 index 00000000000..558600fbc5b Binary files /dev/null and b/.yarn/offline-mirror/@storybook-react-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-router-6.5.13.tgz b/.yarn/offline-mirror/@storybook-router-6.5.13.tgz deleted file mode 100644 index a3f7a7e64fa..00000000000 Binary files a/.yarn/offline-mirror/@storybook-router-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-router-6.5.15.tgz b/.yarn/offline-mirror/@storybook-router-6.5.15.tgz new file mode 100644 index 00000000000..18278728a09 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-router-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-source-loader-6.5.13.tgz b/.yarn/offline-mirror/@storybook-source-loader-6.5.13.tgz deleted file mode 100644 index 8f433b5bc00..00000000000 Binary files a/.yarn/offline-mirror/@storybook-source-loader-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-source-loader-6.5.15.tgz b/.yarn/offline-mirror/@storybook-source-loader-6.5.15.tgz new file mode 100644 index 00000000000..527fd24d795 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-source-loader-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-store-6.5.13.tgz b/.yarn/offline-mirror/@storybook-store-6.5.13.tgz deleted file mode 100644 index 99863592215..00000000000 Binary files a/.yarn/offline-mirror/@storybook-store-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-store-6.5.15.tgz b/.yarn/offline-mirror/@storybook-store-6.5.15.tgz new file mode 100644 index 00000000000..d1697316a14 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-store-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-telemetry-6.5.13.tgz b/.yarn/offline-mirror/@storybook-telemetry-6.5.13.tgz deleted file mode 100644 index 6844902a06c..00000000000 Binary files a/.yarn/offline-mirror/@storybook-telemetry-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-telemetry-6.5.15.tgz b/.yarn/offline-mirror/@storybook-telemetry-6.5.15.tgz new file mode 100644 index 00000000000..164ffddbb92 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-telemetry-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-theming-6.5.13.tgz b/.yarn/offline-mirror/@storybook-theming-6.5.13.tgz deleted file mode 100644 index 6918a7080cd..00000000000 Binary files a/.yarn/offline-mirror/@storybook-theming-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-theming-6.5.15.tgz b/.yarn/offline-mirror/@storybook-theming-6.5.15.tgz new file mode 100644 index 00000000000..c699d8fca71 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-theming-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-ui-6.5.13.tgz b/.yarn/offline-mirror/@storybook-ui-6.5.13.tgz deleted file mode 100644 index ec944dd025f..00000000000 Binary files a/.yarn/offline-mirror/@storybook-ui-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-ui-6.5.15.tgz b/.yarn/offline-mirror/@storybook-ui-6.5.15.tgz new file mode 100644 index 00000000000..5ad1e7e4f39 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-ui-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@storybook-web-components-6.5.13.tgz b/.yarn/offline-mirror/@storybook-web-components-6.5.13.tgz deleted file mode 100644 index ba01bfdaeb0..00000000000 Binary files a/.yarn/offline-mirror/@storybook-web-components-6.5.13.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@storybook-web-components-6.5.15.tgz b/.yarn/offline-mirror/@storybook-web-components-6.5.15.tgz new file mode 100644 index 00000000000..94970ddc487 Binary files /dev/null and b/.yarn/offline-mirror/@storybook-web-components-6.5.15.tgz differ diff --git a/.yarn/offline-mirror/@szmarczak-http-timer-4.0.6.tgz b/.yarn/offline-mirror/@szmarczak-http-timer-4.0.6.tgz deleted file mode 100644 index 88747ec7ebe..00000000000 Binary files a/.yarn/offline-mirror/@szmarczak-http-timer-4.0.6.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@trysound-sax-0.2.0.tgz b/.yarn/offline-mirror/@trysound-sax-0.2.0.tgz new file mode 100644 index 00000000000..a54e1549cc2 Binary files /dev/null and b/.yarn/offline-mirror/@trysound-sax-0.2.0.tgz differ diff --git a/.yarn/offline-mirror/@types-bluebird-3.5.36.tgz b/.yarn/offline-mirror/@types-bluebird-3.5.36.tgz new file mode 100644 index 00000000000..7321e830cdf Binary files /dev/null and b/.yarn/offline-mirror/@types-bluebird-3.5.36.tgz differ diff --git a/.yarn/offline-mirror/@types-body-parser-1.19.2.tgz b/.yarn/offline-mirror/@types-body-parser-1.19.2.tgz new file mode 100644 index 00000000000..eafcdf8bc5b Binary files /dev/null and b/.yarn/offline-mirror/@types-body-parser-1.19.2.tgz differ diff --git a/.yarn/offline-mirror/@types-bonjour-3.5.10.tgz b/.yarn/offline-mirror/@types-bonjour-3.5.10.tgz new file mode 100644 index 00000000000..0416b4cff1e Binary files /dev/null and b/.yarn/offline-mirror/@types-bonjour-3.5.10.tgz differ diff --git a/.yarn/offline-mirror/@types-cacheable-request-6.0.2.tgz b/.yarn/offline-mirror/@types-cacheable-request-6.0.2.tgz deleted file mode 100644 index 33605a20e28..00000000000 Binary files a/.yarn/offline-mirror/@types-cacheable-request-6.0.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@types-chai-4.3.3.tgz b/.yarn/offline-mirror/@types-chai-4.3.3.tgz new file mode 100644 index 00000000000..f70ca9bcbf9 Binary files /dev/null and b/.yarn/offline-mirror/@types-chai-4.3.3.tgz differ diff --git a/.yarn/offline-mirror/@types-connect-3.4.35.tgz b/.yarn/offline-mirror/@types-connect-3.4.35.tgz new file mode 100644 index 00000000000..1a400dce6f6 Binary files /dev/null and b/.yarn/offline-mirror/@types-connect-3.4.35.tgz differ diff --git a/.yarn/offline-mirror/@types-connect-history-api-fallback-1.3.5.tgz b/.yarn/offline-mirror/@types-connect-history-api-fallback-1.3.5.tgz new file mode 100644 index 00000000000..1b131b05312 Binary files /dev/null and b/.yarn/offline-mirror/@types-connect-history-api-fallback-1.3.5.tgz differ diff --git a/.yarn/offline-mirror/@types-eslint-8.4.6.tgz b/.yarn/offline-mirror/@types-eslint-8.4.6.tgz deleted file mode 100644 index 18b6ab192ad..00000000000 Binary files a/.yarn/offline-mirror/@types-eslint-8.4.6.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@types-eslint-8.4.7.tgz b/.yarn/offline-mirror/@types-eslint-8.4.7.tgz new file mode 100644 index 00000000000..6ee0d6271bb Binary files /dev/null and b/.yarn/offline-mirror/@types-eslint-8.4.7.tgz differ diff --git a/.yarn/offline-mirror/@types-eslint-visitor-keys-1.0.0.tgz b/.yarn/offline-mirror/@types-eslint-visitor-keys-1.0.0.tgz deleted file mode 100644 index 9df52868e4a..00000000000 Binary files a/.yarn/offline-mirror/@types-eslint-visitor-keys-1.0.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@types-express-4.17.14.tgz b/.yarn/offline-mirror/@types-express-4.17.14.tgz new file mode 100644 index 00000000000..b14aeeb6009 Binary files /dev/null and b/.yarn/offline-mirror/@types-express-4.17.14.tgz differ diff --git a/.yarn/offline-mirror/@types-express-serve-static-core-4.17.31.tgz b/.yarn/offline-mirror/@types-express-serve-static-core-4.17.31.tgz new file mode 100644 index 00000000000..3c0091eea09 Binary files /dev/null and b/.yarn/offline-mirror/@types-express-serve-static-core-4.17.31.tgz differ diff --git a/.yarn/offline-mirror/@types-http-cache-semantics-4.0.1.tgz b/.yarn/offline-mirror/@types-http-cache-semantics-4.0.1.tgz deleted file mode 100644 index a55e7c72228..00000000000 Binary files a/.yarn/offline-mirror/@types-http-cache-semantics-4.0.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@types-http-proxy-1.17.9.tgz b/.yarn/offline-mirror/@types-http-proxy-1.17.9.tgz new file mode 100644 index 00000000000..f8099143b8b Binary files /dev/null and b/.yarn/offline-mirror/@types-http-proxy-1.17.9.tgz differ diff --git a/.yarn/offline-mirror/@types-jest-29.1.2.tgz b/.yarn/offline-mirror/@types-jest-29.1.2.tgz deleted file mode 100644 index c396b3fe3b0..00000000000 Binary files a/.yarn/offline-mirror/@types-jest-29.1.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@types-jest-29.2.0.tgz b/.yarn/offline-mirror/@types-jest-29.2.0.tgz new file mode 100644 index 00000000000..df081c33a84 Binary files /dev/null and b/.yarn/offline-mirror/@types-jest-29.2.0.tgz differ diff --git a/.yarn/offline-mirror/@types-jest-29.2.3.tgz b/.yarn/offline-mirror/@types-jest-29.2.3.tgz new file mode 100644 index 00000000000..07a716b0759 Binary files /dev/null and b/.yarn/offline-mirror/@types-jest-29.2.3.tgz differ diff --git a/.yarn/offline-mirror/@types-keyv-3.1.4.tgz b/.yarn/offline-mirror/@types-keyv-3.1.4.tgz deleted file mode 100644 index 472d2f39305..00000000000 Binary files a/.yarn/offline-mirror/@types-keyv-3.1.4.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@types-mime-3.0.1.tgz b/.yarn/offline-mirror/@types-mime-3.0.1.tgz new file mode 100644 index 00000000000..588738b674f Binary files /dev/null and b/.yarn/offline-mirror/@types-mime-3.0.1.tgz differ diff --git a/.yarn/offline-mirror/@types-node-16.11.66.tgz b/.yarn/offline-mirror/@types-node-16.11.66.tgz deleted file mode 100644 index 708bf3fe27f..00000000000 Binary files a/.yarn/offline-mirror/@types-node-16.11.66.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@types-node-16.18.0.tgz b/.yarn/offline-mirror/@types-node-16.18.0.tgz new file mode 100644 index 00000000000..6766e58f8a9 Binary files /dev/null and b/.yarn/offline-mirror/@types-node-16.18.0.tgz differ diff --git a/.yarn/offline-mirror/@types-node-18.11.0.tgz b/.yarn/offline-mirror/@types-node-18.11.0.tgz deleted file mode 100644 index 5524b986240..00000000000 Binary files a/.yarn/offline-mirror/@types-node-18.11.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@types-node-18.11.4.tgz b/.yarn/offline-mirror/@types-node-18.11.4.tgz new file mode 100644 index 00000000000..60f21db34e6 Binary files /dev/null and b/.yarn/offline-mirror/@types-node-18.11.4.tgz differ diff --git a/.yarn/offline-mirror/@types-node-18.11.9.tgz b/.yarn/offline-mirror/@types-node-18.11.9.tgz new file mode 100644 index 00000000000..7d4a41e5a65 Binary files /dev/null and b/.yarn/offline-mirror/@types-node-18.11.9.tgz differ diff --git a/.yarn/offline-mirror/@types-range-parser-1.2.4.tgz b/.yarn/offline-mirror/@types-range-parser-1.2.4.tgz new file mode 100644 index 00000000000..14a1b60e930 Binary files /dev/null and b/.yarn/offline-mirror/@types-range-parser-1.2.4.tgz differ diff --git a/.yarn/offline-mirror/@types-responselike-1.0.0.tgz b/.yarn/offline-mirror/@types-responselike-1.0.0.tgz deleted file mode 100644 index 75763200494..00000000000 Binary files a/.yarn/offline-mirror/@types-responselike-1.0.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@types-retry-0.12.0.tgz b/.yarn/offline-mirror/@types-retry-0.12.0.tgz new file mode 100644 index 00000000000..82fced0cece Binary files /dev/null and b/.yarn/offline-mirror/@types-retry-0.12.0.tgz differ diff --git a/.yarn/offline-mirror/@types-semver-7.3.13.tgz b/.yarn/offline-mirror/@types-semver-7.3.13.tgz new file mode 100644 index 00000000000..655881bd2c8 Binary files /dev/null and b/.yarn/offline-mirror/@types-semver-7.3.13.tgz differ diff --git a/.yarn/offline-mirror/@types-serve-index-1.9.1.tgz b/.yarn/offline-mirror/@types-serve-index-1.9.1.tgz new file mode 100644 index 00000000000..0e527708402 Binary files /dev/null and b/.yarn/offline-mirror/@types-serve-index-1.9.1.tgz differ diff --git a/.yarn/offline-mirror/@types-serve-static-1.15.0.tgz b/.yarn/offline-mirror/@types-serve-static-1.15.0.tgz new file mode 100644 index 00000000000..87c12085ab3 Binary files /dev/null and b/.yarn/offline-mirror/@types-serve-static-1.15.0.tgz differ diff --git a/.yarn/offline-mirror/@types-sinonjs__fake-timers-6.0.4.tgz b/.yarn/offline-mirror/@types-sinonjs__fake-timers-6.0.4.tgz new file mode 100644 index 00000000000..dc203897f41 Binary files /dev/null and b/.yarn/offline-mirror/@types-sinonjs__fake-timers-6.0.4.tgz differ diff --git a/.yarn/offline-mirror/@types-sockjs-0.3.33.tgz b/.yarn/offline-mirror/@types-sockjs-0.3.33.tgz new file mode 100644 index 00000000000..919a8cf3c5c Binary files /dev/null and b/.yarn/offline-mirror/@types-sockjs-0.3.33.tgz differ diff --git a/.yarn/offline-mirror/@types-uglify-js-3.17.0.tgz b/.yarn/offline-mirror/@types-uglify-js-3.17.0.tgz deleted file mode 100644 index 545fe4215c2..00000000000 Binary files a/.yarn/offline-mirror/@types-uglify-js-3.17.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@types-uglify-js-3.17.1.tgz b/.yarn/offline-mirror/@types-uglify-js-3.17.1.tgz new file mode 100644 index 00000000000..5563669f59a Binary files /dev/null and b/.yarn/offline-mirror/@types-uglify-js-3.17.1.tgz differ diff --git a/.yarn/offline-mirror/@types-ws-8.5.3.tgz b/.yarn/offline-mirror/@types-ws-8.5.3.tgz new file mode 100644 index 00000000000..34688829aa6 Binary files /dev/null and b/.yarn/offline-mirror/@types-ws-8.5.3.tgz differ diff --git a/.yarn/offline-mirror/@types-yargs-16.0.4.tgz b/.yarn/offline-mirror/@types-yargs-16.0.4.tgz new file mode 100644 index 00000000000..f0480917666 Binary files /dev/null and b/.yarn/offline-mirror/@types-yargs-16.0.4.tgz differ diff --git a/.yarn/offline-mirror/@typescript-eslint-eslint-plugin-2.34.0.tgz b/.yarn/offline-mirror/@typescript-eslint-eslint-plugin-2.34.0.tgz deleted file mode 100644 index cc040cd8ccb..00000000000 Binary files a/.yarn/offline-mirror/@typescript-eslint-eslint-plugin-2.34.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@typescript-eslint-eslint-plugin-5.43.0.tgz b/.yarn/offline-mirror/@typescript-eslint-eslint-plugin-5.43.0.tgz new file mode 100644 index 00000000000..62fd265faee Binary files /dev/null and b/.yarn/offline-mirror/@typescript-eslint-eslint-plugin-5.43.0.tgz differ diff --git a/.yarn/offline-mirror/@typescript-eslint-experimental-utils-2.34.0.tgz b/.yarn/offline-mirror/@typescript-eslint-experimental-utils-2.34.0.tgz deleted file mode 100644 index 994063f42a2..00000000000 Binary files a/.yarn/offline-mirror/@typescript-eslint-experimental-utils-2.34.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@typescript-eslint-parser-2.34.0.tgz b/.yarn/offline-mirror/@typescript-eslint-parser-2.34.0.tgz deleted file mode 100644 index 8dd638ee955..00000000000 Binary files a/.yarn/offline-mirror/@typescript-eslint-parser-2.34.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@typescript-eslint-parser-5.43.0.tgz b/.yarn/offline-mirror/@typescript-eslint-parser-5.43.0.tgz new file mode 100644 index 00000000000..69b7442900f Binary files /dev/null and b/.yarn/offline-mirror/@typescript-eslint-parser-5.43.0.tgz differ diff --git a/.yarn/offline-mirror/@typescript-eslint-scope-manager-5.43.0.tgz b/.yarn/offline-mirror/@typescript-eslint-scope-manager-5.43.0.tgz new file mode 100644 index 00000000000..0321a1cb980 Binary files /dev/null and b/.yarn/offline-mirror/@typescript-eslint-scope-manager-5.43.0.tgz differ diff --git a/.yarn/offline-mirror/@typescript-eslint-type-utils-5.43.0.tgz b/.yarn/offline-mirror/@typescript-eslint-type-utils-5.43.0.tgz new file mode 100644 index 00000000000..d1852103ffd Binary files /dev/null and b/.yarn/offline-mirror/@typescript-eslint-type-utils-5.43.0.tgz differ diff --git a/.yarn/offline-mirror/@typescript-eslint-types-5.43.0.tgz b/.yarn/offline-mirror/@typescript-eslint-types-5.43.0.tgz new file mode 100644 index 00000000000..c8d0d3ef367 Binary files /dev/null and b/.yarn/offline-mirror/@typescript-eslint-types-5.43.0.tgz differ diff --git a/.yarn/offline-mirror/@typescript-eslint-typescript-estree-2.34.0.tgz b/.yarn/offline-mirror/@typescript-eslint-typescript-estree-2.34.0.tgz deleted file mode 100644 index a2b615aa1a5..00000000000 Binary files a/.yarn/offline-mirror/@typescript-eslint-typescript-estree-2.34.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/@typescript-eslint-typescript-estree-5.43.0.tgz b/.yarn/offline-mirror/@typescript-eslint-typescript-estree-5.43.0.tgz new file mode 100644 index 00000000000..66eaf69045b Binary files /dev/null and b/.yarn/offline-mirror/@typescript-eslint-typescript-estree-5.43.0.tgz differ diff --git a/.yarn/offline-mirror/@typescript-eslint-utils-5.43.0.tgz b/.yarn/offline-mirror/@typescript-eslint-utils-5.43.0.tgz new file mode 100644 index 00000000000..a8d93fa0bd4 Binary files /dev/null and b/.yarn/offline-mirror/@typescript-eslint-utils-5.43.0.tgz differ diff --git a/.yarn/offline-mirror/@typescript-eslint-visitor-keys-5.43.0.tgz b/.yarn/offline-mirror/@typescript-eslint-visitor-keys-5.43.0.tgz new file mode 100644 index 00000000000..50359d9442f Binary files /dev/null and b/.yarn/offline-mirror/@typescript-eslint-visitor-keys-5.43.0.tgz differ diff --git a/.yarn/offline-mirror/@webcomponents-custom-elements-1.5.0.tgz b/.yarn/offline-mirror/@webcomponents-custom-elements-1.5.0.tgz new file mode 100644 index 00000000000..ec92ad1edf1 Binary files /dev/null and b/.yarn/offline-mirror/@webcomponents-custom-elements-1.5.0.tgz differ diff --git a/.yarn/offline-mirror/@webcomponents-shadycss-1.11.0.tgz b/.yarn/offline-mirror/@webcomponents-shadycss-1.11.0.tgz new file mode 100644 index 00000000000..2f9d7bd3def Binary files /dev/null and b/.yarn/offline-mirror/@webcomponents-shadycss-1.11.0.tgz differ diff --git a/.yarn/offline-mirror/@webcomponents-shadydom-1.9.0.tgz b/.yarn/offline-mirror/@webcomponents-shadydom-1.9.0.tgz new file mode 100644 index 00000000000..679cb8b6544 Binary files /dev/null and b/.yarn/offline-mirror/@webcomponents-shadydom-1.9.0.tgz differ diff --git a/.yarn/offline-mirror/@webcomponents-template-1.5.0.tgz b/.yarn/offline-mirror/@webcomponents-template-1.5.0.tgz new file mode 100644 index 00000000000..85d629b3af7 Binary files /dev/null and b/.yarn/offline-mirror/@webcomponents-template-1.5.0.tgz differ diff --git a/.yarn/offline-mirror/@webcomponents-url-0.7.8.tgz b/.yarn/offline-mirror/@webcomponents-url-0.7.8.tgz new file mode 100644 index 00000000000..5e9903d5c6f Binary files /dev/null and b/.yarn/offline-mirror/@webcomponents-url-0.7.8.tgz differ diff --git a/.yarn/offline-mirror/@webcomponents-webcomponents-platform-1.0.1.tgz b/.yarn/offline-mirror/@webcomponents-webcomponents-platform-1.0.1.tgz new file mode 100644 index 00000000000..df5e484a5a6 Binary files /dev/null and b/.yarn/offline-mirror/@webcomponents-webcomponents-platform-1.0.1.tgz differ diff --git a/.yarn/offline-mirror/acorn-8.8.1.tgz b/.yarn/offline-mirror/acorn-8.8.1.tgz new file mode 100644 index 00000000000..582130d49c5 Binary files /dev/null and b/.yarn/offline-mirror/acorn-8.8.1.tgz differ diff --git a/.yarn/offline-mirror/acorn-globals-6.0.0.tgz b/.yarn/offline-mirror/acorn-globals-6.0.0.tgz new file mode 100644 index 00000000000..7a58b27da07 Binary files /dev/null and b/.yarn/offline-mirror/acorn-globals-6.0.0.tgz differ diff --git a/.yarn/offline-mirror/ajv-formats-2.1.1.tgz b/.yarn/offline-mirror/ajv-formats-2.1.1.tgz new file mode 100644 index 00000000000..ff6708c534a Binary files /dev/null and b/.yarn/offline-mirror/ajv-formats-2.1.1.tgz differ diff --git a/.yarn/offline-mirror/ajv-keywords-5.1.0.tgz b/.yarn/offline-mirror/ajv-keywords-5.1.0.tgz new file mode 100644 index 00000000000..ada3322644e Binary files /dev/null and b/.yarn/offline-mirror/ajv-keywords-5.1.0.tgz differ diff --git a/.yarn/offline-mirror/alphanum-sort-1.0.2.tgz b/.yarn/offline-mirror/alphanum-sort-1.0.2.tgz deleted file mode 100644 index 1b0c97e82fc..00000000000 Binary files a/.yarn/offline-mirror/alphanum-sort-1.0.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/amdefine-1.0.1.tgz b/.yarn/offline-mirror/amdefine-1.0.1.tgz deleted file mode 100644 index 7019fbd36fd..00000000000 Binary files a/.yarn/offline-mirror/amdefine-1.0.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/are-we-there-yet-3.0.1.tgz b/.yarn/offline-mirror/are-we-there-yet-3.0.1.tgz new file mode 100644 index 00000000000..1761d2f944f Binary files /dev/null and b/.yarn/offline-mirror/are-we-there-yet-3.0.1.tgz differ diff --git a/.yarn/offline-mirror/array-flatten-2.1.2.tgz b/.yarn/offline-mirror/array-flatten-2.1.2.tgz new file mode 100644 index 00000000000..661883bd0e2 Binary files /dev/null and b/.yarn/offline-mirror/array-flatten-2.1.2.tgz differ diff --git a/.yarn/offline-mirror/axios-0.25.0.tgz b/.yarn/offline-mirror/axios-0.25.0.tgz new file mode 100644 index 00000000000..112f90a0209 Binary files /dev/null and b/.yarn/offline-mirror/axios-0.25.0.tgz differ diff --git a/.yarn/offline-mirror/babel-jest-26.6.3.tgz b/.yarn/offline-mirror/babel-jest-26.6.3.tgz new file mode 100644 index 00000000000..464def88c28 Binary files /dev/null and b/.yarn/offline-mirror/babel-jest-26.6.3.tgz differ diff --git a/.yarn/offline-mirror/babel-plugin-jest-hoist-26.6.2.tgz b/.yarn/offline-mirror/babel-plugin-jest-hoist-26.6.2.tgz new file mode 100644 index 00000000000..f36d769d881 Binary files /dev/null and b/.yarn/offline-mirror/babel-plugin-jest-hoist-26.6.2.tgz differ diff --git a/.yarn/offline-mirror/babel-preset-current-node-syntax-1.0.1.tgz b/.yarn/offline-mirror/babel-preset-current-node-syntax-1.0.1.tgz new file mode 100644 index 00000000000..fdaa61105f7 Binary files /dev/null and b/.yarn/offline-mirror/babel-preset-current-node-syntax-1.0.1.tgz differ diff --git a/.yarn/offline-mirror/babel-preset-jest-26.6.2.tgz b/.yarn/offline-mirror/babel-preset-jest-26.6.2.tgz new file mode 100644 index 00000000000..366e0a2171f Binary files /dev/null and b/.yarn/offline-mirror/babel-preset-jest-26.6.2.tgz differ diff --git a/.yarn/offline-mirror/basic-auth-2.0.1.tgz b/.yarn/offline-mirror/basic-auth-2.0.1.tgz new file mode 100644 index 00000000000..dd495ca706f Binary files /dev/null and b/.yarn/offline-mirror/basic-auth-2.0.1.tgz differ diff --git a/.yarn/offline-mirror/batch-0.6.1.tgz b/.yarn/offline-mirror/batch-0.6.1.tgz new file mode 100644 index 00000000000..9094af12b88 Binary files /dev/null and b/.yarn/offline-mirror/batch-0.6.1.tgz differ diff --git a/.yarn/offline-mirror/body-parser-1.20.0.tgz b/.yarn/offline-mirror/body-parser-1.20.0.tgz new file mode 100644 index 00000000000..e350adbc152 Binary files /dev/null and b/.yarn/offline-mirror/body-parser-1.20.0.tgz differ diff --git a/.yarn/offline-mirror/bonjour-service-1.0.14.tgz b/.yarn/offline-mirror/bonjour-service-1.0.14.tgz new file mode 100644 index 00000000000..cedd93afb72 Binary files /dev/null and b/.yarn/offline-mirror/bonjour-service-1.0.14.tgz differ diff --git a/.yarn/offline-mirror/cacheable-lookup-5.0.4.tgz b/.yarn/offline-mirror/cacheable-lookup-5.0.4.tgz deleted file mode 100644 index 980dad5597f..00000000000 Binary files a/.yarn/offline-mirror/cacheable-lookup-5.0.4.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/cacheable-request-7.0.2.tgz b/.yarn/offline-mirror/cacheable-request-7.0.2.tgz deleted file mode 100644 index 79b3c396284..00000000000 Binary files a/.yarn/offline-mirror/cacheable-request-7.0.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/caniuse-lite-1.0.30001420.tgz b/.yarn/offline-mirror/caniuse-lite-1.0.30001420.tgz deleted file mode 100644 index d3e03bc304a..00000000000 Binary files a/.yarn/offline-mirror/caniuse-lite-1.0.30001420.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/caniuse-lite-1.0.30001423.tgz b/.yarn/offline-mirror/caniuse-lite-1.0.30001423.tgz new file mode 100644 index 00000000000..9bc4d8d6395 Binary files /dev/null and b/.yarn/offline-mirror/caniuse-lite-1.0.30001423.tgz differ diff --git a/.yarn/offline-mirror/carbon-components-10.52.0.tgz b/.yarn/offline-mirror/carbon-components-10.52.0.tgz deleted file mode 100644 index a6c106b1e5d..00000000000 Binary files a/.yarn/offline-mirror/carbon-components-10.52.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/carbon-components-react-7.59.4.tgz b/.yarn/offline-mirror/carbon-components-react-7.59.4.tgz deleted file mode 100644 index 24455953a0d..00000000000 Binary files a/.yarn/offline-mirror/carbon-components-react-7.59.4.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/carbon-components-react-7.59.5.tgz b/.yarn/offline-mirror/carbon-components-react-7.59.5.tgz new file mode 100644 index 00000000000..ee80a062f83 Binary files /dev/null and b/.yarn/offline-mirror/carbon-components-react-7.59.5.tgz differ diff --git a/.yarn/offline-mirror/carbon-web-components-1.21.0.tgz b/.yarn/offline-mirror/carbon-web-components-1.21.0.tgz deleted file mode 100644 index dcbef3987e1..00000000000 Binary files a/.yarn/offline-mirror/carbon-web-components-1.21.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/child-process-promise-2.2.1.tgz b/.yarn/offline-mirror/child-process-promise-2.2.1.tgz new file mode 100644 index 00000000000..819c6fb90b4 Binary files /dev/null and b/.yarn/offline-mirror/child-process-promise-2.2.1.tgz differ diff --git a/.yarn/offline-mirror/cjs-module-lexer-0.6.0.tgz b/.yarn/offline-mirror/cjs-module-lexer-0.6.0.tgz new file mode 100644 index 00000000000..b6b3745cff1 Binary files /dev/null and b/.yarn/offline-mirror/cjs-module-lexer-0.6.0.tgz differ diff --git a/.yarn/offline-mirror/clone-deep-0.2.4.tgz b/.yarn/offline-mirror/clone-deep-0.2.4.tgz new file mode 100644 index 00000000000..aa029d4daba Binary files /dev/null and b/.yarn/offline-mirror/clone-deep-0.2.4.tgz differ diff --git a/.yarn/offline-mirror/colord-2.9.3.tgz b/.yarn/offline-mirror/colord-2.9.3.tgz new file mode 100644 index 00000000000..4ce78b8a281 Binary files /dev/null and b/.yarn/offline-mirror/colord-2.9.3.tgz differ diff --git a/.yarn/offline-mirror/colorspace-1.1.4.tgz b/.yarn/offline-mirror/colorspace-1.1.4.tgz deleted file mode 100644 index 4488c76a228..00000000000 Binary files a/.yarn/offline-mirror/colorspace-1.1.4.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/commander-3.0.2.tgz b/.yarn/offline-mirror/commander-3.0.2.tgz new file mode 100644 index 00000000000..3691b436ec1 Binary files /dev/null and b/.yarn/offline-mirror/commander-3.0.2.tgz differ diff --git a/.yarn/offline-mirror/comment-parser-0.7.6.tgz b/.yarn/offline-mirror/comment-parser-0.7.6.tgz deleted file mode 100644 index ceba731c6f3..00000000000 Binary files a/.yarn/offline-mirror/comment-parser-0.7.6.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/comment-parser-1.3.1.tgz b/.yarn/offline-mirror/comment-parser-1.3.1.tgz new file mode 100644 index 00000000000..891d36aa7e0 Binary files /dev/null and b/.yarn/offline-mirror/comment-parser-1.3.1.tgz differ diff --git a/.yarn/offline-mirror/connect-history-api-fallback-2.0.0.tgz b/.yarn/offline-mirror/connect-history-api-fallback-2.0.0.tgz new file mode 100644 index 00000000000..d9847f387bf Binary files /dev/null and b/.yarn/offline-mirror/connect-history-api-fallback-2.0.0.tgz differ diff --git a/.yarn/offline-mirror/convert-source-map-1.8.0.tgz b/.yarn/offline-mirror/convert-source-map-1.8.0.tgz new file mode 100644 index 00000000000..7a2096d87bf Binary files /dev/null and b/.yarn/offline-mirror/convert-source-map-1.8.0.tgz differ diff --git a/.yarn/offline-mirror/core-js-3.25.1.tgz b/.yarn/offline-mirror/core-js-3.25.1.tgz new file mode 100644 index 00000000000..a5cda3eb18b Binary files /dev/null and b/.yarn/offline-mirror/core-js-3.25.1.tgz differ diff --git a/.yarn/offline-mirror/core-js-3.25.5.tgz b/.yarn/offline-mirror/core-js-3.25.5.tgz deleted file mode 100644 index f368d146217..00000000000 Binary files a/.yarn/offline-mirror/core-js-3.25.5.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/core-js-3.26.0.tgz b/.yarn/offline-mirror/core-js-3.26.0.tgz new file mode 100644 index 00000000000..0c341468926 Binary files /dev/null and b/.yarn/offline-mirror/core-js-3.26.0.tgz differ diff --git a/.yarn/offline-mirror/core-js-compat-3.25.5.tgz b/.yarn/offline-mirror/core-js-compat-3.25.5.tgz deleted file mode 100644 index eb19861406c..00000000000 Binary files a/.yarn/offline-mirror/core-js-compat-3.25.5.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/core-js-compat-3.26.0.tgz b/.yarn/offline-mirror/core-js-compat-3.26.0.tgz new file mode 100644 index 00000000000..46731449417 Binary files /dev/null and b/.yarn/offline-mirror/core-js-compat-3.26.0.tgz differ diff --git a/.yarn/offline-mirror/core-js-pure-3.25.5.tgz b/.yarn/offline-mirror/core-js-pure-3.25.5.tgz deleted file mode 100644 index 71662538013..00000000000 Binary files a/.yarn/offline-mirror/core-js-pure-3.25.5.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/core-js-pure-3.26.0.tgz b/.yarn/offline-mirror/core-js-pure-3.26.0.tgz new file mode 100644 index 00000000000..cd94c75139f Binary files /dev/null and b/.yarn/offline-mirror/core-js-pure-3.26.0.tgz differ diff --git a/.yarn/offline-mirror/cross-spawn-4.0.2.tgz b/.yarn/offline-mirror/cross-spawn-4.0.2.tgz new file mode 100644 index 00000000000..a5c1af0333b Binary files /dev/null and b/.yarn/offline-mirror/cross-spawn-4.0.2.tgz differ diff --git a/.yarn/offline-mirror/css-3.0.0.tgz b/.yarn/offline-mirror/css-3.0.0.tgz new file mode 100644 index 00000000000..556c1e9fc72 Binary files /dev/null and b/.yarn/offline-mirror/css-3.0.0.tgz differ diff --git a/.yarn/offline-mirror/css-color-names-0.0.4.tgz b/.yarn/offline-mirror/css-color-names-0.0.4.tgz deleted file mode 100644 index 04355d6cd77..00000000000 Binary files a/.yarn/offline-mirror/css-color-names-0.0.4.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/css-declaration-sorter-4.0.1.tgz b/.yarn/offline-mirror/css-declaration-sorter-4.0.1.tgz deleted file mode 100644 index 5573b8998d0..00000000000 Binary files a/.yarn/offline-mirror/css-declaration-sorter-4.0.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/css-declaration-sorter-6.3.1.tgz b/.yarn/offline-mirror/css-declaration-sorter-6.3.1.tgz new file mode 100644 index 00000000000..c74db524429 Binary files /dev/null and b/.yarn/offline-mirror/css-declaration-sorter-6.3.1.tgz differ diff --git a/.yarn/offline-mirror/cssnano-4.1.11.tgz b/.yarn/offline-mirror/cssnano-4.1.11.tgz deleted file mode 100644 index 61a3806970d..00000000000 Binary files a/.yarn/offline-mirror/cssnano-4.1.11.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/cssnano-5.1.13.tgz b/.yarn/offline-mirror/cssnano-5.1.13.tgz new file mode 100644 index 00000000000..aaacb2fa661 Binary files /dev/null and b/.yarn/offline-mirror/cssnano-5.1.13.tgz differ diff --git a/.yarn/offline-mirror/cssnano-preset-default-4.0.8.tgz b/.yarn/offline-mirror/cssnano-preset-default-4.0.8.tgz deleted file mode 100644 index e750860f71a..00000000000 Binary files a/.yarn/offline-mirror/cssnano-preset-default-4.0.8.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/cssnano-preset-default-5.2.12.tgz b/.yarn/offline-mirror/cssnano-preset-default-5.2.12.tgz new file mode 100644 index 00000000000..a0c70ff29f4 Binary files /dev/null and b/.yarn/offline-mirror/cssnano-preset-default-5.2.12.tgz differ diff --git a/.yarn/offline-mirror/cssnano-util-get-arguments-4.0.0.tgz b/.yarn/offline-mirror/cssnano-util-get-arguments-4.0.0.tgz deleted file mode 100644 index 8fc763a720f..00000000000 Binary files a/.yarn/offline-mirror/cssnano-util-get-arguments-4.0.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/cssnano-util-get-match-4.0.0.tgz b/.yarn/offline-mirror/cssnano-util-get-match-4.0.0.tgz deleted file mode 100644 index b9fc8afb975..00000000000 Binary files a/.yarn/offline-mirror/cssnano-util-get-match-4.0.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/cssnano-util-raw-cache-4.0.1.tgz b/.yarn/offline-mirror/cssnano-util-raw-cache-4.0.1.tgz deleted file mode 100644 index 535f8b16d6b..00000000000 Binary files a/.yarn/offline-mirror/cssnano-util-raw-cache-4.0.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/cssnano-util-same-parent-4.0.1.tgz b/.yarn/offline-mirror/cssnano-util-same-parent-4.0.1.tgz deleted file mode 100644 index 807aa009cda..00000000000 Binary files a/.yarn/offline-mirror/cssnano-util-same-parent-4.0.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/cssnano-utils-3.1.0.tgz b/.yarn/offline-mirror/cssnano-utils-3.1.0.tgz new file mode 100644 index 00000000000..f97241b4ff9 Binary files /dev/null and b/.yarn/offline-mirror/cssnano-utils-3.1.0.tgz differ diff --git a/.yarn/offline-mirror/cwd-0.10.0.tgz b/.yarn/offline-mirror/cwd-0.10.0.tgz new file mode 100644 index 00000000000..e6605f5b46c Binary files /dev/null and b/.yarn/offline-mirror/cwd-0.10.0.tgz differ diff --git a/.yarn/offline-mirror/cypress-8.7.0.tgz b/.yarn/offline-mirror/cypress-8.7.0.tgz new file mode 100644 index 00000000000..9b05c073bac Binary files /dev/null and b/.yarn/offline-mirror/cypress-8.7.0.tgz differ diff --git a/.yarn/offline-mirror/data-urls-2.0.0.tgz b/.yarn/offline-mirror/data-urls-2.0.0.tgz new file mode 100644 index 00000000000..caa0b54bd46 Binary files /dev/null and b/.yarn/offline-mirror/data-urls-2.0.0.tgz differ diff --git a/.yarn/offline-mirror/dayjs-1.11.5.tgz b/.yarn/offline-mirror/dayjs-1.11.5.tgz deleted file mode 100644 index 969a76e5a26..00000000000 Binary files a/.yarn/offline-mirror/dayjs-1.11.5.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/dayjs-1.11.6.tgz b/.yarn/offline-mirror/dayjs-1.11.6.tgz new file mode 100644 index 00000000000..08e2ea557a0 Binary files /dev/null and b/.yarn/offline-mirror/dayjs-1.11.6.tgz differ diff --git a/.yarn/offline-mirror/decamelize-keys-1.1.1.tgz b/.yarn/offline-mirror/decamelize-keys-1.1.1.tgz new file mode 100644 index 00000000000..796456f4f4d Binary files /dev/null and b/.yarn/offline-mirror/decamelize-keys-1.1.1.tgz differ diff --git a/.yarn/offline-mirror/decimal.js-10.4.0.tgz b/.yarn/offline-mirror/decimal.js-10.4.0.tgz new file mode 100644 index 00000000000..3002c7240dc Binary files /dev/null and b/.yarn/offline-mirror/decimal.js-10.4.0.tgz differ diff --git a/.yarn/offline-mirror/decimal.js-10.4.2.tgz b/.yarn/offline-mirror/decimal.js-10.4.2.tgz deleted file mode 100644 index 4d36cf4cc7f..00000000000 Binary files a/.yarn/offline-mirror/decimal.js-10.4.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/decimal.js-10.4.3.tgz b/.yarn/offline-mirror/decimal.js-10.4.3.tgz new file mode 100644 index 00000000000..14203a23ec2 Binary files /dev/null and b/.yarn/offline-mirror/decimal.js-10.4.3.tgz differ diff --git a/.yarn/offline-mirror/decode-uri-component-0.2.0.tgz b/.yarn/offline-mirror/decode-uri-component-0.2.0.tgz deleted file mode 100644 index cec4e6339b0..00000000000 Binary files a/.yarn/offline-mirror/decode-uri-component-0.2.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/decode-uri-component-0.2.2.tgz b/.yarn/offline-mirror/decode-uri-component-0.2.2.tgz new file mode 100644 index 00000000000..e7adebe25b7 Binary files /dev/null and b/.yarn/offline-mirror/decode-uri-component-0.2.2.tgz differ diff --git a/.yarn/offline-mirror/decompress-response-6.0.0.tgz b/.yarn/offline-mirror/decompress-response-6.0.0.tgz deleted file mode 100644 index 9ec0bf1fdfb..00000000000 Binary files a/.yarn/offline-mirror/decompress-response-6.0.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/default-gateway-6.0.3.tgz b/.yarn/offline-mirror/default-gateway-6.0.3.tgz new file mode 100644 index 00000000000..89060bacb32 Binary files /dev/null and b/.yarn/offline-mirror/default-gateway-6.0.3.tgz differ diff --git a/.yarn/offline-mirror/defer-to-connect-2.0.1.tgz b/.yarn/offline-mirror/defer-to-connect-2.0.1.tgz deleted file mode 100644 index 374c8ce5569..00000000000 Binary files a/.yarn/offline-mirror/defer-to-connect-2.0.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/detect-node-2.1.0.tgz b/.yarn/offline-mirror/detect-node-2.1.0.tgz new file mode 100644 index 00000000000..66194764bd0 Binary files /dev/null and b/.yarn/offline-mirror/detect-node-2.1.0.tgz differ diff --git a/.yarn/offline-mirror/devtools-protocol-0.0.981744.tgz b/.yarn/offline-mirror/devtools-protocol-0.0.981744.tgz new file mode 100644 index 00000000000..1d3839d9326 Binary files /dev/null and b/.yarn/offline-mirror/devtools-protocol-0.0.981744.tgz differ diff --git a/.yarn/offline-mirror/dns-equal-1.0.0.tgz b/.yarn/offline-mirror/dns-equal-1.0.0.tgz new file mode 100644 index 00000000000..ab6a3b08833 Binary files /dev/null and b/.yarn/offline-mirror/dns-equal-1.0.0.tgz differ diff --git a/.yarn/offline-mirror/dns-packet-5.4.0.tgz b/.yarn/offline-mirror/dns-packet-5.4.0.tgz new file mode 100644 index 00000000000..197c3f6d650 Binary files /dev/null and b/.yarn/offline-mirror/dns-packet-5.4.0.tgz differ diff --git a/.yarn/offline-mirror/domexception-2.0.1.tgz b/.yarn/offline-mirror/domexception-2.0.1.tgz new file mode 100644 index 00000000000..0ffa8782f0a Binary files /dev/null and b/.yarn/offline-mirror/domexception-2.0.1.tgz differ diff --git a/.yarn/offline-mirror/duplexify-4.1.2.tgz b/.yarn/offline-mirror/duplexify-4.1.2.tgz new file mode 100644 index 00000000000..4e9ab32dcb0 Binary files /dev/null and b/.yarn/offline-mirror/duplexify-4.1.2.tgz differ diff --git a/.yarn/offline-mirror/electron-to-chromium-1.4.283.tgz b/.yarn/offline-mirror/electron-to-chromium-1.4.283.tgz deleted file mode 100644 index 97ebb2fa54c..00000000000 Binary files a/.yarn/offline-mirror/electron-to-chromium-1.4.283.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/electron-to-chromium-1.4.284.tgz b/.yarn/offline-mirror/electron-to-chromium-1.4.284.tgz new file mode 100644 index 00000000000..118d7acb881 Binary files /dev/null and b/.yarn/offline-mirror/electron-to-chromium-1.4.284.tgz differ diff --git a/.yarn/offline-mirror/emittery-0.7.2.tgz b/.yarn/offline-mirror/emittery-0.7.2.tgz new file mode 100644 index 00000000000..e711a61f97e Binary files /dev/null and b/.yarn/offline-mirror/emittery-0.7.2.tgz differ diff --git a/.yarn/offline-mirror/enabled-2.0.0.tgz b/.yarn/offline-mirror/enabled-2.0.0.tgz deleted file mode 100644 index 0e1cfb0e75e..00000000000 Binary files a/.yarn/offline-mirror/enabled-2.0.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/eslint-config-airbnb-18.2.1.tgz b/.yarn/offline-mirror/eslint-config-airbnb-18.2.1.tgz deleted file mode 100644 index 5147c94567b..00000000000 Binary files a/.yarn/offline-mirror/eslint-config-airbnb-18.2.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/eslint-config-airbnb-19.0.4.tgz b/.yarn/offline-mirror/eslint-config-airbnb-19.0.4.tgz new file mode 100644 index 00000000000..355604d100b Binary files /dev/null and b/.yarn/offline-mirror/eslint-config-airbnb-19.0.4.tgz differ diff --git a/.yarn/offline-mirror/eslint-config-airbnb-base-13.2.0.tgz b/.yarn/offline-mirror/eslint-config-airbnb-base-13.2.0.tgz deleted file mode 100644 index 2aac24908c9..00000000000 Binary files a/.yarn/offline-mirror/eslint-config-airbnb-base-13.2.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/eslint-config-airbnb-base-14.2.1.tgz b/.yarn/offline-mirror/eslint-config-airbnb-base-14.2.1.tgz deleted file mode 100644 index bff4693c2a1..00000000000 Binary files a/.yarn/offline-mirror/eslint-config-airbnb-base-14.2.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/eslint-config-airbnb-base-15.0.0.tgz b/.yarn/offline-mirror/eslint-config-airbnb-base-15.0.0.tgz new file mode 100644 index 00000000000..add41215997 Binary files /dev/null and b/.yarn/offline-mirror/eslint-config-airbnb-base-15.0.0.tgz differ diff --git a/.yarn/offline-mirror/eslint-config-carbon-base-1.0.1.tgz b/.yarn/offline-mirror/eslint-config-carbon-base-1.0.1.tgz deleted file mode 100644 index a5ff00d08b2..00000000000 Binary files a/.yarn/offline-mirror/eslint-config-carbon-base-1.0.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/eslint-config-prettier-6.15.0.tgz b/.yarn/offline-mirror/eslint-config-prettier-6.15.0.tgz deleted file mode 100644 index c31d4849a01..00000000000 Binary files a/.yarn/offline-mirror/eslint-config-prettier-6.15.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/eslint-config-prettier-8.5.0.tgz b/.yarn/offline-mirror/eslint-config-prettier-8.5.0.tgz new file mode 100644 index 00000000000..f16b4141434 Binary files /dev/null and b/.yarn/offline-mirror/eslint-config-prettier-8.5.0.tgz differ diff --git a/.yarn/offline-mirror/eslint-plugin-babel-5.3.1.tgz b/.yarn/offline-mirror/eslint-plugin-babel-5.3.1.tgz deleted file mode 100644 index 736a0466159..00000000000 Binary files a/.yarn/offline-mirror/eslint-plugin-babel-5.3.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/eslint-plugin-jsdoc-24.0.6.tgz b/.yarn/offline-mirror/eslint-plugin-jsdoc-24.0.6.tgz deleted file mode 100644 index b3b67feb380..00000000000 Binary files a/.yarn/offline-mirror/eslint-plugin-jsdoc-24.0.6.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/eslint-plugin-jsdoc-39.6.2.tgz b/.yarn/offline-mirror/eslint-plugin-jsdoc-39.6.2.tgz new file mode 100644 index 00000000000..9258d2079f5 Binary files /dev/null and b/.yarn/offline-mirror/eslint-plugin-jsdoc-39.6.2.tgz differ diff --git a/.yarn/offline-mirror/eslint-plugin-prettier-3.4.1.tgz b/.yarn/offline-mirror/eslint-plugin-prettier-3.4.1.tgz deleted file mode 100644 index 868045e928c..00000000000 Binary files a/.yarn/offline-mirror/eslint-plugin-prettier-3.4.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/eslint-plugin-prettier-4.2.1.tgz b/.yarn/offline-mirror/eslint-plugin-prettier-4.2.1.tgz new file mode 100644 index 00000000000..46f63746f4f Binary files /dev/null and b/.yarn/offline-mirror/eslint-plugin-prettier-4.2.1.tgz differ diff --git a/.yarn/offline-mirror/eslint-plugin-react-hooks-3.0.0.tgz b/.yarn/offline-mirror/eslint-plugin-react-hooks-3.0.0.tgz deleted file mode 100644 index a382a4cfba1..00000000000 Binary files a/.yarn/offline-mirror/eslint-plugin-react-hooks-3.0.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/eslint-plugin-react-hooks-4.6.0.tgz b/.yarn/offline-mirror/eslint-plugin-react-hooks-4.6.0.tgz new file mode 100644 index 00000000000..77754a9bf57 Binary files /dev/null and b/.yarn/offline-mirror/eslint-plugin-react-hooks-4.6.0.tgz differ diff --git a/.yarn/offline-mirror/eslint-rule-composer-0.3.0.tgz b/.yarn/offline-mirror/eslint-rule-composer-0.3.0.tgz deleted file mode 100644 index ffbeee296d5..00000000000 Binary files a/.yarn/offline-mirror/eslint-rule-composer-0.3.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/eslint-utils-2.1.0.tgz b/.yarn/offline-mirror/eslint-utils-2.1.0.tgz deleted file mode 100644 index 88af29ccf50..00000000000 Binary files a/.yarn/offline-mirror/eslint-utils-2.1.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/eslint-utils-3.0.0.tgz b/.yarn/offline-mirror/eslint-utils-3.0.0.tgz new file mode 100644 index 00000000000..142cb8cecb1 Binary files /dev/null and b/.yarn/offline-mirror/eslint-utils-3.0.0.tgz differ diff --git a/.yarn/offline-mirror/eslint-visitor-keys-2.1.0.tgz b/.yarn/offline-mirror/eslint-visitor-keys-2.1.0.tgz new file mode 100644 index 00000000000..6030749538e Binary files /dev/null and b/.yarn/offline-mirror/eslint-visitor-keys-2.1.0.tgz differ diff --git a/.yarn/offline-mirror/eslint-visitor-keys-3.3.0.tgz b/.yarn/offline-mirror/eslint-visitor-keys-3.3.0.tgz new file mode 100644 index 00000000000..51887772bad Binary files /dev/null and b/.yarn/offline-mirror/eslint-visitor-keys-3.3.0.tgz differ diff --git a/.yarn/offline-mirror/execa-6.1.0.tgz b/.yarn/offline-mirror/execa-6.1.0.tgz new file mode 100644 index 00000000000..d2b271d0a9b Binary files /dev/null and b/.yarn/offline-mirror/execa-6.1.0.tgz differ diff --git a/.yarn/offline-mirror/expand-tilde-1.2.2.tgz b/.yarn/offline-mirror/expand-tilde-1.2.2.tgz new file mode 100644 index 00000000000..8a4b5b878b7 Binary files /dev/null and b/.yarn/offline-mirror/expand-tilde-1.2.2.tgz differ diff --git a/.yarn/offline-mirror/expect-29.2.0.tgz b/.yarn/offline-mirror/expect-29.2.0.tgz deleted file mode 100644 index d2f877457f6..00000000000 Binary files a/.yarn/offline-mirror/expect-29.2.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/expect-29.2.1.tgz b/.yarn/offline-mirror/expect-29.2.1.tgz new file mode 100644 index 00000000000..4bf617a0b0e Binary files /dev/null and b/.yarn/offline-mirror/expect-29.2.1.tgz differ diff --git a/.yarn/offline-mirror/expect-playwright-0.2.6.tgz b/.yarn/offline-mirror/expect-playwright-0.2.6.tgz new file mode 100644 index 00000000000..e38824076bc Binary files /dev/null and b/.yarn/offline-mirror/expect-playwright-0.2.6.tgz differ diff --git a/.yarn/offline-mirror/expect-playwright-0.8.0.tgz b/.yarn/offline-mirror/expect-playwright-0.8.0.tgz new file mode 100644 index 00000000000..b59ed00c073 Binary files /dev/null and b/.yarn/offline-mirror/expect-playwright-0.8.0.tgz differ diff --git a/.yarn/offline-mirror/expect-puppeteer-6.1.1.tgz b/.yarn/offline-mirror/expect-puppeteer-6.1.1.tgz new file mode 100644 index 00000000000..7890dac25c6 Binary files /dev/null and b/.yarn/offline-mirror/expect-puppeteer-6.1.1.tgz differ diff --git a/.yarn/offline-mirror/express-4.18.1.tgz b/.yarn/offline-mirror/express-4.18.1.tgz new file mode 100644 index 00000000000..e0c715f3d84 Binary files /dev/null and b/.yarn/offline-mirror/express-4.18.1.tgz differ diff --git a/.yarn/offline-mirror/faye-websocket-0.11.4.tgz b/.yarn/offline-mirror/faye-websocket-0.11.4.tgz new file mode 100644 index 00000000000..e94d5e42561 Binary files /dev/null and b/.yarn/offline-mirror/faye-websocket-0.11.4.tgz differ diff --git a/.yarn/offline-mirror/fecha-4.2.3.tgz b/.yarn/offline-mirror/fecha-4.2.3.tgz deleted file mode 100644 index 85e8dd15ec9..00000000000 Binary files a/.yarn/offline-mirror/fecha-4.2.3.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/find-file-up-0.1.3.tgz b/.yarn/offline-mirror/find-file-up-0.1.3.tgz new file mode 100644 index 00000000000..deabd2df22c Binary files /dev/null and b/.yarn/offline-mirror/find-file-up-0.1.3.tgz differ diff --git a/.yarn/offline-mirror/find-pkg-0.1.2.tgz b/.yarn/offline-mirror/find-pkg-0.1.2.tgz new file mode 100644 index 00000000000..c48080641f2 Binary files /dev/null and b/.yarn/offline-mirror/find-pkg-0.1.2.tgz differ diff --git a/.yarn/offline-mirror/find-process-1.4.7.tgz b/.yarn/offline-mirror/find-process-1.4.7.tgz new file mode 100644 index 00000000000..e9d3ea5c206 Binary files /dev/null and b/.yarn/offline-mirror/find-process-1.4.7.tgz differ diff --git a/.yarn/offline-mirror/flatpickr-4.6.13.tgz b/.yarn/offline-mirror/flatpickr-4.6.13.tgz new file mode 100644 index 00000000000..773989ad8d6 Binary files /dev/null and b/.yarn/offline-mirror/flatpickr-4.6.13.tgz differ diff --git a/.yarn/offline-mirror/fn.name-1.1.0.tgz b/.yarn/offline-mirror/fn.name-1.1.0.tgz deleted file mode 100644 index 33f2bc958f6..00000000000 Binary files a/.yarn/offline-mirror/fn.name-1.1.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/for-in-0.1.8.tgz b/.yarn/offline-mirror/for-in-0.1.8.tgz new file mode 100644 index 00000000000..b300e296206 Binary files /dev/null and b/.yarn/offline-mirror/for-in-0.1.8.tgz differ diff --git a/.yarn/offline-mirror/fork-stream-0.0.4.tgz b/.yarn/offline-mirror/fork-stream-0.0.4.tgz new file mode 100644 index 00000000000..936e4fa1b42 Binary files /dev/null and b/.yarn/offline-mirror/fork-stream-0.0.4.tgz differ diff --git a/.yarn/offline-mirror/fs-exists-sync-0.1.0.tgz b/.yarn/offline-mirror/fs-exists-sync-0.1.0.tgz new file mode 100644 index 00000000000..75981891ee4 Binary files /dev/null and b/.yarn/offline-mirror/fs-exists-sync-0.1.0.tgz differ diff --git a/.yarn/offline-mirror/gauge-4.0.4.tgz b/.yarn/offline-mirror/gauge-4.0.4.tgz new file mode 100644 index 00000000000..10e82387cd3 Binary files /dev/null and b/.yarn/offline-mirror/gauge-4.0.4.tgz differ diff --git a/.yarn/offline-mirror/get-stdin-6.0.0.tgz b/.yarn/offline-mirror/get-stdin-6.0.0.tgz deleted file mode 100644 index a1a456f8d74..00000000000 Binary files a/.yarn/offline-mirror/get-stdin-6.0.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/global-modules-0.2.3.tgz b/.yarn/offline-mirror/global-modules-0.2.3.tgz new file mode 100644 index 00000000000..9e157c08d49 Binary files /dev/null and b/.yarn/offline-mirror/global-modules-0.2.3.tgz differ diff --git a/.yarn/offline-mirror/global-prefix-0.1.5.tgz b/.yarn/offline-mirror/global-prefix-0.1.5.tgz new file mode 100644 index 00000000000..116d42b100e Binary files /dev/null and b/.yarn/offline-mirror/global-prefix-0.1.5.tgz differ diff --git a/.yarn/offline-mirror/got-11.8.5.tgz b/.yarn/offline-mirror/got-11.8.5.tgz deleted file mode 100644 index 207754f91d1..00000000000 Binary files a/.yarn/offline-mirror/got-11.8.5.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/gulp-exclude-gitignore-1.2.0.tgz b/.yarn/offline-mirror/gulp-exclude-gitignore-1.2.0.tgz new file mode 100644 index 00000000000..72e09995435 Binary files /dev/null and b/.yarn/offline-mirror/gulp-exclude-gitignore-1.2.0.tgz differ diff --git a/.yarn/offline-mirror/gulp-filter-7.0.0.tgz b/.yarn/offline-mirror/gulp-filter-7.0.0.tgz new file mode 100644 index 00000000000..7d151119bb6 Binary files /dev/null and b/.yarn/offline-mirror/gulp-filter-7.0.0.tgz differ diff --git a/.yarn/offline-mirror/gulp-if-3.0.0.tgz b/.yarn/offline-mirror/gulp-if-3.0.0.tgz new file mode 100644 index 00000000000..1a9acf5cd99 Binary files /dev/null and b/.yarn/offline-mirror/gulp-if-3.0.0.tgz differ diff --git a/.yarn/offline-mirror/gulp-ignore-2.0.2.tgz b/.yarn/offline-mirror/gulp-ignore-2.0.2.tgz new file mode 100644 index 00000000000..b7835c51103 Binary files /dev/null and b/.yarn/offline-mirror/gulp-ignore-2.0.2.tgz differ diff --git a/.yarn/offline-mirror/gulp-match-1.1.0.tgz b/.yarn/offline-mirror/gulp-match-1.1.0.tgz new file mode 100644 index 00000000000..eafaaa83275 Binary files /dev/null and b/.yarn/offline-mirror/gulp-match-1.1.0.tgz differ diff --git a/.yarn/offline-mirror/gulp-postcss-8.0.0.tgz b/.yarn/offline-mirror/gulp-postcss-8.0.0.tgz deleted file mode 100644 index 52b3ac5a830..00000000000 Binary files a/.yarn/offline-mirror/gulp-postcss-8.0.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/gulp-postcss-9.0.1.tgz b/.yarn/offline-mirror/gulp-postcss-9.0.1.tgz new file mode 100644 index 00000000000..54996562a78 Binary files /dev/null and b/.yarn/offline-mirror/gulp-postcss-9.0.1.tgz differ diff --git a/.yarn/offline-mirror/gulp-prettier-4.0.0.tgz b/.yarn/offline-mirror/gulp-prettier-4.0.0.tgz new file mode 100644 index 00000000000..15da7b520af Binary files /dev/null and b/.yarn/offline-mirror/gulp-prettier-4.0.0.tgz differ diff --git a/.yarn/offline-mirror/gulp-sourcemaps-3.0.0.tgz b/.yarn/offline-mirror/gulp-sourcemaps-3.0.0.tgz new file mode 100644 index 00000000000..eab9fa9e3f9 Binary files /dev/null and b/.yarn/offline-mirror/gulp-sourcemaps-3.0.0.tgz differ diff --git a/.yarn/offline-mirror/handle-thing-2.0.1.tgz b/.yarn/offline-mirror/handle-thing-2.0.1.tgz new file mode 100644 index 00000000000..027bc960ec6 Binary files /dev/null and b/.yarn/offline-mirror/handle-thing-2.0.1.tgz differ diff --git a/.yarn/offline-mirror/hex-color-regex-1.1.0.tgz b/.yarn/offline-mirror/hex-color-regex-1.1.0.tgz deleted file mode 100644 index 7bd3668283d..00000000000 Binary files a/.yarn/offline-mirror/hex-color-regex-1.1.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/hpack.js-2.1.6.tgz b/.yarn/offline-mirror/hpack.js-2.1.6.tgz new file mode 100644 index 00000000000..ac2f5c068df Binary files /dev/null and b/.yarn/offline-mirror/hpack.js-2.1.6.tgz differ diff --git a/.yarn/offline-mirror/hsl-regex-1.0.0.tgz b/.yarn/offline-mirror/hsl-regex-1.0.0.tgz deleted file mode 100644 index 1fab7c13f3b..00000000000 Binary files a/.yarn/offline-mirror/hsl-regex-1.0.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/hsla-regex-1.0.0.tgz b/.yarn/offline-mirror/hsla-regex-1.0.0.tgz deleted file mode 100644 index adee7ea0a83..00000000000 Binary files a/.yarn/offline-mirror/hsla-regex-1.0.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/html-encoding-sniffer-2.0.1.tgz b/.yarn/offline-mirror/html-encoding-sniffer-2.0.1.tgz new file mode 100644 index 00000000000..ddfc0e9b99e Binary files /dev/null and b/.yarn/offline-mirror/html-encoding-sniffer-2.0.1.tgz differ diff --git a/.yarn/offline-mirror/http-deceiver-1.2.7.tgz b/.yarn/offline-mirror/http-deceiver-1.2.7.tgz new file mode 100644 index 00000000000..500c27ada50 Binary files /dev/null and b/.yarn/offline-mirror/http-deceiver-1.2.7.tgz differ diff --git a/.yarn/offline-mirror/http-errors-1.6.3.tgz b/.yarn/offline-mirror/http-errors-1.6.3.tgz new file mode 100644 index 00000000000..88111c55257 Binary files /dev/null and b/.yarn/offline-mirror/http-errors-1.6.3.tgz differ diff --git a/.yarn/offline-mirror/http-parser-js-0.5.8.tgz b/.yarn/offline-mirror/http-parser-js-0.5.8.tgz new file mode 100644 index 00000000000..edd9d63c677 Binary files /dev/null and b/.yarn/offline-mirror/http-parser-js-0.5.8.tgz differ diff --git a/.yarn/offline-mirror/http-proxy-middleware-2.0.6.tgz b/.yarn/offline-mirror/http-proxy-middleware-2.0.6.tgz new file mode 100644 index 00000000000..f79153e4af8 Binary files /dev/null and b/.yarn/offline-mirror/http-proxy-middleware-2.0.6.tgz differ diff --git a/.yarn/offline-mirror/http-server-14.1.1.tgz b/.yarn/offline-mirror/http-server-14.1.1.tgz new file mode 100644 index 00000000000..05fa6746cad Binary files /dev/null and b/.yarn/offline-mirror/http-server-14.1.1.tgz differ diff --git a/.yarn/offline-mirror/http2-wrapper-1.0.3.tgz b/.yarn/offline-mirror/http2-wrapper-1.0.3.tgz deleted file mode 100644 index 5abd9e8586f..00000000000 Binary files a/.yarn/offline-mirror/http2-wrapper-1.0.3.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/human-signals-3.0.1.tgz b/.yarn/offline-mirror/human-signals-3.0.1.tgz new file mode 100644 index 00000000000..4d3adf92390 Binary files /dev/null and b/.yarn/offline-mirror/human-signals-3.0.1.tgz differ diff --git a/.yarn/offline-mirror/ipaddr.js-2.0.1.tgz b/.yarn/offline-mirror/ipaddr.js-2.0.1.tgz new file mode 100644 index 00000000000..983c7f16d25 Binary files /dev/null and b/.yarn/offline-mirror/ipaddr.js-2.0.1.tgz differ diff --git a/.yarn/offline-mirror/is-absolute-url-2.1.0.tgz b/.yarn/offline-mirror/is-absolute-url-2.1.0.tgz deleted file mode 100644 index bf7687be40c..00000000000 Binary files a/.yarn/offline-mirror/is-absolute-url-2.1.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/is-color-stop-1.1.0.tgz b/.yarn/offline-mirror/is-color-stop-1.1.0.tgz deleted file mode 100644 index 4c0a284380e..00000000000 Binary files a/.yarn/offline-mirror/is-color-stop-1.1.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/is-core-module-2.10.0.tgz b/.yarn/offline-mirror/is-core-module-2.10.0.tgz deleted file mode 100644 index 9da363f3fe1..00000000000 Binary files a/.yarn/offline-mirror/is-core-module-2.10.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/is-core-module-2.11.0.tgz b/.yarn/offline-mirror/is-core-module-2.11.0.tgz new file mode 100644 index 00000000000..4c162eb7f1e Binary files /dev/null and b/.yarn/offline-mirror/is-core-module-2.11.0.tgz differ diff --git a/.yarn/offline-mirror/is-plain-obj-3.0.0.tgz b/.yarn/offline-mirror/is-plain-obj-3.0.0.tgz new file mode 100644 index 00000000000..c23a65f29ae Binary files /dev/null and b/.yarn/offline-mirror/is-plain-obj-3.0.0.tgz differ diff --git a/.yarn/offline-mirror/is-port-reachable-3.1.0.tgz b/.yarn/offline-mirror/is-port-reachable-3.1.0.tgz new file mode 100644 index 00000000000..aae8fbc73e9 Binary files /dev/null and b/.yarn/offline-mirror/is-port-reachable-3.1.0.tgz differ diff --git a/.yarn/offline-mirror/is-resolvable-1.1.0.tgz b/.yarn/offline-mirror/is-resolvable-1.1.0.tgz deleted file mode 100644 index e0d2fc4ecd9..00000000000 Binary files a/.yarn/offline-mirror/is-resolvable-1.1.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/is-stream-3.0.0.tgz b/.yarn/offline-mirror/is-stream-3.0.0.tgz new file mode 100644 index 00000000000..13d9c82ee04 Binary files /dev/null and b/.yarn/offline-mirror/is-stream-3.0.0.tgz differ diff --git a/.yarn/offline-mirror/is-windows-0.2.0.tgz b/.yarn/offline-mirror/is-windows-0.2.0.tgz new file mode 100644 index 00000000000..84d06785449 Binary files /dev/null and b/.yarn/offline-mirror/is-windows-0.2.0.tgz differ diff --git a/.yarn/offline-mirror/isomorphic-dompurify-0.24.0.tgz b/.yarn/offline-mirror/isomorphic-dompurify-0.24.0.tgz deleted file mode 100644 index 9d8a048ca98..00000000000 Binary files a/.yarn/offline-mirror/isomorphic-dompurify-0.24.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/isomorphic-dompurify-0.26.0.tgz b/.yarn/offline-mirror/isomorphic-dompurify-0.26.0.tgz new file mode 100644 index 00000000000..6bc3c24535b Binary files /dev/null and b/.yarn/offline-mirror/isomorphic-dompurify-0.26.0.tgz differ diff --git a/.yarn/offline-mirror/jasmine-core-4.4.0.tgz b/.yarn/offline-mirror/jasmine-core-4.4.0.tgz new file mode 100644 index 00000000000..b274f17ba6b Binary files /dev/null and b/.yarn/offline-mirror/jasmine-core-4.4.0.tgz differ diff --git a/.yarn/offline-mirror/jest-circus-26.6.3.tgz b/.yarn/offline-mirror/jest-circus-26.6.3.tgz new file mode 100644 index 00000000000..c6c8b57bdda Binary files /dev/null and b/.yarn/offline-mirror/jest-circus-26.6.3.tgz differ diff --git a/.yarn/offline-mirror/jest-config-26.6.3.tgz b/.yarn/offline-mirror/jest-config-26.6.3.tgz new file mode 100644 index 00000000000..f369eb5b3fe Binary files /dev/null and b/.yarn/offline-mirror/jest-config-26.6.3.tgz differ diff --git a/.yarn/offline-mirror/jest-dev-server-4.4.0.tgz b/.yarn/offline-mirror/jest-dev-server-4.4.0.tgz new file mode 100644 index 00000000000..629377154ac Binary files /dev/null and b/.yarn/offline-mirror/jest-dev-server-4.4.0.tgz differ diff --git a/.yarn/offline-mirror/jest-dev-server-6.1.1.tgz b/.yarn/offline-mirror/jest-dev-server-6.1.1.tgz new file mode 100644 index 00000000000..a0659a98a7d Binary files /dev/null and b/.yarn/offline-mirror/jest-dev-server-6.1.1.tgz differ diff --git a/.yarn/offline-mirror/jest-diff-29.2.0.tgz b/.yarn/offline-mirror/jest-diff-29.2.0.tgz deleted file mode 100644 index f017a7f1214..00000000000 Binary files a/.yarn/offline-mirror/jest-diff-29.2.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/jest-diff-29.2.1.tgz b/.yarn/offline-mirror/jest-diff-29.2.1.tgz new file mode 100644 index 00000000000..5487c92fa43 Binary files /dev/null and b/.yarn/offline-mirror/jest-diff-29.2.1.tgz differ diff --git a/.yarn/offline-mirror/jest-docblock-26.0.0.tgz b/.yarn/offline-mirror/jest-docblock-26.0.0.tgz new file mode 100644 index 00000000000..2c34d7bae01 Binary files /dev/null and b/.yarn/offline-mirror/jest-docblock-26.0.0.tgz differ diff --git a/.yarn/offline-mirror/jest-each-26.6.2.tgz b/.yarn/offline-mirror/jest-each-26.6.2.tgz new file mode 100644 index 00000000000..6228b07d9d3 Binary files /dev/null and b/.yarn/offline-mirror/jest-each-26.6.2.tgz differ diff --git a/.yarn/offline-mirror/jest-environment-jsdom-26.6.2.tgz b/.yarn/offline-mirror/jest-environment-jsdom-26.6.2.tgz new file mode 100644 index 00000000000..4ffcc5a9075 Binary files /dev/null and b/.yarn/offline-mirror/jest-environment-jsdom-26.6.2.tgz differ diff --git a/.yarn/offline-mirror/jest-environment-node-26.6.2.tgz b/.yarn/offline-mirror/jest-environment-node-26.6.2.tgz new file mode 100644 index 00000000000..40d8bdd19e0 Binary files /dev/null and b/.yarn/offline-mirror/jest-environment-node-26.6.2.tgz differ diff --git a/.yarn/offline-mirror/jest-environment-node-27.5.1.tgz b/.yarn/offline-mirror/jest-environment-node-27.5.1.tgz new file mode 100644 index 00000000000..e905215bac2 Binary files /dev/null and b/.yarn/offline-mirror/jest-environment-node-27.5.1.tgz differ diff --git a/.yarn/offline-mirror/jest-environment-puppeteer-6.1.1.tgz b/.yarn/offline-mirror/jest-environment-puppeteer-6.1.1.tgz new file mode 100644 index 00000000000..0a563023fd0 Binary files /dev/null and b/.yarn/offline-mirror/jest-environment-puppeteer-6.1.1.tgz differ diff --git a/.yarn/offline-mirror/jest-jasmine2-26.6.3.tgz b/.yarn/offline-mirror/jest-jasmine2-26.6.3.tgz new file mode 100644 index 00000000000..be879cd5eef Binary files /dev/null and b/.yarn/offline-mirror/jest-jasmine2-26.6.3.tgz differ diff --git a/.yarn/offline-mirror/jest-leak-detector-26.6.2.tgz b/.yarn/offline-mirror/jest-leak-detector-26.6.2.tgz new file mode 100644 index 00000000000..4a06f4d3217 Binary files /dev/null and b/.yarn/offline-mirror/jest-leak-detector-26.6.2.tgz differ diff --git a/.yarn/offline-mirror/jest-matcher-utils-29.2.0.tgz b/.yarn/offline-mirror/jest-matcher-utils-29.2.0.tgz deleted file mode 100644 index 6e005c0e0ce..00000000000 Binary files a/.yarn/offline-mirror/jest-matcher-utils-29.2.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/jest-matcher-utils-29.2.1.tgz b/.yarn/offline-mirror/jest-matcher-utils-29.2.1.tgz new file mode 100644 index 00000000000..0c86e08b800 Binary files /dev/null and b/.yarn/offline-mirror/jest-matcher-utils-29.2.1.tgz differ diff --git a/.yarn/offline-mirror/jest-message-util-27.5.1.tgz b/.yarn/offline-mirror/jest-message-util-27.5.1.tgz new file mode 100644 index 00000000000..d797f48611a Binary files /dev/null and b/.yarn/offline-mirror/jest-message-util-27.5.1.tgz differ diff --git a/.yarn/offline-mirror/jest-message-util-29.2.0.tgz b/.yarn/offline-mirror/jest-message-util-29.2.0.tgz deleted file mode 100644 index 0d100869946..00000000000 Binary files a/.yarn/offline-mirror/jest-message-util-29.2.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/jest-message-util-29.2.1.tgz b/.yarn/offline-mirror/jest-message-util-29.2.1.tgz new file mode 100644 index 00000000000..1ff5b1011ad Binary files /dev/null and b/.yarn/offline-mirror/jest-message-util-29.2.1.tgz differ diff --git a/.yarn/offline-mirror/jest-mock-26.6.2.tgz b/.yarn/offline-mirror/jest-mock-26.6.2.tgz new file mode 100644 index 00000000000..6a176711f22 Binary files /dev/null and b/.yarn/offline-mirror/jest-mock-26.6.2.tgz differ diff --git a/.yarn/offline-mirror/jest-mock-27.5.1.tgz b/.yarn/offline-mirror/jest-mock-27.5.1.tgz new file mode 100644 index 00000000000..2ade017ae6a Binary files /dev/null and b/.yarn/offline-mirror/jest-mock-27.5.1.tgz differ diff --git a/.yarn/offline-mirror/jest-playwright-preset-0.2.5.tgz b/.yarn/offline-mirror/jest-playwright-preset-0.2.5.tgz new file mode 100644 index 00000000000..bb973ac1fe7 Binary files /dev/null and b/.yarn/offline-mirror/jest-playwright-preset-0.2.5.tgz differ diff --git a/.yarn/offline-mirror/jest-runner-26.6.3.tgz b/.yarn/offline-mirror/jest-runner-26.6.3.tgz new file mode 100644 index 00000000000..020fbbe9861 Binary files /dev/null and b/.yarn/offline-mirror/jest-runner-26.6.3.tgz differ diff --git a/.yarn/offline-mirror/jest-runtime-26.6.3.tgz b/.yarn/offline-mirror/jest-runtime-26.6.3.tgz new file mode 100644 index 00000000000..0d88eff0a4f Binary files /dev/null and b/.yarn/offline-mirror/jest-runtime-26.6.3.tgz differ diff --git a/.yarn/offline-mirror/jest-util-27.5.1.tgz b/.yarn/offline-mirror/jest-util-27.5.1.tgz new file mode 100644 index 00000000000..9b07437b0fe Binary files /dev/null and b/.yarn/offline-mirror/jest-util-27.5.1.tgz differ diff --git a/.yarn/offline-mirror/jest-util-29.2.0.tgz b/.yarn/offline-mirror/jest-util-29.2.0.tgz deleted file mode 100644 index bac4531de85..00000000000 Binary files a/.yarn/offline-mirror/jest-util-29.2.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/jest-util-29.2.1.tgz b/.yarn/offline-mirror/jest-util-29.2.1.tgz new file mode 100644 index 00000000000..6c209201ea6 Binary files /dev/null and b/.yarn/offline-mirror/jest-util-29.2.1.tgz differ diff --git a/.yarn/offline-mirror/jest-validate-26.6.2.tgz b/.yarn/offline-mirror/jest-validate-26.6.2.tgz new file mode 100644 index 00000000000..942b486ea21 Binary files /dev/null and b/.yarn/offline-mirror/jest-validate-26.6.2.tgz differ diff --git a/.yarn/offline-mirror/joi-17.6.0.tgz b/.yarn/offline-mirror/joi-17.6.0.tgz new file mode 100644 index 00000000000..10f052d48a7 Binary files /dev/null and b/.yarn/offline-mirror/joi-17.6.0.tgz differ diff --git a/.yarn/offline-mirror/joi-17.6.3.tgz b/.yarn/offline-mirror/joi-17.6.3.tgz deleted file mode 100644 index 69fdf37a31f..00000000000 Binary files a/.yarn/offline-mirror/joi-17.6.3.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/joi-17.6.4.tgz b/.yarn/offline-mirror/joi-17.6.4.tgz new file mode 100644 index 00000000000..5f021f044e6 Binary files /dev/null and b/.yarn/offline-mirror/joi-17.6.4.tgz differ diff --git a/.yarn/offline-mirror/jsdoc-type-pratt-parser-3.1.0.tgz b/.yarn/offline-mirror/jsdoc-type-pratt-parser-3.1.0.tgz new file mode 100644 index 00000000000..24a5611b3f2 Binary files /dev/null and b/.yarn/offline-mirror/jsdoc-type-pratt-parser-3.1.0.tgz differ diff --git a/.yarn/offline-mirror/jsdoctypeparser-6.1.0.tgz b/.yarn/offline-mirror/jsdoctypeparser-6.1.0.tgz deleted file mode 100644 index 35a741e0c1f..00000000000 Binary files a/.yarn/offline-mirror/jsdoctypeparser-6.1.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/jsdom-16.7.0.tgz b/.yarn/offline-mirror/jsdom-16.7.0.tgz new file mode 100644 index 00000000000..952c3220485 Binary files /dev/null and b/.yarn/offline-mirror/jsdom-16.7.0.tgz differ diff --git a/.yarn/offline-mirror/jsdom-20.0.1.tgz b/.yarn/offline-mirror/jsdom-20.0.1.tgz deleted file mode 100644 index 68c492704c0..00000000000 Binary files a/.yarn/offline-mirror/jsdom-20.0.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/jsdom-21.0.0.tgz b/.yarn/offline-mirror/jsdom-21.0.0.tgz new file mode 100644 index 00000000000..dde03d82baf Binary files /dev/null and b/.yarn/offline-mirror/jsdom-21.0.0.tgz differ diff --git a/.yarn/offline-mirror/json-buffer-3.0.1.tgz b/.yarn/offline-mirror/json-buffer-3.0.1.tgz deleted file mode 100644 index 124547874e2..00000000000 Binary files a/.yarn/offline-mirror/json-buffer-3.0.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/json5-1.0.1.tgz b/.yarn/offline-mirror/json5-1.0.1.tgz deleted file mode 100644 index 48fc0174bfd..00000000000 Binary files a/.yarn/offline-mirror/json5-1.0.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/json5-1.0.2.tgz b/.yarn/offline-mirror/json5-1.0.2.tgz new file mode 100644 index 00000000000..3c794a9a32d Binary files /dev/null and b/.yarn/offline-mirror/json5-1.0.2.tgz differ diff --git a/.yarn/offline-mirror/karma-accessibility-checker-3.1.39.tgz b/.yarn/offline-mirror/karma-accessibility-checker-3.1.39.tgz deleted file mode 100644 index f9b91d03cfc..00000000000 Binary files a/.yarn/offline-mirror/karma-accessibility-checker-3.1.39.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/karma-accessibility-checker-3.1.40.tgz b/.yarn/offline-mirror/karma-accessibility-checker-3.1.40.tgz new file mode 100644 index 00000000000..37027221f98 Binary files /dev/null and b/.yarn/offline-mirror/karma-accessibility-checker-3.1.40.tgz differ diff --git a/.yarn/offline-mirror/karma-chrome-launcher-3.1.1.tgz b/.yarn/offline-mirror/karma-chrome-launcher-3.1.1.tgz new file mode 100644 index 00000000000..48c0d204f95 Binary files /dev/null and b/.yarn/offline-mirror/karma-chrome-launcher-3.1.1.tgz differ diff --git a/.yarn/offline-mirror/karma-firefox-launcher-2.1.2.tgz b/.yarn/offline-mirror/karma-firefox-launcher-2.1.2.tgz new file mode 100644 index 00000000000..db37d5be2d0 Binary files /dev/null and b/.yarn/offline-mirror/karma-firefox-launcher-2.1.2.tgz differ diff --git a/.yarn/offline-mirror/karma-jasmine-4.0.2.tgz b/.yarn/offline-mirror/karma-jasmine-4.0.2.tgz new file mode 100644 index 00000000000..b3ab64d3a21 Binary files /dev/null and b/.yarn/offline-mirror/karma-jasmine-4.0.2.tgz differ diff --git a/.yarn/offline-mirror/karma-spec-reporter-0.0.34.tgz b/.yarn/offline-mirror/karma-spec-reporter-0.0.34.tgz deleted file mode 100644 index d2368d45e45..00000000000 Binary files a/.yarn/offline-mirror/karma-spec-reporter-0.0.34.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/karma-spec-reporter-0.0.36.tgz b/.yarn/offline-mirror/karma-spec-reporter-0.0.36.tgz new file mode 100644 index 00000000000..a10d1498954 Binary files /dev/null and b/.yarn/offline-mirror/karma-spec-reporter-0.0.36.tgz differ diff --git a/.yarn/offline-mirror/keyv-4.5.0.tgz b/.yarn/offline-mirror/keyv-4.5.0.tgz deleted file mode 100644 index bb32d0d5e8b..00000000000 Binary files a/.yarn/offline-mirror/keyv-4.5.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/kuler-2.0.0.tgz b/.yarn/offline-mirror/kuler-2.0.0.tgz deleted file mode 100644 index f6535e3a54d..00000000000 Binary files a/.yarn/offline-mirror/kuler-2.0.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/lazy-cache-0.2.7.tgz b/.yarn/offline-mirror/lazy-cache-0.2.7.tgz new file mode 100644 index 00000000000..881bc7d9f80 Binary files /dev/null and b/.yarn/offline-mirror/lazy-cache-0.2.7.tgz differ diff --git a/.yarn/offline-mirror/lazy-cache-1.0.4.tgz b/.yarn/offline-mirror/lazy-cache-1.0.4.tgz new file mode 100644 index 00000000000..e9133db5f71 Binary files /dev/null and b/.yarn/offline-mirror/lazy-cache-1.0.4.tgz differ diff --git a/.yarn/offline-mirror/lilconfig-2.0.6.tgz b/.yarn/offline-mirror/lilconfig-2.0.6.tgz new file mode 100644 index 00000000000..36890b0961f Binary files /dev/null and b/.yarn/offline-mirror/lilconfig-2.0.6.tgz differ diff --git a/.yarn/offline-mirror/lint-staged-13.0.3.tgz b/.yarn/offline-mirror/lint-staged-13.0.3.tgz new file mode 100644 index 00000000000..26614dd1249 Binary files /dev/null and b/.yarn/offline-mirror/lint-staged-13.0.3.tgz differ diff --git a/.yarn/offline-mirror/loader-utils-2.0.2.tgz b/.yarn/offline-mirror/loader-utils-2.0.2.tgz deleted file mode 100644 index 1c2cbdebcb7..00000000000 Binary files a/.yarn/offline-mirror/loader-utils-2.0.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/loader-utils-2.0.3.tgz b/.yarn/offline-mirror/loader-utils-2.0.3.tgz new file mode 100644 index 00000000000..7bed2bb98de Binary files /dev/null and b/.yarn/offline-mirror/loader-utils-2.0.3.tgz differ diff --git a/.yarn/offline-mirror/loader-utils-2.0.4.tgz b/.yarn/offline-mirror/loader-utils-2.0.4.tgz new file mode 100644 index 00000000000..e3014777770 Binary files /dev/null and b/.yarn/offline-mirror/loader-utils-2.0.4.tgz differ diff --git a/.yarn/offline-mirror/logform-2.4.2.tgz b/.yarn/offline-mirror/logform-2.4.2.tgz deleted file mode 100644 index 536568139a0..00000000000 Binary files a/.yarn/offline-mirror/logform-2.4.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/lru-cache-4.1.5.tgz b/.yarn/offline-mirror/lru-cache-4.1.5.tgz new file mode 100644 index 00000000000..c662ad453c9 Binary files /dev/null and b/.yarn/offline-mirror/lru-cache-4.1.5.tgz differ diff --git a/.yarn/offline-mirror/magic-string-0.26.7.tgz b/.yarn/offline-mirror/magic-string-0.26.7.tgz deleted file mode 100644 index bf382709768..00000000000 Binary files a/.yarn/offline-mirror/magic-string-0.26.7.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/magic-string-0.27.0.tgz b/.yarn/offline-mirror/magic-string-0.27.0.tgz new file mode 100644 index 00000000000..d0590429e33 Binary files /dev/null and b/.yarn/offline-mirror/magic-string-0.27.0.tgz differ diff --git a/.yarn/offline-mirror/memfs-3.4.11.tgz b/.yarn/offline-mirror/memfs-3.4.11.tgz new file mode 100644 index 00000000000..a053a0f4b99 Binary files /dev/null and b/.yarn/offline-mirror/memfs-3.4.11.tgz differ diff --git a/.yarn/offline-mirror/merge-deep-3.0.3.tgz b/.yarn/offline-mirror/merge-deep-3.0.3.tgz new file mode 100644 index 00000000000..bcb2513ec69 Binary files /dev/null and b/.yarn/offline-mirror/merge-deep-3.0.3.tgz differ diff --git a/.yarn/offline-mirror/mimic-fn-4.0.0.tgz b/.yarn/offline-mirror/mimic-fn-4.0.0.tgz new file mode 100644 index 00000000000..f192a160914 Binary files /dev/null and b/.yarn/offline-mirror/mimic-fn-4.0.0.tgz differ diff --git a/.yarn/offline-mirror/mimic-response-3.1.0.tgz b/.yarn/offline-mirror/mimic-response-3.1.0.tgz deleted file mode 100644 index ed4bea3b896..00000000000 Binary files a/.yarn/offline-mirror/mimic-response-3.1.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/mini-css-extract-plugin-2.7.0.tgz b/.yarn/offline-mirror/mini-css-extract-plugin-2.7.0.tgz new file mode 100644 index 00000000000..28404b2859e Binary files /dev/null and b/.yarn/offline-mirror/mini-css-extract-plugin-2.7.0.tgz differ diff --git a/.yarn/offline-mirror/minipass-4.0.0.tgz b/.yarn/offline-mirror/minipass-4.0.0.tgz new file mode 100644 index 00000000000..8a841bd89d4 Binary files /dev/null and b/.yarn/offline-mirror/minipass-4.0.0.tgz differ diff --git a/.yarn/offline-mirror/mixin-object-2.0.1.tgz b/.yarn/offline-mirror/mixin-object-2.0.1.tgz new file mode 100644 index 00000000000..ebaeac71391 Binary files /dev/null and b/.yarn/offline-mirror/mixin-object-2.0.1.tgz differ diff --git a/.yarn/offline-mirror/mkdirp-classic-0.5.3.tgz b/.yarn/offline-mirror/mkdirp-classic-0.5.3.tgz new file mode 100644 index 00000000000..42b5483c2ea Binary files /dev/null and b/.yarn/offline-mirror/mkdirp-classic-0.5.3.tgz differ diff --git a/.yarn/offline-mirror/multicast-dns-7.2.5.tgz b/.yarn/offline-mirror/multicast-dns-7.2.5.tgz new file mode 100644 index 00000000000..3e1227b0c8a Binary files /dev/null and b/.yarn/offline-mirror/multicast-dns-7.2.5.tgz differ diff --git a/.yarn/offline-mirror/natural-compare-lite-1.4.0.tgz b/.yarn/offline-mirror/natural-compare-lite-1.4.0.tgz new file mode 100644 index 00000000000..789040638a4 Binary files /dev/null and b/.yarn/offline-mirror/natural-compare-lite-1.4.0.tgz differ diff --git a/.yarn/offline-mirror/node-forge-1.3.1.tgz b/.yarn/offline-mirror/node-forge-1.3.1.tgz new file mode 100644 index 00000000000..902dc85f847 Binary files /dev/null and b/.yarn/offline-mirror/node-forge-1.3.1.tgz differ diff --git a/.yarn/offline-mirror/node-gyp-8.4.1.tgz b/.yarn/offline-mirror/node-gyp-8.4.1.tgz new file mode 100644 index 00000000000..9feb263bf8c Binary files /dev/null and b/.yarn/offline-mirror/node-gyp-8.4.1.tgz differ diff --git a/.yarn/offline-mirror/node-sass-5.0.0.tgz b/.yarn/offline-mirror/node-sass-5.0.0.tgz deleted file mode 100644 index bf1dfd6ef41..00000000000 Binary files a/.yarn/offline-mirror/node-sass-5.0.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/node-sass-7.0.3.tgz b/.yarn/offline-mirror/node-sass-7.0.3.tgz new file mode 100644 index 00000000000..0792acc8a10 Binary files /dev/null and b/.yarn/offline-mirror/node-sass-7.0.3.tgz differ diff --git a/.yarn/offline-mirror/node-version-1.2.0.tgz b/.yarn/offline-mirror/node-version-1.2.0.tgz new file mode 100644 index 00000000000..9608ddc0d08 Binary files /dev/null and b/.yarn/offline-mirror/node-version-1.2.0.tgz differ diff --git a/.yarn/offline-mirror/normalize-url-3.3.0.tgz b/.yarn/offline-mirror/normalize-url-3.3.0.tgz deleted file mode 100644 index 3d7c6ab639a..00000000000 Binary files a/.yarn/offline-mirror/normalize-url-3.3.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/npm-run-path-5.1.0.tgz b/.yarn/offline-mirror/npm-run-path-5.1.0.tgz new file mode 100644 index 00000000000..07c9a209bad Binary files /dev/null and b/.yarn/offline-mirror/npm-run-path-5.1.0.tgz differ diff --git a/.yarn/offline-mirror/npmlog-6.0.2.tgz b/.yarn/offline-mirror/npmlog-6.0.2.tgz new file mode 100644 index 00000000000..764d22b5b1e Binary files /dev/null and b/.yarn/offline-mirror/npmlog-6.0.2.tgz differ diff --git a/.yarn/offline-mirror/obuf-1.1.2.tgz b/.yarn/offline-mirror/obuf-1.1.2.tgz new file mode 100644 index 00000000000..31709aa66bb Binary files /dev/null and b/.yarn/offline-mirror/obuf-1.1.2.tgz differ diff --git a/.yarn/offline-mirror/one-time-1.0.0.tgz b/.yarn/offline-mirror/one-time-1.0.0.tgz deleted file mode 100644 index 4a9690e2070..00000000000 Binary files a/.yarn/offline-mirror/one-time-1.0.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/onetime-6.0.0.tgz b/.yarn/offline-mirror/onetime-6.0.0.tgz new file mode 100644 index 00000000000..f7a844ed039 Binary files /dev/null and b/.yarn/offline-mirror/onetime-6.0.0.tgz differ diff --git a/.yarn/offline-mirror/p-cancelable-2.1.1.tgz b/.yarn/offline-mirror/p-cancelable-2.1.1.tgz deleted file mode 100644 index d13ef3f4122..00000000000 Binary files a/.yarn/offline-mirror/p-cancelable-2.1.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/p-retry-4.6.2.tgz b/.yarn/offline-mirror/p-retry-4.6.2.tgz new file mode 100644 index 00000000000..d601ba99a4e Binary files /dev/null and b/.yarn/offline-mirror/p-retry-4.6.2.tgz differ diff --git a/.yarn/offline-mirror/path-key-4.0.0.tgz b/.yarn/offline-mirror/path-key-4.0.0.tgz new file mode 100644 index 00000000000..765223947c0 Binary files /dev/null and b/.yarn/offline-mirror/path-key-4.0.0.tgz differ diff --git a/.yarn/offline-mirror/pidtree-0.6.0.tgz b/.yarn/offline-mirror/pidtree-0.6.0.tgz new file mode 100644 index 00000000000..b83f881b3ac Binary files /dev/null and b/.yarn/offline-mirror/pidtree-0.6.0.tgz differ diff --git a/.yarn/offline-mirror/playwright-1.25.2.tgz b/.yarn/offline-mirror/playwright-1.25.2.tgz new file mode 100644 index 00000000000..1829177ffb4 Binary files /dev/null and b/.yarn/offline-mirror/playwright-1.25.2.tgz differ diff --git a/.yarn/offline-mirror/playwright-core-1.25.2.tgz b/.yarn/offline-mirror/playwright-core-1.25.2.tgz new file mode 100644 index 00000000000..28b480c3bd8 Binary files /dev/null and b/.yarn/offline-mirror/playwright-core-1.25.2.tgz differ diff --git a/.yarn/offline-mirror/postcss-8.4.16.tgz b/.yarn/offline-mirror/postcss-8.4.16.tgz new file mode 100644 index 00000000000..007e88abfc2 Binary files /dev/null and b/.yarn/offline-mirror/postcss-8.4.16.tgz differ diff --git a/.yarn/offline-mirror/postcss-calc-7.0.5.tgz b/.yarn/offline-mirror/postcss-calc-7.0.5.tgz deleted file mode 100644 index 2e5e1cb58fd..00000000000 Binary files a/.yarn/offline-mirror/postcss-calc-7.0.5.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-calc-8.2.4.tgz b/.yarn/offline-mirror/postcss-calc-8.2.4.tgz new file mode 100644 index 00000000000..55f5aa19caa Binary files /dev/null and b/.yarn/offline-mirror/postcss-calc-8.2.4.tgz differ diff --git a/.yarn/offline-mirror/postcss-colormin-4.0.3.tgz b/.yarn/offline-mirror/postcss-colormin-4.0.3.tgz deleted file mode 100644 index 22ea0759569..00000000000 Binary files a/.yarn/offline-mirror/postcss-colormin-4.0.3.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-colormin-5.3.0.tgz b/.yarn/offline-mirror/postcss-colormin-5.3.0.tgz new file mode 100644 index 00000000000..9ed3801ecf9 Binary files /dev/null and b/.yarn/offline-mirror/postcss-colormin-5.3.0.tgz differ diff --git a/.yarn/offline-mirror/postcss-convert-values-4.0.1.tgz b/.yarn/offline-mirror/postcss-convert-values-4.0.1.tgz deleted file mode 100644 index 991991f18c2..00000000000 Binary files a/.yarn/offline-mirror/postcss-convert-values-4.0.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-convert-values-5.1.2.tgz b/.yarn/offline-mirror/postcss-convert-values-5.1.2.tgz new file mode 100644 index 00000000000..f99ae494265 Binary files /dev/null and b/.yarn/offline-mirror/postcss-convert-values-5.1.2.tgz differ diff --git a/.yarn/offline-mirror/postcss-discard-comments-4.0.2.tgz b/.yarn/offline-mirror/postcss-discard-comments-4.0.2.tgz deleted file mode 100644 index 08286b3c617..00000000000 Binary files a/.yarn/offline-mirror/postcss-discard-comments-4.0.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-discard-comments-5.1.2.tgz b/.yarn/offline-mirror/postcss-discard-comments-5.1.2.tgz new file mode 100644 index 00000000000..fbf11021122 Binary files /dev/null and b/.yarn/offline-mirror/postcss-discard-comments-5.1.2.tgz differ diff --git a/.yarn/offline-mirror/postcss-discard-duplicates-4.0.2.tgz b/.yarn/offline-mirror/postcss-discard-duplicates-4.0.2.tgz deleted file mode 100644 index fb0809c8c0d..00000000000 Binary files a/.yarn/offline-mirror/postcss-discard-duplicates-4.0.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-discard-duplicates-5.1.0.tgz b/.yarn/offline-mirror/postcss-discard-duplicates-5.1.0.tgz new file mode 100644 index 00000000000..26472661b5c Binary files /dev/null and b/.yarn/offline-mirror/postcss-discard-duplicates-5.1.0.tgz differ diff --git a/.yarn/offline-mirror/postcss-discard-empty-4.0.1.tgz b/.yarn/offline-mirror/postcss-discard-empty-4.0.1.tgz deleted file mode 100644 index a31e8d13209..00000000000 Binary files a/.yarn/offline-mirror/postcss-discard-empty-4.0.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-discard-empty-5.1.1.tgz b/.yarn/offline-mirror/postcss-discard-empty-5.1.1.tgz new file mode 100644 index 00000000000..96febf8b076 Binary files /dev/null and b/.yarn/offline-mirror/postcss-discard-empty-5.1.1.tgz differ diff --git a/.yarn/offline-mirror/postcss-discard-overridden-4.0.1.tgz b/.yarn/offline-mirror/postcss-discard-overridden-4.0.1.tgz deleted file mode 100644 index c34dec5137f..00000000000 Binary files a/.yarn/offline-mirror/postcss-discard-overridden-4.0.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-discard-overridden-5.1.0.tgz b/.yarn/offline-mirror/postcss-discard-overridden-5.1.0.tgz new file mode 100644 index 00000000000..c1a47abb929 Binary files /dev/null and b/.yarn/offline-mirror/postcss-discard-overridden-5.1.0.tgz differ diff --git a/.yarn/offline-mirror/postcss-load-config-3.1.4.tgz b/.yarn/offline-mirror/postcss-load-config-3.1.4.tgz new file mode 100644 index 00000000000..157bae2967e Binary files /dev/null and b/.yarn/offline-mirror/postcss-load-config-3.1.4.tgz differ diff --git a/.yarn/offline-mirror/postcss-merge-longhand-4.0.11.tgz b/.yarn/offline-mirror/postcss-merge-longhand-4.0.11.tgz deleted file mode 100644 index fb809a37f77..00000000000 Binary files a/.yarn/offline-mirror/postcss-merge-longhand-4.0.11.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-merge-longhand-5.1.6.tgz b/.yarn/offline-mirror/postcss-merge-longhand-5.1.6.tgz new file mode 100644 index 00000000000..faccc303fb2 Binary files /dev/null and b/.yarn/offline-mirror/postcss-merge-longhand-5.1.6.tgz differ diff --git a/.yarn/offline-mirror/postcss-merge-rules-4.0.3.tgz b/.yarn/offline-mirror/postcss-merge-rules-4.0.3.tgz deleted file mode 100644 index 02de7212c93..00000000000 Binary files a/.yarn/offline-mirror/postcss-merge-rules-4.0.3.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-merge-rules-5.1.2.tgz b/.yarn/offline-mirror/postcss-merge-rules-5.1.2.tgz new file mode 100644 index 00000000000..8b9ea253ae7 Binary files /dev/null and b/.yarn/offline-mirror/postcss-merge-rules-5.1.2.tgz differ diff --git a/.yarn/offline-mirror/postcss-minify-font-values-4.0.2.tgz b/.yarn/offline-mirror/postcss-minify-font-values-4.0.2.tgz deleted file mode 100644 index c89772ccba0..00000000000 Binary files a/.yarn/offline-mirror/postcss-minify-font-values-4.0.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-minify-font-values-5.1.0.tgz b/.yarn/offline-mirror/postcss-minify-font-values-5.1.0.tgz new file mode 100644 index 00000000000..63bf71e2cdf Binary files /dev/null and b/.yarn/offline-mirror/postcss-minify-font-values-5.1.0.tgz differ diff --git a/.yarn/offline-mirror/postcss-minify-gradients-4.0.2.tgz b/.yarn/offline-mirror/postcss-minify-gradients-4.0.2.tgz deleted file mode 100644 index d05bc4ead95..00000000000 Binary files a/.yarn/offline-mirror/postcss-minify-gradients-4.0.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-minify-gradients-5.1.1.tgz b/.yarn/offline-mirror/postcss-minify-gradients-5.1.1.tgz new file mode 100644 index 00000000000..21af4abd2dd Binary files /dev/null and b/.yarn/offline-mirror/postcss-minify-gradients-5.1.1.tgz differ diff --git a/.yarn/offline-mirror/postcss-minify-params-4.0.2.tgz b/.yarn/offline-mirror/postcss-minify-params-4.0.2.tgz deleted file mode 100644 index 4eebfbea6b4..00000000000 Binary files a/.yarn/offline-mirror/postcss-minify-params-4.0.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-minify-params-5.1.3.tgz b/.yarn/offline-mirror/postcss-minify-params-5.1.3.tgz new file mode 100644 index 00000000000..27553fa25bb Binary files /dev/null and b/.yarn/offline-mirror/postcss-minify-params-5.1.3.tgz differ diff --git a/.yarn/offline-mirror/postcss-minify-selectors-4.0.2.tgz b/.yarn/offline-mirror/postcss-minify-selectors-4.0.2.tgz deleted file mode 100644 index 8b9e4b1c8f2..00000000000 Binary files a/.yarn/offline-mirror/postcss-minify-selectors-4.0.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-minify-selectors-5.2.1.tgz b/.yarn/offline-mirror/postcss-minify-selectors-5.2.1.tgz new file mode 100644 index 00000000000..6fb24325bef Binary files /dev/null and b/.yarn/offline-mirror/postcss-minify-selectors-5.2.1.tgz differ diff --git a/.yarn/offline-mirror/postcss-normalize-charset-4.0.1.tgz b/.yarn/offline-mirror/postcss-normalize-charset-4.0.1.tgz deleted file mode 100644 index eea3ab13c1d..00000000000 Binary files a/.yarn/offline-mirror/postcss-normalize-charset-4.0.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-normalize-charset-5.1.0.tgz b/.yarn/offline-mirror/postcss-normalize-charset-5.1.0.tgz new file mode 100644 index 00000000000..b1b96b74c2d Binary files /dev/null and b/.yarn/offline-mirror/postcss-normalize-charset-5.1.0.tgz differ diff --git a/.yarn/offline-mirror/postcss-normalize-display-values-4.0.2.tgz b/.yarn/offline-mirror/postcss-normalize-display-values-4.0.2.tgz deleted file mode 100644 index 24b8795e31c..00000000000 Binary files a/.yarn/offline-mirror/postcss-normalize-display-values-4.0.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-normalize-display-values-5.1.0.tgz b/.yarn/offline-mirror/postcss-normalize-display-values-5.1.0.tgz new file mode 100644 index 00000000000..106f508f5de Binary files /dev/null and b/.yarn/offline-mirror/postcss-normalize-display-values-5.1.0.tgz differ diff --git a/.yarn/offline-mirror/postcss-normalize-positions-4.0.2.tgz b/.yarn/offline-mirror/postcss-normalize-positions-4.0.2.tgz deleted file mode 100644 index 9c7eb1653af..00000000000 Binary files a/.yarn/offline-mirror/postcss-normalize-positions-4.0.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-normalize-positions-5.1.1.tgz b/.yarn/offline-mirror/postcss-normalize-positions-5.1.1.tgz new file mode 100644 index 00000000000..d2c557d84d9 Binary files /dev/null and b/.yarn/offline-mirror/postcss-normalize-positions-5.1.1.tgz differ diff --git a/.yarn/offline-mirror/postcss-normalize-repeat-style-4.0.2.tgz b/.yarn/offline-mirror/postcss-normalize-repeat-style-4.0.2.tgz deleted file mode 100644 index 56dfb1ccb03..00000000000 Binary files a/.yarn/offline-mirror/postcss-normalize-repeat-style-4.0.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-normalize-repeat-style-5.1.1.tgz b/.yarn/offline-mirror/postcss-normalize-repeat-style-5.1.1.tgz new file mode 100644 index 00000000000..92d6efdc7c4 Binary files /dev/null and b/.yarn/offline-mirror/postcss-normalize-repeat-style-5.1.1.tgz differ diff --git a/.yarn/offline-mirror/postcss-normalize-string-4.0.2.tgz b/.yarn/offline-mirror/postcss-normalize-string-4.0.2.tgz deleted file mode 100644 index 112db52aa42..00000000000 Binary files a/.yarn/offline-mirror/postcss-normalize-string-4.0.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-normalize-string-5.1.0.tgz b/.yarn/offline-mirror/postcss-normalize-string-5.1.0.tgz new file mode 100644 index 00000000000..d32ae0cb43e Binary files /dev/null and b/.yarn/offline-mirror/postcss-normalize-string-5.1.0.tgz differ diff --git a/.yarn/offline-mirror/postcss-normalize-timing-functions-4.0.2.tgz b/.yarn/offline-mirror/postcss-normalize-timing-functions-4.0.2.tgz deleted file mode 100644 index 5f29937d6be..00000000000 Binary files a/.yarn/offline-mirror/postcss-normalize-timing-functions-4.0.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-normalize-timing-functions-5.1.0.tgz b/.yarn/offline-mirror/postcss-normalize-timing-functions-5.1.0.tgz new file mode 100644 index 00000000000..0dd9e6a4b57 Binary files /dev/null and b/.yarn/offline-mirror/postcss-normalize-timing-functions-5.1.0.tgz differ diff --git a/.yarn/offline-mirror/postcss-normalize-unicode-4.0.1.tgz b/.yarn/offline-mirror/postcss-normalize-unicode-4.0.1.tgz deleted file mode 100644 index a1ceaf1f78b..00000000000 Binary files a/.yarn/offline-mirror/postcss-normalize-unicode-4.0.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-normalize-unicode-5.1.0.tgz b/.yarn/offline-mirror/postcss-normalize-unicode-5.1.0.tgz new file mode 100644 index 00000000000..8e9947569ff Binary files /dev/null and b/.yarn/offline-mirror/postcss-normalize-unicode-5.1.0.tgz differ diff --git a/.yarn/offline-mirror/postcss-normalize-url-4.0.1.tgz b/.yarn/offline-mirror/postcss-normalize-url-4.0.1.tgz deleted file mode 100644 index 6a0ecdeb383..00000000000 Binary files a/.yarn/offline-mirror/postcss-normalize-url-4.0.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-normalize-url-5.1.0.tgz b/.yarn/offline-mirror/postcss-normalize-url-5.1.0.tgz new file mode 100644 index 00000000000..800e2d73081 Binary files /dev/null and b/.yarn/offline-mirror/postcss-normalize-url-5.1.0.tgz differ diff --git a/.yarn/offline-mirror/postcss-normalize-whitespace-4.0.2.tgz b/.yarn/offline-mirror/postcss-normalize-whitespace-4.0.2.tgz deleted file mode 100644 index 19f00fd1571..00000000000 Binary files a/.yarn/offline-mirror/postcss-normalize-whitespace-4.0.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-normalize-whitespace-5.1.1.tgz b/.yarn/offline-mirror/postcss-normalize-whitespace-5.1.1.tgz new file mode 100644 index 00000000000..1edab4fd6fd Binary files /dev/null and b/.yarn/offline-mirror/postcss-normalize-whitespace-5.1.1.tgz differ diff --git a/.yarn/offline-mirror/postcss-ordered-values-4.1.2.tgz b/.yarn/offline-mirror/postcss-ordered-values-4.1.2.tgz deleted file mode 100644 index d2925f07935..00000000000 Binary files a/.yarn/offline-mirror/postcss-ordered-values-4.1.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-ordered-values-5.1.3.tgz b/.yarn/offline-mirror/postcss-ordered-values-5.1.3.tgz new file mode 100644 index 00000000000..71b6e6a0ff6 Binary files /dev/null and b/.yarn/offline-mirror/postcss-ordered-values-5.1.3.tgz differ diff --git a/.yarn/offline-mirror/postcss-reduce-initial-4.0.3.tgz b/.yarn/offline-mirror/postcss-reduce-initial-4.0.3.tgz deleted file mode 100644 index 1c70514640a..00000000000 Binary files a/.yarn/offline-mirror/postcss-reduce-initial-4.0.3.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-reduce-initial-5.1.0.tgz b/.yarn/offline-mirror/postcss-reduce-initial-5.1.0.tgz new file mode 100644 index 00000000000..e4c4556c145 Binary files /dev/null and b/.yarn/offline-mirror/postcss-reduce-initial-5.1.0.tgz differ diff --git a/.yarn/offline-mirror/postcss-reduce-transforms-4.0.2.tgz b/.yarn/offline-mirror/postcss-reduce-transforms-4.0.2.tgz deleted file mode 100644 index b87f5fe58fe..00000000000 Binary files a/.yarn/offline-mirror/postcss-reduce-transforms-4.0.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-reduce-transforms-5.1.0.tgz b/.yarn/offline-mirror/postcss-reduce-transforms-5.1.0.tgz new file mode 100644 index 00000000000..8dac546d21e Binary files /dev/null and b/.yarn/offline-mirror/postcss-reduce-transforms-5.1.0.tgz differ diff --git a/.yarn/offline-mirror/postcss-svgo-4.0.3.tgz b/.yarn/offline-mirror/postcss-svgo-4.0.3.tgz deleted file mode 100644 index 1ac7347cd38..00000000000 Binary files a/.yarn/offline-mirror/postcss-svgo-4.0.3.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-svgo-5.1.0.tgz b/.yarn/offline-mirror/postcss-svgo-5.1.0.tgz new file mode 100644 index 00000000000..490964a85da Binary files /dev/null and b/.yarn/offline-mirror/postcss-svgo-5.1.0.tgz differ diff --git a/.yarn/offline-mirror/postcss-unique-selectors-4.0.1.tgz b/.yarn/offline-mirror/postcss-unique-selectors-4.0.1.tgz deleted file mode 100644 index d3e70ec22ee..00000000000 Binary files a/.yarn/offline-mirror/postcss-unique-selectors-4.0.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/postcss-unique-selectors-5.1.1.tgz b/.yarn/offline-mirror/postcss-unique-selectors-5.1.1.tgz new file mode 100644 index 00000000000..543b7758c29 Binary files /dev/null and b/.yarn/offline-mirror/postcss-unique-selectors-5.1.1.tgz differ diff --git a/.yarn/offline-mirror/preact-render-to-string-5.2.5.tgz b/.yarn/offline-mirror/preact-render-to-string-5.2.5.tgz deleted file mode 100644 index d6b9e0d32c1..00000000000 Binary files a/.yarn/offline-mirror/preact-render-to-string-5.2.5.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/preact-render-to-string-5.2.6.tgz b/.yarn/offline-mirror/preact-render-to-string-5.2.6.tgz new file mode 100644 index 00000000000..ad14899d651 Binary files /dev/null and b/.yarn/offline-mirror/preact-render-to-string-5.2.6.tgz differ diff --git a/.yarn/offline-mirror/prettier-2.7.1.tgz b/.yarn/offline-mirror/prettier-2.7.1.tgz new file mode 100644 index 00000000000..04668e7d396 Binary files /dev/null and b/.yarn/offline-mirror/prettier-2.7.1.tgz differ diff --git a/.yarn/offline-mirror/pretty-format-27.5.1.tgz b/.yarn/offline-mirror/pretty-format-27.5.1.tgz new file mode 100644 index 00000000000..2559db7cf42 Binary files /dev/null and b/.yarn/offline-mirror/pretty-format-27.5.1.tgz differ diff --git a/.yarn/offline-mirror/pretty-format-29.2.0.tgz b/.yarn/offline-mirror/pretty-format-29.2.0.tgz deleted file mode 100644 index bf51778e118..00000000000 Binary files a/.yarn/offline-mirror/pretty-format-29.2.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/pretty-format-29.2.1.tgz b/.yarn/offline-mirror/pretty-format-29.2.1.tgz new file mode 100644 index 00000000000..a1a7dd15947 Binary files /dev/null and b/.yarn/offline-mirror/pretty-format-29.2.1.tgz differ diff --git a/.yarn/offline-mirror/promise-polyfill-6.1.0.tgz b/.yarn/offline-mirror/promise-polyfill-6.1.0.tgz new file mode 100644 index 00000000000..ae9b6c6adc4 Binary files /dev/null and b/.yarn/offline-mirror/promise-polyfill-6.1.0.tgz differ diff --git a/.yarn/offline-mirror/proxy-from-env-1.1.0.tgz b/.yarn/offline-mirror/proxy-from-env-1.1.0.tgz new file mode 100644 index 00000000000..342c2696bd6 Binary files /dev/null and b/.yarn/offline-mirror/proxy-from-env-1.1.0.tgz differ diff --git a/.yarn/offline-mirror/pseudomap-1.0.2.tgz b/.yarn/offline-mirror/pseudomap-1.0.2.tgz new file mode 100644 index 00000000000..5358cd4db79 Binary files /dev/null and b/.yarn/offline-mirror/pseudomap-1.0.2.tgz differ diff --git a/.yarn/offline-mirror/puppeteer-13.7.0.tgz b/.yarn/offline-mirror/puppeteer-13.7.0.tgz new file mode 100644 index 00000000000..3a9742d39f4 Binary files /dev/null and b/.yarn/offline-mirror/puppeteer-13.7.0.tgz differ diff --git a/.yarn/offline-mirror/qs-6.10.3.tgz b/.yarn/offline-mirror/qs-6.10.3.tgz new file mode 100644 index 00000000000..e2a72995246 Binary files /dev/null and b/.yarn/offline-mirror/qs-6.10.3.tgz differ diff --git a/.yarn/offline-mirror/quick-lru-5.1.1.tgz b/.yarn/offline-mirror/quick-lru-5.1.1.tgz deleted file mode 100644 index faf5ed65f9d..00000000000 Binary files a/.yarn/offline-mirror/quick-lru-5.1.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/ramda-0.27.2.tgz b/.yarn/offline-mirror/ramda-0.27.2.tgz new file mode 100644 index 00000000000..518d397b4b3 Binary files /dev/null and b/.yarn/offline-mirror/ramda-0.27.2.tgz differ diff --git a/.yarn/offline-mirror/react-16.9.0.tgz b/.yarn/offline-mirror/react-16.9.0.tgz deleted file mode 100644 index 0e82cf4e2d1..00000000000 Binary files a/.yarn/offline-mirror/react-16.9.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/react-dom-16.9.0.tgz b/.yarn/offline-mirror/react-dom-16.9.0.tgz deleted file mode 100644 index 37e085ad3dc..00000000000 Binary files a/.yarn/offline-mirror/react-dom-16.9.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/regenerator-runtime-0.13.11.tgz b/.yarn/offline-mirror/regenerator-runtime-0.13.11.tgz new file mode 100644 index 00000000000..93dcda996d9 Binary files /dev/null and b/.yarn/offline-mirror/regenerator-runtime-0.13.11.tgz differ diff --git a/.yarn/offline-mirror/regextras-0.7.1.tgz b/.yarn/offline-mirror/regextras-0.7.1.tgz deleted file mode 100644 index 6e960ff6f9e..00000000000 Binary files a/.yarn/offline-mirror/regextras-0.7.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/resolve-alpn-1.2.1.tgz b/.yarn/offline-mirror/resolve-alpn-1.2.1.tgz deleted file mode 100644 index b76c44195c5..00000000000 Binary files a/.yarn/offline-mirror/resolve-alpn-1.2.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/resolve-dir-0.1.1.tgz b/.yarn/offline-mirror/resolve-dir-0.1.1.tgz new file mode 100644 index 00000000000..ed6603c56f5 Binary files /dev/null and b/.yarn/offline-mirror/resolve-dir-0.1.1.tgz differ diff --git a/.yarn/offline-mirror/responselike-2.0.1.tgz b/.yarn/offline-mirror/responselike-2.0.1.tgz deleted file mode 100644 index b7f3dc8e9e0..00000000000 Binary files a/.yarn/offline-mirror/responselike-2.0.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/retry-0.13.1.tgz b/.yarn/offline-mirror/retry-0.13.1.tgz new file mode 100644 index 00000000000..4b42c6e852f Binary files /dev/null and b/.yarn/offline-mirror/retry-0.13.1.tgz differ diff --git a/.yarn/offline-mirror/rgb-regex-1.0.1.tgz b/.yarn/offline-mirror/rgb-regex-1.0.1.tgz deleted file mode 100644 index 1c1ffc301ac..00000000000 Binary files a/.yarn/offline-mirror/rgb-regex-1.0.1.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/rgba-regex-1.0.0.tgz b/.yarn/offline-mirror/rgba-regex-1.0.0.tgz deleted file mode 100644 index 73733b20f7c..00000000000 Binary files a/.yarn/offline-mirror/rgba-regex-1.0.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/rtlcss-3.5.0.tgz b/.yarn/offline-mirror/rtlcss-3.5.0.tgz new file mode 100644 index 00000000000..f8b915e9f1d Binary files /dev/null and b/.yarn/offline-mirror/rtlcss-3.5.0.tgz differ diff --git a/.yarn/offline-mirror/rx-4.1.0.tgz b/.yarn/offline-mirror/rx-4.1.0.tgz new file mode 100644 index 00000000000..4b03f848c8f Binary files /dev/null and b/.yarn/offline-mirror/rx-4.1.0.tgz differ diff --git a/.yarn/offline-mirror/rxjs-7.5.6.tgz b/.yarn/offline-mirror/rxjs-7.5.6.tgz new file mode 100644 index 00000000000..70c9a7055a6 Binary files /dev/null and b/.yarn/offline-mirror/rxjs-7.5.6.tgz differ diff --git a/.yarn/offline-mirror/safe-stable-stringify-2.4.0.tgz b/.yarn/offline-mirror/safe-stable-stringify-2.4.0.tgz deleted file mode 100644 index c4078b01068..00000000000 Binary files a/.yarn/offline-mirror/safe-stable-stringify-2.4.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/sass-1.57.0.tgz b/.yarn/offline-mirror/sass-1.57.0.tgz new file mode 100644 index 00000000000..0407ed05050 Binary files /dev/null and b/.yarn/offline-mirror/sass-1.57.0.tgz differ diff --git a/.yarn/offline-mirror/sass-graph-2.2.5.tgz b/.yarn/offline-mirror/sass-graph-2.2.5.tgz deleted file mode 100644 index 15e4abf1f21..00000000000 Binary files a/.yarn/offline-mirror/sass-graph-2.2.5.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/sass-graph-4.0.1.tgz b/.yarn/offline-mirror/sass-graph-4.0.1.tgz new file mode 100644 index 00000000000..beec98f7e43 Binary files /dev/null and b/.yarn/offline-mirror/sass-graph-4.0.1.tgz differ diff --git a/.yarn/offline-mirror/saxes-5.0.1.tgz b/.yarn/offline-mirror/saxes-5.0.1.tgz new file mode 100644 index 00000000000..cd8d3e19996 Binary files /dev/null and b/.yarn/offline-mirror/saxes-5.0.1.tgz differ diff --git a/.yarn/offline-mirror/scheduler-0.15.0.tgz b/.yarn/offline-mirror/scheduler-0.15.0.tgz deleted file mode 100644 index 83d5a8043b9..00000000000 Binary files a/.yarn/offline-mirror/scheduler-0.15.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/schema-utils-4.0.0.tgz b/.yarn/offline-mirror/schema-utils-4.0.0.tgz new file mode 100644 index 00000000000..471080b68d7 Binary files /dev/null and b/.yarn/offline-mirror/schema-utils-4.0.0.tgz differ diff --git a/.yarn/offline-mirror/scss-tokenizer-0.2.3.tgz b/.yarn/offline-mirror/scss-tokenizer-0.2.3.tgz deleted file mode 100644 index b6f1c41879e..00000000000 Binary files a/.yarn/offline-mirror/scss-tokenizer-0.2.3.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/scss-tokenizer-0.4.3.tgz b/.yarn/offline-mirror/scss-tokenizer-0.4.3.tgz new file mode 100644 index 00000000000..967ce60b4b6 Binary files /dev/null and b/.yarn/offline-mirror/scss-tokenizer-0.4.3.tgz differ diff --git a/.yarn/offline-mirror/select-hose-2.0.0.tgz b/.yarn/offline-mirror/select-hose-2.0.0.tgz new file mode 100644 index 00000000000..1a4c335c7e4 Binary files /dev/null and b/.yarn/offline-mirror/select-hose-2.0.0.tgz differ diff --git a/.yarn/offline-mirror/selfsigned-2.1.1.tgz b/.yarn/offline-mirror/selfsigned-2.1.1.tgz new file mode 100644 index 00000000000..ea036576391 Binary files /dev/null and b/.yarn/offline-mirror/selfsigned-2.1.1.tgz differ diff --git a/.yarn/offline-mirror/serve-index-1.9.1.tgz b/.yarn/offline-mirror/serve-index-1.9.1.tgz new file mode 100644 index 00000000000..a21cba17826 Binary files /dev/null and b/.yarn/offline-mirror/serve-index-1.9.1.tgz differ diff --git a/.yarn/offline-mirror/setprototypeof-1.1.0.tgz b/.yarn/offline-mirror/setprototypeof-1.1.0.tgz new file mode 100644 index 00000000000..e3759ec8a19 Binary files /dev/null and b/.yarn/offline-mirror/setprototypeof-1.1.0.tgz differ diff --git a/.yarn/offline-mirror/shallow-clone-0.1.2.tgz b/.yarn/offline-mirror/shallow-clone-0.1.2.tgz new file mode 100644 index 00000000000..e5e35dd3f93 Binary files /dev/null and b/.yarn/offline-mirror/shallow-clone-0.1.2.tgz differ diff --git a/.yarn/offline-mirror/sockjs-0.3.24.tgz b/.yarn/offline-mirror/sockjs-0.3.24.tgz new file mode 100644 index 00000000000..67298468e96 Binary files /dev/null and b/.yarn/offline-mirror/sockjs-0.3.24.tgz differ diff --git a/.yarn/offline-mirror/source-map-0.4.4.tgz b/.yarn/offline-mirror/source-map-0.4.4.tgz deleted file mode 100644 index 5fd81d6df8d..00000000000 Binary files a/.yarn/offline-mirror/source-map-0.4.4.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/source-map-resolve-0.6.0.tgz b/.yarn/offline-mirror/source-map-resolve-0.6.0.tgz new file mode 100644 index 00000000000..127e1f7f91f Binary files /dev/null and b/.yarn/offline-mirror/source-map-resolve-0.6.0.tgz differ diff --git a/.yarn/offline-mirror/spawnd-4.4.0.tgz b/.yarn/offline-mirror/spawnd-4.4.0.tgz new file mode 100644 index 00000000000..570bb401b6f Binary files /dev/null and b/.yarn/offline-mirror/spawnd-4.4.0.tgz differ diff --git a/.yarn/offline-mirror/spawnd-6.0.2.tgz b/.yarn/offline-mirror/spawnd-6.0.2.tgz new file mode 100644 index 00000000000..025a057de40 Binary files /dev/null and b/.yarn/offline-mirror/spawnd-6.0.2.tgz differ diff --git a/.yarn/offline-mirror/spdy-4.0.2.tgz b/.yarn/offline-mirror/spdy-4.0.2.tgz new file mode 100644 index 00000000000..39a66990e1f Binary files /dev/null and b/.yarn/offline-mirror/spdy-4.0.2.tgz differ diff --git a/.yarn/offline-mirror/spdy-transport-3.0.0.tgz b/.yarn/offline-mirror/spdy-transport-3.0.0.tgz new file mode 100644 index 00000000000..702e7c8d1c5 Binary files /dev/null and b/.yarn/offline-mirror/spdy-transport-3.0.0.tgz differ diff --git a/.yarn/offline-mirror/strip-final-newline-3.0.0.tgz b/.yarn/offline-mirror/strip-final-newline-3.0.0.tgz new file mode 100644 index 00000000000..cddc422d216 Binary files /dev/null and b/.yarn/offline-mirror/strip-final-newline-3.0.0.tgz differ diff --git a/.yarn/offline-mirror/stylehacks-4.0.3.tgz b/.yarn/offline-mirror/stylehacks-4.0.3.tgz deleted file mode 100644 index 5628edd7c6c..00000000000 Binary files a/.yarn/offline-mirror/stylehacks-4.0.3.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/stylehacks-5.1.0.tgz b/.yarn/offline-mirror/stylehacks-5.1.0.tgz new file mode 100644 index 00000000000..7d12761c586 Binary files /dev/null and b/.yarn/offline-mirror/stylehacks-5.1.0.tgz differ diff --git a/.yarn/offline-mirror/svgo-2.8.0.tgz b/.yarn/offline-mirror/svgo-2.8.0.tgz new file mode 100644 index 00000000000..11cff526657 Binary files /dev/null and b/.yarn/offline-mirror/svgo-2.8.0.tgz differ diff --git a/.yarn/offline-mirror/tar-6.1.13.tgz b/.yarn/offline-mirror/tar-6.1.13.tgz new file mode 100644 index 00000000000..bc3d3c6b1e2 Binary files /dev/null and b/.yarn/offline-mirror/tar-6.1.13.tgz differ diff --git a/.yarn/offline-mirror/tar-fs-2.1.1.tgz b/.yarn/offline-mirror/tar-fs-2.1.1.tgz new file mode 100644 index 00000000000..1eedb5b94a9 Binary files /dev/null and b/.yarn/offline-mirror/tar-fs-2.1.1.tgz differ diff --git a/.yarn/offline-mirror/ternary-stream-3.0.0.tgz b/.yarn/offline-mirror/ternary-stream-3.0.0.tgz new file mode 100644 index 00000000000..f068f0aa0f8 Binary files /dev/null and b/.yarn/offline-mirror/ternary-stream-3.0.0.tgz differ diff --git a/.yarn/offline-mirror/text-hex-1.0.0.tgz b/.yarn/offline-mirror/text-hex-1.0.0.tgz deleted file mode 100644 index db8cea7a086..00000000000 Binary files a/.yarn/offline-mirror/text-hex-1.0.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/thunky-1.1.0.tgz b/.yarn/offline-mirror/thunky-1.1.0.tgz new file mode 100644 index 00000000000..7e572b17bbe Binary files /dev/null and b/.yarn/offline-mirror/thunky-1.1.0.tgz differ diff --git a/.yarn/offline-mirror/timsort-0.3.0.tgz b/.yarn/offline-mirror/timsort-0.3.0.tgz deleted file mode 100644 index 2d2a3fc24f7..00000000000 Binary files a/.yarn/offline-mirror/timsort-0.3.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/tree-kill-1.2.2.tgz b/.yarn/offline-mirror/tree-kill-1.2.2.tgz new file mode 100644 index 00000000000..d21dd84dd90 Binary files /dev/null and b/.yarn/offline-mirror/tree-kill-1.2.2.tgz differ diff --git a/.yarn/offline-mirror/triple-beam-1.3.0.tgz b/.yarn/offline-mirror/triple-beam-1.3.0.tgz deleted file mode 100644 index f93024e6e86..00000000000 Binary files a/.yarn/offline-mirror/triple-beam-1.3.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/ts-loader-6.2.2.tgz b/.yarn/offline-mirror/ts-loader-6.2.2.tgz new file mode 100644 index 00000000000..32e8aace7f9 Binary files /dev/null and b/.yarn/offline-mirror/ts-loader-6.2.2.tgz differ diff --git a/.yarn/offline-mirror/tsickle-0.46.3.tgz b/.yarn/offline-mirror/tsickle-0.46.3.tgz new file mode 100644 index 00000000000..37e35dd499b Binary files /dev/null and b/.yarn/offline-mirror/tsickle-0.46.3.tgz differ diff --git a/.yarn/offline-mirror/uglify-js-3.17.0.tgz b/.yarn/offline-mirror/uglify-js-3.17.0.tgz deleted file mode 100644 index fa5d5fb09ed..00000000000 Binary files a/.yarn/offline-mirror/uglify-js-3.17.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/uglify-js-3.17.3.tgz b/.yarn/offline-mirror/uglify-js-3.17.3.tgz deleted file mode 100644 index 983ebfeed6f..00000000000 Binary files a/.yarn/offline-mirror/uglify-js-3.17.3.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/uglify-js-3.17.4.tgz b/.yarn/offline-mirror/uglify-js-3.17.4.tgz new file mode 100644 index 00000000000..dfa47d17b07 Binary files /dev/null and b/.yarn/offline-mirror/uglify-js-3.17.4.tgz differ diff --git a/.yarn/offline-mirror/unbzip2-stream-1.4.3.tgz b/.yarn/offline-mirror/unbzip2-stream-1.4.3.tgz new file mode 100644 index 00000000000..87e59c2e2cd Binary files /dev/null and b/.yarn/offline-mirror/unbzip2-stream-1.4.3.tgz differ diff --git a/.yarn/offline-mirror/uniqs-2.0.0.tgz b/.yarn/offline-mirror/uniqs-2.0.0.tgz deleted file mode 100644 index 60c296e445d..00000000000 Binary files a/.yarn/offline-mirror/uniqs-2.0.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/url-join-4.0.1.tgz b/.yarn/offline-mirror/url-join-4.0.1.tgz new file mode 100644 index 00000000000..9b2fac8e73a Binary files /dev/null and b/.yarn/offline-mirror/url-join-4.0.1.tgz differ diff --git a/.yarn/offline-mirror/use-debounce-3.4.3.tgz b/.yarn/offline-mirror/use-debounce-3.4.3.tgz new file mode 100644 index 00000000000..63c8b13c089 Binary files /dev/null and b/.yarn/offline-mirror/use-debounce-3.4.3.tgz differ diff --git a/.yarn/offline-mirror/vendors-1.0.4.tgz b/.yarn/offline-mirror/vendors-1.0.4.tgz deleted file mode 100644 index 2e2c03aaa0b..00000000000 Binary files a/.yarn/offline-mirror/vendors-1.0.4.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/vfile-message-3.1.2.tgz b/.yarn/offline-mirror/vfile-message-3.1.2.tgz deleted file mode 100644 index 9a22ad71598..00000000000 Binary files a/.yarn/offline-mirror/vfile-message-3.1.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/vfile-message-3.1.3.tgz b/.yarn/offline-mirror/vfile-message-3.1.3.tgz new file mode 100644 index 00000000000..e23efc6d8e6 Binary files /dev/null and b/.yarn/offline-mirror/vfile-message-3.1.3.tgz differ diff --git a/.yarn/offline-mirror/w3c-xmlserializer-2.0.0.tgz b/.yarn/offline-mirror/w3c-xmlserializer-2.0.0.tgz new file mode 100644 index 00000000000..af8bbc3cde3 Binary files /dev/null and b/.yarn/offline-mirror/w3c-xmlserializer-2.0.0.tgz differ diff --git a/.yarn/offline-mirror/w3c-xmlserializer-3.0.0.tgz b/.yarn/offline-mirror/w3c-xmlserializer-3.0.0.tgz deleted file mode 100644 index c7fe0ad9af4..00000000000 Binary files a/.yarn/offline-mirror/w3c-xmlserializer-3.0.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/w3c-xmlserializer-4.0.0.tgz b/.yarn/offline-mirror/w3c-xmlserializer-4.0.0.tgz new file mode 100644 index 00000000000..957975005f6 Binary files /dev/null and b/.yarn/offline-mirror/w3c-xmlserializer-4.0.0.tgz differ diff --git a/.yarn/offline-mirror/wait-on-3.3.0.tgz b/.yarn/offline-mirror/wait-on-3.3.0.tgz new file mode 100644 index 00000000000..74e1c09bb9e Binary files /dev/null and b/.yarn/offline-mirror/wait-on-3.3.0.tgz differ diff --git a/.yarn/offline-mirror/wait-on-6.0.1.tgz b/.yarn/offline-mirror/wait-on-6.0.1.tgz new file mode 100644 index 00000000000..31b2f592bf2 Binary files /dev/null and b/.yarn/offline-mirror/wait-on-6.0.1.tgz differ diff --git a/.yarn/offline-mirror/wait-port-0.2.14.tgz b/.yarn/offline-mirror/wait-port-0.2.14.tgz new file mode 100644 index 00000000000..f68aa56450d Binary files /dev/null and b/.yarn/offline-mirror/wait-port-0.2.14.tgz differ diff --git a/.yarn/offline-mirror/wbuf-1.7.3.tgz b/.yarn/offline-mirror/wbuf-1.7.3.tgz new file mode 100644 index 00000000000..5403b0ed3ae Binary files /dev/null and b/.yarn/offline-mirror/wbuf-1.7.3.tgz differ diff --git a/.yarn/offline-mirror/webidl-conversions-5.0.0.tgz b/.yarn/offline-mirror/webidl-conversions-5.0.0.tgz new file mode 100644 index 00000000000..0a0511a742b Binary files /dev/null and b/.yarn/offline-mirror/webidl-conversions-5.0.0.tgz differ diff --git a/.yarn/offline-mirror/webpack-5.75.0.tgz b/.yarn/offline-mirror/webpack-5.75.0.tgz new file mode 100644 index 00000000000..4c8e07b25fd Binary files /dev/null and b/.yarn/offline-mirror/webpack-5.75.0.tgz differ diff --git a/.yarn/offline-mirror/webpack-dev-middleware-5.3.3.tgz b/.yarn/offline-mirror/webpack-dev-middleware-5.3.3.tgz new file mode 100644 index 00000000000..afbf414a526 Binary files /dev/null and b/.yarn/offline-mirror/webpack-dev-middleware-5.3.3.tgz differ diff --git a/.yarn/offline-mirror/webpack-dev-server-4.11.0.tgz b/.yarn/offline-mirror/webpack-dev-server-4.11.0.tgz new file mode 100644 index 00000000000..2cfcd76ee9f Binary files /dev/null and b/.yarn/offline-mirror/webpack-dev-server-4.11.0.tgz differ diff --git a/.yarn/offline-mirror/webpack-virtual-modules-0.4.5.tgz b/.yarn/offline-mirror/webpack-virtual-modules-0.4.5.tgz deleted file mode 100644 index 748b0aa55a6..00000000000 Binary files a/.yarn/offline-mirror/webpack-virtual-modules-0.4.5.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/webpack-virtual-modules-0.4.6.tgz b/.yarn/offline-mirror/webpack-virtual-modules-0.4.6.tgz new file mode 100644 index 00000000000..a22c0f684b5 Binary files /dev/null and b/.yarn/offline-mirror/webpack-virtual-modules-0.4.6.tgz differ diff --git a/.yarn/offline-mirror/websocket-driver-0.7.4.tgz b/.yarn/offline-mirror/websocket-driver-0.7.4.tgz new file mode 100644 index 00000000000..0ecfe541101 Binary files /dev/null and b/.yarn/offline-mirror/websocket-driver-0.7.4.tgz differ diff --git a/.yarn/offline-mirror/websocket-extensions-0.1.4.tgz b/.yarn/offline-mirror/websocket-extensions-0.1.4.tgz new file mode 100644 index 00000000000..6f296520b04 Binary files /dev/null and b/.yarn/offline-mirror/websocket-extensions-0.1.4.tgz differ diff --git a/.yarn/offline-mirror/winston-3.8.2.tgz b/.yarn/offline-mirror/winston-3.8.2.tgz deleted file mode 100644 index 1471b584137..00000000000 Binary files a/.yarn/offline-mirror/winston-3.8.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/winston-transport-4.5.0.tgz b/.yarn/offline-mirror/winston-transport-4.5.0.tgz deleted file mode 100644 index 04a38c425c4..00000000000 Binary files a/.yarn/offline-mirror/winston-transport-4.5.0.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/ws-8.12.0.tgz b/.yarn/offline-mirror/ws-8.12.0.tgz new file mode 100644 index 00000000000..22872a59b1f Binary files /dev/null and b/.yarn/offline-mirror/ws-8.12.0.tgz differ diff --git a/.yarn/offline-mirror/ws-8.5.0.tgz b/.yarn/offline-mirror/ws-8.5.0.tgz new file mode 100644 index 00000000000..3026cf23539 Binary files /dev/null and b/.yarn/offline-mirror/ws-8.5.0.tgz differ diff --git a/.yarn/offline-mirror/ws-8.8.1.tgz b/.yarn/offline-mirror/ws-8.8.1.tgz new file mode 100644 index 00000000000..14befaaa5ea Binary files /dev/null and b/.yarn/offline-mirror/ws-8.8.1.tgz differ diff --git a/.yarn/offline-mirror/yallist-2.1.2.tgz b/.yarn/offline-mirror/yallist-2.1.2.tgz new file mode 100644 index 00000000000..0e8111e75a7 Binary files /dev/null and b/.yarn/offline-mirror/yallist-2.1.2.tgz differ diff --git a/.yarn/offline-mirror/yargs-13.3.2.tgz b/.yarn/offline-mirror/yargs-13.3.2.tgz deleted file mode 100644 index 14784c3e0d9..00000000000 Binary files a/.yarn/offline-mirror/yargs-13.3.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/yargs-17.6.2.tgz b/.yarn/offline-mirror/yargs-17.6.2.tgz new file mode 100644 index 00000000000..3baf730d45a Binary files /dev/null and b/.yarn/offline-mirror/yargs-17.6.2.tgz differ diff --git a/.yarn/offline-mirror/yargs-parser-13.1.2.tgz b/.yarn/offline-mirror/yargs-parser-13.1.2.tgz deleted file mode 100644 index 7abcef40811..00000000000 Binary files a/.yarn/offline-mirror/yargs-parser-13.1.2.tgz and /dev/null differ diff --git a/.yarn/offline-mirror/zone.js-0.12.0.tgz b/.yarn/offline-mirror/zone.js-0.12.0.tgz new file mode 100644 index 00000000000..ff360c95140 Binary files /dev/null and b/.yarn/offline-mirror/zone.js-0.12.0.tgz differ diff --git a/gulp-tasks/lint.js b/gulp-tasks/lint.js index 6d93ce31403..93027a97300 100644 --- a/gulp-tasks/lint.js +++ b/gulp-tasks/lint.js @@ -1,5 +1,5 @@ /** - * Copyright IBM Corp. 2020, 2021 + * Copyright IBM Corp. 2020, 2022 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. @@ -35,7 +35,7 @@ const gulpCheckLicense = () => { } done(null, file); }, - done => { + (done) => { if (filesWithError.length > 0) { done( new Error( diff --git a/package.json b/package.json index 206bce9a107..b356ef0a67e 100644 --- a/package.json +++ b/package.json @@ -20,8 +20,8 @@ "ci-check": "npm run format:diff && yarn lint:license && yarn lint && yarn lint:styles", "clean": "lerna run clean && lerna clean --yes && rimraf node_modules", "doctoc": "doctoc --title '## Table of Contents' docs", - "format": "prettier --write '**/*.{js,md,scss}'", - "format:diff": "prettier --list-different '**/*.{js,md,scss}'", + "format": "prettier --cache --write '**/*.{js,md,scss,ts}'", + "format:diff": "prettier --cache --list-different '**/*.{js,md,scss,ts}'", "lint": "eslint packages", "lint:license": "gulp lint:license", "lint:license:staged": "tasks/check-license.js -w", @@ -59,11 +59,6 @@ "doctoc": "^2.0.0", "enzyme-to-json": "^3.3.5", "eslint": "^6.8.0", - "eslint-plugin-babel": "^5.3.0", - "eslint-plugin-jsdoc": "^24.0.0", - "eslint-plugin-jsx-a11y": "^6.2.3", - "eslint-plugin-react": "^7.19.0", - "eslint-plugin-react-hooks": "^3.0.0", "gitignore-to-glob": "^0.3.0", "globby": "^10.0.0", "gulp": "^4.0.0", @@ -73,10 +68,10 @@ "jest-circus": "25.5.4", "jest-junit": "^6.4.0", "lerna": "^4.0.0", - "lint-staged": "^12.3.8", + "lint-staged": "^13.0.3", "node-fetch": "^2.6.0", - "prettier": "^1.17.0", - "react": "16.9.0", + "prettier": "^2.7.1", + "react": "16.14.0", "rimraf": "^2.6.3", "sass": "^1.19.0", "stylelint": "^10.1.0", diff --git a/packages/carbon-web-components/.babelrc b/packages/carbon-web-components/.babelrc new file mode 100644 index 00000000000..a35b94a04d3 --- /dev/null +++ b/packages/carbon-web-components/.babelrc @@ -0,0 +1,11 @@ +{ + "plugins": [ + "@babel/plugin-transform-typescript", + "@babel/plugin-proposal-class-properties", + ["@babel/plugin-proposal-decorators", { "decoratorsBeforeExport": true }], + "@babel/plugin-proposal-nullish-coalescing-operator", + ["@babel/plugin-proposal-object-rest-spread", { "useBuiltIns": true }], + "@babel/plugin-proposal-optional-chaining", + ["@babel/plugin-transform-runtime", { "useESModules": true, "version": "7.8.0" }] + ] +} diff --git a/packages/carbon-web-components/.cfignore b/packages/carbon-web-components/.cfignore new file mode 100644 index 00000000000..f33b593b5da --- /dev/null +++ b/packages/carbon-web-components/.cfignore @@ -0,0 +1,3 @@ +* +!Staticfile +!storybook-static/ diff --git a/packages/carbon-web-components/.editorconfig b/packages/carbon-web-components/.editorconfig new file mode 100644 index 00000000000..3fd345c8adb --- /dev/null +++ b/packages/carbon-web-components/.editorconfig @@ -0,0 +1,14 @@ +root = true + +[*] + +indent_style = space +indent_size = 2 + +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/packages/carbon-web-components/.eslintignore b/packages/carbon-web-components/.eslintignore new file mode 100644 index 00000000000..f8247477112 --- /dev/null +++ b/packages/carbon-web-components/.eslintignore @@ -0,0 +1,9 @@ +*.d.ts +.yarn +dist +docs/js +es +lib +node_modules +tests/coverage +examples diff --git a/packages/carbon-web-components/.eslintrc.js b/packages/carbon-web-components/.eslintrc.js new file mode 100644 index 00000000000..daae3767316 --- /dev/null +++ b/packages/carbon-web-components/.eslintrc.js @@ -0,0 +1,173 @@ +/** + * @license + * + * Copyright IBM Corp. 2020, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +'use strict'; + +const restrictedGlobals = require('eslint-restricted-globals'); + +module.exports = { + parser: 'babel-eslint', + parserOptions: { + ecmaVersion: 6, + sourceType: 'script', + }, + extends: ['../eslint-config-ibmdotcom'], + env: { + node: true, + es6: true, + }, + rules: { + 'no-restricted-globals': ['error', 'isFinite'].concat(restrictedGlobals), + // 'no-unused-expressions': 0, + // 'babel/no-unused-expressions': 2, + 'import/extensions': 0, + // 'import/no-extraneous-dependencies': [ + // 2, + // { + // devDependencies: true, + // optionalDependencies: true, + // peerDependencies: false, + // }, + // ], + // 'import/no-unresolved': [2, { ignore: ['^carbon-web-components/es/icons/'] }], + }, + settings: { + 'import/resolver': { + node: { + extensions: ['.js', '.ts', '.tsx', '.d.ts'], + }, + }, + }, + overrides: [ + { + files: ['**/*.ts'], + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint'], + rules: { + 'no-unused-vars': 0, + '@typescript-eslint/no-unused-vars': 0, + 'jsdoc/require-param-type': 0, + 'jsdoc/require-returns-type': 0, + 'no-undef': 0, + }, + }, + { + files: ['**/*.tsx', '**/components-react/**/*-container.ts'], + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint', 'react'], + rules: { + 'no-unused-vars': 0, + // TODO: See why the ESLint plugin does not work with `.tsx` + '@carbon/react-prop-type-comments/require-proptype-comment': 0, + '@typescript-eslint/no-unused-vars': 2, + // 'import/no-unresolved': [ + // 2, + // { + // ignore: ['^./'], + // }, + // ], + 'jsdoc/require-param-type': 0, + 'jsdoc/require-returns-type': 0, + 'react/jsx-uses-react': 2, + 'react/jsx-uses-vars': 2, + }, + }, + { + files: ['**/defs.ts'], + rules: { + 'import/prefer-default-export': 0, + }, + }, + { + files: ['**/*.stories.react.tsx'], + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint', 'react'], + rules: { + 'no-unused-vars': 0, + '@typescript-eslint/no-unused-vars': 2, + // 'import/no-extraneous-dependencies': 0, + // 'import/no-unresolved': [ + // 2, + // { + // ignore: [ + // '^carbon-web-components/es/(components-react|icons)/', + // '^@carbon/ibmdotcom-web-components/es/(components-react|icons)/', + // '/components-react/', + // ], + // }, + // ], + 'react/jsx-uses-react': 2, + 'react/jsx-uses-vars': 2, + 'react/prop-types': 0, + }, + }, + { + files: ['examples/codesandbox/**/*.js', 'examples/codesandbox/**/*.ts'], + parserOptions: { + sourceType: 'module', + }, + rules: { + // 'import/no-unresolved': 0, + }, + }, + { + files: [ + 'tests/e2e/cypress/**/*.js', + 'tests/e2e-storybook/cypress/**/*.js', + ], + parserOptions: { + sourceType: 'module', + }, + rules: { + // 'import/no-unresolved': 0, + }, + }, + { + files: ['examples/codesandbox/{react,form/redux-form}/**/*.js'], + plugins: ['react'], + rules: { + 'react/jsx-uses-react': 2, + 'react/jsx-uses-vars': 2, + }, + }, + { + files: [ + 'examples/codesandbox/**/*.config.js', + 'examples/codesandbox/**/app.js', + ], + parserOptions: { + sourceType: 'script', + }, + }, + { + files: [ + 'tests/e2e/**/*.e2e.js', + 'tests/e2e/**/*.cdn.e2e.js', + 'src/components/**/*.e2e.js', + 'tests/cdn-build/**/*.js', + ], + extends: ['plugin:cypress/recommended'], + parserOptions: { + sourceType: 'module', + }, + }, + { + files: ['tests/a11y/**/*.js', 'tests/utils/**/*.js'], + parserOptions: { + sourceType: 'module', + }, + rules: { + // 'import/no-unresolved': 0, + }, + globals: { + aChecker: true, + }, + }, + ], +}; diff --git a/packages/carbon-web-components/.gitignore b/packages/carbon-web-components/.gitignore new file mode 100644 index 00000000000..da16608ad4f --- /dev/null +++ b/packages/carbon-web-components/.gitignore @@ -0,0 +1,15 @@ +custom-elements.json +docs/js +dist +.DS_Store +es +lib +node_modules +scss +storybook-static +tests/coverage +.vscode +.idea +.env +.npmrc +yarn-error.log diff --git a/packages/carbon-web-components/.percy.json b/packages/carbon-web-components/.percy.json new file mode 100644 index 00000000000..8d02ba7c6b5 --- /dev/null +++ b/packages/carbon-web-components/.percy.json @@ -0,0 +1,11 @@ +{ + "version": 2, + "snapshot": { + "widths": [320, 1280], + "min-height": 800, + "enable-javascript": true + }, + "discovery": { + "network-idle-timeout": 250 + } +} diff --git a/packages/carbon-web-components/.storybook/_container.scss b/packages/carbon-web-components/.storybook/_container.scss new file mode 100644 index 00000000000..4b30e9e0343 --- /dev/null +++ b/packages/carbon-web-components/.storybook/_container.scss @@ -0,0 +1,96 @@ +// +// @license +// +// Copyright IBM Corp. 2019, 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@import 'carbon-components/scss/globals/scss/css--helpers'; +@import 'carbon-components/scss/globals/scss/css--font-face'; +@import 'carbon-components/scss/globals/scss/vendor/@carbon/elements/scss/themes/mixins'; +@import 'carbon-components/scss/globals/scss/component-tokens'; +@import 'carbon-components/src/components/tag/tag'; +@import 'carbon-components/src/components/notification/inline-notification'; +@import 'carbon-components/src/components/notification/toast-notification'; + +// The default theme is "white" (White) +:root { + @include carbon--theme($carbon--theme--white, true) { + @include emit-component-tokens($tag-colors); + @include emit-component-tokens($notification-colors); + } +} + +// Set the theme attribute to "g10" to use the Gray 10 theme +// +:root[storybook-carbon-theme='g10'] { + @include carbon--theme($carbon--theme--g10, true) { + @include emit-component-tokens($tag-colors); + @include emit-component-tokens($notification-colors); + } +} + +// Set the theme attribute to "g90" to use the Gray 90 theme +// +:root[storybook-carbon-theme='g90'] { + @include carbon--theme($carbon--theme--g90, true) { + @include emit-component-tokens($tag-colors); + @include emit-component-tokens($notification-colors); + } +} + +// Set the theme attribute to "g100" to use the Gray 100 theme +// +:root[storybook-carbon-theme='g100'] { + @include carbon--theme($carbon--theme--g100, true) { + @include emit-component-tokens($tag-colors); + @include emit-component-tokens($notification-colors); + } +} + +html, +body, +#root, +#root-inner, +[name='main-content'] { + position: relative; + height: 100%; +} + +// Reverts Carbon reset style of lists for docs page +#docs-root { + ol { + list-style-type: decimal; + } + + ul { + list-style-type: disc; + } +} + +.bx-ce-demo-devenv--container { + padding: 3em; + display: flex; + flex-direction: column; + align-items: center; + position: relative; +} + +.bx--content.bx-ce-demo-devenv--ui-shell-content { + background-color: $ui-01; + margin: 0; + height: 100vh; + width: 100%; + + h2 { + font-weight: 800; + margin: 30px 0; + font-size: 20px; + } + + p { + line-height: 20px; + } +} diff --git a/packages/carbon-web-components/.storybook/addon-carbon-theme/components/Panel.tsx b/packages/carbon-web-components/.storybook/addon-carbon-theme/components/Panel.tsx new file mode 100644 index 00000000000..9b0a02b11c4 --- /dev/null +++ b/packages/carbon-web-components/.storybook/addon-carbon-theme/components/Panel.tsx @@ -0,0 +1,72 @@ +// @ts-nocheck +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React, { useCallback, useState } from 'react'; +import PropTypes from 'prop-types'; +import { Form } from '@storybook/components'; +import { CURRENT_THEME } from '../shared'; + +/** + * Storybook add-on panel for Carbon theme switcher. + */ +const Panel = ({ api, active }) => { + const [currentTheme, setCurrentTheme] = useState('white'); + const handleChange = useCallback( + event => { + const { value } = event.target; + setCurrentTheme(value); + api.getChannel().emit(CURRENT_THEME, value); + }, + [api] + ); + return ( + active && ( +
+ + + + + + + + +
+ ) + ); +}; + +Panel.propTypes = { + /** + * The Storybook API object. + */ + api: PropTypes.shape({ + getChannel: PropTypes.func, + }).isRequired, + + /** + * `true` if this Storybook add-on panel is active. + */ + active: PropTypes.bool.isRequired, +}; + +export default Panel; diff --git a/packages/carbon-web-components/.storybook/addon-carbon-theme/index.js b/packages/carbon-web-components/.storybook/addon-carbon-theme/index.js new file mode 100644 index 00000000000..ad1078e12a1 --- /dev/null +++ b/packages/carbon-web-components/.storybook/addon-carbon-theme/index.js @@ -0,0 +1,16 @@ +/** + * @license + * + * Copyright IBM Corp. 2020, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +function managerEntries(entry = []) { + return [...entry, require.resolve('./register.tsx')]; +} + +module.exports = { + managerEntries, +}; diff --git a/packages/carbon-web-components/.storybook/addon-carbon-theme/register.tsx b/packages/carbon-web-components/.storybook/addon-carbon-theme/register.tsx new file mode 100644 index 00000000000..a2c08bf69c8 --- /dev/null +++ b/packages/carbon-web-components/.storybook/addon-carbon-theme/register.tsx @@ -0,0 +1,23 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import addons from '@storybook/addons'; +import Panel from './components/Panel'; +import { ADDON_ID, PANEL_ID } from './shared'; + +addons.register(ADDON_ID, api => { + addons.addPanel(PANEL_ID, { + title: 'Carbon theme', + // eslint-disable-next-line react/prop-types + render: ({ active, key }) => ( + + ), + }); +}); diff --git a/packages/carbon-web-components/.storybook/addon-carbon-theme/shared.ts b/packages/carbon-web-components/.storybook/addon-carbon-theme/shared.ts new file mode 100644 index 00000000000..cbc859665bd --- /dev/null +++ b/packages/carbon-web-components/.storybook/addon-carbon-theme/shared.ts @@ -0,0 +1,12 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +export const ADDON_ID = 'carbon-theme'; +export const CURRENT_THEME = `${ADDON_ID}/current`; +export const PANEL_ID = `${ADDON_ID}/panel`; diff --git a/packages/carbon-web-components/.storybook/addon-knobs-args/decorators.ts b/packages/carbon-web-components/.storybook/addon-knobs-args/decorators.ts new file mode 100644 index 00000000000..640d6f5722b --- /dev/null +++ b/packages/carbon-web-components/.storybook/addon-knobs-args/decorators.ts @@ -0,0 +1,40 @@ +/** + * @license + * + * Copyright IBM Corp. 2020, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { StoryContext } from '@storybook/addons'; + +/** + * The list of knobs factories set in story parameters. + */ +type KnobParameters = { + [componentName: string]: () => { [propName: string]: any }; +}; + +export const decorators = [ + /** + * A Storybook decorator that takes list of knobs factories set in story parameters, + * generates knob values from those, and sets them to story args. + * @param story The original story factory. + * @param context The story context. + */ + function decoratorKnobs( + story, + { args, parameters: { knobs } }: StoryContext + ) { + if (Object(knobs) === knobs) { + Object.keys(knobs).forEach((name) => { + const { [name]: knobsForComponent } = knobs as KnobParameters; + if (typeof knobsForComponent === 'function') { + args[name] = knobsForComponent(); + } + }, {}); + } + return story(); + }, +]; diff --git a/packages/carbon-web-components/.storybook/addon-knobs-args/index.js b/packages/carbon-web-components/.storybook/addon-knobs-args/index.js new file mode 100644 index 00000000000..4e2c20185e3 --- /dev/null +++ b/packages/carbon-web-components/.storybook/addon-knobs-args/index.js @@ -0,0 +1,16 @@ +/** + * @license + * + * Copyright IBM Corp. 2020, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +function config(entry = []) { + return [...entry, require.resolve('./decorators.ts')]; +} + +module.exports = { + config, +}; diff --git a/packages/carbon-web-components/.storybook/basic-example-cdn.html b/packages/carbon-web-components/.storybook/basic-example-cdn.html new file mode 100644 index 00000000000..cabef998e54 --- /dev/null +++ b/packages/carbon-web-components/.storybook/basic-example-cdn.html @@ -0,0 +1,32 @@ + + + + + + + +
+ + Option 1 + Option 2 + Option 3 + Option 4 + Option 5 + +
+ + diff --git a/packages/carbon-web-components/.storybook/bootstrap-story.ts b/packages/carbon-web-components/.storybook/bootstrap-story.ts new file mode 100644 index 00000000000..3830b31e271 --- /dev/null +++ b/packages/carbon-web-components/.storybook/bootstrap-story.ts @@ -0,0 +1,13 @@ +/** + * @license + * + * Copyright IBM Corp. 2020, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { setCustomElements } from '@storybook/web-components'; +import customElementsMetadata from '../custom-elements.json'; + +setCustomElements(customElementsMetadata); diff --git a/packages/carbon-web-components/.storybook/container.ts b/packages/carbon-web-components/.storybook/container.ts new file mode 100644 index 00000000000..31f0e1c1a91 --- /dev/null +++ b/packages/carbon-web-components/.storybook/container.ts @@ -0,0 +1,42 @@ +/** + * @license + * + * Copyright IBM Corp. 2020, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { html } from 'lit-html'; +import type { TemplateResult } from 'lit-html'; +import '../src/components/skip-to-content/skip-to-content'; +import containerStyles from './_container.scss'; // eslint-disable-line import/first + +/** + * @param options The rendering options. + * @param [options.hasMainTag] `true` if the story itself has `
` tag. + * @param [options.children] The story content. + * @returns The content that wraps the story. + */ +const container = ({ + hasMainTag, + children, +}: { + hasMainTag?: boolean; + children: TemplateResult; +}) => html` + + +
+ ${children} +
+`; + +export default container; diff --git a/packages/carbon-web-components/.storybook/knob-text-nullable.ts b/packages/carbon-web-components/.storybook/knob-text-nullable.ts new file mode 100644 index 00000000000..84204b96bdb --- /dev/null +++ b/packages/carbon-web-components/.storybook/knob-text-nullable.ts @@ -0,0 +1,24 @@ +/** + * @license + * + * Copyright IBM Corp. 2020, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { text } from '@storybook/addon-knobs'; + +/** + * A Storybook text knob, where a empty text is treated as `undefined`. + */ +const textNullable = ( + name: string, + value: string, + groupId?: string | undefined +) => { + const content = text(name, value, groupId); + return content === '' ? null : content; +}; + +export default textNullable; diff --git a/packages/carbon-web-components/.storybook/main.js b/packages/carbon-web-components/.storybook/main.js new file mode 100644 index 00000000000..c4d29448004 --- /dev/null +++ b/packages/carbon-web-components/.storybook/main.js @@ -0,0 +1,181 @@ +/** + * @license + * + * Copyright IBM Corp. 2020, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +const path = require('path'); +const sass = require('sass'); +const rtlcss = require('rtlcss'); +const deepReplace = require('../tools/deep-replace'); + +const { getPaths } = deepReplace; +const useRtl = process.env.STORYBOOK_CARBON_CUSTOM_ELEMENTS_USE_RTL === 'true'; + +const arrayify = (value) => + Array.isArray(value) ? value : value != null ? [value] : []; // eslint-disable-line no-nested-ternary +const testMatches = (test, s) => + arrayify(test).some((item) => item.test && item.test(s)); + +module.exports = { + stories: [ + './bootstrap-story.ts', + '../docs/**/*-story.mdx', + '../src/**/*-story.ts', + ], + addons: [ + '@storybook/addon-actions', + '@storybook/addon-docs', + '@storybook/addon-knobs', + '@storybook/addon-storysource', + path.resolve(__dirname, 'addon-carbon-theme'), + path.resolve(__dirname, 'addon-knobs-args'), + ], + managerWebpack(config) { + // Ignores our `.babelrc` for manager + config.module.rules = deepReplace( + config.module.rules, + (value, key, parent) => + key === 'options' && /babel-loader/i.test(parent.loader), + (value) => ({ + ...value, + babelrc: false, + configFile: false, + }) + ); + return config; + }, + webpackFinal(config) { + // Uses our own option for `@babel/preset-env` + config.module.rules = deepReplace( + config.module.rules, + (value, key, parent, parents) => + getPaths(parents) === 'use.options.presets' && + Array.isArray(value) && + /@babel\/preset-env/i.test(value[0]), + (value) => [ + value[0], + { + modules: false, + targets: ['last 1 version', 'Firefox ESR', 'ie >= 11'], + }, + ] + ); + // Uses `@babel/plugin-proposal-decorators` configuration in our `.babelrc` + config.module.rules = deepReplace( + config.module.rules, + (value, key, parent, parents) => + getPaths(parents) === 'use.options.plugins' && + Array.isArray(value) && + /@babel\/plugin-proposal-decorators/i.test(value[0]), + () => deepReplace.DELETE + ); + // Normalizes several plugins with `loose: false` option + config.module.rules = deepReplace( + config.module.rules, + (value, key, parent, parents) => + getPaths(parents) === 'use.options.plugins' && + Array.isArray(value) && + value[1] && + value[1].loose, + (value) => [ + value[0], + { + ...value[1], + loose: false, + }, + ] + ); + // Supports `*-story.mdx` + config.module.rules = deepReplace( + config.module.rules, + (value, key) => + key === 'test' && + testMatches(value, 'button.stories.mdx') && + !testMatches(value, 'foo.mdx'), + (value) => [...arrayify(value), /\-story.mdx$/] + ); + config.module.rules = deepReplace( + config.module.rules, + (value, key) => + key === 'exclude' && + testMatches(value, 'button.stories.mdx') && + !testMatches(value, 'foo.mdx'), + (value) => [...arrayify(value), /\-story.mdx$/] + ); + + config.module.rules.push( + { + test: /@carbon[\\/]icons[\\/]/i, + use: [ + { + loader: 'babel-loader', + options: { + cacheDirectory: true, + presets: [ + [ + '@babel/preset-env', + { + modules: false, + targets: ['last 1 version', 'Firefox ESR'], + }, + ], + ], + }, + }, + require.resolve('../tools/svg-result-carbon-icon-loader'), + ], + }, + { + test: /\.scss$/, + sideEffects: true, + use: [ + 'cache-loader', + require.resolve('../tools/css-result-loader'), + { + loader: 'postcss-loader', + options: { + plugins: () => [ + require('../tools/postcss-fix-host-pseudo')(), + require('autoprefixer')(), + ...(useRtl ? [rtlcss] : []), + ], + }, + }, + { + loader: 'sass-loader', + options: { + additionalData: ` + $feature-flags: ( + enable-css-custom-properties: true, + ); + `, + implementation: sass, + webpackImporter: false, + sassOptions: { + includePaths: [path.resolve(__dirname, '..', 'node_modules')], + }, + }, + }, + ], + }, + { + test: /\.html$/, + use: 'file-loader', + } + ); + + if (!config.resolve.alias) { + config.resolve.alias = {}; + } + // In our development environment (where `carbon-web-components/es/icons` may not have been built yet), + // we load icons from `@carbon/icons` and use a WebPack loader to convert the icons to `lit-html` version + config.resolve.alias['carbon-web-components/es/icons'] = + '@carbon/icons/lib'; + + return config; + }, +}; diff --git a/packages/carbon-web-components/.storybook/manager-head.html b/packages/carbon-web-components/.storybook/manager-head.html new file mode 100644 index 00000000000..ee43c04799e --- /dev/null +++ b/packages/carbon-web-components/.storybook/manager-head.html @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + diff --git a/packages/carbon-web-components/.storybook/preview-head.html b/packages/carbon-web-components/.storybook/preview-head.html new file mode 100644 index 00000000000..59a3219f186 --- /dev/null +++ b/packages/carbon-web-components/.storybook/preview-head.html @@ -0,0 +1,14 @@ + + diff --git a/packages/carbon-web-components/.storybook/preview.ts b/packages/carbon-web-components/.storybook/preview.ts new file mode 100644 index 00000000000..4a89dfb6b13 --- /dev/null +++ b/packages/carbon-web-components/.storybook/preview.ts @@ -0,0 +1,57 @@ +/** + * @license + * + * Copyright IBM Corp. 2020, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import addons from '@storybook/addons'; +import { CURRENT_THEME } from './addon-carbon-theme/shared'; +import theme from './theme'; +import container from './container'; + +if (process.env.STORYBOOK_CARBON_CUSTOM_ELEMENTS_USE_RTL === 'true') { + document.documentElement.setAttribute('dir', 'rtl'); +} + +addons.getChannel().on(CURRENT_THEME, (theme) => { + document.documentElement.setAttribute('storybook-carbon-theme', theme); +}); + +addons.setConfig({ + showRoots: true, + theme, +}); + +const SORT_ORDER = [ + 'introduction-welcome--page', + 'introduction-form-paticipation--page', + 'introduction-custom-styles--page', +]; + +export const parameters = { + layout: 'fullscreen', // https://github.com/storybookjs/storybook/issues/12041 + options: { + storySort(lhs, rhs) { + const [lhsId] = lhs; + const [rhsId] = rhs; + const lhsSortOrder = SORT_ORDER.indexOf(lhsId); + const rhsSortOrder = SORT_ORDER.indexOf(rhsId); + if (lhsSortOrder >= 0 && rhsSortOrder >= 0) { + return lhsSortOrder - rhsSortOrder; + } + return 0; + }, + theme, + }, +}; + +export const decorators = [ + function decoratorContainer(story) { + const result = story(); + const { hasMainTag } = result as any; + return container({ hasMainTag, children: result }); + }, +]; diff --git a/packages/carbon-web-components/.storybook/theme.ts b/packages/carbon-web-components/.storybook/theme.ts new file mode 100644 index 00000000000..8bef5e2dfd5 --- /dev/null +++ b/packages/carbon-web-components/.storybook/theme.ts @@ -0,0 +1,16 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { create, ThemeVars } from '@storybook/theming'; +import { version } from '../package.json'; + +export default create({ + brandTitle: `carbon-web-components ${version}`, + brandUrl: 'https://github.com/carbon-design-system/carbon-web-components', +} as ThemeVars); diff --git a/packages/carbon-web-components/CHANGELOG.md b/packages/carbon-web-components/CHANGELOG.md new file mode 100644 index 00000000000..cee6a18427b --- /dev/null +++ b/packages/carbon-web-components/CHANGELOG.md @@ -0,0 +1,79 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# [1.23.0-rc.0](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/compare/@carbon/web-components@1.22.0...@carbon/web-components@1.23.0-rc.0) (2023-01-04) + + +### Bug Fixes + +* **deps:** update dependency carbon-components to v10.58.3 ([#9849](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/issues/9849)) ([152eb57](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/commit/152eb5739ef811336ffecc14faa8fda695d72ca6)) +* **deps:** update dependency flatpickr to v4.6.13 ([#9666](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/issues/9666)) ([7995814](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/commit/79958142bd036972906dd1ba18458e4e4c192f56)) +* **notification/tag:** token documentation ([#9809](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/issues/9809)) ([f9e1b1c](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/commit/f9e1b1c2d21a1f47bb068c98cb7fe5a09c3cee07)), closes [carbon-design-system/carbon-for-ibm-dotcom#9757](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/issues/9757) +* **progress-indicator:** add missing import for progress indicator skeleton ([#9853](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/issues/9853)) ([7b28a85](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/commit/7b28a85d6ad7799c80b0865e3dd66b95da266bb7)), closes [#9825](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/issues/9825) +* **rollup:** update cwc rollup config ([#9854](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/issues/9854)) ([ca282b3](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/commit/ca282b35c83f8d0efaef0d2a534fe7b8843a2728)) +* **tabs:** basic keyboard navigation ([#9811](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/issues/9811)) ([b785e61](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/commit/b785e617602d27a11927398a495fb473d8efb43e)) +* **tooltip:** interpolate sass var ([#9880](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/issues/9880)) ([20cd1dc](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/commit/20cd1dca7bb5fff5b9edc9eaa0e4d0ef1bd31e72)) + + + + + +# [1.22.0](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/compare/@carbon/web-components@1.22.0-rc.3...@carbon/web-components@1.22.0) (2022-12-06) + +**Note:** Version bump only for package @carbon/web-components + + + + + +# 1.22.0-rc.3 (2022-12-06) + + + +# 1.41.0-rc.2 (2022-12-05) + + + +# 1.41.0-rc.1 (2022-11-23) + + + +# 1.41.0-rc.0 (2022-11-22) + + +### Bug Fixes + +* **cwc:** percy update ([5ac2674](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/commit/5ac2674bdac3d7d033335c693e36a1ae33042242)) +* **cwc:** update package.json & karma test ([a52ab2f](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/commit/a52ab2f5937d9576c79c63748065a1dcf03ee2b0)) +* **packages:** update versions to get working storybooks ([42d8eee](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/commit/42d8eeee12c732c56599de24861252159e91905b)) + + + + + +# [1.22.0-rc.2](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/compare/@carbon/web-components@1.22.0-rc.1...@carbon/web-components@1.22.0-rc.2) (2022-12-05) + +**Note:** Version bump only for package @carbon/web-components + + + + + +# [1.22.0-rc.1](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/compare/@carbon/web-components@1.22.0-rc.0...@carbon/web-components@1.22.0-rc.1) (2022-11-23) + +**Note:** Version bump only for package @carbon/web-components + + + + + +# 1.22.0-rc.0 (2022-11-22) + + +### Bug Fixes + +* **cwc:** percy update ([5ac2674](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/commit/5ac2674bdac3d7d033335c693e36a1ae33042242)) +* **cwc:** update package.json & karma test ([a52ab2f](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/commit/a52ab2f5937d9576c79c63748065a1dcf03ee2b0)) +* **packages:** update versions to get working storybooks ([42d8eee](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/commit/42d8eeee12c732c56599de24861252159e91905b)) diff --git a/packages/carbon-web-components/LICENSE b/packages/carbon-web-components/LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/packages/carbon-web-components/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/carbon-web-components/README.md b/packages/carbon-web-components/README.md new file mode 100644 index 00000000000..2af6280cd18 --- /dev/null +++ b/packages/carbon-web-components/README.md @@ -0,0 +1,507 @@ +A Carbon Design System variant that's as easy to use as native HTML elements, +with no framework tax, no framework silo. + +

+ + Carbon Design System + +

+ +> Carbon is an open-source design system built by IBM. With the IBM Design +> Language as its foundation, the system consists of working code, design tools +> and resources, human interface guidelines, and a vibrant community of +> contributors. + +

+ + Carbon is released under the Apache-2.0 license + +

+

+ + This project is using Percy.io for visual regression testing + +

+ +# `carbon-web-components` + +`carbon-web-components` is a variant of Carbon Design System with Custom +Elements v1 and Shadow DOM v1 specs. + +> The original `carbon-web-components` repository has been archived. All future +> work for the package will take place in this monorepo. Please visit the +> [original repository](https://github.com/carbon-design-system/carbon-web-components) +> for full history of the files. + +The effort stems from +https://github.com/carbon-design-system/issue-tracking/issues/121. If you are +interested in this project, adding ๐Ÿ‘ to the description of that GH issue, or +even contributing, will be greatly appreciated! + + + + +- [Getting started](#getting-started) + - [Using CDN](#using-cdn) + - [How to install](#how-to-install) + - [Basic usage](#basic-usage) + - [Using ES imports](#using-es-imports) + - [How to install](#how-to-install-1) + - [Basic usage](#basic-usage-1) + - [Other usage guides](#other-usage-guides) +- [JavaScript framework support](#javascript-framework-support) + - [Angular](#angular) + - [React](#react) + - [Vue](#vue) +- [Getting started with development](#getting-started-with-development) +- [Running React/Angular/Vue Storybook demo](#running-reactangularvue-storybook-demo) +- [List of available components](#list-of-available-components) +- [Browser support](#browser-support) +- [Coding conventions](#coding-conventions) +- [Creating build](#creating-build) +- [Running unit test](#running-unit-test) +- [Running build integration test](#running-build-integration-test) +- [Running UI integration test](#running-ui-integration-test) + + + +## Getting started + +### Using CDN + +#### How to install + +All components are available via CDN. This means that they can be added to your +application without the need of any bundler configuration. Each component is +available by the `latest` tag, or referencing a specific version (starting at +version `v1.16.0`): + +```html + + + + + +``` + +These are the list of available components via CDN: + +- accordion.min.js +- breadcrumb.min.js +- button.min.js +- checkbox.min.js +- code-snippet.min.js +- combo-box.min.js +- content-switcher.min.js +- copy-button.min.js +- data-table.min.js +- date-picker.min.js +- dropdown.min.js +- file-uploader.min.js +- floating-menu.min.js +- form.min.js +- inline-loading.min.js +- input.min.js +- link.min.js +- list.min.js +- loading.min.js +- modal.min.js +- multi-select.min.js +- notification.min.js +- number-input.min.js +- overflow-menu.min.js +- pagination.min.js +- progress-indicator.min.js +- radio-button.min.js +- search.min.js +- select.min.js +- skeleton-placeholder.min.js +- skeleton-text.min.js +- skip-to-content.min.js +- slider.min.js +- structured-list.min.js +- tabs.min.js +- tag.min.js +- textarea.min.js +- tile.min.js +- toggle.min.js +- tooltip.min.js +- ui-shell.min.js + +To use the right-to-left (RTL) version of the artifacts, change the file +extention from `.min.js` to `.rtl.min.js`. For example: + +```html + + + + + +``` + +#### Basic usage + +The CDN artifacts define the custom elements for the browser, so they can be +directly used once the script tag has been added to the page. For example: + +```html + + + + + + + +
+ + Option 1 + Option 2 + Option 3 + Option 4 + Option 5 + +
+ + +``` + +Our example at [CodeSandbox](https://codesandbox.io) shows usage with only CDN +artifacts: + +[![Edit carbon-web-components](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/carbon-design-system/carbon-web-components/tree/main/examples/codesandbox/cdn) + +### Using ES imports + +#### How to install + +To install `@carbon/web-components` in your project, you will need to run the +following command using [npm](https://www.npmjs.com/): + +```bash +npm install --save @carbon/web-components +``` + +If you prefer [Yarn](https://yarnpkg.com/en/), use the following command +instead: + +```bash +yarn add @carbon/web-components +``` + +> NOTE: Carbon and Lit dependencies will be managed by Carbon Web Components +> starting in `v1.19.0`. For earlier versions, these dependencies will have to +> be installed separately: +> +> npm: +> +> ```bash +> npm install --save carbon-components lit-html lit-element +> ``` +> +> Yarn: +> +> ```bash +> yarn add carbon-components lit-html lit-element +> ``` + +#### Basic usage + +Our example at [CodeSandbox](https://codesandbox.io) shows the most basic usage: + +[![Edit carbon-web-components](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/carbon-web-components/examples/codesandbox/basic) + +The first thing you need is **setting up a module bundler** to resolve +ECMAScript `import`s. The above example uses [Webpack](https://webpack.js.org), +but you can use other bundlers like [Rollup](https://rollupjs.org/) too. + +Once you set up a module bundler, you can start importing our component modules, +for example: + +```javascript +import '@carbon/web-components/es/components/dropdown/dropdown.js'; +import '@carbon/web-components/es/components/dropdown/dropdown-item.js'; +``` + +Once you've imported the component modules, you can use our components in the +same manner as native HTML tags, for example: + +```html + + Option 1 + Option 2 + Option 3 + Option 4 + Option 5 + +``` + +### Other usage guides + +- [Having components participate in form](./docs/form.md) +- [Using custom styles in components](./docs/styling.md) +- [Using `carbon-web-components` with old build toolchain](./docs/old-build-toolchain.md) + +## JavaScript framework support + +In addition to the available Web Component versions of Carbon components, this +library also supports usage with JavaScript frameworks like Angular, React, and +Vue if the desire is to use instead of the pure framework versions of Carbon +components. Specifically for React, this library comes with a wrapper +implementation around the Carbon Web Components for more seamless integration +with your React application. + +This is achievable since Web Components is the modern browser standard, and +works well with other front-end frameworks that exist in the application. In +turn, this also comes with the benefits of encapsulation within the Shadow DOM: + +### Angular + +[![Edit carbon-web-components with Angular](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/carbon-design-system/carbon-web-components/tree/main/examples/codesandbox/angular) + +Angular users can use our components in the same manner as native HTML tags, +too, once you add +[`CUSTOM_ELEMENTS_SCHEMA`](https://angular.io/api/core/CUSTOM_ELEMENTS_SCHEMA) +schema to your Angular module, for example: + +```javascript +import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; + +import { AppComponent } from './app.component'; + +@NgModule({ + schemas: [CUSTOM_ELEMENTS_SCHEMA], + declarations: [AppComponent], + imports: [BrowserModule], + bootstrap: [AppComponent], +}) +export class AppModule {} +``` + +The `.d.ts` files in `carbon-web-components` package are compiled with +TypeScript 3.7. You can use TypeScript 3.7 in your Angular application with +upcoming Angular `9.0` release, or with the following instructions, so your +application can use those `.d.ts` files: + +- Set `true` to + [`angularCompilerOptions.disableTypeScriptVersionCheck`](https://angular.io/guide/angular-compiler-options#disabletypescriptversioncheck) + in `tsconfig.json` +- In `polyfills.ts`, change + [`__importDefault` TypeScript helper](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#example-8) + as follows: + `window.__importDefault = mod => (mod?.__esModule ? mod : { default: mod })` + +### React + +[![Edit carbon-web-components with React](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/carbon-design-system/carbon-web-components/tree/main/examples/codesandbox/react) + +You can use wrapper React components in +`carbon-web-components/es/components-react` generated +[automatically from the custom elements](./src/globals/wrappers/createReactCustomElementType.ts) +which allows you to use our components seamlessly in your React code. Here's an +example: + +```javascript +import React from 'react'; +import { render } from 'react-dom'; +import BXDropdown from '@carbon/web-components/es/components-react/dropdown/dropdown.js'; +import BXDropdownItem from '@carbon/web-components/es/components-react/dropdown/dropdown-item.js'; + +const App = () => ( + + Option 1 + Option 2 + Option 3 + Option 4 + Option 5 + +); + +render(, document.getElementById('root')); +``` + +Note: Using the React wrapper requires an additional dependency, +[`prop-types`](https://www.npmjs.com/package/prop-types). + +To run the wrapper React components in SSR environment requires Node `12.16.3` +or above that supports +["conditional mapping" feature](https://github.com/jkrems/proposal-pkg-exports#2-conditional-mapping): + +[![Edit carbon-web-components with React SSR](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/carbon-design-system/carbon-web-components/tree/main/examples/codesandbox/react-ssr) + +Same Node version requirement applies to Next.js: + +[![Edit carbon-web-components with React SSR](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/carbon-design-system/carbon-web-components/tree/main/examples/codesandbox/next) + +### Vue + +[![Edit carbon-web-components with Vue](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/carbon-design-system/carbon-web-components/tree/main/examples/codesandbox/vue) + +Vue users can use our components in the same manner as native HTML tags, without +any additional steps! + +## Getting started with development + +1. Fork this repository and clone it +2. `yarn install` +3. `yarn wca && yarn storybook` + +## Running React/Angular/Vue Storybook demo + +- React: `yarn storybook:react` (Live demo: + https://web-components.carbondesignsystem.com/react/index.html) +- Angular: `yarn storybook:angular` (Live demo: + https://web-components.carbondesignsystem.com/angular/index.html) +- Vue: `yarn storybook:vue` (Live demo: + https://web-components.carbondesignsystem.com/vue/index.html) + +## List of available components + +View available web components at: +https://www.ibm.com/standards/carbon/carbon-web-components. You can see usage +information in several ways: + +1. Going to Docs tab, where it shows the usage and available attributes, + properties and custom events. +2. Clicking the **KNOBS** tab at the bottom and changing values there. Most + knobs are shown as something like `Button kind (kind)`, where `kind` is the + attribute name +3. Clicking the **ACTION LOGGER** tab at the bottom and interacting with the + selected component. You may see something like `bx-modal-closed` which + typically indicates that an event with such event type is fired. You can also + expand the twistie to see the details of the event + +## Browser support + +- Latest Chrome/Safari/FF ESR +- IE/Edge support is bast-effort basis + - Some components may not be supported + +To support IE, you need a couple additional setups: + +- Toolstack to re-transpile our code to ES5 (e.g. by specifying IE11 in + [`@babel/preset-env`](https://babeljs.io/docs/en/babel-preset-env) + configuration) +- Polyfills, listed + [here](https://github.com/carbon-design-system/carbon-web-components/blob/main/src/polyfills/index.ts) + +Here's an example code that shows such setup: + +[![Edit carbon-web-components with IE](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/carbon-design-system/carbon-web-components/tree/main/examples/codesandbox/ie) + +## Coding conventions + +Can be found at [here](./src/coding-conventions.md). + +## Creating build + +``` +> yarn clean +> yarn build +``` + +You'll see the build artifacts in `/path/to/carbon-web-components/es` directory. + +## Running unit test + +You can run unit test by: + +``` +> gulp test:unit +``` + +You can run specific test spec by: + +``` +> gulp test:unit -s tests/spec/dropdown_spec.ts +``` + +You can choose a browser (instead of Headless Chrome) by: + +``` +> gulp test:unit -b Firefox +``` + +You can keep the browser after the test (and re-run the test when files change) +by: + +``` +> gulp test:unit -b Chrome -k +``` + +You can prevent code coverate instrumentation code from being generated by: + +``` +> gulp test:unit -d +``` + +You can update snapshots by: + +``` +> gulp test:unit --update-snapshot +``` + +Above options can be used together. This is useful to debug your code as you +test: + +``` +> gulp test:unit -s tests/spec/dropdown_spec.ts -b Chrome -d -k +``` + +## Running build integration test + +You can run build integration test by: + +``` +> yarn test:integration:build +``` + +You can run a specific set of UI test steps (e.g. running +`tests/integration/build/form-angular_steps.js` only) by: + +``` +> yarn test:integration:build form-angular_steps +``` + +By default Chrome runs in headless mode. You can show Chrome UI by: + +``` +> CI=false yarn test:integration:build +``` + +## Running UI integration test + +You can run UI integration test by: + +``` +> yarn test:integration:ui +``` + +You can run a specific set of UI test steps (e.g. running +`tests/integration/ui/dropdown_steps.js` only) by: + +``` +> yarn test:integration:ui dropdown_steps +``` + +By default Chrome runs in headless mode. You can show Chrome UI by: + +``` +> CI=false yarn test:integration:ui +``` diff --git a/packages/carbon-web-components/Staticfile b/packages/carbon-web-components/Staticfile new file mode 100644 index 00000000000..50d8902c17b --- /dev/null +++ b/packages/carbon-web-components/Staticfile @@ -0,0 +1,2 @@ +root: storybook-static +force_https: true diff --git a/packages/carbon-web-components/docs/form-story.mdx b/packages/carbon-web-components/docs/form-story.mdx new file mode 100644 index 00000000000..a32e682832a --- /dev/null +++ b/packages/carbon-web-components/docs/form-story.mdx @@ -0,0 +1,40 @@ +import { Meta } from '@storybook/addon-docs/blocks'; + + + +# Having components participate in form + +Though form elements in `carbon-web-components` (e.g. ``) are not native form elements like ``, form elements in `carbon-web-components` have some extra APIs that align well to web/framework standards that allow those form elements to participate in form. + +## `formdata` event + +Browsers supporting [`formdata` event](https://www.chromestatus.com/feature/5662230242656256) fire that event when the user clicks on ` +
+ +
+ `; + } + + /** + * The CSS classes for breakpoints. + * + * @private + */ + static get _classesBreakpoints() { + return { + [ACCORDION_ITEM_BREAKPOINT.SMALL]: `${prefix}-ce--accordion__content--${ACCORDION_ITEM_BREAKPOINT.SMALL}`, + [ACCORDION_ITEM_BREAKPOINT.MEDIUM]: `${prefix}-ce--accordion__content--${ACCORDION_ITEM_BREAKPOINT.MEDIUM}`, + }; + } + + /** + * The breakpoints. + * + * @private + */ + static get _sizesBreakpoints() { + return { + [ACCORDION_ITEM_BREAKPOINT.SMALL]: 480, + [ACCORDION_ITEM_BREAKPOINT.MEDIUM]: 640, + }; + } + + /** + * The name of the custom event fired before this accordion item is being toggled upon a user gesture. + * Cancellation of this event stops the user-initiated action of toggling this accordion item. + */ + static get eventBeforeToggle() { + return `${prefix}-accordion-item-beingtoggled`; + } + + /** + * The name of the custom event fired after this accordion item is toggled upon a user gesture. + */ + static get eventToggle() { + return `${prefix}-accordion-item-toggled`; + } + + static styles = styles; +} + +export default BXAccordionItem; diff --git a/packages/carbon-web-components/src/components/accordion/accordion-story.mdx b/packages/carbon-web-components/src/components/accordion/accordion-story.mdx new file mode 100644 index 00000000000..43f80d67dbc --- /dev/null +++ b/packages/carbon-web-components/src/components/accordion/accordion-story.mdx @@ -0,0 +1,76 @@ +import { Props, Description } from '@storybook/addon-docs/blocks'; +import { cdnJs, cdnCss } from '../../globals/internal/storybook-cdn'; + +# Accordion + +> ๐Ÿ’ก Check our +> [CodeSandbox](https://codesandbox.io/s/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/carbon-web-components/examples/codesandbox/basic/components/accordion) +> example implementation. + +[![Edit carbon-web-components](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/carbon-web-components/examples/codesandbox/basic/components/accordion) + +The accordion component delivers large amounts of content in a small space +through progressive disclosure. That is, the user gets key details about the +underlying content and can choose to expand that content within the constraints +of the accordion. Accordions work especially well on mobile interfaces or +whenever vertical space is at a premium. + +Avoid โ€œnestedโ€ accordionsโ€”that is, collapsible content within collapsible +content. This type of pattern goes against UX best practices. + +The Carbon accordion allows for multiple sections to be expanded simultaneously. + +A chevron is used to indicate the โ€œexpand/collapseโ€ action, though the entire +header area is clickable for the same action. + +## Getting started + +Here's a quick example to get you started. + +### JS (via import) + +```javascript +import '@carbon/web-components/es/components/accordion/index.js'; +``` + + + + +### HTML + +```html + + +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim + veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea + commodo consequat. +

+
+ +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim + veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea + commodo consequat. +

+
+ +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim + veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea + commodo consequat. +

+
+
+``` + +## `` attributes, properties and events + +Note: For `boolean` attributes, `true` means simply setting the attribute (e.g. +``) and `false` means not setting the attribute (e.g. +`` without `open` attribute). + + diff --git a/packages/carbon-web-components/src/components/accordion/accordion-story.ts b/packages/carbon-web-components/src/components/accordion/accordion-story.ts new file mode 100644 index 00000000000..ef9dbd7a2e6 --- /dev/null +++ b/packages/carbon-web-components/src/components/accordion/accordion-story.ts @@ -0,0 +1,100 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { html } from 'lit-element'; +import { action } from '@storybook/addon-actions'; +import { boolean, select, text } from '@storybook/addon-knobs'; +import { ACCORDION_SIZE } from './accordion'; +import './accordion-item'; +import storyDocs from './accordion-story.mdx'; + +const sizes = { + 'Regular size': null, + [`Small size (${ACCORDION_SIZE.SMALL})`]: ACCORDION_SIZE.SMALL, + [`XL size (${ACCORDION_SIZE.EXTRA_LARGE})`]: ACCORDION_SIZE.EXTRA_LARGE, +}; + +const noop = () => {}; + +export const Default = (args) => { + const { + open, + titleText, + disabled, + disableToggle, + onBeforeToggle = noop, + onToggle = noop, + size, + } = args?.['bx-accordion'] ?? {}; + const handleBeforeToggle = (event: CustomEvent) => { + onBeforeToggle(event); + if (disableToggle) { + event.preventDefault(); + } + }; + + return html` + + +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad + minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. +

+
+ +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad + minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. +

+
+ +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad + minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. +

+ ${titleText} +
+
+ `; +}; + +Default.storyName = 'Default'; + +export default { + title: 'Components/Accordion', + parameters: { + ...storyDocs.parameters, + knobs: { + 'bx-accordion': () => ({ + open: boolean('Open the section (open)', false), + titleText: text('The title (title-text)', 'Section title'), + size: select('Accordion size (size)', sizes, null), + disabled: boolean('Disable accordion item (disabled)', false), + disableToggle: boolean( + 'Disable user-initiated toggle action (Call event.preventDefault() in bx-accordion-beingtoggled event)', + false + ), + onBeforeToggle: action('bx-accordion-item-beingtoggled'), + onToggle: action('bx-accordion-item-toggled'), + }), + }, + }, +}; diff --git a/packages/carbon-web-components/src/components/accordion/accordion.scss b/packages/carbon-web-components/src/components/accordion/accordion.scss new file mode 100644 index 00000000000..832910b32f1 --- /dev/null +++ b/packages/carbon-web-components/src/components/accordion/accordion.scss @@ -0,0 +1,57 @@ +// +// Copyright IBM Corp. 2019, 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +$css--plex: true !default; + +@import 'carbon-components/scss/components/accordion/accordion'; + +:host(#{$prefix}-accordion) { + @extend .#{$prefix}--accordion; +} + +:host(#{$prefix}-accordion-item) { + @extend .#{$prefix}--accordion__item; + + display: block; + outline: none; + + .#{$prefix}--accordion__heading { + padding-top: calc( + (#{$container-03} - #{map-get($body-long-01, 'line-height')}rem) / 2 + ); + min-height: $container-03; + } + + &[size='sm'] { + .#{$prefix}--accordion__heading { + min-height: rem(32px); + padding: rem(5px) 0; + } + } + + &[size='xl'] { + .#{$prefix}--accordion__heading { + min-height: rem(48px); + } + } +} + +:host(#{$prefix}-accordion-item[open]:not([disabled])) { + @extend .#{$prefix}--accordion__item--active; + + .#{$prefix}--accordion__content { + padding-right: $carbon--spacing-05; + } + + .#{$prefix}-ce--accordion__content--sm { + padding-right: $carbon--spacing-09; + } + + .#{$prefix}-ce--accordion__content--md { + padding-right: 25%; + } +} diff --git a/packages/carbon-web-components/src/components/accordion/accordion.ts b/packages/carbon-web-components/src/components/accordion/accordion.ts new file mode 100644 index 00000000000..5dd3b663114 --- /dev/null +++ b/packages/carbon-web-components/src/components/accordion/accordion.ts @@ -0,0 +1,65 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { html, property, customElement, LitElement } from 'lit-element'; +import settings from 'carbon-components/es/globals/js/settings'; +import { forEach } from '../../globals/internal/collection-helpers'; +import { ACCORDION_SIZE } from './defs'; +import styles from './accordion.scss'; + +export { ACCORDION_SIZE }; + +const { prefix } = settings; + +/** + * Accordion container. + * + * @element bx-accordion + */ +@customElement(`${prefix}-accordion`) +class BXAccordion extends LitElement { + /** + * Accordion size. + */ + @property({ reflect: true }) + size = ACCORDION_SIZE.REGULAR; + + connectedCallback() { + if (!this.hasAttribute('role')) { + this.setAttribute('role', 'list'); + } + super.connectedCallback(); + } + + updated(changedProperties) { + if (changedProperties.has('size')) { + // Propagate `size` attribute to descendants until `:host-context()` gets supported in all major browsers + forEach( + this.querySelectorAll( + (this.constructor as typeof BXAccordion).selectorAccordionItems + ), + (elem) => { + elem.setAttribute('size', this.size); + } + ); + } + } + + render() { + return html` `; + } + + static get selectorAccordionItems() { + return `${prefix}-accordion-item`; + } + + static styles = styles; +} + +export default BXAccordion; diff --git a/packages/carbon-web-components/src/components/accordion/defs.ts b/packages/carbon-web-components/src/components/accordion/defs.ts new file mode 100644 index 00000000000..75d4ee800b5 --- /dev/null +++ b/packages/carbon-web-components/src/components/accordion/defs.ts @@ -0,0 +1,43 @@ +/** + * @license + * + * Copyright IBM Corp. 2020 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * Breakpoints for accordion items. It's different from one in `@carbon/layout` library. + */ +export enum ACCORDION_ITEM_BREAKPOINT { + /** + * Small breakpoint. + */ + SMALL = 'sm', + + /** + * Medium breakpoint. + */ + MEDIUM = 'md', +} + +/** + * Button size. + */ +export enum ACCORDION_SIZE { + /** + * Regular size. + */ + REGULAR = '', + + /** + * Small size. + */ + SMALL = 'sm', + + /** + * X-Large size. + */ + EXTRA_LARGE = 'xl', +} diff --git a/packages/carbon-web-components/src/components/accordion/index.ts b/packages/carbon-web-components/src/components/accordion/index.ts new file mode 100644 index 00000000000..fa3b5b8c2ec --- /dev/null +++ b/packages/carbon-web-components/src/components/accordion/index.ts @@ -0,0 +1,11 @@ +/** + * @license + * + * Copyright IBM Corp. 2021 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import './accordion'; +import './accordion-item'; diff --git a/packages/carbon-web-components/src/components/breadcrumb/breadcrumb-item.ts b/packages/carbon-web-components/src/components/breadcrumb/breadcrumb-item.ts new file mode 100644 index 00000000000..b9abe902c9d --- /dev/null +++ b/packages/carbon-web-components/src/components/breadcrumb/breadcrumb-item.ts @@ -0,0 +1,37 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { html, customElement, LitElement } from 'lit-element'; +import settings from 'carbon-components/es/globals/js/settings'; +import styles from './breadcrumb.scss'; + +const { prefix } = settings; + +/** + * Breadcrumb item. + * + * @element bx-breadcrumb-item + */ +@customElement(`${prefix}-breadcrumb-item`) +class BXBreadcrumbItem extends LitElement { + connectedCallback() { + if (!this.hasAttribute('role')) { + this.setAttribute('role', 'listitem'); + } + super.connectedCallback(); + } + + render() { + return html` `; + } + + static styles = styles; +} + +export default BXBreadcrumbItem; diff --git a/packages/carbon-web-components/src/components/breadcrumb/breadcrumb-link.ts b/packages/carbon-web-components/src/components/breadcrumb/breadcrumb-link.ts new file mode 100644 index 00000000000..9819284ed46 --- /dev/null +++ b/packages/carbon-web-components/src/components/breadcrumb/breadcrumb-link.ts @@ -0,0 +1,27 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { customElement } from 'lit-element'; +import settings from 'carbon-components/es/globals/js/settings'; +import BXLink from '../link/link'; +import styles from './breadcrumb.scss'; + +const { prefix } = settings; + +/** + * Link in breadcrumb. + * + * @element bx-breadcrumb-link + */ +@customElement(`${prefix}-breadcrumb-link`) +class BXBreadcrumbLink extends BXLink { + static styles = styles; +} + +export default BXBreadcrumbLink; diff --git a/packages/carbon-web-components/src/components/breadcrumb/breadcrumb-overflow-menu.ts b/packages/carbon-web-components/src/components/breadcrumb/breadcrumb-overflow-menu.ts new file mode 100644 index 00000000000..e3aab0ac9e4 --- /dev/null +++ b/packages/carbon-web-components/src/components/breadcrumb/breadcrumb-overflow-menu.ts @@ -0,0 +1,38 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { customElement, html } from 'lit-element'; +import settings from 'carbon-components/es/globals/js/settings'; +import OverflowMenuHorizontal16 from '@carbon/icons/lib/overflow-menu--horizontal/16'; +import BXOverflowMenu from '../overflow-menu/overflow-menu'; +import styles from './breadcrumb.scss'; + +const { prefix } = settings; + +/** + * Overflow menu in breadcrumb. + * + * @element bx-breadcrumb-overflow-menu + */ +@customElement(`${prefix}-breadcrumb-overflow-menu`) +class BXBreadcrumbOverflowMenu extends BXOverflowMenu { + render() { + return html` + + ${OverflowMenuHorizontal16({ + class: `${prefix}--overflow-menu__icon`, + })} + + `; + } + + static styles = styles; +} + +export default BXBreadcrumbOverflowMenu; diff --git a/packages/carbon-web-components/src/components/breadcrumb/breadcrumb-story.mdx b/packages/carbon-web-components/src/components/breadcrumb/breadcrumb-story.mdx new file mode 100644 index 00000000000..c32a35dcca7 --- /dev/null +++ b/packages/carbon-web-components/src/components/breadcrumb/breadcrumb-story.mdx @@ -0,0 +1,71 @@ +import { Props, Description } from '@storybook/addon-docs/blocks'; +import { cdnJs, cdnCss } from '../../globals/internal/storybook-cdn'; + +# Breadcrumb + +> ๐Ÿ’ก Check our +> [CodeSandbox](https://codesandbox.io/s/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/carbon-web-components/examples/codesandbox/basic/components/breadcrumb) +> example implementation. + +[![Edit carbon-web-components](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/carbon-web-components/examples/codesandbox/basic/components/breadcrumb) + +## Getting started + +Here's a quick example to get you started. + +### JS (via import) + +```javascript +import '@carbon/web-components/es/components/breadcrumb/index.js'; +``` + + + + +### HTML + +```html + + + Breadcrumb 1 + + + Breadcrumb 2 + + + Breadcrumb 3 + + +``` + +### HTML (with overflow-menu) + +```html + + + Breadcrumb 1 + + + Breadcrumb 2 + + + + + Option 1 + Option 2 + + + + + Breadcrumb 3 + + +``` + +## `` attributes, properties and events + + diff --git a/packages/carbon-web-components/src/components/breadcrumb/breadcrumb-story.ts b/packages/carbon-web-components/src/components/breadcrumb/breadcrumb-story.ts new file mode 100644 index 00000000000..f8cbd731abb --- /dev/null +++ b/packages/carbon-web-components/src/components/breadcrumb/breadcrumb-story.ts @@ -0,0 +1,67 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { html } from 'lit-element'; +import './breadcrumb'; +import './breadcrumb-item'; +import './breadcrumb-link'; +import './breadcrumb-overflow-menu'; +import storyDocs from './breadcrumb-story.mdx'; + +export const Default = () => + html` + + + Breadcrumb 1 + + + Breadcrumb 2 + + + Breadcrumb 3 + + + `; + +Default.storyName = 'Default'; + +export default { + title: 'Components/Breadcrumb', + parameters: { + ...storyDocs.parameters, + }, +}; + +export const withOverflowMenu = () => html` + + + Breadcrumb 1 + + + Breadcrumb 2 + + + + + Option 1 + Option 2 + + + + + Breadcrumb 3 + + +`; + +withOverflowMenu.storyName = 'with Overflow Menu'; diff --git a/packages/carbon-web-components/src/components/breadcrumb/breadcrumb.scss b/packages/carbon-web-components/src/components/breadcrumb/breadcrumb.scss new file mode 100644 index 00000000000..ea6c104c305 --- /dev/null +++ b/packages/carbon-web-components/src/components/breadcrumb/breadcrumb.scss @@ -0,0 +1,90 @@ +// +// Copyright IBM Corp. 2019, 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +$css--plex: true !default; + +@import 'carbon-components/scss/components/link/link'; +@import 'carbon-components/scss/components/breadcrumb/breadcrumb'; +@import '../overflow-menu/overflow-menu'; + +:host(#{$prefix}-breadcrumb) { + @extend .#{$prefix}--breadcrumb; +} + +:host(#{$prefix}-breadcrumb-item) { + @extend .#{$prefix}--breadcrumb-item; +} + +:host(#{$prefix}-breadcrumb-overflow-menu) { + position: relative; + width: rem(20px); + height: rem(18px); + + &:focus { + outline: 1px solid $focus; + } + + &:hover { + background: transparent; + ::after { + opacity: 1; + } + } + + // Used to mimic link underline + ::after { + position: absolute; + bottom: 2px; + width: rem(12px); + height: 1px; + background: $link-primary-hover; + content: ''; + opacity: 0; + transition: opacity $duration--fast-01 motion(standard, productive); + } +} + +:host(#{$prefix}-breadcrumb-overflow-menu[open]) { + background: transparent; + box-shadow: none; +} + +:host(#{$prefix}-breadcrumb-overflow-menu) svg { + position: relative; + fill: $link-01; + transform: translateY(4px); +} + +:host(#{$prefix}-breadcrumb-overflow-menu):hover svg { + fill: $link-primary-hover; +} + +:host(#{$prefix}-breadcrumb-item:last-of-type)::after { + content: ''; +} + +:host(#{$prefix}-breadcrumb-link) { + outline: none; + + // Re-define the ruleset so this wins over `.bx--link:visited`, etc. + .#{$prefix}--link--disabled { + color: $disabled-02; + } + + .#{$prefix}--link__icon[hidden] { + display: none; + } +} + +:host(#{$prefix}-breadcrumb-link[aria-current='page']) .#{$prefix}--link { + color: $text-01; + cursor: auto; + + &:hover { + text-decoration: none; + } +} diff --git a/packages/carbon-web-components/src/components/breadcrumb/breadcrumb.ts b/packages/carbon-web-components/src/components/breadcrumb/breadcrumb.ts new file mode 100644 index 00000000000..7215dfb036e --- /dev/null +++ b/packages/carbon-web-components/src/components/breadcrumb/breadcrumb.ts @@ -0,0 +1,42 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { html, customElement, LitElement } from 'lit-element'; +import settings from 'carbon-components/es/globals/js/settings'; +import styles from './breadcrumb.scss'; + +const { prefix } = settings; + +/** + * Breadcrumb. + * + * @element bx-breadcrumb + */ +@customElement(`${prefix}-breadcrumb`) +class BXBreadcrumb extends LitElement { + connectedCallback() { + if (!this.hasAttribute('role')) { + this.setAttribute('role', 'nav'); + } + super.connectedCallback(); + } + + render() { + return html` +
    + +
+ `; + } + + static styles = styles; // `styles` here is a `CSSResult` generated by custom WebPack loader +} + +export default BXBreadcrumb; diff --git a/packages/carbon-web-components/src/components/breadcrumb/index.ts b/packages/carbon-web-components/src/components/breadcrumb/index.ts new file mode 100644 index 00000000000..e849fc90d61 --- /dev/null +++ b/packages/carbon-web-components/src/components/breadcrumb/index.ts @@ -0,0 +1,12 @@ +/** + * @license + * + * Copyright IBM Corp. 2021 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import './breadcrumb'; +import './breadcrumb-item'; +import './breadcrumb-link'; diff --git a/packages/carbon-web-components/src/components/button/button-skeleton.ts b/packages/carbon-web-components/src/components/button/button-skeleton.ts new file mode 100644 index 00000000000..9109de2a304 --- /dev/null +++ b/packages/carbon-web-components/src/components/button/button-skeleton.ts @@ -0,0 +1,82 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import settings from 'carbon-components/es/globals/js/settings'; +import { classMap } from 'lit-html/directives/class-map'; +import { html, customElement } from 'lit-element'; +import ifNonNull from '../../globals/directives/if-non-null'; +import BXButton from './button'; +import styles from './button.scss'; + +const { prefix } = settings; + +/** + * Button skeleton. + */ +@customElement(`${prefix}-btn-skeleton`) +class BXButtonSkeleton extends BXButton { + /** + * Handles `click` event on the `
. + * + * @param event The event. + */ + private _handleClickLinkSkeleton(event: MouseEvent) { + if (this.disabled) { + event.preventDefault(); // Stop following the link + event.stopPropagation(); // Stop firing `onClick` + } + } + + render() { + const { + autofocus, + disabled, + download, + href, + hreflang, + ping, + rel, + size, + target, + type, + } = this; + const classes = classMap({ + [`${prefix}--btn`]: true, + [`${prefix}--skeleton`]: true, + [`${prefix}--btn--${size}`]: size, + }); + return href + ? html` + + ` + : html` + + `; + } + + static styles = styles; // `styles` here is a `CSSResult` generated by custom WebPack loader +} + +export default BXButtonSkeleton; diff --git a/packages/carbon-web-components/src/components/button/button-story.mdx b/packages/carbon-web-components/src/components/button/button-story.mdx new file mode 100644 index 00000000000..2f021bc43a1 --- /dev/null +++ b/packages/carbon-web-components/src/components/button/button-story.mdx @@ -0,0 +1,62 @@ +import { Props, Description } from '@storybook/addon-docs/blocks'; +import { cdnJs, cdnCss } from '../../globals/internal/storybook-cdn'; + +# Button + +> ๐Ÿ’ก Check our +> [CodeSandbox](https://codesandbox.io/s/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/carbon-web-components/examples/codesandbox/basic/components/button) +> example implementation. + +[![Edit carbon-web-components](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/carbon-web-components/examples/codesandbox/basic/components/button) + +Buttons are used to initialize an action, either in the background or foreground +of an experience. + +There are several kinds of buttons: + +- Primary buttons should be used for the principal call to action on the page. +- Secondary buttons should be used for secondary actions on each page. +- Danger buttons should be used for a negative action (such as Delete) on the + page. + +Small buttons may be used when there is not enough space for a regular sized +button. This issue is most often found in tables. Small buttons should have +three words or fewer. + +When words are not enough, icons can be used in buttons to better communicate +what the button does. Icons are always paired with text. + +## Getting started + +Here's a quick example to get you started. + +### JS (via import) + +```javascript +import '@carbon/web-components/es/components/button/index.js'; +``` + + + + +### HTML + +```html + Button +``` + +## Skeleton + +For the skeleton variation, utilize ``. + +```html + +``` + +## `` attributes and properties + +Note: For `boolean` attributes, `true` means simply setting the attribute (e.g. +``) and `false` means not setting the attribute (e.g. +`` without `autofocus` attribute). + + diff --git a/packages/carbon-web-components/src/components/button/button-story.ts b/packages/carbon-web-components/src/components/button/button-story.ts new file mode 100644 index 00000000000..92303290e18 --- /dev/null +++ b/packages/carbon-web-components/src/components/button/button-story.ts @@ -0,0 +1,184 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { html } from 'lit-html'; +import { action } from '@storybook/addon-actions'; +import { boolean, select } from '@storybook/addon-knobs'; +// Below path will be there when an application installs `carbon-web-components` package. +// In our dev env, we auto-generate the file and re-map below path to to point to the generated file. +// @ts-ignore +import Add16 from 'carbon-web-components/es/icons/add/16'; +import ifNonNull from '../../globals/directives/if-non-null'; +import { BUTTON_KIND, BUTTON_SIZE, BUTTON_ICON_LAYOUT } from './button'; +import './button-skeleton'; +import textNullable from '../../../.storybook/knob-text-nullable'; +import storyDocs from './button-story.mdx'; + +const kinds = { + [`Primary button (${BUTTON_KIND.PRIMARY})`]: BUTTON_KIND.PRIMARY, + [`Secondary button (${BUTTON_KIND.SECONDARY})`]: BUTTON_KIND.SECONDARY, + [`Tertiary button (${BUTTON_KIND.TERTIARY})`]: BUTTON_KIND.TERTIARY, + [`Danger button (${BUTTON_KIND.DANGER})`]: BUTTON_KIND.DANGER, + [`Danger tertiary button (${BUTTON_KIND.DANGER_TERTIARY})`]: + BUTTON_KIND.DANGER_TERTIARY, + [`Danger ghost button (${BUTTON_KIND.DANGER_GHOST})`]: + BUTTON_KIND.DANGER_GHOST, + [`Ghost button (${BUTTON_KIND.GHOST})`]: BUTTON_KIND.GHOST, +}; + +const sizes = { + 'Regular size': null, + [`Small size (${BUTTON_SIZE.SMALL})`]: BUTTON_SIZE.SMALL, + [`XL size (${BUTTON_SIZE.EXTRA_LARGE})`]: BUTTON_SIZE.EXTRA_LARGE, + [`Size for form field (${BUTTON_SIZE.FIELD})`]: BUTTON_SIZE.FIELD, +}; + +const iconLayouts = { + Regular: null, + [`Condensed (${BUTTON_ICON_LAYOUT.CONDENSED})`]: BUTTON_ICON_LAYOUT.CONDENSED, +}; + +export const Default = (args) => { + const { + autofocus, + disabled, + download, + href, + hreflang, + isExpressive, + kind, + linkRole, + ping, + rel, + size, + target, + type, + onClick, + } = args?.['bx-btn'] ?? {}; + return html` + + Button + + `; +}; + +Default.parameters = { + knobs: { + 'bx-btn': () => ({ + kind: select('Button kind (kind)', kinds, BUTTON_KIND.PRIMARY), + disabled: boolean('Disabled (disabled)', false), + size: select('Button size (size)', sizes, null), + href: textNullable('Link href (href)', ''), + onClick: action('click'), + isExpressive: boolean('expressive (isExpressive)', false), + }), + }, +}; + +export const icon = (args) => { + const { kind, disabled, size, href, isExpressive, onClick } = + args?.['bx-btn'] ?? {}; + return html` + + ${Add16({ slot: 'icon' })} + + `; +}; + +icon.parameters = Default.parameters; + +export const textAndIcon = (args) => { + const { kind, disabled, size, href, iconLayout, isExpressive, onClick } = + args?.['bx-btn'] ?? {}; + return html` + + Button ${Add16({ slot: 'icon' })} + + `; +}; + +textAndIcon.storyName = 'Text and icon'; + +textAndIcon.parameters = { + knobs: { + 'bx-btn': () => ({ + iconLayout: select('Icon layout (icon-layout)', iconLayouts, null), + kind: select('Button kind (kind)', kinds, BUTTON_KIND.PRIMARY), + disabled: boolean('Disabled (disabled)', false), + size: select('Button size (size)', sizes, null), + href: textNullable('Link href (href)', ''), + onClick: action('click'), + isExpressive: boolean('expressive (isExpressive)', false), + }), + }, +}; + +export const skeleton = (args) => { + const { disabled, size, href, isExpressive, onClick } = + args?.['bx-btn-skeleton']; + return html` + + + `; +}; + +skeleton.parameters = { + percy: { + skip: true, + }, + knobs: { + 'bx-btn-skeleton': () => ({ + kind: select('Button kind (kind)', kinds, BUTTON_KIND.PRIMARY), + disabled: boolean('Disabled (disabled)', false), + size: select('Button size (size)', sizes, null), + href: textNullable('Link href (href)', ''), + onClick: action('click'), + isExpressive: boolean('expressive (isExpressive)', false), + }), + }, +}; + +export default { + title: 'Components/Button', + parameters: { + ...storyDocs.parameters, + }, +}; diff --git a/packages/carbon-web-components/src/components/button/button.scss b/packages/carbon-web-components/src/components/button/button.scss new file mode 100644 index 00000000000..ee5a9d7a946 --- /dev/null +++ b/packages/carbon-web-components/src/components/button/button.scss @@ -0,0 +1,59 @@ +// +// Copyright IBM Corp. 2019, 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +$css--plex: true !default; + +@import 'carbon-components/scss/components/button/button'; + +:host(#{$prefix}-btn), +:host(#{$prefix}-modal-footer-button) { + display: inline-flex; + max-width: rem(320px); + outline: none; + + .#{$prefix}--btn { + flex-grow: 1; + max-width: 100%; + } + + ::slotted([slot='icon']) { + fill: currentColor; + position: absolute; + right: rem(16px); + flex-shrink: 0; + } + + &[isExpressive] ::slotted([slot='icon']) { + width: rem(20px); + height: rem(20px); + } + + &[icon-layout='condensed'] .#{$prefix}--btn { + padding-right: rem(39px); + } + + .#{$prefix}--btn--icon-only ::slotted([slot='icon']) { + position: static; + } + + &[kind='ghost'], + &[kind='danger-ghost'] { + ::slotted([slot='icon']) { + position: static; + margin-left: rem(8px); + } + + &[icon-layout='condensed'] .#{$prefix}--btn { + padding-right: rem(16px); + } + } +} + +:host(#{$prefix}-btn[kind='ghost']:hover) .#{$prefix}--btn--ghost, +:host(#{$prefix}-btn[kind='ghost']) .#{$prefix}--btn--ghost:active { + outline: none; +} diff --git a/packages/carbon-web-components/src/components/button/button.ts b/packages/carbon-web-components/src/components/button/button.ts new file mode 100644 index 00000000000..9342d9a2ae3 --- /dev/null +++ b/packages/carbon-web-components/src/components/button/button.ts @@ -0,0 +1,231 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import settings from 'carbon-components/es/globals/js/settings'; +import { classMap } from 'lit-html/directives/class-map'; +import { html, property, customElement, LitElement } from 'lit-element'; +import ifNonNull from '../../globals/directives/if-non-null'; +import FocusMixin from '../../globals/mixins/focus'; +import { BUTTON_KIND, BUTTON_SIZE, BUTTON_ICON_LAYOUT } from './defs'; +import styles from './button.scss'; +import HostListener from '../../globals/decorators/host-listener'; +import HostListenerMixin from '../../globals/mixins/host-listener'; + +export { BUTTON_KIND, BUTTON_SIZE, BUTTON_ICON_LAYOUT }; + +const { prefix } = settings; + +/** + * Button. + * + * @element bx-btn + * @csspart button The button. + */ +@customElement(`${prefix}-btn`) +class BXButton extends HostListenerMixin(FocusMixin(LitElement)) { + /** + * `true` if there is an icon. + */ + private _hasIcon = false; + + /** + * `true` if there is a non-icon content. + */ + private _hasMainContent = false; + + /** + * Handles `slotchange` event. + */ + private _handleSlotChange({ target }: Event) { + const { name } = target as HTMLSlotElement; + const hasContent = (target as HTMLSlotElement) + .assignedNodes() + .some( + (node) => node.nodeType !== Node.TEXT_NODE || node!.textContent!.trim() + ); + this[name === 'icon' ? '_hasIcon' : '_hasMainContent'] = hasContent; + this.requestUpdate(); + } + + @HostListener('click', { capture: true }) + // @ts-ignore + private _handleDisabledClick(event: Event) { + const { disabled } = this; + if (disabled) { + event.stopPropagation(); + } + } + + /** + * `true` if the button should have input focus when the page loads. + */ + @property({ type: Boolean, reflect: true }) + autofocus = false; + + /** + * `true` if the button should be disabled. + */ + @property({ type: Boolean, reflect: true }) + disabled = false; + + /** + * The default file name, used if this button is rendered as ``. + */ + @property({ reflect: true }) + download!: string; + + /** + * Link `href`. If present, this button is rendered as ``. + */ + @property({ reflect: true }) + href!: string; + + /** + * The language of what `href` points to, if this button is rendered as ``. + */ + @property({ reflect: true }) + hreflang!: string; + + /** + * Button icon layout. + */ + @property({ reflect: true, attribute: 'icon-layout' }) + iconLayout = BUTTON_ICON_LAYOUT.REGULAR; + + /** + * `true` if expressive theme enabled. + */ + @property({ type: Boolean, reflect: true }) + isExpressive = false; + + /** + * Button kind. + */ + @property({ reflect: true }) + kind = BUTTON_KIND.PRIMARY; + + /** + * The a11y role for ``. + */ + @property({ attribute: 'link-role' }) + linkRole = 'button'; + + /** + * URLs to ping, if this button is rendered as ``. + */ + @property({ reflect: true }) + ping!: string; + + /** + * The link type, if this button is rendered as ``. + */ + @property({ reflect: true }) + rel!: string; + + /** + * Button size. + */ + @property({ reflect: true }) + size = BUTTON_SIZE.REGULAR; + + /** + * The link target, if this button is rendered as ``. + */ + @property({ reflect: true }) + target!: string; + + /** + * The default behavior if the button is rendered as ` + `; + } + + static styles = styles; // `styles` here is a `CSSResult` generated by custom WebPack loader +} + +export default BXButton; diff --git a/packages/carbon-web-components/src/components/button/defs.ts b/packages/carbon-web-components/src/components/button/defs.ts new file mode 100644 index 00000000000..a9b4d3661c8 --- /dev/null +++ b/packages/carbon-web-components/src/components/button/defs.ts @@ -0,0 +1,88 @@ +/** + * @license + * + * Copyright IBM Corp. 2020 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * Button kinds. + */ +export enum BUTTON_KIND { + /** + * Primary button. + */ + PRIMARY = 'primary', + + /** + * Secondary button. + */ + SECONDARY = 'secondary', + + /** + * Tertiary button. + */ + TERTIARY = 'tertiary', + + /** + * Ghost button. + */ + GHOST = 'ghost', + + /** + * Danger button. + */ + DANGER = 'danger', + + /** + * Danger tertiary button. + */ + DANGER_TERTIARY = 'danger-tertiary', + + /** + * Danger ghost button, + */ + DANGER_GHOST = 'danger-ghost', +} + +/** + * Button size. + */ +export enum BUTTON_SIZE { + /** + * Regular size. + */ + REGULAR = '', + + /** + * Small size. + */ + SMALL = 'sm', + + /** + * X-Large size. + */ + EXTRA_LARGE = 'xl', + + /** + * Size for form field. + */ + FIELD = 'field', +} + +/** + * Button icon layout. + */ +export enum BUTTON_ICON_LAYOUT { + /** + * Regular layout. + */ + REGULAR = '', + + /** + * Condensed layout. + */ + CONDENSED = 'condensed', +} diff --git a/packages/carbon-web-components/src/components/button/index.ts b/packages/carbon-web-components/src/components/button/index.ts new file mode 100644 index 00000000000..cc7fb99588f --- /dev/null +++ b/packages/carbon-web-components/src/components/button/index.ts @@ -0,0 +1,11 @@ +/** + * @license + * + * Copyright IBM Corp. 2021 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import './button'; +import './button-skeleton'; diff --git a/packages/carbon-web-components/src/components/checkbox/checkbox-story.mdx b/packages/carbon-web-components/src/components/checkbox/checkbox-story.mdx new file mode 100644 index 00000000000..ff065ef806b --- /dev/null +++ b/packages/carbon-web-components/src/components/checkbox/checkbox-story.mdx @@ -0,0 +1,43 @@ +import { Props, Description } from '@storybook/addon-docs/blocks'; +import { cdnJs, cdnCss } from '../../globals/internal/storybook-cdn'; + +# Check box + +> ๐Ÿ’ก Check our +> [CodeSandbox](https://codesandbox.io/s/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/carbon-web-components/examples/codesandbox/basic/components/checkbox) +> example implementation. + +[![Edit carbon-web-components](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/carbon-web-components/examples/codesandbox/basic/components/checkbox) + +Check box in `carbon-web-components` represents a combination of a check box and +its label. + +## Getting started + +Here's a quick example to get you started. + +### JS (via import) + +```javascript +import '@carbon/web-components/es/components/checkbox/index.js'; +``` + + + + +### HTML + +```html + +``` + +## `` attributes, properties and events + +Unlike regular checkbox, `` does _not_ fire `change` event. Please +use `bx-checkbox-changed` event instead. + +Note: For `boolean` attributes, `true` means simply setting the attribute (e.g. +``) and `false` means not setting the attribute (e.g. +`` without `checked` attribute). + + diff --git a/packages/carbon-web-components/src/components/checkbox/checkbox-story.ts b/packages/carbon-web-components/src/components/checkbox/checkbox-story.ts new file mode 100644 index 00000000000..9ca19676f94 --- /dev/null +++ b/packages/carbon-web-components/src/components/checkbox/checkbox-story.ts @@ -0,0 +1,61 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { html } from 'lit-element'; +import { action } from '@storybook/addon-actions'; +import { boolean } from '@storybook/addon-knobs'; +import textNullable from '../../../.storybook/knob-text-nullable'; +import ifNonNull from '../../globals/directives/if-non-null'; +import './checkbox'; +import storyDocs from './checkbox-story.mdx'; + +export const Default = (args) => { + const { + checked, + disabled, + hideLabel, + indeterminate, + labelText, + name, + value, + onChange, + } = args?.['bx-checkbox'] ?? {}; + return html` + + `; +}; + +Default.storyName = 'Default'; + +export default { + title: 'Components/Checkbox', + parameters: { + ...storyDocs.parameters, + knobs: { + 'bx-checkbox': () => ({ + checked: boolean('Checked (checked)', false), + disabled: boolean('Disabled (disabled)', false), + hideLabel: boolean('Hide label (hide-label)', false), + indeterminate: boolean('Indeterminate state (indeterminate)', false), + labelText: textNullable('Label text (label-text)', 'Checkbox'), + name: textNullable('Name (name)', ''), + value: textNullable('Value (value)', ''), + onChange: action('bx-checkbox-changed'), + }), + }, + }, +}; diff --git a/packages/carbon-web-components/src/components/checkbox/checkbox.scss b/packages/carbon-web-components/src/components/checkbox/checkbox.scss new file mode 100644 index 00000000000..19327554000 --- /dev/null +++ b/packages/carbon-web-components/src/components/checkbox/checkbox.scss @@ -0,0 +1,19 @@ +// +// Copyright IBM Corp. 2019, 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +$css--plex: true !default; + +@import 'carbon-components/scss/globals/scss/css--helpers'; +@import 'carbon-components/scss/components/form/form'; +@import 'carbon-components/scss/components/checkbox/checkbox'; + +:host(#{$prefix}-checkbox) { + @extend .#{$prefix}--form-item; + @extend .#{$prefix}--checkbox-wrapper; + + outline: none; +} diff --git a/packages/carbon-web-components/src/components/checkbox/checkbox.ts b/packages/carbon-web-components/src/components/checkbox/checkbox.ts new file mode 100644 index 00000000000..16ffb562ecc --- /dev/null +++ b/packages/carbon-web-components/src/components/checkbox/checkbox.ts @@ -0,0 +1,157 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { classMap } from 'lit-html/directives/class-map'; +import { html, property, query, customElement, LitElement } from 'lit-element'; +import settings from 'carbon-components/es/globals/js/settings'; +import ifNonNull from '../../globals/directives/if-non-null'; +import FocusMixin from '../../globals/mixins/focus'; +import FormMixin from '../../globals/mixins/form'; +import styles from './checkbox.scss'; + +const { prefix } = settings; + +/** + * Check box. + * + * @element bx-checkbox + * @fires bx-checkbox-changed - The custom event fired after this changebox changes its checked state. + * @csspart input The checkbox. + * @csspart label The label. + */ +@customElement(`${prefix}-checkbox`) +class BXCheckbox extends FocusMixin(FormMixin(LitElement)) { + @query('input') + protected _checkboxNode!: HTMLInputElement; + + /** + * Handles `click` event on the `` in the shadow DOM. + */ + protected _handleChange() { + const { checked, indeterminate } = this._checkboxNode; + this.checked = checked; + this.indeterminate = indeterminate; + const { eventChange } = this.constructor as typeof BXCheckbox; + this.dispatchEvent( + new CustomEvent(eventChange, { + bubbles: true, + composed: true, + detail: { + indeterminate, + }, + }) + ); + } + + _handleFormdata(event: Event) { + const { formData } = event as any; // TODO: Wait for `FormDataEvent` being available in `lib.dom.d.ts` + const { checked, disabled, name, value = 'on' } = this; + if (!disabled && checked) { + formData.append(name, value); + } + } + + /** + * `true` if the check box should be checked. + */ + @property({ type: Boolean, reflect: true }) + checked = false; + + /** + * `true` if the check box should be disabled. + */ + @property({ type: Boolean, reflect: true }) + disabled = false; + + /** + * `true` if the label should be hidden. + */ + @property({ type: Boolean, reflect: true, attribute: 'hide-label' }) + hideLabel = false; + + /** + * `true` if the check box should show its UI of the indeterminate state. + */ + @property({ type: Boolean, reflect: true }) + indeterminate = false; + + /** + * The label text. + */ + @property({ attribute: 'label-text' }) + labelText = ''; + + /** + * The form name. + */ + @property() + name!: string; + + /** + * The value. + */ + @property() + value!: string; + + createRenderRoot() { + return this.attachShadow({ + mode: 'open', + delegatesFocus: + Number((/Safari\/(\d+)/.exec(navigator.userAgent) ?? ['', 0])[1]) <= + 537, + }); + } + + render() { + const { + checked, + disabled, + hideLabel, + indeterminate, + labelText, + name, + value, + _handleChange: handleChange, + } = this; + const labelClasses = classMap({ + [`${prefix}--checkbox-label`]: true, + [`${prefix}--visually-hidden`]: hideLabel, + }); + return html` + + + `; + } + + /** + * The name of the custom event fired after this changebox changes its checked state. + */ + static get eventChange() { + return `${prefix}-checkbox-changed`; + } + + static styles = styles; // `styles` here is a `CSSResult` generated by custom WebPack loader +} + +export default BXCheckbox; diff --git a/packages/carbon-web-components/src/components/checkbox/index.ts b/packages/carbon-web-components/src/components/checkbox/index.ts new file mode 100644 index 00000000000..24c3f81018d --- /dev/null +++ b/packages/carbon-web-components/src/components/checkbox/index.ts @@ -0,0 +1,10 @@ +/** + * @license + * + * Copyright IBM Corp. 2021 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import './checkbox'; diff --git a/packages/carbon-web-components/src/components/code-snippet/code-snippet-skeleton.ts b/packages/carbon-web-components/src/components/code-snippet/code-snippet-skeleton.ts new file mode 100644 index 00000000000..66af11772d4 --- /dev/null +++ b/packages/carbon-web-components/src/components/code-snippet/code-snippet-skeleton.ts @@ -0,0 +1,41 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { html, property, customElement, LitElement } from 'lit-element'; +import settings from 'carbon-components/es/globals/js/settings'; +import { CODE_SNIPPET_TYPE } from './code-snippet'; +import styles from './code-snippet.scss'; + +const { prefix } = settings; + +/** + * Skeleton of code snippet. + */ +@customElement(`${prefix}-code-snippet-skeleton`) +class BXCodeSnippetSkeleton extends LitElement { + /** + * The type of code snippet. Corresponds to the attribute with the same name. + */ + @property({ reflect: true }) + type = CODE_SNIPPET_TYPE.SINGLE; + + render() { + return html` +
+ ${this.type !== CODE_SNIPPET_TYPE.MULTI + ? html` ` + : html` `} +
+ `; + } + + static styles = styles; +} + +export default BXCodeSnippetSkeleton; diff --git a/packages/carbon-web-components/src/components/code-snippet/code-snippet-story.mdx b/packages/carbon-web-components/src/components/code-snippet/code-snippet-story.mdx new file mode 100644 index 00000000000..b98a57357dc --- /dev/null +++ b/packages/carbon-web-components/src/components/code-snippet/code-snippet-story.mdx @@ -0,0 +1,83 @@ +import { Props, Description } from '@storybook/addon-docs/blocks'; +import { cdnJs, cdnCss } from '../../globals/internal/storybook-cdn'; + +# Code snippet + +> ๐Ÿ’ก Check our +> [CodeSandbox](https://codesandbox.io/s/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/carbon-web-components/examples/codesandbox/basic/components/code-snippet) +> example implementation. + +[![Edit carbon-web-components](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/carbon-web-components/examples/codesandbox/basic/components/code-snippet) + +Code snippets are small blocks of reusable code that can be inserted in a code +file. + +## Getting started + +Here's a quick example to get you started. + +### JS (via import) + +```javascript +import '@carbon/web-components/es/components/code-snippet/index.js'; +``` + + + + +### HTML + +```html + + node -v Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis, + veritatis voluptate id incidunt molestiae officia possimus, quasi itaque + alias, architecto hic, dicta fugit? Debitis delectus quidem explicabo vitae + laboriosam! + +``` + +## Single line + +The Terminal style is for single-line. + +```html + + node -v Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis, + veritatis voluptate id incidunt molestiae officia possimus, quasi itaque + alias, architecto hic, dicta fugit? Debitis delectus quidem explicabo vitae + laboriosam! + +``` + +## Multi line + +The Code style is for larger, multi-line code snippets. + +```html + + node -v Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis, + veritatis voluptate id incidunt molestiae officia possimus, quasi itaque + alias, architecto hic, dicta fugit? Debitis delectus quidem explicabo vitae + laboriosam! + +``` + +## Inline + +The Inline style is for code used within a block of text. + +```html + node -v +``` + +## Skeleton + +For the skeleton variation, utilize ``. + +```html + +``` + +## `` attributes and properties + + diff --git a/packages/carbon-web-components/src/components/code-snippet/code-snippet-story.ts b/packages/carbon-web-components/src/components/code-snippet/code-snippet-story.ts new file mode 100644 index 00000000000..eda4420b5a9 --- /dev/null +++ b/packages/carbon-web-components/src/components/code-snippet/code-snippet-story.ts @@ -0,0 +1,205 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { html } from 'lit-element'; +import { action } from '@storybook/addon-actions'; +import { number, select } from '@storybook/addon-knobs'; +import textNullable from '../../../.storybook/knob-text-nullable'; +import ifNonNull from '../../globals/directives/if-non-null'; +import { CODE_SNIPPET_COLOR_SCHEME } from './code-snippet'; +import storyDocs from './code-snippet-story.mdx'; +import './code-snippet-skeleton'; + +const colorSchemes = { + [`Regular`]: null, + [`Light (${CODE_SNIPPET_COLOR_SCHEME.LIGHT})`]: + CODE_SNIPPET_COLOR_SCHEME.LIGHT, +}; + +const defaultKnobs = { + 'bx-code-snippet': () => ({ + codeAssistiveText: textNullable( + 'Assistive text for the code portion (code-assistive-text)', + '' + ), + copyButtonAssistiveText: textNullable( + 'Assistive text for the copy button (copy-button-assistive-text)', + '' + ), + copyButtonFeedbackText: textNullable( + 'Feedback text for copy button (copy-button-feedback-text)', + '' + ), + copyButtonFeedbackTimeout: number( + 'Feedback timeout for copy button (copy-buttobn-feedback-timeout)', + 2000 + ), + colorScheme: select('Color scheme (color-scheme)', colorSchemes, null), + onClick: action('click'), + }), +}; + +export const singleLine = (args) => { + const { + codeAssistiveText, + copyButtonAssistiveText, + copyButtonFeedbackText, + copyButtonFeedbackTimeout, + colorScheme, + onClick, + } = args?.['bx-code-snippet'] ?? {}; + const children = ` + node -v Lorem ipsum dolor sit amet, consectetur adipisicing elit. Blanditiis, veritatis voluptate id incidunt molestiae + officia possimus, quasi itaque alias, architecto hic, dicta fugit? Debitis delectus quidem explicabo vitae + laboriosam! + `; + return html` + ${children} + `; +}; + +singleLine.storyName = 'Single line'; + +singleLine.parameters = { + knobs: defaultKnobs, +}; + +export const multiLine = (args) => { + const { + codeAssistiveText, + copyButtonAssistiveText, + copyButtonFeedbackText, + copyButtonFeedbackTimeout, + collapseButtonText, + expandButtonText, + colorScheme, + onClick, + } = args?.['bx-code-snippet'] ?? {}; + const children = ` +@mixin grid-container { + width: 100%; + padding-right: padding(mobile); + padding-left: padding(mobile); + + @include breakpoint(bp--xs--major) { + padding-right: padding(xs); + padding-left: padding(xs); + } +} + +$z-indexes: ( + modal : 9000, + overlay : 8000, + dropdown : 7000, + header : 6000, + footer : 5000, + hidden : - 1, + overflowHidden: - 1, + floating: 10000 +); +`.trim(); + // prettier-ignore + return html` + ${children} +`; +}; + +multiLine.storyName = 'Multi line'; + +multiLine.parameters = { + knobs: { + 'bx-code-snippet': () => ({ + ...defaultKnobs['bx-code-snippet'](), + collapseButtonText: textNullable( + 'The text for the collapse button (collapse-button-text)', + '' + ), + expandButtonText: textNullable( + 'The text for the expand button (expand-button-text)', + '' + ), + }), + }, +}; + +export const inline = (args) => { + const { + codeAssistiveText, + copyButtonAssistiveText, + copyButtonFeedbackText, + copyButtonFeedbackTimeout, + colorScheme, + onClick, + } = args?.['bx-code-snippet'] ?? {}; + return html` + node -v + `; +}; + +inline.storyName = 'Inline'; + +inline.parameters = { + knobs: defaultKnobs, +}; + +export const skeletonSingleLine = () => + html` `; + +skeletonSingleLine.storyName = 'Skeleton single line'; + +skeletonSingleLine.parameters = { + percy: { + skip: true, + }, +}; + +export const skeletonMultiLine = () => + html` `; + +skeletonMultiLine.storyName = 'Skeleton multi line'; + +skeletonMultiLine.parameters = { + percy: { + skip: true, + }, +}; + +export default { + title: 'Components/Code snippet', + parameters: { + ...storyDocs.parameters, + }, +}; diff --git a/packages/carbon-web-components/src/components/code-snippet/code-snippet.scss b/packages/carbon-web-components/src/components/code-snippet/code-snippet.scss new file mode 100644 index 00000000000..f139aaa2856 --- /dev/null +++ b/packages/carbon-web-components/src/components/code-snippet/code-snippet.scss @@ -0,0 +1,174 @@ +// +// Copyright IBM Corp. 2019, 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +$css--plex: true !default; + +@import 'carbon-components/scss/globals/scss/helper-mixins'; +@import 'carbon-components/scss/components/code-snippet/code-snippet'; +@import 'carbon-components/scss/components/copy-button/copy-button'; + +:host(#{$prefix}-code-snippet), +:host(#{$prefix}-code-snippet-skeleton) { + @extend .#{$prefix}--snippet--single; + + outline: none; + + &::after { + background-color: $ui-01; + background-image: none; + mask-image: linear-gradient(to right, transparent 0%, $ui-01 100%); + @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { + background-color: transparent; + background-image: linear-gradient(to right, transparent, $ui-01); + } + } + + .#{$prefix}--snippet-button .#{$prefix}--btn--copy__feedback { + left: 50%; + right: auto; + } + + .#{$prefix}--snippet-container { + display: flex; + align-items: center; + overflow-x: auto; + position: relative; + height: 100%; + } + + .#{$prefix}--snippet-btn--expand { + z-index: 1; + min-height: rem(40px); + } + + pre { + white-space: nowrap; + @include type-style('code-01'); + + padding-right: $spacing-xs; + } +} + +:host(#{$prefix}-code-snippet[color-scheme='light']) { + background-color: $ui-02; + + button.#{$prefix}--btn.#{$prefix}--snippet-btn--expand { + background-color: $ui-02; + } + + &:hover { + background-color: $hover-ui-light; + } + + .#{$prefix}--snippet-button:hover, + button.#{$prefix}--btn.#{$prefix}--snippet-btn--expand:hover { + background-color: $hover-ui-light; + } +} + +:host(#{$prefix}-code-snippet[type='multi']), +:host(#{$prefix}-code-snippet-skeleton[type='multi']) { + @extend .#{$prefix}--snippet--multi; + + height: auto; + + &::after { + position: absolute; + content: ''; + left: 0; + top: auto; + bottom: rem(16px); + width: 100%; + height: rem(16px); + background-color: $ui-01; + background-image: none; + mask-image: linear-gradient(to bottom, transparent 0%, $ui-01 100%); + @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { + background-color: transparent; + background-image: linear-gradient(to bottom, transparent, $ui-01); + } + } + + .#{$prefix}--snippet-container { + display: block; + overflow: hidden; + position: relative; + height: auto; + padding-bottom: 0; + max-height: rem(238px); + min-height: rem(56px); + transition: max-height $duration--moderate-01 motion(standard, productive); + + pre { + overflow: hidden; + padding-bottom: rem(24px); + white-space: pre; + padding-right: 0; + + &::after { + // Use top-level pseudo element instead because `
` here is inside a scrolling container
+        content: none;
+      }
+
+      code {
+        overflow: hidden;
+      }
+    }
+  }
+
+  .#{$prefix}-ce--snippet-container--expanded {
+    max-height: rem(1500px);
+    transition: max-height $duration--moderate-01 motion(standard, productive);
+
+    pre {
+      overflow-x: auto;
+    }
+  }
+}
+
+:host(#{$prefix}-code-snippet[type='inline']) {
+  display: inline-flex;
+  width: auto;
+  height: auto;
+  min-width: auto;
+  max-width: auto;
+  padding: 0;
+
+  &::after {
+    content: none;
+  }
+
+  .#{$prefix}--btn--copy__feedback {
+    // Half of the diagonal line of `0.6rem` square
+    top: rem(6.7882px);
+  }
+}
+
+:host(#{$prefix}-code-snippet-skeleton) {
+  @extend .#{$prefix}--skeleton;
+
+  span {
+    @include skeleton;
+
+    width: 100%;
+    height: 1rem;
+    display: block;
+    margin-top: 0.5rem;
+
+    &:first-child {
+      margin: 0;
+    }
+
+    &:nth-child(2) {
+      width: 85%;
+    }
+
+    &:nth-child(3) {
+      width: 95%;
+    }
+  }
+}
diff --git a/packages/carbon-web-components/src/components/code-snippet/code-snippet.ts b/packages/carbon-web-components/src/components/code-snippet/code-snippet.ts
new file mode 100644
index 00000000000..4a090f6f94b
--- /dev/null
+++ b/packages/carbon-web-components/src/components/code-snippet/code-snippet.ts
@@ -0,0 +1,301 @@
+/**
+ * @license
+ *
+ * Copyright IBM Corp. 2019, 2022
+ *
+ * This source code is licensed under the Apache-2.0 license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import { classMap } from 'lit-html/directives/class-map';
+import { TemplateResult } from 'lit-html';
+import { html, property, query, customElement, LitElement } from 'lit-element';
+import ChevronDown16 from '@carbon/icons/lib/chevron--down/16';
+import settings from 'carbon-components/es/globals/js/settings';
+import FocusMixin from '../../globals/mixins/focus';
+import {
+  _createHandleFeedbackTooltip as createHandleCopyButtonFeedbackTooltip,
+  _renderButton as renderCopyButton,
+} from '../copy-button/copy-button';
+import { CODE_SNIPPET_COLOR_SCHEME, CODE_SNIPPET_TYPE } from './defs';
+import styles from './code-snippet.scss';
+
+export { CODE_SNIPPET_COLOR_SCHEME, CODE_SNIPPET_TYPE };
+
+const { prefix } = settings;
+
+/**
+ * @param values The values to render.
+ * @param values.children The child nodes.
+ * @param values.handleClick The handler for the `click` event on the button.
+ * @returns The template result for the expando.
+ */
+const renderExpando = ({
+  children,
+  handleClick,
+}: {
+  children: string | TemplateResult;
+  handleClick: EventListener;
+}) => html`
+  
+`;
+
+/**
+ * @param values The values to render.
+ * @param values.assistiveText The assistive text to announce that the node is for code snippet.
+ * @param [values.expanded] `true` to show the expanded state (for multi-line variant).
+ * @param values.children The child nodes.
+ * @returns The template result for the code snippet.
+ */
+const renderCode = ({
+  assistiveText,
+  expanded,
+  children,
+}: {
+  assistiveText: string;
+  expanded?: boolean;
+  children: string | TemplateResult;
+}) => {
+  const classes = classMap({
+    [`${prefix}--snippet-container`]: true,
+    [`${prefix}-ce--snippet-container--expanded`]: Boolean(expanded),
+  });
+  // Ensures no extra whitespace text node
+  // prettier-ignore
+  return html`
+    
${children}
+ `; +}; + +/** + * Basic code snippet. + * + * @element bx-code-snippet + */ +@customElement(`${prefix}-code-snippet`) +class BXCodeSnippet extends FocusMixin(LitElement) { + /** + * `true` to expand multi-line variant of code snippet. + */ + private _expanded = false; + + /** + * `true` to show the feedback tooltip. + */ + private _showCopyButtonFeedback = false; + + /** + * `true` to show the expando. + */ + private _showExpando = false; + + /** + * Handles `click` event on the copy button. + */ + private _handleClickCopyButton() { + const { ownerDocument: doc } = this; + const selection = doc!.defaultView!.getSelection(); + selection!.removeAllRanges(); + const code = doc!.createElement('code'); + code.className = `${prefix}--visually-hidden`; + const pre = doc!.createElement('pre'); + pre.textContent = this.textContent; + code.appendChild(pre); + // Using `` in shadow DOM seems to lose the LFs in some browsers + doc!.body.appendChild(code); + const range = doc!.createRange(); + range.selectNodeContents(code); + selection!.addRange(range); + doc!.execCommand('copy'); + this._handleCopyButtonFeedbackTooltip(this.copyButtonFeedbackTimeout); + doc!.body.removeChild(code); + selection!.removeAllRanges(); + } + + /** + * Handles showing/hiding the feedback tooltip. + */ + private _handleCopyButtonFeedbackTooltip = + createHandleCopyButtonFeedbackTooltip( + ({ showFeedback = false }: { showFeedback?: boolean }) => { + this._showCopyButtonFeedback = showFeedback; + this.requestUpdate(); + } + ); + + /** + * Handles `click` event on the expando. + */ + private _handleClickExpando() { + this._expanded = !this._expanded; + this.requestUpdate(); + } + + /** + * Handles change in slot content to determine if the content + */ + private _handleSlotChange() { + const { type, _preNode: preNode } = this; + if (type === CODE_SNIPPET_TYPE.MULTI) { + if (preNode.getBoundingClientRect().height > 255) { + this._showExpando = true; + this.requestUpdate(); + } + } + } + + /** + * The `
` element in the shadow DOM.
+   */
+  @query('pre')
+  private _preNode!: HTMLPreElement;
+
+  /**
+   * An assistive text for screen reader to advice a DOM node is for code snippet.
+   */
+  @property({ attribute: 'code-assistive-text' })
+  codeAssistiveText = 'code-snippet';
+
+  /**
+   * The context content for the collapse button.
+   */
+  @property({ attribute: 'collapse-button-text' })
+  collapseButtonText = 'Show less';
+
+  /**
+   * The color scheme.
+   */
+  @property({ attribute: 'color-scheme', reflect: true })
+  colorScheme = CODE_SNIPPET_COLOR_SCHEME.REGULAR;
+
+  /**
+   * An assistive text for screen reader to announce, telling that the button copies the content to the clipboard.
+   */
+  @property({ attribute: 'copy-button-assistive-text' })
+  copyButtonAssistiveText = 'Copy to clipboard';
+
+  /**
+   * The feedback text for the copy button.
+   */
+  @property({ attribute: 'copy-button-feedback-text' })
+  copyButtonFeedbackText = 'Copied!';
+
+  /**
+   * The number in milliseconds to determine how long the tooltip for the copy button should remain.
+   */
+  @property({ type: Number, attribute: 'copy-button-feedback-timeout' })
+  copyButtonFeedbackTimeout = 2000;
+
+  /**
+   * The context content for the expand button.
+   */
+  @property({ attribute: 'expand-button-text' })
+  expandButtonText = 'Show more';
+
+  /**
+   * The type of code snippet.
+   */
+  @property({ reflect: true })
+  type = CODE_SNIPPET_TYPE.SINGLE;
+
+  createRenderRoot() {
+    return this.attachShadow({
+      mode: 'open',
+      delegatesFocus:
+        Number((/Safari\/(\d+)/.exec(navigator.userAgent) ?? ['', 0])[1]) <=
+        537,
+    });
+  }
+
+  render() {
+    const {
+      codeAssistiveText,
+      collapseButtonText,
+      copyButtonAssistiveText,
+      copyButtonFeedbackText,
+      expandButtonText,
+      type,
+      _expanded: expanded,
+      _showCopyButtonFeedback: showCopyButtonFeedback,
+      _showExpando: showExpando,
+      _handleClickCopyButton: handleClickCopyButton,
+      _handleClickExpando: handleClickExpando,
+      _handleSlotChange: handleSlotChange,
+    } = this;
+
+    if (type === CODE_SNIPPET_TYPE.SINGLE) {
+      // Ensures no extra whitespace text node
+      // prettier-ignore
+      return html`
+        ${renderCode({
+          assistiveText: codeAssistiveText,
+          expanded,
+          children: html``,
+        })}
+        ${renderCopyButton({
+          assistiveText: copyButtonAssistiveText,
+          feedbackText: copyButtonFeedbackText,
+          showFeedback: showCopyButtonFeedback,
+          handleClickButton: handleClickCopyButton,
+          className: `${prefix}--snippet-button`,
+        })}
+      `;
+    }
+
+    if (type === CODE_SNIPPET_TYPE.MULTI) {
+      // Ensures no extra whitespace text node
+      // prettier-ignore
+      return html`
+        ${renderCode({
+          assistiveText: codeAssistiveText,
+          expanded,
+          children: html``,
+        })}
+        ${renderCopyButton({
+          assistiveText: copyButtonAssistiveText,
+          feedbackText: copyButtonFeedbackText,
+          showFeedback: showCopyButtonFeedback,
+          handleClickButton: handleClickCopyButton,
+          className: `${prefix}--snippet-button`,
+        })}
+        ${!showExpando
+          ? undefined
+          : renderExpando({
+              children: expanded
+                ? html`${collapseButtonText}`
+                : html`${expandButtonText}`,
+              handleClick: handleClickExpando,
+            })}
+      `;
+    }
+
+    // Ensures no extra whitespace text node
+    // prettier-ignore
+    return html`
+      ${renderCopyButton({
+        assistiveText: copyButtonAssistiveText,
+        feedbackText: copyButtonFeedbackText,
+        showFeedback: showCopyButtonFeedback,
+        handleClickButton: handleClickCopyButton,
+        className: `${prefix}--snippet ${prefix}--snippet--inline`,
+        children: html``,
+      })}
+    `;
+  }
+
+  static styles = styles;
+}
+
+export default BXCodeSnippet;
diff --git a/packages/carbon-web-components/src/components/code-snippet/defs.ts b/packages/carbon-web-components/src/components/code-snippet/defs.ts
new file mode 100644
index 00000000000..c8106c989e1
--- /dev/null
+++ b/packages/carbon-web-components/src/components/code-snippet/defs.ts
@@ -0,0 +1,30 @@
+/**
+ * @license
+ *
+ * Copyright IBM Corp. 2020
+ *
+ * This source code is licensed under the Apache-2.0 license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+export { FORM_ELEMENT_COLOR_SCHEME as CODE_SNIPPET_COLOR_SCHEME } from '../../globals/shared-enums';
+
+/**
+ * Code snippet types.
+ */
+export enum CODE_SNIPPET_TYPE {
+  /**
+   * Single variant.
+   */
+  SINGLE = 'single',
+
+  /**
+   * Inline variant.
+   */
+  INLINE = 'inline',
+
+  /**
+   * Multi-line variant.
+   */
+  MULTI = 'multi',
+}
diff --git a/packages/carbon-web-components/src/components/code-snippet/index.ts b/packages/carbon-web-components/src/components/code-snippet/index.ts
new file mode 100644
index 00000000000..54068df03ee
--- /dev/null
+++ b/packages/carbon-web-components/src/components/code-snippet/index.ts
@@ -0,0 +1,11 @@
+/**
+ * @license
+ *
+ * Copyright IBM Corp. 2021
+ *
+ * This source code is licensed under the Apache-2.0 license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import './code-snippet';
+import './code-snippet-skeleton';
diff --git a/packages/carbon-web-components/src/components/combo-box/combo-box-item.ts b/packages/carbon-web-components/src/components/combo-box/combo-box-item.ts
new file mode 100644
index 00000000000..b0a350c89ab
--- /dev/null
+++ b/packages/carbon-web-components/src/components/combo-box/combo-box-item.ts
@@ -0,0 +1,27 @@
+/**
+ * @license
+ *
+ * Copyright IBM Corp. 2019, 2022
+ *
+ * This source code is licensed under the Apache-2.0 license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import settings from 'carbon-components/es/globals/js/settings';
+import { customElement } from 'lit-element';
+import BXDropdownItem from '../dropdown/dropdown-item';
+import styles from './combo-box.scss';
+
+const { prefix } = settings;
+
+/**
+ * Combo box item.
+ *
+ * @element bx-combo-box-item
+ */
+@customElement(`${prefix}-combo-box-item`)
+class BXComboBoxItem extends BXDropdownItem {
+  static styles = styles;
+}
+
+export default BXComboBoxItem;
diff --git a/packages/carbon-web-components/src/components/combo-box/combo-box-story.mdx b/packages/carbon-web-components/src/components/combo-box/combo-box-story.mdx
new file mode 100644
index 00000000000..30fc0063523
--- /dev/null
+++ b/packages/carbon-web-components/src/components/combo-box/combo-box-story.mdx
@@ -0,0 +1,79 @@
+import { Props, Description } from '@storybook/addon-docs/blocks';
+import { cdnJs, cdnCss } from '../../globals/internal/storybook-cdn';
+
+# Combo box
+
+> ๐Ÿ’ก Check our
+> [CodeSandbox](https://codesandbox.io/s/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/carbon-web-components/examples/codesandbox/basic/components/combo-box)
+> example implementation.
+
+[![Edit carbon-web-components](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/carbon-web-components/examples/codesandbox/basic/components/combo-box)
+
+Combo box realizes a notion of "filterable dropdown". By default, the dropdown
+displays a label when closed. When the user hovers over the label area, a text
+cursor will appear. The drawer opens on click (anywhere in the field) and the
+user can type to filter through the list of options below. Once the user begins
+typing, the close (X) icon will appear to the right of the label. This will
+clear any user-inputted text. Selecting an item from the dropdown will close the
+drawer and the selected option will replace the default label.
+
+## Getting started
+
+Here's a quick example to get you started.
+
+### JS (via import)
+
+```javascript
+import '@carbon/web-components/es/components/combo-box/index.js';
+```
+
+
+
+
+### HTML
+
+```html
+
+  Option 1
+  Option 2
+  Option 3
+  Option 4
+  Option 5
+  Option 6
+  Option 7
+  Option 8
+
+```
+
+## Selection
+
+When user attempts to select a combo box item, `bx-combo-box-beingselected`
+event fires on ``, which has the following properties in the event
+details:
+
+| Property | Description                               |
+| -------- | ----------------------------------------- |
+| `item`   | The `` being selected. |
+
+`bx-combo-box-beingselected` bubbles and is cancelable. Canceling this event
+means canceling change in selection.
+
+## `` attributes, properties and events
+
+Note: For `boolean` attributes, `true` means simply setting the attribute (e.g.
+``) and `false` means not setting the attribute (e.g.
+`` without `open` attribute).
+
+
+
+## `` attributes and properties
+
+Note: For `boolean` attributes, `true` means simply setting the attribute (e.g.
+``) and `false` means not setting the attribute
+(e.g. `` without `disabled` attribute).
+
+
diff --git a/packages/carbon-web-components/src/components/combo-box/combo-box-story.ts b/packages/carbon-web-components/src/components/combo-box/combo-box-story.ts
new file mode 100644
index 00000000000..f14b5b3ae89
--- /dev/null
+++ b/packages/carbon-web-components/src/components/combo-box/combo-box-story.ts
@@ -0,0 +1,141 @@
+/**
+ * @license
+ *
+ * Copyright IBM Corp. 2019, 2022
+ *
+ * This source code is licensed under the Apache-2.0 license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import { html } from 'lit-element';
+import { action } from '@storybook/addon-actions';
+import { boolean, select, text } from '@storybook/addon-knobs';
+import ifNonNull from '../../globals/directives/if-non-null';
+import {
+  DROPDOWN_COLOR_SCHEME,
+  DROPDOWN_SIZE,
+  DROPDOWN_TYPE,
+} from './combo-box';
+import './combo-box-item';
+import storyDocs from './combo-box-story.mdx';
+
+const colorSchemes = {
+  [`Regular`]: null,
+  [`Light (${DROPDOWN_COLOR_SCHEME.LIGHT})`]: DROPDOWN_COLOR_SCHEME.LIGHT,
+};
+
+const types = {
+  Regular: null,
+  [`Inline (${DROPDOWN_TYPE.INLINE})`]: DROPDOWN_TYPE.INLINE,
+};
+
+const sizes = {
+  'Regular size': null,
+  [`Small size (${DROPDOWN_SIZE.SMALL})`]: DROPDOWN_SIZE.SMALL,
+  [`Extra large size (${DROPDOWN_SIZE.EXTRA_LARGE})`]:
+    DROPDOWN_SIZE.EXTRA_LARGE,
+};
+
+export const Default = (args) => {
+  const {
+    open,
+    colorScheme,
+    disabled,
+    helperText,
+    invalid,
+    labelText,
+    size,
+    triggerContent,
+    type,
+    validityMessage,
+    value,
+    disableSelection,
+    disableToggle,
+    onBeforeSelect,
+    onBeforeToggle,
+    onSelect,
+    onToggle,
+  } = args?.['bx-combo-box'] ?? {};
+  const handleBeforeSelect = (event: CustomEvent) => {
+    if (onBeforeSelect) {
+      onBeforeSelect(event);
+    }
+    if (disableSelection) {
+      event.preventDefault();
+    }
+  };
+  const handleBeforeToggle = (event: CustomEvent) => {
+    if (onBeforeToggle) {
+      onBeforeToggle(event);
+    }
+    if (disableToggle) {
+      event.preventDefault();
+    }
+  };
+  return html`
+    
+      Option 1
+      Option 2
+      Option 3
+      Option 4
+      Option 5
+      Option 6
+      Option 7
+      Option 8
+    
+  `;
+};
+
+Default.storyName = 'Default';
+
+export default {
+  title: 'Components/Combo box',
+  parameters: {
+    ...storyDocs.parameters,
+    knobs: {
+      'bx-combo-box': () => ({
+        open: boolean('Open (open)', false),
+        colorScheme: select('Color scheme (color-scheme)', colorSchemes, null),
+        disabled: boolean('Disabled (disabled)', false),
+        helperText: text('Helper text (helper-text)', 'Optional helper text'),
+        invalid: boolean('Show invalid state  (invalid)', false),
+        labelText: text('Label text (label-text)', 'Combo box title'),
+        size: select('Dropdown size (size)', sizes, null),
+        triggerContent: text(
+          'The placeholder content (trigger-content)',
+          'Filter...'
+        ),
+        type: select('UI type (type)', types, null),
+        validityMessage: text('The validity message (validity-message)', ''),
+        value: text('The value of the selected item (value)', ''),
+        disableSelection: boolean(
+          'Disable user-initiated selection change (Call event.preventDefault() in bx-combo-box-beingselected event)',
+          false
+        ),
+        disableToggle: boolean(
+          'Disable user-initiated toggle of open state (Call event.preventDefault() in bx-combo-box-beingtoggled event)',
+          false
+        ),
+        onBeforeSelect: action('bx-combo-box-beingselected'),
+        onBeforeToggle: action('bx-combo-box-beingtoggled'),
+        onSelect: action('bx-combo-box-selected'),
+        onToggle: action('bx-combo-box-toggled'),
+      }),
+    },
+  },
+};
diff --git a/packages/carbon-web-components/src/components/combo-box/combo-box.scss b/packages/carbon-web-components/src/components/combo-box/combo-box.scss
new file mode 100644
index 00000000000..0e4247ad6fa
--- /dev/null
+++ b/packages/carbon-web-components/src/components/combo-box/combo-box.scss
@@ -0,0 +1,101 @@
+//
+// Copyright IBM Corp. 2019, 2022
+//
+// This source code is licensed under the Apache-2.0 license found in the
+// LICENSE file in the root directory of this source tree.
+//
+
+$css--plex: true !default;
+
+@import 'carbon-components/scss/components/combo-box/combo-box';
+@import 'carbon-components/scss/components/form/form';
+@import 'carbon-components/scss/components/text-input/text-input';
+
+:host(#{$prefix}-combo-box) {
+  outline: none;
+
+  .#{$prefix}--assistive-text {
+    // Hides screen reader cursor
+    left: -100%;
+    top: -100%;
+  }
+
+  .#{$prefix}--label[hidden] {
+    display: none;
+  }
+
+  .#{$prefix}--list-box__field,
+  // To get more specifity than:
+  // https://github.com/carbon-design-system/carbon/blob/v10.16.0/packages/components/src/components/list-box/_list-box.scss#L126
+  .#{$prefix}--list-box[data-invalid] .#{$prefix}--list-box__field {
+    padding: 0;
+  }
+
+  .#{$prefix}--list-box__menu {
+    top: 100%;
+    margin-top: 1px;
+  }
+}
+
+:host(#{$prefix}-combo-box[type='inline']) {
+  @extend .#{$prefix}--list-box__wrapper--inline;
+
+  .#{$prefix}--list-box__field {
+    padding-left: 0;
+  }
+
+  .#{$prefix}--text-input {
+    border-bottom: none;
+  }
+}
+
+:host(#{$prefix}-combo-box-item) {
+  @extend .#{$prefix}--list-box__menu-item;
+
+  display: block;
+
+  .#{$prefix}--list-box__menu-item__option {
+    height: 100%;
+  }
+}
+
+:host(#{$prefix}-combo-box-item[size='sm']) {
+  height: rem(32px);
+
+  .#{$prefix}--list-box__menu-item__option {
+    padding-top: rem(7px);
+    padding-bottom: rem(7px);
+  }
+}
+
+:host(#{$prefix}-combo-box-item[size='xl']) {
+  height: rem(48px);
+
+  .#{$prefix}--list-box__menu-item__option {
+    padding-top: rem(15px);
+    padding-bottom: rem(15px);
+  }
+}
+
+:host(#{$prefix}-combo-box-item[disabled])
+  .#{$prefix}--list-box__menu-item__option {
+  color: $disabled-02;
+  text-decoration: none;
+}
+
+:host(#{$prefix}-combo-box-item[highlighted]) {
+  @extend .#{$prefix}--list-box__menu-item--highlighted;
+}
+
+:host(#{$prefix}-combo-box-item[selected]) {
+  @extend .#{$prefix}--list-box__menu-item--active;
+  @extend .#{$prefix}--list-box__menu-item--highlighted;
+
+  .#{$prefix}--list-box__menu-item__option {
+    color: $text-01;
+  }
+
+  .#{$prefix}--list-box__menu-item__selected-icon {
+    display: block;
+  }
+}
diff --git a/packages/carbon-web-components/src/components/combo-box/combo-box.ts b/packages/carbon-web-components/src/components/combo-box/combo-box.ts
new file mode 100644
index 00000000000..62538e3ebf5
--- /dev/null
+++ b/packages/carbon-web-components/src/components/combo-box/combo-box.ts
@@ -0,0 +1,339 @@
+/**
+ * @license
+ *
+ * Copyright IBM Corp. 2019, 2022
+ *
+ * This source code is licensed under the Apache-2.0 license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import settings from 'carbon-components/es/globals/js/settings';
+import { TemplateResult } from 'lit-html';
+import { html, property, query, customElement } from 'lit-element';
+import Close16 from '@carbon/icons/lib/close/16';
+import { findIndex, forEach } from '../../globals/internal/collection-helpers';
+import BXDropdown, { DROPDOWN_KEYBOARD_ACTION } from '../dropdown/dropdown';
+import BXComboBoxItem from './combo-box-item';
+import styles from './combo-box.scss';
+
+export {
+  DROPDOWN_COLOR_SCHEME,
+  DROPDOWN_SIZE,
+  DROPDOWN_TYPE,
+} from '../dropdown/dropdown';
+
+const { prefix } = settings;
+
+/**
+ * Combo box.
+ *
+ * @element bx-combo-box
+ * @fires bx-combo-box-beingselected
+ *   The custom event fired before a combo box item is selected upon a user gesture.
+ *   Cancellation of this event stops changing the user-initiated selection.
+ * @fires bx-combo-box-beingtoggled
+ *   The custom event fired before the open state of this combo box is toggled upon a user gesture.
+ *   Cancellation of this event stops the user-initiated toggling.
+ * @fires bx-combo-box-selected - The custom event fired after a combo box item is selected upon a user gesture.
+ * @fires bx-combo-box-toggled - The custom event fired after the open state of this combo box is toggled upon a user gesture.
+ */
+@customElement(`${prefix}-combo-box`)
+class BXComboBox extends BXDropdown {
+  /**
+   * The text content that should be set to the `` for filtering.
+   */
+  protected _filterInputValue = '';
+
+  protected _shouldTriggerBeFocusable = false;
+
+  /**
+   * The `` for filtering.
+   */
+  @query('input')
+  private _filterInputNode!: HTMLInputElement;
+
+  /**
+   * The menu containing all selectable items.
+   */
+  @query('#menu-body')
+  private _itemMenu!: HTMLElement;
+
+  /**
+   * The selection button.
+   */
+  @query('#selection-button')
+  private _selectionButtonNode!: HTMLElement;
+
+  /**
+   * @param item A combo box item.
+   * @returns `true` if the given combo box item matches the query text user types.
+   */
+  protected _testItemWithQueryText(item) {
+    return (this.itemMatches || this._defaultItemMatches)(
+      item,
+      this._filterInputNode.value
+    );
+  }
+
+  /* eslint-disable class-methods-use-this */
+  /**
+   * The default item matching callback.
+   *
+   * @param item The combo box item.
+   * @param queryText The query text user types.
+   * @returns `true` if the given combo box item matches the given query text.
+   */
+  protected _defaultItemMatches(
+    item: BXComboBoxItem,
+    queryText: string
+  ): boolean {
+    return (
+      item.textContent!.toLowerCase().indexOf(queryText.toLowerCase()) >= 0
+    );
+  }
+  /* eslint-enable class-methods-use-this */
+
+  /**
+   * Handles `input` event on the `` for filtering.
+   */
+  protected _handleInput() {
+    const items = this.querySelectorAll(
+      (this.constructor as typeof BXComboBox).selectorItem
+    );
+    const index = !this._filterInputNode.value
+      ? -1
+      : findIndex(items, this._testItemWithQueryText, this);
+    forEach(items, (item, i) => {
+      if (i === index) {
+        const menuRect = this._itemMenu?.getBoundingClientRect();
+        const itemRect = item.getBoundingClientRect();
+
+        if (menuRect && itemRect) {
+          const isViewable =
+            menuRect!.top <= itemRect?.top &&
+            itemRect?.bottom <= menuRect?.top + this._itemMenu!.clientHeight;
+          if (!isViewable) {
+            const scrollTop = itemRect?.top - menuRect?.top;
+            const scrollBot = itemRect?.bottom - menuRect?.bottom;
+
+            if (Math.abs(scrollTop) < Math.abs(scrollBot)) {
+              this._itemMenu!.scrollTop += scrollTop;
+            } else {
+              this._itemMenu!.scrollTop += scrollBot;
+            }
+          }
+        }
+      }
+      (item as BXComboBoxItem).highlighted = i === index;
+    });
+    const { _filterInputNode: filterInput } = this;
+    this._filterInputValue = !filterInput ? '' : filterInput.value;
+    this.open = true;
+    this.requestUpdate(); // If the only change is to `_filterInputValue`, auto-update doesn't happen
+  }
+
+  protected _handleClickInner(event: MouseEvent) {
+    if (this._selectionButtonNode?.contains(event.target as Node)) {
+      this._handleUserInitiatedClearInput();
+    } else {
+      super._handleClickInner(event);
+    }
+  }
+
+  protected _handleKeypressInner(event: KeyboardEvent) {
+    const { key } = event;
+    const action = (this.constructor as typeof BXDropdown).getAction(key);
+    const { TRIGGERING } = DROPDOWN_KEYBOARD_ACTION;
+    if (
+      this._selectionButtonNode?.contains(event.target as Node) &&
+      // Space key should be handled by `` unless "clear selection" button has focus
+      (action === TRIGGERING || key === ' ')
+    ) {
+      this._handleUserInitiatedClearInput();
+    } else {
+      super._handleKeypressInner(event);
+    }
+  }
+
+  /**
+   * Handles user-initiated clearing the `` for filtering.
+   */
+  protected _handleUserInitiatedClearInput() {
+    forEach(
+      this.querySelectorAll(
+        (this.constructor as typeof BXComboBox).selectorItem
+      ),
+      (item) => {
+        (item as BXComboBoxItem).highlighted = false;
+      }
+    );
+    this._filterInputValue = '';
+    this._filterInputNode.focus();
+    this._handleUserInitiatedSelectItem();
+  }
+
+  protected _handleUserInitiatedSelectItem(item?: BXComboBoxItem) {
+    if (item && !this._selectionShouldChange(item)) {
+      // Escape hatch for `shouldUpdate()` logic that updates `._filterInputValue()` when selection changes,
+      // given we want to update the `` and close the dropdown even if selection doesn't update.
+      // Use case:
+      // 1. Select the 2nd item in combo box drop down
+      // 2. Type some text in the ``
+      // 3. Re-select the 2nd item in combo box drop down,
+      //    the `` has to updated with the 2nd item and the dropdown should be closed,
+      //    even if there is no change in the selected value
+      this._filterInputValue = item.textContent || '';
+      this.open = false;
+      this.requestUpdate();
+    }
+    super._handleUserInitiatedSelectItem(item);
+  }
+
+  protected _selectionDidChange(itemToSelect?: BXComboBoxItem) {
+    this.value = !itemToSelect ? '' : itemToSelect.value;
+    forEach(
+      this.querySelectorAll(
+        (this.constructor as typeof BXDropdown).selectorItemSelected
+      ),
+      (item) => {
+        (item as BXComboBoxItem).selected = false;
+      }
+    );
+    if (itemToSelect) {
+      itemToSelect.selected = true;
+      this._assistiveStatusText = this.selectedItemAssistiveText;
+    }
+    this._handleUserInitiatedToggle(false);
+  }
+
+  protected _renderTriggerContent(): TemplateResult {
+    const {
+      disabled,
+      inputLabel,
+      triggerContent,
+      _filterInputValue: filterInputValue,
+      _handleInput: handleInput,
+    } = this;
+    return html`
+      
+    `;
+  }
+
+  protected _renderFollowingTriggerContent(): TemplateResult | void {
+    const { clearSelectionLabel, _filterInputValue: filterInputValue } = this;
+    return filterInputValue.length === 0
+      ? undefined
+      : html`
+          
+ ${Close16({ 'aria-label': clearSelectionLabel })} +
+ `; + } + + /** + * The `aria-label` attribute for the icon to clear selection. + */ + @property({ attribute: 'clear-selection-label' }) + clearSelectionLabel = ''; + + /** + * The `aria-label` attribute for the `` for filtering. + */ + @property({ attribute: 'input-label' }) + inputLabel = ''; + + /** + * The custom item matching callback. + */ + @property({ attribute: false }) + itemMatches!: (item: BXComboBoxItem, queryText: string) => boolean; + + shouldUpdate(changedProperties) { + super.shouldUpdate(changedProperties); + const { _selectedItemContent: selectedItemContent } = this; + if (selectedItemContent && changedProperties.has('value')) { + this._filterInputValue = selectedItemContent?.textContent || ''; + } + return true; + } + + updated() { + const { _listBoxNode: listBoxNode } = this; + if (listBoxNode) { + listBoxNode.classList.add(`${prefix}--combo-box`); + } + } + + // For combo box, open/selection with space key is disabled given the input box should take it over + static TRIGGER_KEYS = new Set(['Enter']); + + /** + * A selector that will return highlighted items. + */ + static get selectorItemHighlighted() { + return `${prefix}-combo-box-item[highlighted]`; + } + + /** + * A selector that will return combo box items. + */ + static get selectorItem() { + return `${prefix}-combo-box-item`; + } + + /** + * A selector that will return selected items. + */ + static get selectorItemSelected() { + return `${prefix}-combo-box-item[selected]`; + } + + /** + * The name of the custom event fired before this combo box item is being toggled upon a user gesture. + * Cancellation of this event stops the user-initiated action of toggling this combo box item. + */ + static get eventBeforeToggle() { + return `${prefix}-combo-box-beingtoggled`; + } + + /** + * The name of the custom event fired after this combo box item is toggled upon a user gesture. + */ + static get eventToggle() { + return `${prefix}-combo-box-toggled`; + } + + /** + * The name of the custom event fired before a combo box item is selected upon a user gesture. + * Cancellation of this event stops changing the user-initiated selection. + */ + static get eventBeforeSelect() { + return `${prefix}-combo-box-beingselected`; + } + + /** + * The name of the custom event fired after a a combo box item is selected upon a user gesture. + */ + static get eventSelect() { + return `${prefix}-combo-box-selected`; + } + + static styles = styles; +} + +export default BXComboBox; diff --git a/packages/carbon-web-components/src/components/combo-box/index.ts b/packages/carbon-web-components/src/components/combo-box/index.ts new file mode 100644 index 00000000000..bd2143dcc30 --- /dev/null +++ b/packages/carbon-web-components/src/components/combo-box/index.ts @@ -0,0 +1,11 @@ +/** + * @license + * + * Copyright IBM Corp. 2021 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import './combo-box'; +import './combo-box-item'; diff --git a/packages/carbon-web-components/src/components/content-switcher/content-switcher-item.ts b/packages/carbon-web-components/src/components/content-switcher/content-switcher-item.ts new file mode 100644 index 00000000000..e6f3485be42 --- /dev/null +++ b/packages/carbon-web-components/src/components/content-switcher/content-switcher-item.ts @@ -0,0 +1,106 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { classMap } from 'lit-html/directives/class-map'; +import { html, property, customElement, LitElement } from 'lit-element'; +import settings from 'carbon-components/es/globals/js/settings'; +import ifNonNull from '../../globals/directives/if-non-null'; +import FocusMixin from '../../globals/mixins/focus'; +import styles from './content-switcher.scss'; + +const { prefix } = settings; + +/** + * Content switcher button. + * + * @element bx-content-switcher-item + */ +@customElement(`${prefix}-content-switcher-item`) +class BXContentSwitcherItem extends FocusMixin(LitElement) { + /** + * `true` if this content switcher item should be disabled. + */ + @property({ type: Boolean, reflect: true }) + disabled = false; + + /** + * `true` to hide the divider at the left. + * + * @private + */ + @property({ type: Boolean, reflect: true, attribute: 'hide-divider' }) + hideDivider = false; + + /** + * `true` if the content switcher button should be selected. + * + * @private + */ + @property({ type: Boolean, reflect: true }) + selected = false; + + /** + * The element ID of target panel. + */ + @property() + target!: string; + + /** + * The `value` attribute that is set to the parent `` when this content switcher item is selected. + */ + @property() + value = ''; + + createRenderRoot() { + return this.attachShadow({ + mode: 'open', + delegatesFocus: + Number((/Safari\/(\d+)/.exec(navigator.userAgent) ?? ['', 0])[1]) <= + 537, + }); + } + + shouldUpdate(changedProperties) { + if (changedProperties.has('selected') || changedProperties.has('target')) { + const { selected, target } = this; + if (target) { + const doc = this.getRootNode() as HTMLDocument; + // `doc` can be an element if such element is orphaned + const targetNode = doc.getElementById && doc.getElementById(target); + if (targetNode) { + targetNode.toggleAttribute('hidden', !selected); + } + } + } + return true; + } + + render() { + const { disabled, selected, target } = this; + const className = classMap({ + [`${prefix}--content-switcher-btn`]: true, + [`${prefix}--content-switcher--selected`]: selected, + }); + return html` + + `; + } + + static styles = styles; +} + +export default BXContentSwitcherItem; diff --git a/packages/carbon-web-components/src/components/content-switcher/content-switcher-story.mdx b/packages/carbon-web-components/src/components/content-switcher/content-switcher-story.mdx new file mode 100644 index 00000000000..4e551b8614d --- /dev/null +++ b/packages/carbon-web-components/src/components/content-switcher/content-switcher-story.mdx @@ -0,0 +1,49 @@ +import { Props, Description } from '@storybook/addon-docs/blocks'; +import { cdnJs, cdnCss } from '../../globals/internal/storybook-cdn'; + +# Content switcher + +> ๐Ÿ’ก Check our +> [CodeSandbox](https://codesandbox.io/s/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/carbon-web-components/examples/codesandbox/basic/components/content-switcher) +> example implementation. + +[![Edit carbon-web-components](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/carbon-web-components/examples/codesandbox/basic/components/content-switcher) + +Content switcher manipulates the content shown following an exclusive or +โ€œeither/orโ€ pattern. It is used to toggle between two or more content sections +within the same space on screen. Only one section can be shown at a time. + +## Getting started + +Here's a quick example to get you started. + +### JS (via import) + +```javascript +import '@carbon/web-components/es/components/content-switcher/index.js'; +``` + + + + +### HTML + +```html + + Option 1 + Option 2 + Option 3 + Option 4 + Option 5 + +``` + +## `` attributes, properties and events + + + +## `` attributes and properties + + diff --git a/packages/carbon-web-components/src/components/content-switcher/content-switcher-story.ts b/packages/carbon-web-components/src/components/content-switcher/content-switcher-story.ts new file mode 100644 index 00000000000..cf4d52e0d91 --- /dev/null +++ b/packages/carbon-web-components/src/components/content-switcher/content-switcher-story.ts @@ -0,0 +1,82 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { html } from 'lit-element'; +import { action } from '@storybook/addon-actions'; +import { boolean, select } from '@storybook/addon-knobs'; +import textNullable from '../../../.storybook/knob-text-nullable'; +import ifNonNull from '../../globals/directives/if-non-null'; +import { CONTENT_SWITCHER_SIZE } from './content-switcher'; +import './content-switcher-item'; +import storyDocs from './content-switcher-story.mdx'; + +const noop = () => {}; + +const sizes = { + 'Regular size': null, + [`Small size (${CONTENT_SWITCHER_SIZE.SMALL})`]: CONTENT_SWITCHER_SIZE.SMALL, + [`XL size (${CONTENT_SWITCHER_SIZE.EXTRA_LARGE})`]: + CONTENT_SWITCHER_SIZE.EXTRA_LARGE, +}; + +export const Default = (args) => { + const { + value, + disableSelection, + onBeforeSelect = noop, + onSelect = noop, + size, + } = args?.['bx-content-switcher'] ?? {}; + const handleBeforeSelected = (event: CustomEvent) => { + onBeforeSelect(event); + if (disableSelection) { + event.preventDefault(); + } + }; + return html` + + Option 1 + Option 2 + Option 3 + Option 4 + Option 5 + + `; +}; + +Default.storyName = 'Default'; + +export default { + title: 'Components/Content switcher', + parameters: { + ...storyDocs.parameters, + knobs: { + 'bx-content-switcher': () => ({ + value: textNullable('The value of the selected item (value)', ''), + size: select('Button size (size)', sizes, null), + disableSelection: boolean( + 'Disable user-initiated selection change (Call event.preventDefault() in bx-content-switcher-beingselected event)', + false + ), + onBeforeSelect: action('bx-content-switcher-beingselected'), + onSelect: action('bx-content-switcher-selected'), + }), + }, + }, +}; diff --git a/packages/carbon-web-components/src/components/content-switcher/content-switcher.scss b/packages/carbon-web-components/src/components/content-switcher/content-switcher.scss new file mode 100644 index 00000000000..3c294a9b403 --- /dev/null +++ b/packages/carbon-web-components/src/components/content-switcher/content-switcher.scss @@ -0,0 +1,93 @@ +// +// Copyright IBM Corp. 2019, 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +$css--plex: true !default; + +@import 'carbon-components/scss/components/content-switcher/content-switcher'; + +:host(#{$prefix}-content-switcher) { + @extend .#{$prefix}--content-switcher; +} + +:host(#{$prefix}-content-switcher[size='sm']) { + @extend .#{$prefix}--content-switcher--sm; +} + +:host(#{$prefix}-content-switcher[size='xl']) { + @extend .#{$prefix}--content-switcher--xl; +} + +:host(#{$prefix}-content-switcher-item) { + width: 100%; + outline: none; + + .#{$prefix}--content-switcher-btn { + height: 100%; + + &:first-child, + &:last-child { + border-radius: 0; + border-left: none; + border-right: none; + } + + &::before { + content: ''; + display: block; + height: rem(16px); + width: rem(1px); + background-color: $content-switcher-divider; + position: absolute; + z-index: 2; + left: 0; + } + + &.#{$prefix}--content-switcher--selected, + &:focus, + &:hover { + &::before { + background-color: transparent; + } + } + + &:disabled { + border-top-color: $ui-05; + border-bottom-color: $ui-05; + } + } +} + +:host(#{$prefix}-content-switcher-item[hide-divider]) + .#{$prefix}--content-switcher-btn::before { + background-color: transparent; +} + +:host(#{$prefix}-content-switcher-item:first-of-type) + .#{$prefix}--content-switcher-btn { + border-top-left-radius: rem(4px); + border-bottom-left-radius: rem(4px); + border-left: rem(1px) solid $ui-05; + + &::before { + content: none; + } + + &.#{$prefix}--content-switcher--selected { + border-left: none; + } +} + +:host(#{$prefix}-content-switcher-item:last-of-type) + .#{$prefix}--content-switcher-btn { + border-top-right-radius: rem(4px); + border-bottom-right-radius: rem(4px); + border-right: rem(1px) solid $ui-05; + + &.#{$prefix}--content-switcher--selected { + border-right: none; + } +} diff --git a/packages/carbon-web-components/src/components/content-switcher/content-switcher.ts b/packages/carbon-web-components/src/components/content-switcher/content-switcher.ts new file mode 100644 index 00000000000..d945b170f1f --- /dev/null +++ b/packages/carbon-web-components/src/components/content-switcher/content-switcher.ts @@ -0,0 +1,240 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { html, property, customElement, LitElement } from 'lit-element'; +import settings from 'carbon-components/es/globals/js/settings'; +import { forEach, indexOf } from '../../globals/internal/collection-helpers'; +import { NAVIGATION_DIRECTION, CONTENT_SWITCHER_SIZE } from './defs'; +import BXSwitch from './content-switcher-item'; +import styles from './content-switcher.scss'; + +export { NAVIGATION_DIRECTION, CONTENT_SWITCHER_SIZE }; + +const { prefix } = settings; + +/** + * @param index The index + * @param length The length of the array. + * @returns The new index, adjusting overflow/underflow. + */ +const capIndex = (index: number, length: number) => { + if (index < 0) { + return length - 1; + } + if (index >= length) { + return 0; + } + return index; +}; + +/** + * Content switcher. + * + * @element bx-content-switcher + * @fires bx-content-switcher-beingselected + * The custom event fired before a content switcher item is selected upon a user gesture. + * Cancellation of this event stops changing the user-initiated selection. + * @fires bx-content-switcher-selected - The custom event fired after a a content switcher item is selected upon a user gesture. + */ +@customElement(`${prefix}-content-switcher`) +class BXContentSwitcher extends LitElement { + /** + * Handles `mouseover`/`mouseout` events on ``. + * + * @param event The event. + */ + private _handleHover({ target, type }: MouseEvent) { + const { selectorItem } = this.constructor as typeof BXContentSwitcher; + const items = this.querySelectorAll(selectorItem); + const index = + type !== 'mouseover' + ? -1 + : indexOf(items, (target as Element).closest(selectorItem)!); + const nextIndex = index < 0 ? index : index + 1; + forEach(this.querySelectorAll(selectorItem), (elem, i) => { + // Specifies child `` to hide its divider instead of using CSS, + // until `:host-context()` gets supported in all major browsers + (elem as BXSwitch).hideDivider = i === nextIndex; + }); + } + + /** + * @param currentItem The currently selected item. + * @param direction The navigation direction. + * @returns The item to be selected. + */ + protected _getNextItem(currentItem: BXSwitch, direction: number) { + const items = this.querySelectorAll( + (this.constructor as typeof BXContentSwitcher).selectorItemEnabled + ); + const currentIndex = indexOf(items, currentItem); + const nextIndex = capIndex(currentIndex + direction, items.length); + return nextIndex === currentIndex ? null : items[nextIndex]; + } + + /** + * Handles `click` event on the top-level element in the shadow DOM. + * + * @param event The event. + */ + protected _handleClick({ target }: MouseEvent) { + this._handleUserInitiatedSelectItem(target as BXSwitch); + } + + /** + * Handles `keydown` event on the top-level element in the shadow DOM. + * + * @param event The event. + */ + protected _handleKeydown({ key }: KeyboardEvent) { + if (key in NAVIGATION_DIRECTION) { + this._navigate(NAVIGATION_DIRECTION[key]); + } + } + + /** + * Handles user-initiated selection of a content switcher item. + * + * @param [item] The content switcher item user wants to select. + */ + protected _handleUserInitiatedSelectItem(item: BXSwitch) { + if (!item.disabled && item.value !== this.value) { + const init = { + bubbles: true, + composed: true, + detail: { + item, + }, + }; + const constructor = this.constructor as typeof BXContentSwitcher; + const beforeSelectEvent = new CustomEvent(constructor.eventBeforeSelect, { + ...init, + cancelable: true, + }); + if (this.dispatchEvent(beforeSelectEvent)) { + this._selectionDidChange(item); + const afterSelectEvent = new CustomEvent(constructor.eventSelect, init); + this.dispatchEvent(afterSelectEvent); + } + } + } + + /** + * Navigates through content switcher items. + * + * @param direction `-1` to navigate backward, `1` to navigate forward. + */ + protected _navigate(direction: number) { + const { selectorItemSelected } = this + .constructor as typeof BXContentSwitcher; + const nextItem = this._getNextItem( + this.querySelector(selectorItemSelected) as BXSwitch, + direction + ); + if (nextItem) { + this._handleUserInitiatedSelectItem(nextItem as BXSwitch); + this.requestUpdate(); + } + } + + /** + * A callback that runs after change in content switcher selection upon user interaction is confirmed. + * + * @param itemToSelect A content switcher item. + */ + protected _selectionDidChange(itemToSelect: BXSwitch) { + this.value = itemToSelect.value; + forEach( + this.querySelectorAll( + (this.constructor as typeof BXContentSwitcher).selectorItemSelected + ), + (item) => { + (item as BXSwitch).selected = false; + } + ); + itemToSelect.selected = true; + // Waits for rendering with the new state that updates `tabindex` + Promise.resolve().then(() => { + itemToSelect.focus(); + }); + } + + /** + * The value of the selected item. + */ + @property({ reflect: true }) + value = ''; + + /** + * Content switcher size. + */ + @property({ reflect: true }) + size = CONTENT_SWITCHER_SIZE.REGULAR; + + shouldUpdate(changedProperties) { + if (changedProperties.has('value')) { + const { selectorItem } = this.constructor as typeof BXContentSwitcher; + forEach(this.querySelectorAll(selectorItem), (elem) => { + (elem as BXSwitch).selected = (elem as BXSwitch).value === this.value; + }); + } + return true; + } + + /** + * A selector that will return content switcher items. + */ + static get selectorItem() { + return `${prefix}-content-switcher-item`; + } + + /** + * A selector that will return enabled content switcher items. + */ + static get selectorItemEnabled() { + return `${prefix}-content-switcher-item:not([disabled])`; + } + + /** + * A selector that will return selected items. + */ + static get selectorItemSelected() { + return `${prefix}-content-switcher-item[selected]`; + } + + /** + * The name of the custom event fired before a content switcher item is selected upon a user gesture. + * Cancellation of this event stops changing the user-initiated selection. + */ + static get eventBeforeSelect() { + return `${prefix}-content-switcher-beingselected`; + } + + /** + * The name of the custom event fired after a a content switcher item is selected upon a user gesture. + */ + static get eventSelect() { + return `${prefix}-content-switcher-selected`; + } + + render() { + const { _handleHover: handleHover, _handleKeydown: handleKeydown } = this; + return html` + + `; + } + + static styles = styles; +} + +export default BXContentSwitcher; diff --git a/packages/carbon-web-components/src/components/content-switcher/defs.ts b/packages/carbon-web-components/src/components/content-switcher/defs.ts new file mode 100644 index 00000000000..2496b8c09e5 --- /dev/null +++ b/packages/carbon-web-components/src/components/content-switcher/defs.ts @@ -0,0 +1,38 @@ +/** + * @license + * + * Copyright IBM Corp. 2020 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * Navigation direction, associated with key symbols. + */ +export const NAVIGATION_DIRECTION = { + Left: -1, + ArrowLeft: -1, + Right: 1, + ArrowRight: 1, +}; + +/** + * Button size. + */ +export enum CONTENT_SWITCHER_SIZE { + /** + * Regular size. + */ + REGULAR = '', + + /** + * Small size. + */ + SMALL = 'sm', + + /** + * X-Large size. + */ + EXTRA_LARGE = 'xl', +} diff --git a/packages/carbon-web-components/src/components/content-switcher/index.ts b/packages/carbon-web-components/src/components/content-switcher/index.ts new file mode 100644 index 00000000000..fae956d923e --- /dev/null +++ b/packages/carbon-web-components/src/components/content-switcher/index.ts @@ -0,0 +1,11 @@ +/** + * @license + * + * Copyright IBM Corp. 2021 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import './content-switcher'; +import './content-switcher-item'; diff --git a/packages/carbon-web-components/src/components/copy-button/copy-button-story.mdx b/packages/carbon-web-components/src/components/copy-button/copy-button-story.mdx new file mode 100644 index 00000000000..3c8bf815f80 --- /dev/null +++ b/packages/carbon-web-components/src/components/copy-button/copy-button-story.mdx @@ -0,0 +1,40 @@ +import { Props, Description } from '@storybook/addon-docs/blocks'; +import { cdnJs, cdnCss } from '../../globals/internal/storybook-cdn'; + +# Copy button + +> ๐Ÿ’ก Check our +> [CodeSandbox](https://codesandbox.io/s/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/carbon-web-components/examples/codesandbox/basic/components/copy-button) +> example implementation. + +[![Edit carbon-web-components](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/carbon-web-components/examples/codesandbox/basic/components/copy-button) + +Copy button provides the interface of copy button and its feedback tooltip. No +actual copy is performed, but application can listen to `click` event of +`` and interact with the clipboard. + +## Getting started + +Here's a quick example to get you started. + +### JS (via import) + +```javascript +import '@carbon/web-components/es/components/copy-button/index.js'; +``` + + + + +### HTML + +```html + +``` + +## `` attributes and properties + + diff --git a/packages/carbon-web-components/src/components/copy-button/copy-button-story.ts b/packages/carbon-web-components/src/components/copy-button/copy-button-story.ts new file mode 100644 index 00000000000..e6afcec050f --- /dev/null +++ b/packages/carbon-web-components/src/components/copy-button/copy-button-story.ts @@ -0,0 +1,48 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { html } from 'lit-element'; +import { action } from '@storybook/addon-actions'; +import { number } from '@storybook/addon-knobs'; +import textNullable from '../../../.storybook/knob-text-nullable'; +import ifNonNull from '../../globals/directives/if-non-null'; +import './copy-button'; +import storyDocs from './copy-button-story.mdx'; + +export const Default = (args) => { + const { buttonAssistiveText, feedbackText, feedbackTimeout, onClick } = + args?.['bx-copy-button'] ?? {}; + return html` + + `; +}; + +Default.storyName = 'Default'; + +export default { + title: 'Components/Copy button', + parameters: { + ...storyDocs.parameters, + knobs: { + 'bx-copy-button': () => ({ + buttonAssistiveText: textNullable( + 'Assistive text for the button (button-assistive-text)', + '' + ), + feedbackText: textNullable('Feedback text (feedback-text)', ''), + feedbackTimeout: number('Feedback timeout (feedback-timeout)', 2000), + onClick: action('click'), + }), + }, + }, +}; diff --git a/packages/carbon-web-components/src/components/copy-button/copy-button.scss b/packages/carbon-web-components/src/components/copy-button/copy-button.scss new file mode 100644 index 00000000000..d7e744825f5 --- /dev/null +++ b/packages/carbon-web-components/src/components/copy-button/copy-button.scss @@ -0,0 +1,21 @@ +// +// Copyright IBM Corp. 2019, 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +$css--plex: true !default; + +@import 'carbon-components/scss/components/code-snippet/code-snippet'; +@import 'carbon-components/scss/components/copy-button/copy-button'; + +:host(#{$prefix}-copy-button) { + display: inline-flex; + outline: none; + + .#{$prefix}--snippet-button .#{$prefix}--btn--copy__feedback { + left: 50%; + right: auto; + } +} diff --git a/packages/carbon-web-components/src/components/copy-button/copy-button.ts b/packages/carbon-web-components/src/components/copy-button/copy-button.ts new file mode 100644 index 00000000000..b507d150342 --- /dev/null +++ b/packages/carbon-web-components/src/components/copy-button/copy-button.ts @@ -0,0 +1,160 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { classMap } from 'lit-html/directives/class-map'; +import { TemplateResult } from 'lit-html'; +import { ifDefined } from 'lit-html/directives/if-defined'; +import { html, property, customElement, LitElement } from 'lit-element'; +import Copy16 from '@carbon/icons/lib/copy/16'; +import settings from 'carbon-components/es/globals/js/settings'; +import FocusMixin from '../../globals/mixins/focus'; +import styles from './copy-button.scss'; + +const { prefix } = settings; + +/** + * Note: For `` only. The API is subject to change/removal. + * + * @param update The callback function that dictates how to update the DOM with new feedback tooltip state. + * @returns A function that shows the feedback tooltip for the given duration. + * @private + */ +export const _createHandleFeedbackTooltip = ( + update: (properties: { showFeedback?: boolean }) => void +) => { + let timeoutId: number | void; + return (timeout: number) => { + if (timeoutId) { + clearTimeout(timeoutId); + timeoutId = undefined; + } + update({ showFeedback: true }); + timeoutId = setTimeout(() => { + update({ showFeedback: false }); + }, timeout) as unknown as number; + }; +}; + +/** + * Note: For `` only. The API is subject to change/removal. + * + * @param properties The properties to render. + * @returns The template result for copy button from the given properties. + * @private + */ +export const _renderButton = ({ + assistiveText, + feedbackText, + showFeedback = false, + className = `${prefix}--snippet-button`, + children = html` + ${Copy16({ class: `${prefix}--snippet__icon` })} + `, + handleClickButton, +}: { + assistiveText: string; + feedbackText: string; + showFeedback?: boolean; + className?: string; + children?: TemplateResult; + handleClickButton: EventListener; +}) => { + const feedbackClasses = classMap({ + [`${prefix}--btn--copy__feedback`]: true, + [`${prefix}--btn--copy__feedback--displayed`]: showFeedback, + }); + return html` + + `; +}; + +/** + * Copy button. + * + * @element bx-copy-button + */ +@customElement(`${prefix}-copy-button`) +class BXCopyButton extends FocusMixin(LitElement) { + /** + * Handles showing/hiding the feedback tooltip. + */ + private _handleFeedbackTooltip = _createHandleFeedbackTooltip( + ({ showFeedback = false }: { showFeedback?: boolean }) => { + this._showFeedback = showFeedback; + this.requestUpdate(); + } + ); + + /** + * `true` to show the feedback tooltip. + */ + private _showFeedback = false; + + /** + * Handles `click` event on the copy button. + */ + private _handleClickButton() { + this._handleFeedbackTooltip(this.feedbackTimeout); + } + + /** + * An assistive text for screen reader to announce, telling that the button copies the content to the clipboard. + */ + @property({ attribute: 'button-assistive-text' }) + buttonAssistiveText = 'Copy to clipboard'; + + /** + * The feedback text. + */ + @property({ attribute: 'feedback-text' }) + feedbackText = 'Copied!'; + + /** + * The number in milliseconds to determine how long the tooltip should remain. + */ + @property({ type: Number, attribute: 'feedback-timeout' }) + feedbackTimeout = 2000; + + createRenderRoot() { + return this.attachShadow({ + mode: 'open', + delegatesFocus: + Number((/Safari\/(\d+)/.exec(navigator.userAgent) ?? ['', 0])[1]) <= + 537, + }); + } + + render() { + const { + buttonAssistiveText, + feedbackText, + _handleClickButton: handleClickButton, + _showFeedback: showFeedback, + } = this; + return _renderButton({ + assistiveText: buttonAssistiveText, + feedbackText, + showFeedback, + handleClickButton, + }); + } + + static styles = styles; +} + +export default BXCopyButton; diff --git a/packages/carbon-web-components/src/components/copy-button/index.ts b/packages/carbon-web-components/src/components/copy-button/index.ts new file mode 100644 index 00000000000..fabcb375b23 --- /dev/null +++ b/packages/carbon-web-components/src/components/copy-button/index.ts @@ -0,0 +1,10 @@ +/** + * @license + * + * Copyright IBM Corp. 2021 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import './copy-button'; diff --git a/packages/carbon-web-components/src/components/data-table/_table-action.scss b/packages/carbon-web-components/src/components/data-table/_table-action.scss new file mode 100644 index 00000000000..611476abf0b --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/_table-action.scss @@ -0,0 +1,109 @@ +// +// Copyright IBM Corp. 2019, 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@import 'carbon-components/scss/components/button/button'; +@import 'carbon-components/scss/components/search/search'; +@import 'carbon-components/scss/components/data-table/data-table-action'; + +// +// Table toolbar +// + +:host(#{$prefix}-table-toolbar) { + @extend .#{$prefix}--table-toolbar; +} + +:host(#{$prefix}-table-toolbar-content) { + @extend .#{$prefix}--toolbar-content; + + clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); + + ::slotted(#{$prefix}-overflow-menu) { + @include button-reset; + + display: flex; + cursor: pointer; + height: $layout-04; + width: $layout-04; + padding: $spacing-md; + transition: background-color $duration--fast-02 motion(entrance, productive); + } + + ::slotted(#{$prefix}-overflow-menu:hover) { + background-color: $hover-field; + } + + ::slotted(#{$prefix}-overflow-menu[disabled]:hover) { + background-color: transparent; + } + + .#{$prefix}--search .#{$prefix}--search-input { + // For tool bar animation with (esp.) persistent search box + background-color: transparent; + } +} + +:host(#{$prefix}-table-toolbar-content[has-batch-actions]) { + clip-path: polygon(0 0, 100% 0, 100% 0, 0 0); + transform: translate3d(0, 48px, 0); + transition: transform $duration--fast-02 motion(standard, productive), + clip-path $duration--fast-02 motion(standard, productive); +} + +:host(#{$prefix}-table-toolbar-search) { + @extend .#{$prefix}--toolbar-action; + @extend .#{$prefix}--toolbar-search-container-expandable; + + flex: none; + transition: flex 175ms $carbon--standard-easing; + + .#{$prefix}--search { + width: 100%; + height: 100%; + + .#{$prefix}--search-magnifier { + height: $layout-04; + width: $layout-04; + padding: $spacing-md; + left: 0; + cursor: pointer; + pointer-events: all; + transition: background $duration--fast-02 motion(entrance, productive); + } + + .#{$prefix}--search-close { + height: $layout-04; + width: $layout-04; + + &::before { + top: 2px; + height: calc(100% - 4px); + background-color: $hover-ui; + } + } + } +} + +:host(#{$prefix}-table-toolbar-search[expanded]) { + @extend .#{$prefix}--toolbar-search-container-active; + + flex: auto; +} + +:host(#{$prefix}-table-toolbar-search[persistent]) { + @extend .#{$prefix}--toolbar-search-container-persistent; +} + +:host(#{$prefix}-table-batch-actions) { + @extend .#{$prefix}--batch-actions; + + box-sizing: border-box; +} + +:host(#{$prefix}-table-batch-actions[active]) { + @extend .#{$prefix}--batch-actions--active; +} diff --git a/packages/carbon-web-components/src/components/data-table/_table-core.scss b/packages/carbon-web-components/src/components/data-table/_table-core.scss new file mode 100644 index 00000000000..c274a36b90a --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/_table-core.scss @@ -0,0 +1,190 @@ +// +// Copyright IBM Corp. 2019, 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +// +// Table header and table body +// + +:host(#{$prefix}-table) { + @extend .#{$prefix}--data-table; + + display: table; + + ::slotted(#{$prefix}-table-head) { + @include type-style('heading-01'); + + background-color: $ui-03; + display: table-header-group; + } + + ::slotted(#{$prefix}-table-body) { + @include type-style('body-short-01'); + + background-color: $ui-01; + width: 100%; + display: table-row-group; + } +} + +// +// Common style for table cell and table header cell +// + +:host(#{$prefix}-table-header-row) ::slotted(#{$prefix}-table-header-cell), +:host(#{$prefix}-table-header-row) + ::slotted(#{$prefix}-table-header-cell-skeleton), +:host(#{$prefix}-table-header-row) .#{$prefix}--table-column-checkbox, +:host(#{$prefix}-table-header-expand-row) + ::slotted(#{$prefix}-table-header-cell), +:host(#{$prefix}-table-header-expand-row) + ::slotted(#{$prefix}-table-header-cell-skeleton), +:host(#{$prefix}-table-header-expand-row) .#{$prefix}--table-expand, +:host(#{$prefix}-table-header-expand-row) .#{$prefix}--table-column-checkbox, +:host(#{$prefix}-table-row) ::slotted(#{$prefix}-table-cell), +:host(#{$prefix}-table-row) ::slotted(#{$prefix}-table-cell-skeleton), +:host(#{$prefix}-table-row) .#{$prefix}--table-column-checkbox, +:host(#{$prefix}-table-expand-row) ::slotted(#{$prefix}-table-cell), +:host(#{$prefix}-table-expand-row) ::slotted(#{$prefix}-table-cell-skeleton), +:host(#{$prefix}-table-expand-row) .#{$prefix}--table-expand, +:host(#{$prefix}-table-expand-row) .#{$prefix}--table-column-checkbox { + display: table-cell; +} + +// +// Table header row +// + +:host(#{$prefix}-table-head) ::slotted(#{$prefix}-table-header-row), +:host(#{$prefix}-table-head) ::slotted(#{$prefix}-table-header-expand-row) { + height: $layout-04; + display: table-row; +} + +// +// Table header cell +// + +:host(#{$prefix}-table-header-row), +:host(#{$prefix}-table-header-expand-row) { + outline: none; + + ::slotted(#{$prefix}-table-header-cell), + ::slotted(#{$prefix}-table-header-cell-skeleton) { + color: $text-01; + background-color: $ui-03; + text-align: left; + display: table-cell; + outline: none; + } + + ::slotted(#{$prefix}-table-header-cell:last-of-type), + ::slotted(#{$prefix}-table-header-cell-skeleton:last-of-type) { + position: relative; + width: auto; + } + + ::slotted(#{$prefix}-table-header-cell), + ::slotted(#{$prefix}-table-header-cell-skeleton), + .#{$prefix}--table-expand, + .#{$prefix}--table-column-checkbox { + padding-left: $spacing-04; + padding-right: $spacing-04; + vertical-align: middle; + } +} + +:host(#{$prefix}-table-header-row) { + ::slotted(#{$prefix}-table-header-cell:first-of-type), + ::slotted(#{$prefix}-table-header-cell-skeleton:first-of-type) { + padding-left: $spacing-05; + } +} + +// +// Table row +// + +:host(#{$prefix}-table-body) { + ::slotted(#{$prefix}-table-row), + ::slotted(#{$prefix}-table-expand-row) { + border: none; + height: $layout-04; + width: 100%; + display: table-row; + outline: none; + } +} + +// +// Table cell +// + +:host(#{$prefix}-table-row), +:host(#{$prefix}-table-expand-row) { + ::slotted(#{$prefix}-table-cell), + ::slotted(#{$prefix}-table-cell-skeleton), + .#{$prefix}--table-expand, + .#{$prefix}--table-column-checkbox { + color: $text-02; + border-top: 1px solid $ui-01; + border-bottom: 1px solid $ui-03; + padding: rem(14px) $spacing-04; + padding-bottom: rem(13px); + vertical-align: middle; + } +} + +:host(#{$prefix}-table-row) { + ::slotted(#{$prefix}-table-cell:first-of-type), + ::slotted(#{$prefix}-table-cell-skeleton:first-of-type) { + padding-left: $spacing-05; + } + + ::slotted(#{$prefix}-table-cell:last-of-type), + ::slotted(#{$prefix}-table-cell-skeleton:last-of-type) { + padding-right: $spacing-05; + } +} + +:host(#{$prefix}-table-row[even]) { + ::slotted(#{$prefix}-table-cell), + ::slotted(#{$prefix}-table-cell-skeleton) { + border-bottom: 1px solid $ui-01; + } +} + +:host(#{$prefix}-table-row[odd]) { + ::slotted(#{$prefix}-table-cell), + ::slotted(#{$prefix}-table-cell-skeleton) { + background-color: $data-table-zebra-color; + border-bottom: 1px solid $data-table-zebra-color; + border-top: 1px solid $data-table-zebra-color; + } +} + +:host(#{$prefix}-table-row:hover), +:host(#{$prefix}-table-expand-row:hover) { + ::slotted(#{$prefix}-table-cell), + ::slotted(#{$prefix}-table-cell-skeleton), + .#{$prefix}--table-expand, + .#{$prefix}--table-column-checkbox { + color: $text-01; + background-color: $hover-field; + border-bottom-color: $hover-field; + border-top-color: $hover-field; + } +} + +:host(#{$prefix}-table-row[even]:hover), +:host(#{$prefix}-table-row[odd]:hover) { + ::slotted(#{$prefix}-table-cell), + ::slotted(#{$prefix}-table-cell-skeleton) { + background-color: $hover-field; + border-bottom: 1px solid $hover-field; + border-top: 1px solid $hover-field; + } +} diff --git a/packages/carbon-web-components/src/components/data-table/_table-expandable.scss b/packages/carbon-web-components/src/components/data-table/_table-expandable.scss new file mode 100644 index 00000000000..ca842c949ba --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/_table-expandable.scss @@ -0,0 +1,64 @@ +// +// Copyright IBM Corp. 2020, 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +:host(#{$prefix}-table-expand-row), +:host(#{$prefix}-table-header-expand-row) { + .#{$prefix}--table-expand { + display: table-cell; + width: 2.5rem; + height: 3rem; + vertical-align: middle; + padding: 0; + border-bottom: 1px solid $ui-03; + transition: transform $duration--moderate-01 motion(standard, productive); + } + + &[expanded] .#{$prefix}--table-expand { + border-bottom: 1px solid transparent; + + .#{$prefix}--table-expand__svg { + transform: rotate(270deg); + } + } +} + +:host(#{$prefix}-table-expanded-row) { + display: table-row; + transition: height $duration--moderate-02 motion(standard), + background-color $duration--fast-02 motion(standard); + + &[expanded] { + height: auto; + } + + td { + padding: 0 $spacing-05; + vertical-align: middle; + height: 0; + transition: all $duration--fast-02 motion(standard, productive); + + .#{$prefix}--child-row-inner-container { + overflow: hidden; + height: 0; + } + } + + &[expanded] td { + border-bottom: 1px solid $ui-03; + padding-top: rem(14px); + padding-bottom: rem(13px); + height: auto; + + .#{$prefix}--child-row-inner-container { + height: auto; + } + } + + &[highlighted] { + background-color: $hover-ui; + } +} diff --git a/packages/carbon-web-components/src/components/data-table/_table-selection.scss b/packages/carbon-web-components/src/components/data-table/_table-selection.scss new file mode 100644 index 00000000000..c118c68707e --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/_table-selection.scss @@ -0,0 +1,57 @@ +// +// Copyright IBM Corp. 2019, 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +// +// Selection check box +// + +:host(#{$prefix}-table-header-row) .#{$prefix}--table-column-checkbox { + position: relative; + background-color: $ui-03; + // 16px padding left + 8px padding right + 20px checkbox width + width: rem(44px); + transition: background-color $duration--fast-01 motion(entrance, productive); +} + +:host(#{$prefix}-table-row) .#{$prefix}--table-column-checkbox { + .#{$prefix}--checkbox-label { + padding-left: $spacing-05; + } +} + +:host(#{$prefix}-table-header-row) .#{$prefix}--table-column-checkbox:hover { + // Highlight "select all" columns like sorting column + background-color: $data-table-column-hover; +} + +:host(#{$prefix}-table-row[size='tall']) .#{$prefix}--table-column-checkbox { + padding-top: rem(12px); +} + +// +// Selected rows +// + +:host(#{$prefix}-table-row[selected]) { + ::slotted(#{$prefix}-table-cell), + .#{$prefix}--table-column-checkbox { + color: $text-01; + background-color: $ui-03; + border-top: 1px solid $ui-03; + //bottom border acts as separator from other rows + border-bottom: 1px solid $active-ui; + } +} + +:host(#{$prefix}-table-row[selected]:hover) { + ::slotted(#{$prefix}-table-cell), + .#{$prefix}--table-column-checkbox { + background-color: $data-table-column-hover; + border-top-color: $data-table-column-hover; + border-bottom-color: $data-table-column-hover; + } +} diff --git a/packages/carbon-web-components/src/components/data-table/_table-sizes.scss b/packages/carbon-web-components/src/components/data-table/_table-sizes.scss new file mode 100644 index 00000000000..836064be490 --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/_table-sizes.scss @@ -0,0 +1,59 @@ +// +// Copyright IBM Corp. 2019, 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +// +// "Compact" table size variant +// + +:host(#{$prefix}-table-head) + ::slotted(#{$prefix}-table-header-row[size='compact']), +:host(#{$prefix}-table-body) ::slotted(#{$prefix}-table-row[size='compact']) { + height: rem(24px); +} + +:host(#{$prefix}-table-row[size='compact']) { + ::slotted(#{$prefix}-table-cell), + ::slotted(#{$prefix}-table-cell-skeleton) { + padding-top: rem(2px); + padding-bottom: rem(2px); + } +} + +// +// "Short" table size variant +// + +:host(#{$prefix}-table-head) + ::slotted(#{$prefix}-table-header-row[size='short']), +:host(#{$prefix}-table-body) ::slotted(#{$prefix}-table-row[size='short']) { + height: rem(32px); +} + +:host(#{$prefix}-table-row[size='short']) { + ::slotted(#{$prefix}-table-cell), + ::slotted(#{$prefix}-table-cell-skeleton) { + padding-top: rem(7px); + padding-bottom: rem(6px); + } +} + +// +// "Tall" table size variant +// + +:host(#{$prefix}-table-head) + ::slotted(#{$prefix}-table-header-row[size='tall']), +:host(#{$prefix}-table-body) ::slotted(#{$prefix}-table-row[size='tall']) { + height: rem(64px); +} + +:host(#{$prefix}-table-row[size='tall']) { + ::slotted(#{$prefix}-table-cell), + ::slotted(#{$prefix}-table-cell-skeleton) { + padding-top: rem(16px); + } +} diff --git a/packages/carbon-web-components/src/components/data-table/_table-skeleton.scss b/packages/carbon-web-components/src/components/data-table/_table-skeleton.scss new file mode 100644 index 00000000000..e43b0bb79ab --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/_table-skeleton.scss @@ -0,0 +1,24 @@ +// +// Copyright IBM Corp. 2019, 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@import 'carbon-components/scss/globals/scss/helper-mixins'; + +:host(#{$prefix}-table-header-cell-skeleton), +:host(#{$prefix}-table-cell-skeleton) { + span { + @include skeleton; + + width: 75%; + height: 1rem; + display: block; + } +} + +:host(#{$prefix}-table-header-cell-skeleton) { + border-bottom: 1px solid $brand-01; + vertical-align: middle; +} diff --git a/packages/carbon-web-components/src/components/data-table/_table-sort.scss b/packages/carbon-web-components/src/components/data-table/_table-sort.scss new file mode 100644 index 00000000000..8d7185b0e0b --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/_table-sort.scss @@ -0,0 +1,73 @@ +// +// Copyright IBM Corp. 2019, 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@import 'carbon-components/scss/components/data-table/data-table-sort'; + +:host(#{$prefix}-table-header-row[size='compact']) + ::slotted(#{$prefix}-table-header-cell[sort-direction]) { + height: rem(24px); +} + +:host(#{$prefix}-table-header-row[size='short']) + ::slotted(#{$prefix}-table-header-cell[sort-direction]) { + height: rem(32px); +} + +:host(#{$prefix}-table-header-row[size='tall']) + ::slotted(#{$prefix}-table-header-cell[sort-direction]) { + height: rem(64px); +} + +// Padding of header cell for sorting +// +// Let sort button rather than the cell define the padding +// Ensure sort button takes 100% of the cell, by setting the same height as the parent row + +:host(#{$prefix}-table-header-row) + ::slotted(#{$prefix}-table-header-cell[sort-direction]) { + height: rem(48px); + padding-left: 0; + padding-right: 0; +} + +:host(#{$prefix}-table-header-cell[sort-direction]) .#{$prefix}--table-sort { + height: 100%; + padding-left: $spacing-04; + padding-right: $spacing-04; +} + +:host(#{$prefix}-table-header-cell[sort-direction]:first-of-type) + .#{$prefix}--table-sort { + padding-left: $spacing-05; +} + +// +// Sort icon style +// + +// Show sort icon of primary sorting column or one of hovered column +:host(#{$prefix}-table-header-cell[sort-active]) + .bx--table-sort + .bx--table-sort__icon, +:host(#{$prefix}-table-header-cell) + .bx--table-sort:hover + .bx--table-sort__icon { + opacity: 1; +} + +// `carbon-web-components` uses conditional rendering for choosing Arrows16 vs. ArrowDown16, +// and thus `display:none` here is not needed +:host(#{$prefix}-table-header-cell[sort-direction]) + .bx--table-sort + .bx--table-sort__icon { + display: block; +} + +:host(#{$prefix}-table-header-cell[sort-direction='ascending']) + .#{$prefix}--table-sort__icon { + transform: rotate(180deg); +} diff --git a/packages/carbon-web-components/src/components/data-table/core-library-style-questions.md b/packages/carbon-web-components/src/components/data-table/core-library-style-questions.md new file mode 100644 index 00000000000..67b43b16117 --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/core-library-style-questions.md @@ -0,0 +1,6 @@ +- `` in addition to `` setting `background-color`: + https://github.com/carbon-design-system/carbon/blob/v10.3.0/packages/components/src/components/data-table/_data-table-core.scss#L74-L76 +- Re-definition of text color and border width/style for selected and hovered + ``s: + - https://github.com/carbon-design-system/carbon/blob/v10.3.0/packages/components/src/components/data-table/_data-table-core.scss#L78-L83 + - https://github.com/carbon-design-system/carbon/blob/v10.3.0/packages/components/src/components/data-table/_data-table-core.scss#L304-L314 diff --git a/packages/carbon-web-components/src/components/data-table/data-table-story.mdx b/packages/carbon-web-components/src/components/data-table/data-table-story.mdx new file mode 100644 index 00000000000..bfab025d27b --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/data-table-story.mdx @@ -0,0 +1,336 @@ +import { Props, Description } from '@storybook/addon-docs/blocks'; +import { cdnJs, cdnCss } from '../../globals/internal/storybook-cdn'; + +# Data table + +> ๐Ÿ’ก Check our +> [CodeSandbox](https://codesandbox.io/s/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/carbon-web-components/examples/codesandbox/basic/components/data-table) +> example implementation. + +[![Edit carbon-web-components](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/carbon-design-system/carbon-for-ibm-dotcom/tree/main/packages/carbon-web-components/examples/codesandbox/basic/components/data-table) + +## Getting started + +Here's a quick example to get you started. + +Data table in `carbon-web-components` focuses on primitives that constructs +table UI, consisting of the following: + +| Tag | Description | HTML tag counterpart | +| ------------------------ | --------------- | -------------------- | +| `` | The container | N/A | +| `` | The table | `` | +| `` | The header | `` | +| `` | The header row | `` in `` | +| `` | The header cell | `` | +| `` | The header row | `` in `` | +| `` | The header cell | ` + `; + } + + static styles = styles; // `styles` here is a `CSSResult` generated by custom WebPack loader +} + +export default BXTableExpandedRow; diff --git a/packages/carbon-web-components/src/components/data-table/table-head.ts b/packages/carbon-web-components/src/components/data-table/table-head.ts new file mode 100644 index 00000000000..3fe0cf64420 --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/table-head.ts @@ -0,0 +1,37 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import settings from 'carbon-components/es/globals/js/settings'; +import { html, customElement, LitElement } from 'lit-element'; +import styles from './data-table.scss'; + +const { prefix } = settings; + +/** + * Data table header. + * + * @element bx-table-head + */ +@customElement(`${prefix}-table-head`) +class BXTableHead extends LitElement { + connectedCallback() { + if (!this.hasAttribute('role')) { + this.setAttribute('role', 'rowgroup'); + } + super.connectedCallback(); + } + + render() { + return html` `; + } + + static styles = styles; +} + +export default BXTableHead; diff --git a/packages/carbon-web-components/src/components/data-table/table-header-cell-skeleton.ts b/packages/carbon-web-components/src/components/data-table/table-header-cell-skeleton.ts new file mode 100644 index 00000000000..2a6bd555d7d --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/table-header-cell-skeleton.ts @@ -0,0 +1,24 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { customElement } from 'lit-element'; +import settings from 'carbon-components/es/globals/js/settings'; +import BXTableCell from './table-cell'; + +const { prefix } = settings; + +/** + * Data table header cell with skeleton content. + * + * @element bx-table-header-cell-skeleton + */ +@customElement(`${prefix}-table-header-cell-skeleton`) +class BXTableHeaderCellSkeleton extends BXTableCell {} + +export default BXTableHeaderCellSkeleton; diff --git a/packages/carbon-web-components/src/components/data-table/table-header-cell.ts b/packages/carbon-web-components/src/components/data-table/table-header-cell.ts new file mode 100644 index 00000000000..80ce8719125 --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/table-header-cell.ts @@ -0,0 +1,177 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import settings from 'carbon-components/es/globals/js/settings'; +import { html, property, customElement, LitElement } from 'lit-element'; +import Arrows16 from '@carbon/icons/lib/arrows/16'; +import ArrowDown16 from '@carbon/icons/lib/arrow--down/16'; +import FocusMixin from '../../globals/mixins/focus'; +import { + TABLE_SORT_CYCLE, + TABLE_SORT_CYCLES, + TABLE_SORT_DIRECTION, +} from './defs'; +import styles from './data-table.scss'; + +export { TABLE_SORT_CYCLE, TABLE_SORT_CYCLES, TABLE_SORT_DIRECTION }; + +const { prefix } = settings; + +/** + * Data table header cell. + * + * @element bx-table-header-cell + * @fires bx-table-header-cell-sort + * The custom event fired before a new sort direction is set upon a user gesture. + * Cancellation of this event stops the user-initiated change in sort direction. + */ +@customElement(`${prefix}-table-header-cell`) +class BXTableHeaderCell extends FocusMixin(LitElement) { + /** + * Handles `click` event on the sort button. + * + */ + private _handleClickSortButton() { + const nextSortDirection = this._getNextSort(); + const init = { + bubbles: true, + cancelable: true, + composed: true, + detail: { + oldSortDirection: this.sortDirection, + sortDirection: nextSortDirection, + }, + }; + const constructor = this.constructor as typeof BXTableHeaderCell; + if ( + this.dispatchEvent(new CustomEvent(constructor.eventBeforeSort, init)) + ) { + this.sortActive = true; + this.sortDirection = nextSortDirection; + } + } + + /** + * Handles `slotchange` event. + * + */ + private _handleSlotChange() { + this.requestUpdate(); + } + + /** + * @returns The next sort direction. + */ + private _getNextSort() { + const { + sortCycle = TABLE_SORT_CYCLE.TRI_STATES_FROM_ASCENDING, + sortDirection, + } = this; + if (!sortDirection) { + throw new TypeError( + 'Table sort direction is not defined. ' + + 'Likely that `_getNextSort()` is called with non-sorted table column, which should not happen in regular condition.' + ); + } + const directions = (this.constructor as typeof BXTableHeaderCell) + .TABLE_SORT_CYCLES[sortCycle]; + const index = directions.indexOf(sortDirection as TABLE_SORT_DIRECTION); + if (index < 0) { + if (sortDirection === TABLE_SORT_DIRECTION.NONE) { + // If the current sort direction is `none` in bi-state sort cycle, returns the first one in the cycle + return directions[0]; + } + throw new RangeError( + `The given sort state (${sortDirection}) is not found in the given table sort cycle: ${sortCycle}` + ); + } + return directions[(index + 1) % directions.length]; + } + + /** + * `true` if this table header cell is of a primary sorting column. + */ + @property({ type: Boolean, reflect: true, attribute: 'sort-active' }) + sortActive = false; + + /** + * The table sort cycle in use. + */ + @property({ reflect: true, attribute: 'sort-cycle' }) + sortCycle?: TABLE_SORT_CYCLE; + + /** + * The table sort direction. + * If present, this table header cell will have a sorting UI. Choose between `ascending` or `descending`. + */ + @property({ reflect: true, attribute: 'sort-direction' }) + sortDirection?: TABLE_SORT_DIRECTION; + + createRenderRoot() { + return this.attachShadow({ + mode: 'open', + delegatesFocus: + Number((/Safari\/(\d+)/.exec(navigator.userAgent) ?? ['', 0])[1]) <= + 537, + }); + } + + connectedCallback() { + if (!this.hasAttribute('role')) { + this.setAttribute('role', 'columnheader'); + } + super.connectedCallback(); + } + + render() { + const { sortDirection } = this; + if (sortDirection) { + const sortIcon = + sortDirection === TABLE_SORT_DIRECTION.NONE + ? Arrows16({ + part: 'sort-icon', + class: `${prefix}--table-sort__icon-unsorted`, + }) + : ArrowDown16({ + part: 'sort-icon', + class: `${prefix}--table-sort__icon`, + }); + return html` + + `; + } + return html` `; + } + + /** + * The name of the custom event fired before a new sort direction is set upon a user gesture. + * Cancellation of this event stops the user-initiated change in sort direction. + */ + static get eventBeforeSort() { + return `${prefix}-table-header-cell-sort`; + } + + static styles = styles; + + /** + * Mapping of table sort cycles to table sort states. + */ + static TABLE_SORT_CYCLES = TABLE_SORT_CYCLES; +} + +export default BXTableHeaderCell; diff --git a/packages/carbon-web-components/src/components/data-table/table-header-expand-row.ts b/packages/carbon-web-components/src/components/data-table/table-header-expand-row.ts new file mode 100644 index 00000000000..ad90d2e2405 --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/table-header-expand-row.ts @@ -0,0 +1,47 @@ +/** + * @license + * + * Copyright IBM Corp. 2020, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import settings from 'carbon-components/es/globals/js/settings'; +import { customElement } from 'lit-element'; +import BXTableExpandRow from './table-expand-row'; + +const { prefix } = settings; + +/** + * Data table header row. + * + * @element bx-table-header-expand-row + */ +@customElement(`${prefix}-table-header-expand-row`) +class BXTableHeaderExpandRow extends BXTableExpandRow { + /** + * The name of the custom event fired before this row is selected/unselected upon a user gesture. + * Cancellation of this event stops the user-initiated change in selection. + */ + static get eventBeforeChangeSelection() { + return `${prefix}-table-change-selection-all`; + } + + /** + * The name of the custom event fired before the expanded state this row is being toggled upon a user gesture. + * Cancellation of this event stops the user-initiated action of toggling the expanded state. + */ + static get eventBeforeExpandoToggle() { + return `${prefix}-table-row-expando-beingtoggled-all`; + } + + /** + * The name of the custom event fired after the expanded state this row is toggled upon a user gesture. + */ + static get eventExpandoToggle() { + return `${prefix}-table-row-expando-toggled-all`; + } +} + +export default BXTableHeaderExpandRow; diff --git a/packages/carbon-web-components/src/components/data-table/table-header-row.ts b/packages/carbon-web-components/src/components/data-table/table-header-row.ts new file mode 100644 index 00000000000..6a130b1b47c --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/table-header-row.ts @@ -0,0 +1,32 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import settings from 'carbon-components/es/globals/js/settings'; +import { customElement } from 'lit-element'; +import BXTableRow from './table-row'; + +const { prefix } = settings; + +/** + * Data table header row. + * + * @element bx-table-header-row + */ +@customElement(`${prefix}-table-header-row`) +class BXTableHeaderRow extends BXTableRow { + /** + * The name of the custom event fired before this row is selected/unselected upon a user gesture. + * Cancellation of this event stops the user-initiated change in selection. + */ + static get eventBeforeChangeSelection() { + return `${prefix}-table-change-selection-all`; + } +} + +export default BXTableHeaderRow; diff --git a/packages/carbon-web-components/src/components/data-table/table-row.ts b/packages/carbon-web-components/src/components/data-table/table-row.ts new file mode 100644 index 00000000000..0a2bfc12e74 --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/table-row.ts @@ -0,0 +1,170 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import settings from 'carbon-components/es/globals/js/settings'; +import { html, property, customElement, LitElement } from 'lit-element'; +import FocusMixin from '../../globals/mixins/focus'; +import styles from './data-table.scss'; + +const { prefix } = settings; + +/** + * Data table row. + * + * @element bx-table-row + * @csspart selection-container The container of the checkbox. + * @csspart selection The checkbox. + * @fires bx-table-row-change-selection + * The custom event fired before this row is selected/unselected upon a user gesture. + * Cancellation of this event stops the user-initiated change in selection. + */ +@customElement(`${prefix}-table-row`) +class BXTableRow extends FocusMixin(LitElement) { + /** + * Handles `click` event on the check box. + * + * @param event The event. + */ + private _handleClickSelectionCheckbox(event: Event) { + const selected = (event.target as HTMLInputElement).checked; + const init = { + bubbles: true, + cancelable: true, + composed: true, + detail: { + selected, + }, + }; + const constructor = this.constructor as typeof BXTableRow; + if ( + this.dispatchEvent( + new CustomEvent(constructor.eventBeforeChangeSelection, init) + ) + ) { + this.selected = selected; + } + } + + /** + * @returns The first set of table cells. + */ + protected _renderFirstCells() { + const { + disabled, + selected, + selectionLabel, + selectionName, + selectionValue, + } = this; + // Using `@click` instead of `@change` to support `.preventDefault()` + return !selectionName + ? undefined + : html` +
+ ${html` + + + `} +
+ `; + } + + /** + * `true` if this table row should be disabled. + */ + @property({ type: Boolean, reflect: true }) + disabled = false; + + /** + * `true` if this table row is placed at an even position in parent ``. + * `` sets this property, _only_ in zebra stripe mode. + * + * @private + */ + @property({ type: Boolean, reflect: true }) + even = false; + + /** + * `true` if this table row is placed at an odd position in parent ``. + * `` sets this property, _only_ in zebra stripe mode. + * + * @private + */ + @property({ type: Boolean, reflect: true }) + odd = false; + + /** + * `true` if this table row should be selected. + */ + @property({ type: Boolean, reflect: true }) + selected = false; + + /** + * The `aria-label` attribute for the ` - + `; } diff --git a/packages/web-components/src/components/structured-list/structured-list-head.ts b/packages/web-components/src/components/structured-list/structured-list-head.ts index 94c91118e96..418fc03ab7a 100644 --- a/packages/web-components/src/components/structured-list/structured-list-head.ts +++ b/packages/web-components/src/components/structured-list/structured-list-head.ts @@ -7,7 +7,7 @@ * LICENSE file in the root directory of this source tree. */ -import BXStructuredListHead from 'carbon-web-components/es/components/structured-list/structured-list-head.js'; +import BXStructuredListHead from '@carbon/web-components/es/components/structured-list/structured-list-head.js'; import { customElement } from 'lit-element'; import ddsSettings from '../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; import styles from './structured-list.scss'; diff --git a/packages/web-components/src/components/structured-list/structured-list-header-cell.ts b/packages/web-components/src/components/structured-list/structured-list-header-cell.ts index b63578b23be..624c9d0a3fd 100644 --- a/packages/web-components/src/components/structured-list/structured-list-header-cell.ts +++ b/packages/web-components/src/components/structured-list/structured-list-header-cell.ts @@ -7,7 +7,7 @@ * LICENSE file in the root directory of this source tree. */ -import BXStructuredListHeaderCell from 'carbon-web-components/es/components/structured-list/structured-list-header-cell.js'; +import BXStructuredListHeaderCell from '@carbon/web-components/es/components/structured-list/structured-list-header-cell.js'; import { customElement } from 'lit-element'; import ddsSettings from '../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; import styles from './structured-list.scss'; diff --git a/packages/web-components/src/components/structured-list/structured-list-header-row.ts b/packages/web-components/src/components/structured-list/structured-list-header-row.ts index 3474eee0503..519175beb1e 100644 --- a/packages/web-components/src/components/structured-list/structured-list-header-row.ts +++ b/packages/web-components/src/components/structured-list/structured-list-header-row.ts @@ -7,7 +7,7 @@ * LICENSE file in the root directory of this source tree. */ -import BXStructuredListHeaderRow from 'carbon-web-components/es/components/structured-list/structured-list-header-row.js'; +import BXStructuredListHeaderRow from '@carbon/web-components/es/components/structured-list/structured-list-header-row.js'; import { customElement } from 'lit-element'; import ddsSettings from '../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; import styles from './structured-list.scss'; diff --git a/packages/web-components/src/components/structured-list/structured-list-row.ts b/packages/web-components/src/components/structured-list/structured-list-row.ts index 2f1747229f7..54fcf52b1a5 100644 --- a/packages/web-components/src/components/structured-list/structured-list-row.ts +++ b/packages/web-components/src/components/structured-list/structured-list-row.ts @@ -7,7 +7,7 @@ * LICENSE file in the root directory of this source tree. */ -import BXStructuredListRow from 'carbon-web-components/es/components/structured-list/structured-list-row.js'; +import BXStructuredListRow from '@carbon/web-components/es/components/structured-list/structured-list-row.js'; import { customElement } from 'lit-element'; import { html } from 'lit-html'; import ddsSettings from '../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; @@ -32,9 +32,7 @@ class DDSStructuredListRow extends BXStructuredListRow { /* eslint-enable */ render() { - return html` - - `; + return html` `; } static styles = styles; diff --git a/packages/web-components/src/components/structured-list/structured-list.ts b/packages/web-components/src/components/structured-list/structured-list.ts index 8764eda2597..7fcf80bc494 100644 --- a/packages/web-components/src/components/structured-list/structured-list.ts +++ b/packages/web-components/src/components/structured-list/structured-list.ts @@ -23,18 +23,23 @@ const { prefix } = settings; */ @customElement(`${ddsPrefix}-structured-list`) class DDSStructuredList extends StableSelectorMixin(LitElement) { - private _listMutationObserver = new MutationObserver(this._setColumnSpans.bind(this)); + private _listMutationObserver = new MutationObserver( + this._setColumnSpans.bind(this) + ); /** * Handles attribute changes to attributes starting with `col-span`. */ private _setColumnSpans(entries) { - entries.forEach(entry => { + entries.forEach((entry) => { const attr = entry.attributeName; if (attr?.startsWith('col-span')) { if (this.hasAttribute(attr) && parseInt(this.getAttribute(attr)!, 10)) { - this.style.setProperty(`--${attr}`, parseInt(this.getAttribute(attr)!, 10).toString()); + this.style.setProperty( + `--${attr}`, + parseInt(this.getAttribute(attr)!, 10).toString() + ); } else { this.style.removeProperty(`--${attr}`); } @@ -47,11 +52,16 @@ class DDSStructuredList extends StableSelectorMixin(LitElement) { this.setAttribute('role', 'table'); } super.connectedCallback(); - this._listMutationObserver.observe(this, { attributes: true, attributeOldValue: true }); + this._listMutationObserver.observe(this, { + attributes: true, + attributeOldValue: true, + }); - const colSpanAttributes = Object.values(this.attributes).filter(attr => attr.name.startsWith('col-span')); + const colSpanAttributes = Object.values(this.attributes).filter((attr) => + attr.name.startsWith('col-span') + ); - colSpanAttributes.forEach(attr => { + colSpanAttributes.forEach((attr) => { this.style.setProperty(`--${attr.name}`, attr.value); }); } diff --git a/packages/web-components/src/components/table-of-contents/__stories__/content.ts b/packages/web-components/src/components/table-of-contents/__stories__/content.ts index 42b8ebd16da..aad22be3ae5 100644 --- a/packages/web-components/src/components/table-of-contents/__stories__/content.ts +++ b/packages/web-components/src/components/table-of-contents/__stories__/content.ts @@ -21,29 +21,16 @@ export const headings = [ // eslint-disable-next-line max-len export const LOREM = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras molestie condimentum consectetur. Nulla tristique lacinia elit, at elementum dui gravida non. Mauris et nisl semper, elementum quam non, lacinia purus. Vivamus aliquam vitae sapien volutpat efficitur. Curabitur sagittis neque facilisis magna posuere consectetur. Praesent fermentum sodales facilisis. Mauris a efficitur sem. Aliquam vehicula sapien libero, a viverra felis scelerisque vel. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec fringilla dui tellus, a pretium diam vehicula et. Etiam non vulputate augue. Morbi laoreet diam dapibus sapien pellentesque tristique. Morbi id nibh metus. Integer non scelerisque nisl.`; -const generateCopySections = n => - Array(n).map( - () => - html` -

${LOREM}

- ` - ); +const generateCopySections = (n) => Array(n).map(() => html`

${LOREM}

`); const content = ({ contentClass, items }) => html`
${items.map( ({ heading, copy }, i) => html` -

- ${heading} -

+

${heading}

${copy - ? copy.split('\n').map( - section => - html` -

${section}

- ` - ) + ? copy.split('\n').map((section) => html`

${section}

`) : generateCopySections(3)} ` )} diff --git a/packages/web-components/src/components/table-of-contents/__stories__/table-of-contents.stories.ts b/packages/web-components/src/components/table-of-contents/__stories__/table-of-contents.stories.ts index ded53de5389..15f611303cc 100644 --- a/packages/web-components/src/components/table-of-contents/__stories__/table-of-contents.stories.ts +++ b/packages/web-components/src/components/table-of-contents/__stories__/table-of-contents.stories.ts @@ -10,7 +10,7 @@ import { nothing } from 'lit-html'; import { html } from 'lit-element'; import { boolean, select, text } from '@storybook/addon-knobs'; -import ArrowLeft20 from 'carbon-web-components/es/icons/arrow--left/20.js'; +import ArrowLeft20 from '@carbon/web-components/es/icons/arrow--left/20.js'; import '../table-of-contents'; import '../../horizontal-rule/horizontal-rule'; import '../../image/image'; @@ -21,7 +21,7 @@ import readme from './README.stories.mdx'; import { TOC_TYPES } from '../defs'; import { ICON_PLACEMENT } from '../../../globals/defs'; -export const Default = args => { +export const Default = (args) => { const { numberOfItems: items, withHeadingContent } = args?.Other ?? {}; return html` @@ -30,20 +30,17 @@ export const Default = args => { + href="https://github.com/carbon-design-system/carbon-web-components"> DevOps${ArrowLeft20({ slot: 'icon' })} + href="https://github.com/carbon-design-system/carbon-web-components"> Automation${ArrowLeft20({ slot: 'icon' })} + href="https://github.com/carbon-design-system/carbon-web-components"> Development${ArrowLeft20({ slot: 'icon' })} @@ -55,13 +52,16 @@ export const Default = args => { `; }; -export const Horizontal = args => { +export const Horizontal = (args) => { const { numberOfItems: items } = args?.Other ?? {}; return html`
- ${content({ contentClass: 'bx--tableofcontents-horizontal__contents', items })} + ${content({ + contentClass: 'bx--tableofcontents-horizontal__contents', + items, + })}
@@ -76,7 +76,10 @@ Horizontal.story = { numberOfItems: Array.from({ length: select('Number of items', [5, 6, 7, 8], 5), }).map((_, i) => ({ - heading: text(`Section ${i + 1} heading`, headings[i % headings.length]), + heading: text( + `Section ${i + 1} heading`, + headings[i % headings.length] + ), copy: text(`Section ${i + 1} copy`, `${LOREM}\n`.repeat(3).trim()), })), }), @@ -100,13 +103,11 @@ Horizontal.story = { export default { title: 'Components/Table of contents', decorators: [ - story => html` + (story) => html` -
- ${story()} -
+
${story()}
`, ], parameters: { @@ -118,7 +119,10 @@ export default { numberOfItems: Array.from({ length: select('Number of items', [5, 6, 7, 8], 5), }).map((_, i) => ({ - heading: text(`Section ${i + 1} heading`, headings[i % headings.length]), + heading: text( + `Section ${i + 1} heading`, + headings[i % headings.length] + ), copy: text(`Section ${i + 1} copy`, `${LOREM}\n`.repeat(3).trim()), })), }), diff --git a/packages/web-components/src/components/table-of-contents/__tests__/table-of-contents.steps.js b/packages/web-components/src/components/table-of-contents/__tests__/table-of-contents.steps.js index d82c097d509..836bcad5401 100644 --- a/packages/web-components/src/components/table-of-contents/__tests__/table-of-contents.steps.js +++ b/packages/web-components/src/components/table-of-contents/__tests__/table-of-contents.steps.js @@ -1,7 +1,7 @@ /** * @license * - * Copyright IBM Corp. 2020 + * Copyright IBM Corp. 2020, 2022 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. @@ -9,49 +9,69 @@ describe('dds-table-of-contents', () => { describe('With wide screen', () => { - describe('Without heading content', function() { + describe('Without heading content', function () { beforeEach(async () => { await page.setViewportSize({ width: 1280, height: 720 }); - await page.goto(`http://localhost:${process.env.PORT}/iframe.html?id=components-table-of-contents--default`); + await page.goto( + `http://localhost:${process.env.PORT}/iframe.html?id=components-table-of-contents--default` + ); }); it('should hide the heading container unless it has its content', async () => { - await expect(page).toHaveSelector('dds-table-of-contents .bx--tableofcontents__desktop__children', { state: 'hidden' }); + await expect(page).toHaveSelector( + 'dds-table-of-contents .bx--tableofcontents__desktop__children', + { state: 'hidden' } + ); }); }); describe('With heading content', () => { beforeEach(async () => { await page.setViewportSize({ width: 1280, height: 720 }); - await page.goto(`http://localhost:${process.env.PORT}/iframe.html?id=components-table-of-contents--with-heading-content`); + await page.goto( + `http://localhost:${process.env.PORT}/iframe.html?id=components-table-of-contents--with-heading-content` + ); }); it('should show the heading container', async () => { - await expect(page).toHaveSelector('dds-table-of-contents .bx--tableofcontents__desktop__children', { state: 'visible' }); + await expect(page).toHaveSelector( + 'dds-table-of-contents .bx--tableofcontents__desktop__children', + { state: 'visible' } + ); }); }); }); describe('With narrow screen', () => { - describe('Without heading content', function() { + describe('Without heading content', function () { beforeEach(async () => { await page.setViewportSize({ width: 672, height: 720 }); - await page.goto(`http://localhost:${process.env.PORT}/iframe.html?id=components-table-of-contents--default`); + await page.goto( + `http://localhost:${process.env.PORT}/iframe.html?id=components-table-of-contents--default` + ); }); it('should hide the heading container unless it has its content', async () => { - await expect(page).toHaveSelector('dds-table-of-contents .bx--tableofcontents__children__mobile', { state: 'hidden' }); + await expect(page).toHaveSelector( + 'dds-table-of-contents .bx--tableofcontents__children__mobile', + { state: 'hidden' } + ); }); }); describe('With heading content', () => { beforeEach(async () => { await page.setViewportSize({ width: 672, height: 720 }); - await page.goto(`http://localhost:${process.env.PORT}/iframe.html?id=components-table-of-contents--with-heading-content`); + await page.goto( + `http://localhost:${process.env.PORT}/iframe.html?id=components-table-of-contents--with-heading-content` + ); }); it('should show the heading container', async () => { - await expect(page).toHaveSelector('dds-table-of-contents .bx--tableofcontents__children__mobile', { state: 'visible' }); + await expect(page).toHaveSelector( + 'dds-table-of-contents .bx--tableofcontents__children__mobile', + { state: 'visible' } + ); }); }); }); diff --git a/packages/web-components/src/components/table-of-contents/__tests__/table-of-contents.test.ts b/packages/web-components/src/components/table-of-contents/__tests__/table-of-contents.test.ts index 853c8fcef8c..79aef861e23 100644 --- a/packages/web-components/src/components/table-of-contents/__tests__/table-of-contents.test.ts +++ b/packages/web-components/src/components/table-of-contents/__tests__/table-of-contents.test.ts @@ -10,47 +10,44 @@ import { html, render } from 'lit-html'; import EventManager from '../../../../tests/utils/event-manager'; import MockResizeObserver from '../../../../tests/utils/mock-resize-observer'; -/* eslint-disable import/no-duplicates */ import DDSTableOfContents from '../table-of-contents'; // Above import is interface-only ref and thus code won't be brought into the build import '../table-of-contents'; -/* eslint-enable import/no-duplicates */ const template = (props?) => { const { children } = props ?? {}; - return html` - ${children} - `; + return html` ${children} `; }; -describe('dds-table-of-contents', function() { +describe('dds-table-of-contents', function () { const events = new EventManager(); - describe('Misc attributes', function() { + describe('Misc attributes', function () { let origResizeObserver; - beforeEach(function() { + beforeEach(function () { // TODO: Wait for `.d.ts` update to support `ResizeObserver` origResizeObserver = (window as any).ResizeObserver; // TODO: Wait for `.d.ts` update to support `ResizeObserver` (window as any).ResizeObserver = MockResizeObserver; }); - it('should render with minimum attributes', async function() { + it('should render with minimum attributes', async function () { render(template(), document.body); await Promise.resolve(); - expect(document.body.querySelector('dds-table-of-contents')).toMatchSnapshot({ mode: 'shadow' }); + expect( + document.body.querySelector('dds-table-of-contents') + ).toMatchSnapshot({ mode: 'shadow' }); }); - it('should render the heading and the rule for desktop', async function() { + it('should render the heading and the rule for desktop', async function () { render( template({ children: html` + default-src="https://fpoimg.com/672x672?text=1:1&bg_color=ee5396&text_color=161616"> `, }), @@ -59,40 +56,50 @@ describe('dds-table-of-contents', function() { await Promise.resolve(); // Update cycle for the component await Promise.resolve(); // The cycle where `slotchange` event is called await Promise.resolve(); // Updating cycle upon `slotchange` - expect(document.body.querySelector('dds-table-of-contents')).toMatchSnapshot({ mode: 'shadow' }); + expect( + document.body.querySelector('dds-table-of-contents') + ).toMatchSnapshot({ mode: 'shadow' }); }); - it('should render the heading for mobile', async function() { + it('should render the heading for mobile', async function () { render( template({ children: html` + default-src="https://fpoimg.com/672x672?text=1:1&bg_color=ee5396&text_color=161616"> `, }), document.body ); await Promise.resolve(); // Update cycle for the component - const tableOfContents = document.querySelector('dds-table-of-contents') as DDSTableOfContents; - MockResizeObserver.run(tableOfContents!.shadowRoot!.querySelector('.bx--tableofcontents__mobile')!, { height: 32 }); + const tableOfContents = document.querySelector( + 'dds-table-of-contents' + ) as DDSTableOfContents; + MockResizeObserver.run( + tableOfContents!.shadowRoot!.querySelector( + '.bx--tableofcontents__mobile' + )!, + { height: 32 } + ); await Promise.resolve(); // Update cycle for the component await Promise.resolve(); // The cycle where `slotchange` event is called await Promise.resolve(); // Updating cycle upon `slotchange` - expect(document.body.querySelector('dds-table-of-contents')).toMatchSnapshot({ mode: 'shadow' }); + expect( + document.body.querySelector('dds-table-of-contents') + ).toMatchSnapshot({ mode: 'shadow' }); }); - afterEach(function() { + afterEach(function () { // TODO: Wait for `.d.ts` update to support `ResizeObserver` (window as any).ResizeObserver = origResizeObserver; }); }); - describe('Harvesting the targets', function() { - it('should harvest the title from the text contents', async function() { + describe('Harvesting the targets', function () { + it('should harvest the title from the text contents', async function () { render( template({ children: html` @@ -108,8 +115,10 @@ describe('dds-table-of-contents', function() { await Promise.resolve(); // Updating upon harvesting ``s expect( Array.prototype.map.call( - document.body.querySelector('dds-table-of-contents')!.shadowRoot!.querySelectorAll('a[data-target]'), - elem => ({ + document.body + .querySelector('dds-table-of-contents')! + .shadowRoot!.querySelectorAll('a[data-target]'), + (elem) => ({ target: elem.dataset.target, hash: /(#.*)$/.exec((elem as HTMLAnchorElement).href)?.[1], title: elem.textContent.trim(), @@ -134,7 +143,7 @@ describe('dds-table-of-contents', function() { ]); }); - it('should harvest the title from the descendants from the slotted children', async function() { + it('should harvest the title from the descendants from the slotted children', async function () { render( template({ children: html` @@ -152,8 +161,10 @@ describe('dds-table-of-contents', function() { await Promise.resolve(); // Updating upon harvesting ``s expect( Array.prototype.map.call( - document.body.querySelector('dds-table-of-contents')!.shadowRoot!.querySelectorAll('a[data-target]'), - elem => ({ + document.body + .querySelector('dds-table-of-contents')! + .shadowRoot!.querySelectorAll('a[data-target]'), + (elem) => ({ target: elem.dataset.target, hash: /(#.*)$/.exec((elem as HTMLAnchorElement).href)?.[1], title: elem.textContent.trim(), @@ -179,8 +190,8 @@ describe('dds-table-of-contents', function() { }); }); - describe('Jumping to an anchor', function() { - it('should have clicking on a desktop link cause jumping to the anchor', async function() { + describe('Jumping to an anchor', function () { + it('should have clicking on a desktop link cause jumping to the anchor', async function () { render( template({ children: html` @@ -194,13 +205,21 @@ describe('dds-table-of-contents', function() { await Promise.resolve(); // Update cycle for the component await Promise.resolve(); // The cycle where `slotchange` event is called await Promise.resolve(); // Updating upon harvesting ``s - const tableOfContents = document.querySelector('dds-table-of-contents') as DDSTableOfContents; + const tableOfContents = document.querySelector( + 'dds-table-of-contents' + ) as DDSTableOfContents; spyOn(tableOfContents as any, '_handleUserInitiatedJump'); - (tableOfContents!.shadowRoot!.querySelector('a[data-target="2"]') as HTMLElement).click(); - expect((tableOfContents as any)._handleUserInitiatedJump).toHaveBeenCalledWith('2'); + ( + tableOfContents!.shadowRoot!.querySelector( + 'a[data-target="2"]' + ) as HTMLElement + ).click(); + expect( + (tableOfContents as any)._handleUserInitiatedJump + ).toHaveBeenCalledWith('2'); }); - it('should have selectng a mobile `s - const tableOfContents = document.querySelector('dds-table-of-contents') as DDSTableOfContents; + const tableOfContents = document.querySelector( + 'dds-table-of-contents' + ) as DDSTableOfContents; spyOn(tableOfContents as any, '_handleUserInitiatedJump'); - const select = tableOfContents!.shadowRoot!.querySelector('.bx--tableofcontents__mobile__select') as HTMLSelectElement; + const select = tableOfContents!.shadowRoot!.querySelector( + '.bx--tableofcontents__mobile__select' + ) as HTMLSelectElement; select.value = '2'; select.dispatchEvent(new CustomEvent('change', { bubbles: true })); - expect((tableOfContents as any)._handleUserInitiatedJump).toHaveBeenCalledWith('2'); + expect( + (tableOfContents as any)._handleUserInitiatedJump + ).toHaveBeenCalledWith('2'); }); }); - afterEach(async function() { + afterEach(async function () { await render(undefined!, document.body); events.reset(); }); diff --git a/packages/web-components/src/components/table-of-contents/table-of-contents.scss b/packages/web-components/src/components/table-of-contents/table-of-contents.scss index c73c1b5e229..1e327149e99 100644 --- a/packages/web-components/src/components/table-of-contents/table-of-contents.scss +++ b/packages/web-components/src/components/table-of-contents/table-of-contents.scss @@ -11,7 +11,8 @@ @import '@carbon/ibmdotcom-styles/scss/components/tableofcontents/tableofcontents'; @import '@carbon/ibmdotcom-styles/scss/components/layout/layout'; -:host(#{$dds-prefix}-table-of-contents[toc-layout='horizontal']) .#{$prefix}--tableofcontents__navbar { +:host(#{$dds-prefix}-table-of-contents[toc-layout='horizontal']) + .#{$prefix}--tableofcontents__navbar { @include carbon--breakpoint('lg') { &::before { border-bottom: 1px solid $ui-04; @@ -39,7 +40,8 @@ } } -:host(#{$dds-prefix}-table-of-contents[toc-layout='horizontal']) .#{$prefix}--tableofcontents__desktop-container { +:host(#{$dds-prefix}-table-of-contents[toc-layout='horizontal']) + .#{$prefix}--tableofcontents__desktop-container { @include carbon--breakpoint('lg') { position: relative; overflow: hidden; @@ -47,11 +49,13 @@ } } -:host(#{$dds-prefix}-table-of-contents[toc-layout='horizontal']) .#{$prefix}--tableofcontents__mobile { +:host(#{$dds-prefix}-table-of-contents[toc-layout='horizontal']) + .#{$prefix}--tableofcontents__mobile { margin: 0; } -:host(#{$dds-prefix}-table-of-contents[toc-layout='horizontal']) .#{$prefix}--tableofcontents__content { +:host(#{$dds-prefix}-table-of-contents[toc-layout='horizontal']) + .#{$prefix}--tableofcontents__content { max-width: none; flex: 1; } diff --git a/packages/web-components/src/components/table-of-contents/table-of-contents.ts b/packages/web-components/src/components/table-of-contents/table-of-contents.ts index c865bea3f96..fd17ba70ea1 100644 --- a/packages/web-components/src/components/table-of-contents/table-of-contents.ts +++ b/packages/web-components/src/components/table-of-contents/table-of-contents.ts @@ -10,14 +10,22 @@ import { nothing } from 'lit-html'; import { classMap } from 'lit-html/directives/class-map.js'; import { ifDefined } from 'lit-html/directives/if-defined.js'; -import { html, property, state, query, queryAll, customElement, LitElement } from 'lit-element'; -import CaretLeft20 from 'carbon-web-components/es/icons/caret--left/20.js'; -import CaretRight20 from 'carbon-web-components/es/icons/caret--right/20.js'; +import { + html, + property, + state, + query, + queryAll, + customElement, + LitElement, +} from 'lit-element'; +import CaretLeft20 from '@carbon/web-components/es/icons/caret--left/20.js'; +import CaretRight20 from '@carbon/web-components/es/icons/caret--right/20.js'; import settings from 'carbon-components/es/globals/js/settings.js'; import { baseFontSize, breakpoints } from '@carbon/layout'; -import HostListener from 'carbon-web-components/es/globals/decorators/host-listener.js'; -import HostListenerMixin from 'carbon-web-components/es/globals/mixins/host-listener.js'; -import TableOfContents20 from 'carbon-web-components/es/icons/table-of-contents/20.js'; +import HostListener from '@carbon/web-components/es/globals/decorators/host-listener.js'; +import HostListenerMixin from '@carbon/web-components/es/globals/mixins/host-listener.js'; +import TableOfContents20 from '@carbon/web-components/es/icons/table-of-contents/20.js'; import throttle from 'lodash-es/throttle.js'; import StickyHeader from '../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/StickyHeader/StickyHeader'; import ddsSettings from '../../internal/vendor/@carbon/ibmdotcom-utilities/utilities/settings/settings'; @@ -43,7 +51,11 @@ interface Cancelable { * @param [thisObject] The context object for the given callback function. * @returns The index of the last item in the given array where `predicate` returns `true`. `-1` if no such item is found. */ -function findLastIndex(a: T[], predicate: (search: T, index?: number, thisObject?: any) => boolean, thisObject?: any): number { +function findLastIndex( + a: T[], + predicate: (search: T, index?: number, thisObject?: any) => boolean, + thisObject?: any +): number { for (let i = a.length - 1; i >= 0; --i) { if (predicate(a[i], i, thisObject)) { return i; @@ -61,7 +73,9 @@ function findLastIndex(a: T[], predicate: (search: T, index?: number, thisObj * @slot menu-rule - The menu rule. */ @customElement(`${ddsPrefix}-table-of-contents`) -class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElement)) { +class DDSTableOfContents extends HostListenerMixin( + StableSelectorMixin(LitElement) +) { /** * The formatter for the aria label text for the mobile ToC. * Should be changed upon the locale the component is rendered with. @@ -177,12 +191,14 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen * Boolean checking if page is RTL */ @state() - private _pageIsRTL: Boolean = this.ownerDocument!.documentElement.dir === 'rtl'; + private _pageIsRTL: Boolean = + this.ownerDocument!.documentElement.dir === 'rtl'; /** * The handler for throttled scrolling */ - private _throttleScroll: (((event: Event) => void) & Cancelable) | null = null; + private _throttleScroll: (((event: Event) => void) & Cancelable) | null = + null; /** * Cleans-up and creats the resize observer for the mobile container. @@ -190,7 +206,9 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen * @param [options] The options. * @param [options.create] `true` to create the new resize observer. */ - private _cleanAndCreateObserverResizeMobileContainer({ create }: { create?: boolean } = {}) { + private _cleanAndCreateObserverResizeMobileContainer({ + create, + }: { create?: boolean } = {}) { const { _mobileContainerNode: mobileContainerNode } = this; if (mobileContainerNode) { if (this._observerResizeMobileContainer) { @@ -200,7 +218,9 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen if (create) { // TODO: Wait for `.d.ts` update to support `ResizeObserver` // @ts-ignore - this._observerResizeMobileContainer = new ResizeObserver(this._observeResizeMobileContainer); + this._observerResizeMobileContainer = new ResizeObserver( + this._observeResizeMobileContainer + ); this._observerResizeMobileContainer.observe(mobileContainerNode); } } @@ -221,7 +241,8 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen * @param event The event. */ private _handleClickItem(event: MouseEvent) { - const { selectorDesktopItem } = this.constructor as typeof DDSTableOfContents; + const { selectorDesktopItem } = this + .constructor as typeof DDSTableOfContents; const target = event.target as HTMLAnchorElement; if (target.matches?.(selectorDesktopItem)) { this._handleUserInitiatedJump(target.dataset.target!); @@ -235,7 +256,8 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen * @param event The event. */ private _handleOnKeyDown(event: KeyboardEvent) { - const { selectorDesktopItem } = this.constructor as typeof DDSTableOfContents; + const { selectorDesktopItem } = this + .constructor as typeof DDSTableOfContents; const target = event.target as HTMLAnchorElement; const { _pageIsRTL: pageIsRTL } = this; if (target.matches?.(selectorDesktopItem)) { @@ -244,14 +266,16 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen if (event.shiftKey) { if ( target.parentElement?.previousElementSibling && - target.parentElement?.previousElementSibling.getBoundingClientRect().right > + target.parentElement?.previousElementSibling.getBoundingClientRect() + .right > this._navBar!.getBoundingClientRect().right - buttonWidthOffset ) { this._paginateLeft(); } } else if ( target.parentElement?.nextElementSibling && - target.parentElement?.nextElementSibling.getBoundingClientRect().left < + target.parentElement?.nextElementSibling.getBoundingClientRect() + .left < this._navBar!.getBoundingClientRect().left + buttonWidthOffset ) { this._paginateRight(); @@ -261,14 +285,16 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen if (event.shiftKey) { if ( target.parentElement?.previousElementSibling && - target.parentElement?.previousElementSibling!.getBoundingClientRect().left < + target.parentElement?.previousElementSibling!.getBoundingClientRect() + .left < this._navBar!.getBoundingClientRect().left + buttonWidthOffset ) { this._paginateLeft(); } } else if ( target.parentElement?.nextElementSibling && - target.parentElement?.nextElementSibling!.getBoundingClientRect().right > + target.parentElement?.nextElementSibling!.getBoundingClientRect() + .right > this._navBar!.getBoundingClientRect().right - buttonWidthOffset ) { this._paginateRight(); @@ -288,7 +314,10 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen const items = this._targets .map((elem, index, arr) => ({ elem, - height: arr[index + 1] ? arr[index + 1].getBoundingClientRect().y - elem.getBoundingClientRect().y : null, + height: arr[index + 1] + ? arr[index + 1].getBoundingClientRect().y - + elem.getBoundingClientRect().y + : null, position: elem.getBoundingClientRect().y, })) .filter((elem, index, arr) => @@ -299,7 +328,8 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen // Sets last section as active at the end of page in case there is not enough height for it to dynamically activate const bottomReached = - this.ownerDocument!.scrollingElement!.scrollTop + this.ownerDocument!.scrollingElement!.clientHeight === + this.ownerDocument!.scrollingElement!.scrollTop + + this.ownerDocument!.scrollingElement!.clientHeight === this.ownerDocument!.scrollingElement!.scrollHeight; if (items && items[0] && items[items.length - 1]) { this._currentTarget = !bottomReached @@ -313,15 +343,20 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen /** * Watches for changes to content in the default slot. */ - private _contentMutationObserver = new MutationObserver(this._contentObserverCallback.bind(this)); + private _contentMutationObserver = new MutationObserver( + this._contentObserverCallback.bind(this) + ); /** * Sets table of contents targets whenever any node tree mutation is observed. */ private _contentObserverCallback() { const shadowRoot = this.shadowRoot as ShadowRoot; - const defaultSlot = shadowRoot.querySelector(`.${prefix}--tableofcontents__content slot`) as HTMLSlotElement; - this._setTargets(Array.from(defaultSlot.assignedNodes())); + const allSlots = Array.from( + shadowRoot.querySelectorAll(`slot`) + ) as HTMLSlotElement[]; + const allSlottedNodes = allSlots.flatMap((slot) => slot.assignedNodes()); + this._setTargets(allSlottedNodes); } /** @@ -332,12 +367,18 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen const { selectorTarget } = this.constructor as typeof DDSTableOfContents; this._targets = nodes.reduce((acc, node) => { if (node instanceof HTMLElement) { - const descendants = node.querySelectorAll(selectorTarget) as NodeListOf; - const elems = [node, ...descendants].filter(elem => { + const descendants = node.querySelectorAll( + selectorTarget + ) as NodeListOf; + const elems = [node, ...descendants].filter((elem) => { const notWhiteSpace = /[^\s\n\r]/g; - const hasTitle = elem.innerText.match(notWhiteSpace) || elem.dataset.title?.match(notWhiteSpace); + const hasTitle = + elem.innerText.match(notWhiteSpace) || + elem.dataset.title?.match(notWhiteSpace); const hasNameAttr = elem.matches(selectorTarget); - const notExcluded = !tagNamesToAvoid.includes(elem.tagName.toLowerCase()); + const notExcluded = !tagNamesToAvoid.includes( + elem.tagName.toLowerCase() + ); return hasTitle && hasNameAttr && notExcluded; }); @@ -356,14 +397,20 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen */ private _handleSlotChange(event: Event) { // Handle changes to immediate slotted children. - const slottedElements = (event.target as HTMLSlotElement).assignedNodes().filter(node => node instanceof HTMLElement); + const slottedElements = (event.target as HTMLSlotElement) + .assignedNodes() + .filter((node) => node instanceof HTMLElement); this._setTargets(slottedElements as HTMLElement[]); // Handle changes to slotted contents' children. this._contentMutationObserver.disconnect(); - (event.target as HTMLSlotElement).assignedNodes().forEach(node => { + (event.target as HTMLSlotElement).assignedNodes().forEach((node) => { if (node instanceof HTMLElement) { - this._contentMutationObserver.observe(node, { subtree: true, childList: true }); + this._contentMutationObserver.observe(node, { + subtree: true, + childList: true, + attributeFilter: ['name', 'data-title'], + }); } }); } @@ -372,8 +419,10 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen * Handles `slotchange` event on ``. */ private _handleSlotChangeHeading() { - this._hasHeading = Array.from(this.querySelectorAll('[slot="heading"]')).some( - node => node.nodeType !== Node.TEXT_NODE || node!.textContent!.trim() + this._hasHeading = Array.from( + this.querySelectorAll('[slot="heading"]') + ).some( + (node) => node.nodeType !== Node.TEXT_NODE || node!.textContent!.trim() ); } @@ -384,8 +433,13 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen */ private _handleUserInitiatedJump(target: string) { const elem = this.querySelector(`[name="${target}"]`); - const masthead: HTMLElement | null = this.ownerDocument.querySelector(`${ddsPrefix}-masthead`); - const mobilePadding = window.innerWidth < gridLgBreakpoint ? this._mobileContainerNode?.offsetHeight : 0; + const masthead: HTMLElement | null = this.ownerDocument.querySelector( + `${ddsPrefix}-masthead` + ); + const mobilePadding = + window.innerWidth < gridLgBreakpoint + ? this._mobileContainerNode?.offsetHeight + : 0; if (elem instanceof HTMLElement) { const currentY = window.scrollY; @@ -419,7 +473,9 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen * @param [options] The options. * @param [options.create] `true` to create the new intersection observer. */ - private _cleanAndCreateIntersectionObserverContainer({ create }: { create?: boolean } = {}) { + private _cleanAndCreateIntersectionObserverContainer({ + create, + }: { create?: boolean } = {}) { const { _intersectionLeftSentinelNode: intersectionLeftSentinelNode, _intersectionRightSentinelNode: intersectionRightSentinelNode, @@ -429,10 +485,13 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen this._observerIntersection = null; } if (create) { - this._observerIntersection = new IntersectionObserver(this._observeIntersectionContainer, { - root: this._navBar, - threshold: 0, - }); + this._observerIntersection = new IntersectionObserver( + this._observeIntersectionContainer, + { + root: this._navBar, + threshold: 0, + } + ); if (intersectionLeftSentinelNode) { this._observerIntersection.observe(intersectionLeftSentinelNode); } @@ -447,7 +506,7 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen * * @param records The intersection observer records. */ - private _observeIntersectionContainer = records => { + private _observeIntersectionContainer = (records) => { const { _intersectionLeftSentinelNode: intersectionLeftSentinelNode, _intersectionRightSentinelNode: intersectionRightSentinelNode, @@ -466,7 +525,12 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen * Handles `click` event on the left-hand paginator button. */ private _paginateLeft() { - const { _currentScrollPosition: currentScrollPosition, _navBar: navBar, _itemNodes: itemNodes, _pageIsRTL: pageIsRTL } = this; + const { + _currentScrollPosition: currentScrollPosition, + _navBar: navBar, + _itemNodes: itemNodes, + _pageIsRTL: pageIsRTL, + } = this; // If the right-side intersection sentinel is in the view, it means that right-side caret button is hidden. // Given scrolling to left makes it shown, // `contentContainerNode!.offsetWidth` will shrink as we scroll and we need to adjust for it. @@ -476,27 +540,38 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen const interimLeft = navBar!.getBoundingClientRect().right; const lastVisibleElementIndex = findLastIndex( elems, - elem => elem.getBoundingClientRect().right > interimLeft - buttonWidthOffset + (elem) => + elem.getBoundingClientRect().right > interimLeft - buttonWidthOffset ); if (lastVisibleElementIndex >= 0) { - const lastVisibleElementRight = elems[lastVisibleElementIndex].getBoundingClientRect().left; + const lastVisibleElementRight = + elems[lastVisibleElementIndex].getBoundingClientRect().left; // 48 = button width - button gradient - const newScrollPosition = currentScrollPosition - lastVisibleElementRight + 48; - this._currentScrollPosition = newScrollPosition <= 0 ? 0 : newScrollPosition; + const newScrollPosition = + currentScrollPosition - lastVisibleElementRight + 48; + this._currentScrollPosition = + newScrollPosition <= 0 ? 0 : newScrollPosition; } } else { const lastVisibleElementIndex = findLastIndex( elems, - elem => elem.getBoundingClientRect().left < buttonWidthOffset + navBar!.getBoundingClientRect().left + (elem) => + elem.getBoundingClientRect().left < + buttonWidthOffset + navBar!.getBoundingClientRect().left ); if (lastVisibleElementIndex >= 0) { - const lastVisibleElementRight = elems[lastVisibleElementIndex].getBoundingClientRect().right; + const lastVisibleElementRight = + elems[lastVisibleElementIndex].getBoundingClientRect().right; const newScrollPosition = - lastVisibleElementRight + currentScrollPosition - navBar!.getBoundingClientRect().right + buttonWidthOffset; + lastVisibleElementRight + + currentScrollPosition - + navBar!.getBoundingClientRect().right + + buttonWidthOffset; // If the new scroll position is less than the width of the left caret button, // it means that hiding the left caret button reveals the whole of the left-most nav item. // Snaps the left-most nav item to the left edge of nav container in this case. - this._currentScrollPosition = newScrollPosition <= 0 ? 0 : newScrollPosition; + this._currentScrollPosition = + newScrollPosition <= 0 ? 0 : newScrollPosition; } } } @@ -519,7 +594,8 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen if (pageIsRTL) { const interimLeft = navBar!.getBoundingClientRect().left; const firstVisibleElementIndex = elems.findIndex( - elem => elem.getBoundingClientRect().left < interimLeft + buttonWidthOffset + (elem) => + elem.getBoundingClientRect().left < interimLeft + buttonWidthOffset ); if (firstVisibleElementIndex > 0) { const firstVisibleElementLeft = Math.abs( @@ -528,12 +604,17 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen navBar!.getBoundingClientRect().right ); const maxLeft = contentNode!.scrollWidth - navBar!.offsetWidth; - this._currentScrollPosition = Math.min(firstVisibleElementLeft + currentScrollPosition, maxLeft); + this._currentScrollPosition = Math.min( + firstVisibleElementLeft + currentScrollPosition, + maxLeft + ); } } else { const interimRight = navBar!.getBoundingClientRect().right; const firstVisibleElementIndex = elems.findIndex( - elem => elem.getBoundingClientRect().right > interimRight - buttonWidthOffset + (elem) => + elem.getBoundingClientRect().right > + interimRight - buttonWidthOffset ); if (firstVisibleElementIndex > 0) { const firstVisibleElementLeft = @@ -543,7 +624,10 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen // Ensures that is there is no blank area at the right hand side in scroll area // if we see the right remainder nav items can be contained in a page const maxLeft = contentNode!.scrollWidth - navBar!.offsetWidth; - this._currentScrollPosition = Math.min(firstVisibleElementLeft + currentScrollPosition, maxLeft); + this._currentScrollPosition = Math.min( + firstVisibleElementLeft + currentScrollPosition, + maxLeft + ); } } } @@ -554,7 +638,7 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen * * @param records The resize records. */ - private _observeResizeMobileContainer = records => { + private _observeResizeMobileContainer = (records) => { const entry = records[records.length - 1]; const { height } = entry.contentRect; this._hasMobileContainerVisible = height > 0; @@ -616,7 +700,10 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen updated(changedProperties) { if (changedProperties.has('_currentTarget')) { - const { _currentTarget: currentTarget, _mobileSelectNode: mobileSelectNode } = this; + const { + _currentTarget: currentTarget, + _mobileSelectNode: mobileSelectNode, + } = this; // Ensures setting the `value` after rendering child `
    - ${targets.map(item => { + ${targets.map((item) => { const name = item.getAttribute('name'); - const title = (item.dataset.title ?? item.textContent ?? '').trim(); + const title = ( + item.dataset.title ?? + item.textContent ?? + '' + ).trim(); const selected = item === currentTarget; const itemClasses = classMap({ [`${prefix}--tableofcontents__desktop__item`]: true, - [`${prefix}--tableofcontents__desktop__item--active`]: selected, + [`${prefix}--tableofcontents__desktop__item--active`]: + selected, }); return html` -
  • - +
  • + ${title}
  • @@ -690,13 +796,18 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen
    + style="top: ${this.layout === TOC_TYPES.HORIZONTAL && stickyOffset + ? `${stickyOffset}px` + : 0}"> ${hasMobileContainerVisible ? nothing : html` -
    - +
    +
    `} @@ -706,14 +817,14 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen ${pageIsRTL ? html`
    -
    +
    @@ -725,43 +836,55 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen tabindex="-1" aria-hidden="true" class="${prefix}--toc__navbar-caret-left" - @click="${paginateLeft}" - > + @click="${paginateLeft}"> ${CaretLeft20()} -
    +
    `} ` : ``}
    + style="position: sticky; top: ${stickyOffset && + this.layout !== TOC_TYPES.HORIZONTAL + ? `${stickyOffset}px` + : 0}">
    + style="${pageIsRTL + ? 'right' + : 'left'}: -${currentScrollPosition}px"> ${pageIsRTL - ? html` -
    - ` - : html` -
    - `} + ? html`
    ` + : html`
    `}
      - ${targets.map(item => { + ${targets.map((item) => { const name = item.getAttribute('name'); - const title = (item.dataset.title ?? item.textContent ?? '').trim(); + const title = ( + item.dataset.title ?? + item.textContent ?? + '' + ).trim(); const selected = item === currentTarget; const itemClasses = classMap({ [`${prefix}--tableofcontents__desktop__item`]: true, - [`${prefix}--tableofcontents__desktop__item--active`]: selected, + [`${prefix}--tableofcontents__desktop__item--active`]: + selected, }); return html` -
    • - +
    • + ${title}
    • @@ -769,12 +892,8 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen })}
    ${pageIsRTL - ? html` -
    - ` - : html` -
    - `} + ? html`
    ` + : html`
    `}
    @@ -782,13 +901,18 @@ class DDSTableOfContents extends HostListenerMixin(StableSelectorMixin(LitElemen
` | +| `` | The header body | `
` | + +### JS (via import) + +```javascript +import '@carbon/web-components/es/components/data-table/index.js'; +``` + + + + +### HTML + +```html + + + + + Foo + Bar + Baz + + + + + Foo1 + Bar1 + Baz1 + + + Foo2 + Bar2 + Baz2 + + + Foo3 + Bar3 + Baz3 + + + + +``` + +## Row selection + +Adding `selection-name` attribute to ``/`` +shows the selection UI in the table row. + +The logic of row selection needs to be handled on by the application code. When +user attempts to change row selection, the following events fire: + +| Element | Event | Description | +| ----------------------- | ------------------------------- | ------------------------------------------------------------- | +| `` | `bx-table-row-change-selection` | Indicates user-initiated change in selection of a single row. | +| `` | `bx-table-change-selection-all` | Indicates user-initiated change in selection of all rows. | + +Both of above events have the following properties in the event details: + +| Property | Description | +| ---------- | ------------------------ | +| `selected` | The new selection state. | + +Both of above events bubble and are cancelable. Canceling those events mean +canceling change in selection. + +Application code should listen to those events update its internal state of +table rows. To do so, it's convenient to add a `data-` attribte to each table +rows so the delegated event handler can see which row the events are from. + +Here's an example of [`lit-html`](https://lit-html.polymer-project.org). Note +that those events are native DOM events, and thus something like +`document.addEventListener('bx-table-row-change-selection', event => { ... })` +works, too: + +```javascript +/** + * Handles an event to change in selection of rows, fired from ``, + * to update application's row selection states. + * @param {CustomEvent} event The event. + */ +const handleChangeSelection = event => { + if (!event.defaultPrevented) { + rows = this.rows.map(row => { + // The row ID you set to `` the event is fired on + const targetRowId = event.target.dataset.rowId; + return targetRowId !== row.id + ? row + : { + ...row, + selected: event.detail.selected, + }; + }); + } +}; + +/** + * Handles an event to change in selection of all rows, fired from ``, + * to update application's row selection states. + * @param {CustomEvent} event The event. + */ +const handleChangeSelectionAll = event => { + if (!event.defaultPrevented) { + rows = this.rows.map(row => ({ + ...row, + selected: event.detail.selected, + })); + } +}; + +... + +html` + + + + row.selected)} selection-name="my-row-selection-all"> + Foo + Bar + Baz + + + + ${rows.map( + row => html` + + ${row.foo} + ${row.bar} + ${row.baz} + + ` + )} + + + +`; +``` + +## Sorting + +Adding `sort-direction` attribute to `` shows the sorting +UI in the table header cell. + +The logic of sorting needs to be handled on by the application code. When user +attempts to change sorting, `bx-table-header-cell-sort` event is fired, with the +following properties in the event details: + +| Property | Description | +| ------------------ | ----------------------- | +| `oldSortDirection` | The old sort direction. | +| `sortDirection` | The new sort direction. | + +`bx-table-header-cell-sort` event bubbles and is cancelable. Canceling +`bx-table-header-cell-sort` event means canceling change in sort direction. + +Application code should listen to those events update its internal state of +sorting. An example of the logic needed is available in our codesandbox example +above. To do so, it's convenient to add a `data-` attribte to each table header +cells so the delegated event handler can see which table column the events are +from. + +Here's an example of [`lit-html`](https://lit-html.polymer-project.org). Note +that those events are native DOM events, and thus something like +`document.addEventListener('bx-table-header-cell-sort', event => { ... })` +works, too: + +```javascript +/** + * Handles an event to sort rows, fired from ``, to update application's sorting state. + * @param {CustomEvent} event The event. + */ +const handleChangeSort = event => { + if (!defaultPrevented) { + // Changes the sorting state upon user gesture + sortInfo = { + columnId: event.target.dataset.columnId, + direction: event.detail.direction, + }; + } +}; + +... + +const collator = new Intl.Collator('en'); // Use the locale user is on + +/** + * Rows sorted by application's sorting state. + */ +const sortedRows = rows.slice().sort((lhs, rhs) => { + const lhsValue = lhs[sortInfo.columnId]; + const rhsValue = rhs[sortInfo.columnId]; + return (sortInfo.direction === 'ascending' ? 1 : -1) * collator.compare(lhsValue, rhsValue); +}); + +html` + + + + + Foo + Bar + Baz + + + + ${sortedRows.map( + row => html` + + ${row.foo} + ${row.bar} + ${row.baz} + + ` + )} + + + +`; +``` + +## Skeleton + +For the skeleton variation, utilize ``. + +```html + + + + Name + Protocol + Port + Rule + Attached Groups + Status + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +## Attributes, properties and events + +Note: For `boolean` attributes, `true` means simply setting the attribute (e.g. +``) and `false` means not setting the attribute (e.g. +`` without `sort` attribute). + +### `` + + + +### `` + + + +### `` + + + +### `` + + + +### `` + + + +### `` + + + +### `` + + + +### `` + + diff --git a/packages/carbon-web-components/src/components/data-table/data-table-story.scss b/packages/carbon-web-components/src/components/data-table/data-table-story.scss new file mode 100644 index 00000000000..a91e4ce5e20 --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/data-table-story.scss @@ -0,0 +1,12 @@ +// +// Copyright IBM Corp. 2020, 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +/* stylelint-disable selector-type-no-unknown */ +bx-ce-demo-data-table, +.bx-ce-demo--data-table { + width: 100%; +} diff --git a/packages/carbon-web-components/src/components/data-table/data-table-story.ts b/packages/carbon-web-components/src/components/data-table/data-table-story.ts new file mode 100644 index 00000000000..a4dfdba9075 --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/data-table-story.ts @@ -0,0 +1,911 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import debounce from 'lodash-es/debounce'; +import { html, property, LitElement } from 'lit-element'; +import { repeat } from 'lit-html/directives/repeat'; +import { action } from '@storybook/addon-actions'; +import { boolean, select } from '@storybook/addon-knobs'; +// Below path will be there when an application installs `carbon-web-components` package. +// In our dev env, we auto-generate the file and re-map below path to to point to the generated file. +// @ts-ignore +import Delete16 from 'carbon-web-components/es/icons/delete/16'; +// @ts-ignore +import Download16 from 'carbon-web-components/es/icons/download/16'; +// @ts-ignore +import Settings16 from 'carbon-web-components/es/icons/settings/16'; +import BXBtn from '../button/button'; +import ifNonNull from '../../globals/directives/if-non-null'; +import '../overflow-menu/overflow-menu'; +import '../overflow-menu/overflow-menu-body'; +import '../overflow-menu/overflow-menu-item'; +import '../pagination/pagination'; +import '../pagination/page-sizes-select'; +import '../pagination/pages-select'; +import { TABLE_COLOR_SCHEME, TABLE_SIZE } from './table'; +import './table-head'; +import './table-header-row'; +import { TABLE_SORT_DIRECTION } from './table-header-cell'; +import './table-body'; +import './table-row'; +import './table-cell'; +import './table-header-expand-row'; +import './table-expand-row'; +import './table-expanded-row'; +import './table-toolbar'; +import './table-toolbar-content'; +import './table-toolbar-search'; +import './table-batch-actions'; +import './table-header-cell-skeleton'; +import './table-cell-skeleton'; +import { + rows as demoRows, + rowsMany as demoRowsMany, + columns as demoColumns, + sortInfo as demoSortInfo, +} from './stories/data'; +import { + TDemoTableColumn, + TDemoTableRow, + TDemoSortInfo, +} from './stories/types'; +import styles from './data-table-story.scss'; +import storyDocs from './data-table-story.mdx'; + +/** + * @param row A table row. + * @param searchString A search string. + * @returns `true` if the given table row matches the given search string. + */ +const doesRowMatchSearchString = (row: TDemoTableRow, searchString: string) => + Object.keys(row).some( + (key) => key !== 'id' && String(row[key] ?? '').indexOf(searchString) >= 0 + ); + +/** + * A class to manage table states, like selection and sorting. + * DEMONSTRATION-PURPOSE ONLY. + * Data/state handling in data table tends to involve lots of application-specific logics + * and thus abstracting everything in a library won't be a good return on investment + * vs. letting users copy code here and implement features that fit their needs. + */ +// @ts-ignore `BXCEDemoDataTable` is used (only) for type reference +// eslint-disable-next-line @typescript-eslint/no-unused-vars +class BXCEDemoDataTable extends LitElement { + /** + * The debounced handler for user-initiated change in search string. + */ + private _handleChangeSearchString: + | ((() => void) & { cancel(): void }) + | void = undefined; + + /** + * The table sorting info reflecting user-initiated changes. + */ + private _sortInfo?: TDemoSortInfo; + + /** + * The table rows reflecting selection. + */ + private _rows?: TDemoTableRow[]; + + /** + * The table rows reflecting selection and filtering. + */ + private _filteredRows?: TDemoTableRow[]; + + /** + * The search string. + */ + private _searchString = ''; + + /** + * Unique ID used for form elements. + */ + protected _uniqueId = Math.random().toString(36).slice(2); + + /** + * @param lhs A value. + * @param rhs Another value. + * @returns + * * `0` if the given two values are equal + * * A negative value to sort `lhs` to an index lower than `rhs` + * * A positive value to sort `rhs` to an index lower than `lhs` + */ + private _compare(lhs, rhs) { + if (typeof lhs === 'number' && typeof rhs === 'number') { + return lhs - rhs; + } + return this.collator.compare(lhs, rhs); + } + + /** + * Handles Cancel button in batch action bar. + */ + private _handleCancelSelection() { + const { _rows: oldRows, _searchString: searchString } = this; + this._rows = this._rows!.map((row) => + searchString && !doesRowMatchSearchString(row, searchString) + ? row + : { ...row, selected: false } + ); + this.requestUpdate('_rows', oldRows); + } + + /** + * Handles user-initiated change in search string. + */ + private _handleChangeSearchStringImpl({ detail }: CustomEvent) { + const { _searchString: oldSearchString } = this; + this._searchString = detail.value; + this.requestUpdate('_searchString', oldSearchString); + } + + /** + * Handles an event to change in selection of rows, fired from ``. + * + * @param event The event. + */ + private _handleChangeSelection({ + defaultPrevented, + detail, + target, + }: CustomEvent) { + if (!defaultPrevented) { + const { rowId: changedRowId } = (target as HTMLElement).dataset; + const { selected } = detail; + const { _rows: oldRows } = this; + this._rows = oldRows!.map((row) => + Number(changedRowId) !== row.id ? row : { ...row, selected } + ); + this.requestUpdate('_rows', oldRows); + } + } + + /** + * Handles an event to change in selection of all rows, fired from ``. + * + * @param event The event. + */ + private _handleChangeSelectionAll({ defaultPrevented, detail }: CustomEvent) { + if (!defaultPrevented) { + const { selected } = detail; + const { _rows: oldRows, _searchString: searchString } = this; + this._rows = this._rows!.map((row) => + searchString && !doesRowMatchSearchString(row, searchString) + ? row + : { ...row, selected } + ); + this.requestUpdate('_rows', oldRows); + } + } + + /** + * Handles an event to sort rows, fired from ``. + * + * @param event The event. + */ + private _handleChangeSort({ defaultPrevented, detail, target }: CustomEvent) { + if (!defaultPrevented) { + const { columnId } = (target as HTMLElement).dataset; + const { sortDirection: direction } = detail; + const { _sortInfo: oldSortInfo } = this; + if (direction === TABLE_SORT_DIRECTION.NONE && columnId !== 'name') { + // Resets the sorting, given non-primary sorting column has got in non-sorting state + this._sortInfo = this.sortInfo; + } else { + // Sets the sorting as user desires + this._sortInfo = { + columnId: columnId!, + direction, + }; + } + this.requestUpdate('_sortInfo', oldSortInfo); + } + } + + /** + * Handles `bx-pagination-changed-current` event on the pagination UI. + * + * @param event The event. + */ + private _handleChangeStart({ detail }: CustomEvent) { + this.start = detail.start; + } + + /** + * Handles `bx-pages-select-changed` event on the pagination UI. + * + * @param event The event. + */ + private _handleChangePageSize({ detail }: CustomEvent) { + this.pageSize = detail.value; + } + + /** + * Handles Delete batch action button. + */ + private _handleDeleteRows() { + const { _rows: oldRows, _searchString: searchString } = this; + this._rows = oldRows!.filter( + (row) => !row.selected || !doesRowMatchSearchString(row, searchString) + ); + this.requestUpdate('_rows', oldRows); + } + + /** + * Handles Download batch action button. + * + * @param event The event triggering this action. + */ + private _handleDownloadRows({ target }: MouseEvent) { + const blob = new Blob( + [JSON.stringify(this._filteredRows!.filter((row) => row.selected))], + { type: 'application/json' } + ); + (target as BXBtn).href = URL.createObjectURL(blob); + this._handleCancelSelection(); + } + + /** + * @returns The content of the pagination UI. + */ + private _renderPagination() { + const { + pageSize, + start, + _filteredRows: filteredRows, + _handleChangeStart: handleChangeStart, + _handleChangePageSize: handleChangePageSize, + } = this; + if (typeof pageSize === 'undefined') { + return undefined; + } + return html` + + + + + + + + + `; + } + + /** + * The g11n collator to use. + */ + @property({ attribute: false }) + collator = new Intl.Collator(); + + /** + * Data table columns. + */ + @property({ attribute: false }) + columns?: TDemoTableColumn[]; + + /** + * Data table rows. + */ + @property({ attribute: false }) + rows?: TDemoTableRow[]; + + /** + * Table sorting info. + */ + @property({ attribute: false }) + sortInfo?: TDemoSortInfo; + + /** + * `true` if the the table should support selection UI. + */ + @property({ type: Boolean, reflect: true, attribute: 'has-selection' }) + hasSelection = false; + + /** + * Number of items per page. + */ + @property({ type: Number, attribute: 'page-size' }) + pageSize!: number; + + /** + * The table size. + */ + @property({ reflect: true }) + size = TABLE_SIZE.REGULAR; + + /** + * The table color scheme. + */ + @property({ reflect: true, attribute: 'color-scheme' }) + colorScheme = TABLE_COLOR_SCHEME.REGULAR; + + /** + * The row number where current page start with, index that starts with zero. + */ + @property({ type: Number }) + start = 0; + + connectedCallback() { + super.connectedCallback(); + if (this._handleChangeSearchString) { + this._handleChangeSearchString.cancel(); + } + this._handleChangeSearchString = debounce( + this._handleChangeSearchStringImpl as () => void, + 500 + ); + } + + disconnectedCallback() { + if (this._handleChangeSearchString) { + this._handleChangeSearchString.cancel(); + this._handleChangeSearchString = undefined; + } + super.disconnectedCallback(); + } + + shouldUpdate(changedProperties) { + if (changedProperties.has('sortInfo')) { + this._sortInfo = this.sortInfo; + } + if (changedProperties.has('rows')) { + this._rows = this.rows; + } + if ( + changedProperties.has('rows') || + changedProperties.has('_rows') || + changedProperties.has('_searchString') + ) { + const { + pageSize, + start, + _rows: rows, + _searchString: searchString, + } = this; + this._filteredRows = !searchString + ? rows! + : rows!.filter((row) => doesRowMatchSearchString(row, searchString)); + const count = this._filteredRows.length; + if (count > 0 && start >= count) { + this.start = Math.max( + start - Math.ceil((start - count) / pageSize) * pageSize, + 0 + ); + } + } + return true; + } + + render() { + const { + id: elementId, + colorScheme, + hasSelection, + pageSize = Infinity, + start = 0, + size, + columns, + _filteredRows: filteredRows, + _handleCancelSelection: handleCancelSelection, + _handleDeleteRows: handleDeleteRows, + _handleDownloadRows: handleDownloadRows, + } = this; + const selectionAllName = !hasSelection + ? undefined + : `__bx-ce-demo-data-table_select-all_${elementId || this._uniqueId}`; + const selectedRowsCountInFiltered = filteredRows!.filter( + ({ selected }) => selected! + ).length; + const selectedAllInFiltered = + selectedRowsCountInFiltered > 0 && + filteredRows!.length === selectedRowsCountInFiltered; + const hasBatchActions = hasSelection && selectedRowsCountInFiltered > 0; + const { columnId: sortColumnId, direction: sortDirection } = + this._sortInfo!; + const sortedRows = + sortDirection === TABLE_SORT_DIRECTION.NONE + ? filteredRows! + : filteredRows! + .slice() + .sort( + (lhs, rhs) => + (this.constructor as typeof BXCEDemoDataTable).collationFactors[ + sortDirection + ] * this._compare(lhs[sortColumnId!], rhs[sortColumnId!]) + ); + return html` + + + Delete ${Delete16({ slot: 'icon' })} + + Download ${Download16({ slot: 'icon' })} + + + + + + ${Settings16({ slot: 'icon' })} + + Action 1 + Action 2 + Action 3 + + + Primary Button + + + + + + ${repeat( + columns!, + ({ id: columnId }) => columnId, + ({ id: columnId, sortCycle, title }) => { + const sortDirectionForThisCell = + sortCycle && + (columnId === sortColumnId + ? sortDirection + : TABLE_SORT_DIRECTION.NONE); + return html` + + ${title} + + `; + } + )} + + + + ${repeat( + sortedRows.slice(start, start + pageSize), + ({ id: rowId }) => rowId, + (row) => { + const { id: rowId, selected } = row; + const selectionName = !hasSelection + ? undefined + : `__bx-ce-demo-data-table_${ + elementId || this._uniqueId + }_${rowId}`; + const selectionValue = !hasSelection ? undefined : 'selected'; + return html` + + ${repeat( + columns!, + ({ id: columnId }) => columnId, + ({ id: columnId }) => + html` ${row[columnId]} ` + )} + + `; + } + )} + + + ${this._renderPagination()} + `; + } + + /** + * The map of how sorting direction affects sorting order. + */ + static collationFactors = { + [TABLE_SORT_DIRECTION.ASCENDING]: 1, + [TABLE_SORT_DIRECTION.DESCENDING]: -1, + }; +} + +const colorSchemes = { + 'Regular color scheme': null, + [`Zebra (${TABLE_COLOR_SCHEME.ZEBRA})`]: TABLE_COLOR_SCHEME.ZEBRA, +}; + +const sizes = { + [`Compact size (${TABLE_SIZE.COMPACT})`]: TABLE_SIZE.COMPACT, + [`Short size (${TABLE_SIZE.SHORT})`]: TABLE_SIZE.SHORT, + 'Regular size': null, + [`Tall size (${TABLE_SIZE.TALL})`]: TABLE_SIZE.TALL, +}; + +const defineDemoDataTable = (() => { + let hasDemoDataTableDefined; + return () => { + if (!hasDemoDataTableDefined) { + hasDemoDataTableDefined = true; + const ce = customElements; + // Prevents `web-component-analyzer` from harvesting `` + ce.define('bx-ce-demo-data-table', BXCEDemoDataTable); + } + }; +})(); + +export const Default = (args) => { + const { size } = args?.['bx-table'] ?? {}; + const { colorScheme } = args?.['bx-table-body'] ?? {}; + return html` + + + + Name + Protocol + Port + Rule + Attached Groups + Status + + + + + Load Balancer 1 + HTTP + 80 + Round Robin + Maureen's VM Groups + Active + + + Load Balancer 2 + HTTP + 80 + Round Robin + Maureen's VM Groups + Active + + + Load Balancer 3 + HTTP + 80 + Round Robin + Maureen's VM Groups + Active + + + + `; +}; + +Default.storyName = 'Default'; + +Default.parameters = { + knobs: { + 'bx-table': () => ({ + size: select('Table size (size)', sizes, null), + }), + 'bx-table-body': () => ({ + colorScheme: select( + 'Color scheme (color-scheme in ``)', + colorSchemes, + null + ), + }), + }, +}; + +export const expandable = (args) => { + const { size } = args?.['bx-table'] ?? {}; + const { zebra } = args?.['bx-table-body'] ?? {}; + const handleExpandRowAll = (event) => { + const { currentTarget, detail } = event; + const rows = currentTarget.querySelectorAll('bx-table-expand-row'); + Array.prototype.forEach.call(rows, (row) => { + row.expanded = detail.expanded; + }); + }; + const handleExpandRow = (event) => { + const { currentTarget } = event; + const headerRow = currentTarget.querySelector('bx-table-header-expand-row'); + const rows = currentTarget.querySelectorAll('bx-table-expand-row'); + headerRow.expanded = Array.prototype.every.call( + rows, + (row) => row.expanded + ); + }; + return html` + + + + Name + Protocol + Port + Rule + Attached Groups + Status + + + + + Load Balancer 1 + HTTP + 80 + Round Robin + Maureen's VM Groups + Active + + +

Expandable row content

+

Description here

+
+ + Load Balancer 2 + HTTP + 80 + Round Robin + Maureen's VM Groups + Active + + +

Expandable row content

+

Description here

+
+ + Load Balancer 3 + HTTP + 80 + Round Robin + Maureen's VM Groups + Active + + +

Expandable row content

+

Description here

+
+
+
+ `; +}; + +expandable.parameters = { + knobs: { + ...Default.parameters.knobs, + 'bx-table-body': () => ({}), + }, +}; + +export const sortable = (args) => { + const { size } = args?.['bx-table'] ?? {}; + const { onBeforeChangeSelection: onBeforeChangeSelectionAll } = + args?.['bx-table-header-row'] ?? {}; + const { colorScheme } = args?.['bx-table-body'] ?? {}; + const { hasSelection, disableChangeSelection, onBeforeChangeSelection } = + args?.['bx-table-row'] ?? {}; + const { disableChangeSort, onBeforeSort } = + args?.['bx-table-header-cell'] ?? {}; + const beforeChangeSelectionHandler = { + handleEvent(event: CustomEvent) { + if (event.type === 'bx-table-change-selection-all') { + onBeforeChangeSelectionAll(event); + } else { + onBeforeChangeSelection(event); + } + if (disableChangeSelection) { + event.preventDefault(); + } + }, + capture: true, // To prevent the default behavior before `` handles the event + }; + const beforeChangeSortHandler = { + handleEvent(event: CustomEvent) { + onBeforeSort(event); + if (disableChangeSort) { + event.preventDefault(); + } + }, + capture: true, // To prevent the default behavior before `` handles the event + }; + defineDemoDataTable(); + return html` + + + + + `; +}; + +sortable.parameters = { + knobs: { + ...Default.parameters.knobs, + 'bx-table-header-row': () => ({ + onBeforeChangeSelection: action('bx-table-change-selection-all'), + }), + 'bx-table-row': () => { + const hasSelection = boolean( + 'Supports selection feature (has-selection)', + false + ); + return { + hasSelection, + disableChangeSelection: + hasSelection && + boolean( + 'Disable user-initiated change in selection ' + + '(Call event.preventDefault() in bx-table-row-change-selection/bx-table-change-selection-all events)', + false + ), + onBeforeChangeSelection: action('bx-table-row-change-selection'), + }; + }, + 'bx-table-header-cell': () => ({ + disableChangeSort: boolean( + 'Disable user-initiated change in sorting (Call event.preventDefault() in bx-table-header-cell-sort event)', + false + ), + onBeforeSort: action('bx-table-header-cell-sort'), + }), + }, +}; + +export const sortableWithPagination = (args) => { + const { size } = args?.['bx-table'] ?? {}; + const { onBeforeChangeSelection: onBeforeChangeSelectionAll } = + args?.['bx-table-header-row'] ?? {}; + const { colorScheme } = args?.['bx-table-body'] ?? {}; + const { hasSelection, disableChangeSelection, onBeforeChangeSelection } = + args?.['bx-table-row'] ?? {}; + const { disableChangeSort, onBeforeSort } = + args?.['bx-table-header-cell'] ?? {}; + const beforeChangeSelectionHandler = { + handleEvent(event: CustomEvent) { + if (event.type === 'bx-table-change-selection-all') { + onBeforeChangeSelectionAll(event); + } else { + onBeforeChangeSelection(event); + } + if (disableChangeSelection) { + event.preventDefault(); + } + }, + capture: true, // To prevent the default behavior before `` handles the event + }; + const beforeChangeSortHandler = { + handleEvent(event: CustomEvent) { + onBeforeSort(event); + if (disableChangeSort) { + event.preventDefault(); + } + }, + capture: true, // To prevent the default behavior before `` handles the event + }; + defineDemoDataTable(); + return html` + + + + + `; +}; + +sortableWithPagination.storyName = 'Sortable with pagination'; + +sortableWithPagination.parameters = { + knobs: sortable.parameters.knobs, +}; + +export const skeleton = (args) => { + const { size } = args?.['bx-table']; + const { colorScheme } = args?.['bx-table-body']; + return html` + + + + Name + Protocol + Port + Rule + Attached Groups + Status + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + `; +}; + +skeleton.parameters = { + percy: { + skip: true, + }, + knobs: { + ...Default.parameters.knobs, + }, +}; + +export default { + title: 'Components/Data table', + parameters: { + ...storyDocs.parameters, + }, +}; diff --git a/packages/carbon-web-components/src/components/data-table/data-table.scss b/packages/carbon-web-components/src/components/data-table/data-table.scss new file mode 100644 index 00000000000..4e14c8b9bc4 --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/data-table.scss @@ -0,0 +1,24 @@ +// +// Copyright IBM Corp. 2019, 2022 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +$css--plex: true !default; + +@import 'carbon-components/scss/globals/scss/vendor/@carbon/elements/scss/type/font-family'; +@import 'carbon-components/scss/components/checkbox/checkbox'; + +@import 'carbon-components/scss/components/data-table/data-table-core'; +@import 'carbon-components/scss/components/data-table/data-table-expandable'; +@import 'carbon-components/scss/components/data-table/data-table-inline-edit'; +@import 'carbon-components/scss/components/data-table/data-table-skeleton'; + +@import 'table-action'; +@import 'table-core'; +@import 'table-expandable'; +@import 'table-sizes'; +@import 'table-selection'; +@import 'table-sort'; +@import 'table-skeleton'; diff --git a/packages/carbon-web-components/src/components/data-table/defs.ts b/packages/carbon-web-components/src/components/data-table/defs.ts new file mode 100644 index 00000000000..1e01363f80b --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/defs.ts @@ -0,0 +1,102 @@ +/** + * @license + * + * Copyright IBM Corp. 2020, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * Table color scheme. + */ +export enum TABLE_COLOR_SCHEME { + /** + * Regular color scheme. + */ + REGULAR = '', + + /** + * Color scheme with zebra stripe. + */ + ZEBRA = 'zebra', +} + +/** + * Table size. + */ +export enum TABLE_SIZE { + /** + * Compact size. + */ + COMPACT = 'compact', + + /** + * Short size. + */ + SHORT = 'short', + + /** + * Regular size. + */ + REGULAR = '', + + /** + * Tall size. + */ + TALL = 'tall', +} + +/** + * Table sort state. + */ +export enum TABLE_SORT_DIRECTION { + /** + * Not sorted. + */ + NONE = 'none', + + /** + * Sorted ascendingly. + */ + ASCENDING = 'ascending', + + /** + * Sorted descendingly. + */ + DESCENDING = 'descending', +} + +/** + * Table sort cycle. + */ +export enum TABLE_SORT_CYCLE { + BI_STATES_FROM_ASCENDING = 'bi-states-from-ascending', + BI_STATES_FROM_DESCENDING = 'bi-states-from-descending', + TRI_STATES_FROM_ASCENDING = 'tri-states-from-ascending', + TRI_STATES_FROM_DESCENDING = 'tri-states-from-descending', +} + +/** + * Mapping of table sort cycles to table sort states. + */ +export const TABLE_SORT_CYCLES = { + [TABLE_SORT_CYCLE.BI_STATES_FROM_ASCENDING]: [ + TABLE_SORT_DIRECTION.ASCENDING, + TABLE_SORT_DIRECTION.DESCENDING, + ], + [TABLE_SORT_CYCLE.BI_STATES_FROM_DESCENDING]: [ + TABLE_SORT_DIRECTION.DESCENDING, + TABLE_SORT_DIRECTION.ASCENDING, + ], + [TABLE_SORT_CYCLE.TRI_STATES_FROM_ASCENDING]: [ + TABLE_SORT_DIRECTION.NONE, + TABLE_SORT_DIRECTION.ASCENDING, + TABLE_SORT_DIRECTION.DESCENDING, + ], + [TABLE_SORT_CYCLE.TRI_STATES_FROM_DESCENDING]: [ + TABLE_SORT_DIRECTION.NONE, + TABLE_SORT_DIRECTION.DESCENDING, + TABLE_SORT_DIRECTION.ASCENDING, + ], +}; diff --git a/packages/carbon-web-components/src/components/data-table/index.ts b/packages/carbon-web-components/src/components/data-table/index.ts new file mode 100644 index 00000000000..c363e4f18c8 --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/index.ts @@ -0,0 +1,25 @@ +/** + * @license + * + * Copyright IBM Corp. 2021 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import './table'; +import './table-batch-actions'; +import './table-body'; +import './table-cell'; +import './table-cell-skeleton'; +import './table-expand-row'; +import './table-expanded-row'; +import './table-head'; +import './table-header-cell'; +import './table-header-cell-skeleton'; +import './table-header-expand-row'; +import './table-header-row'; +import './table-row'; +import './table-toolbar'; +import './table-toolbar-content'; +import './table-toolbar-search'; diff --git a/packages/carbon-web-components/src/components/data-table/stories/data.ts b/packages/carbon-web-components/src/components/data-table/stories/data.ts new file mode 100644 index 00000000000..64ac85ebe94 --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/stories/data.ts @@ -0,0 +1,88 @@ +/** + * @license + * + * Copyright IBM Corp. 2019 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import 'core-js/modules/es.array.flat.js'; +import 'core-js/modules/es.string.pad-start.js'; +import { TABLE_SORT_DIRECTION } from '../table-header-cell'; +import { TDemoTableColumn, TDemoTableRow, TDemoSortInfo } from './types'; + +export const columns: TDemoTableColumn[] = [ + { + id: 'name', + title: 'Name', + sortCycle: 'bi-states-from-ascending', + }, + { + id: 'protocol', + title: 'Protocol', + }, + { + id: 'port', + title: 'Port', + sortCycle: 'tri-states-from-ascending', + }, + { + id: 'rule', + title: 'Rule', + }, + { + id: 'attachedGroups', + title: 'Attached Groups', + }, + { + id: 'status', + title: 'Status', + }, +]; + +export const rows: TDemoTableRow[] = [ + { + id: 1, + name: 'Load Balancer 1', + protocol: 'HTTP', + port: 80, + rule: 'Round Robin', + attachedGroups: "Maureen's VM Groups", + status: 'Active', + }, + { + id: 2, + name: 'Load Balancer 2', + protocol: 'HTTPS', + port: 443, + rule: 'Round Robin', + attachedGroups: "Maureen's VM Groups", + status: 'Active', + }, + { + id: 3, + selected: true, + name: 'Load Balancer 3', + protocol: 'HTTP', + port: 80, + rule: 'Round Robin', + attachedGroups: "Maureen's VM Groups", + status: 'Active', + }, +]; + +export const rowsMany: TDemoTableRow[] = Array.from(new Array(50)) + .map((_item, i) => + rows.map((row, j) => ({ + ...row, + id: i * 3 + j, + name: `Load Balancer ${String(i * 3 + j + 1).padStart(3, '0')}`, + })) + ) + .flat(); + +export const sortInfo: TDemoSortInfo = { + columnId: 'name', + direction: TABLE_SORT_DIRECTION.ASCENDING, +}; diff --git a/packages/carbon-web-components/src/components/data-table/stories/types.ts b/packages/carbon-web-components/src/components/data-table/stories/types.ts new file mode 100644 index 00000000000..0e47e6fd9a5 --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/stories/types.ts @@ -0,0 +1,36 @@ +/** + * @license + * + * Copyright IBM Corp. 2019 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { TABLE_SORT_DIRECTION } from '../table-header-cell'; + +/** + * Example data structure of data table column. + */ +export type TDemoTableColumn = { + id: string; + title: string; + sortCycle?: string; +}; + +/** + * Example data structure of data table row. + */ +export type TDemoTableRow = { + id: number; + selected?: boolean; + [key: string]: any; +}; + +/** + * Example structure of table sorting info. + */ +export type TDemoSortInfo = { + columnId: string; + direction: TABLE_SORT_DIRECTION; +}; diff --git a/packages/carbon-web-components/src/components/data-table/table-batch-actions.ts b/packages/carbon-web-components/src/components/data-table/table-batch-actions.ts new file mode 100644 index 00000000000..2e49854c8ad --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/table-batch-actions.ts @@ -0,0 +1,93 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { html, property, customElement, LitElement } from 'lit-element'; +import settings from 'carbon-components/es/globals/js/settings'; +import styles from './data-table.scss'; + +const { prefix } = settings; + +/** + * Table batch actions. + * + * @element bx-table-batch-actions + * @fires bx-table-batch-actions-cancel-clicked - The custom event fired after the Cancel button is clicked. + */ +@customElement(`${prefix}-table-batch-actions`) +class BXTableBatchActions extends LitElement { + /** + * Handles `click` event on the Cancel button. + */ + private _handleCancel() { + const { eventClickCancel } = this.constructor as typeof BXTableBatchActions; + this.dispatchEvent( + new CustomEvent(eventClickCancel, { bubbles: true, composed: true }) + ); + } + + /** + * `true` if this batch actions bar should be active. + */ + @property({ type: Boolean, reflect: true }) + active = false; + + /** + * The formatter for selected items. Should be changed upon the locale the UI is rendered with. + */ + @property({ attribute: false }) + formatSelectedItemsCount = ({ count }) => + `${count} item${count <= 1 ? '' : 's'} selected`; + + /** + * Numeric representation of the total number of items selected in a table. + * This number is used to derive the selection message. + */ + @property({ type: Number, attribute: 'selected-rows-count' }) + selectedRowsCount = 0; + + updated(changedProperties) { + if (changedProperties.has('active')) { + this.setAttribute('tabindex', `${this.active ? '' : '-1'}`); + } + } + + render() { + const { + formatSelectedItemsCount, + selectedRowsCount, + _handleCancel: handleCancel, + } = this; + return html` +
+

+ ${formatSelectedItemsCount({ count: selectedRowsCount })} +

+
+
+ + +
+ `; + } + + /** + * The name of the custom event fired after the Cancel button is clicked. + */ + static get eventClickCancel() { + return `${prefix}-table-batch-actions-cancel-clicked`; + } + + static styles = styles; +} + +export default BXTableBatchActions; diff --git a/packages/carbon-web-components/src/components/data-table/table-body.ts b/packages/carbon-web-components/src/components/data-table/table-body.ts new file mode 100644 index 00000000000..18da5154575 --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/table-body.ts @@ -0,0 +1,81 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import settings from 'carbon-components/es/globals/js/settings'; +import { html, property, query, customElement, LitElement } from 'lit-element'; +import { TABLE_COLOR_SCHEME } from './defs'; +import BXTableRow from './table-row'; +import styles from './data-table.scss'; + +const { prefix } = settings; + +/** + * Data table body. + * + * @element bx-table-body + */ +@customElement(`${prefix}-table-body`) +class BXTableBody extends LitElement { + /** + * The `` element in the shadow DOM. + */ + @query('slot') + private _slotNode!: HTMLSlotElement; + + /** + * Updates `even`/`odd` properties of the child ``s. + */ + private _updateZebra() { + const { colorScheme, _slotNode: slotNode } = this; + slotNode.assignedNodes().forEach((node) => { + if (node.nodeType === Node.ELEMENT_NODE) { + const odd = (node as HTMLElement).matches('*:nth-of-type(odd)'); + (node as BXTableRow).even = + colorScheme === TABLE_COLOR_SCHEME.ZEBRA && !odd; + (node as BXTableRow).odd = + colorScheme === TABLE_COLOR_SCHEME.ZEBRA && odd; + } + }); + } + + /** + * Handles `slotchange` event in the `` element in the shadow DOM. + */ + private _handleSlotChange = () => { + this._updateZebra(); + }; + + /** + * The color scheme. + */ + @property({ reflect: true, attribute: 'color-scheme' }) + colorScheme = TABLE_COLOR_SCHEME.REGULAR; + + connectedCallback() { + if (!this.hasAttribute('role')) { + this.setAttribute('role', 'rowgroup'); + } + super.connectedCallback(); + } + + updated(changedProperties) { + if (changedProperties.has('colorScheme')) { + this._updateZebra(); + } + } + + render() { + const { _handleSlotChange: handleSlotChange } = this; + return html` `; + } + + static styles = styles; +} + +export default BXTableBody; diff --git a/packages/carbon-web-components/src/components/data-table/table-cell-skeleton.ts b/packages/carbon-web-components/src/components/data-table/table-cell-skeleton.ts new file mode 100644 index 00000000000..2eedbab50e8 --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/table-cell-skeleton.ts @@ -0,0 +1,28 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { html, customElement } from 'lit-element'; +import settings from 'carbon-components/es/globals/js/settings'; +import BXTableCell from './table-cell'; + +const { prefix } = settings; + +/** + * Data table cell with skeleton content. + * + * @element bx-table-cell-skeleton + */ +@customElement(`${prefix}-table-cell-skeleton`) +class BXTableCellSkeleton extends BXTableCell { + render() { + return html` `; + } +} + +export default BXTableCellSkeleton; diff --git a/packages/carbon-web-components/src/components/data-table/table-cell.ts b/packages/carbon-web-components/src/components/data-table/table-cell.ts new file mode 100644 index 00000000000..44f4daa8840 --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/table-cell.ts @@ -0,0 +1,37 @@ +/** + * @license + * + * Copyright IBM Corp. 2019, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import settings from 'carbon-components/es/globals/js/settings'; +import { html, customElement, LitElement } from 'lit-element'; +import styles from './data-table.scss'; + +const { prefix } = settings; + +/** + * Data table cell. + * + * @element bx-table-cell + */ +@customElement(`${prefix}-table-cell`) +class BXTableCell extends LitElement { + connectedCallback() { + if (!this.hasAttribute('role')) { + this.setAttribute('role', 'cell'); + } + super.connectedCallback(); + } + + render() { + return html` `; + } + + static styles = styles; +} + +export default BXTableCell; diff --git a/packages/carbon-web-components/src/components/data-table/table-expand-row.ts b/packages/carbon-web-components/src/components/data-table/table-expand-row.ts new file mode 100644 index 00000000000..aea6983e7e2 --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/table-expand-row.ts @@ -0,0 +1,142 @@ +/** + * @license + * + * Copyright IBM Corp. 2020, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { html, property, customElement } from 'lit-element'; +import ChevronRight16 from '@carbon/icons/lib/chevron--right/16'; +import settings from 'carbon-components/es/globals/js/settings'; +import HostListenerMixin from '../../globals/mixins/host-listener'; +import HostListener from '../../globals/decorators/host-listener'; +import BXTableRow from './table-row'; +import BXTableExpandedRow from './table-expanded-row'; +import styles from './data-table.scss'; + +const { prefix } = settings; + +/** + * The expando row in table row. + * + * @element bx-table-expand-row + */ +@customElement(`${prefix}-table-expand-row`) +class BXTableExpandRow extends HostListenerMixin(BXTableRow) { + /** + * Handles `click` event on the expando button. + */ + private _handleClickExpando() { + this._handleUserInitiatedToggleExpando(); + } + + /** + * Handles `mouseover`/`mouseout` event handler on this element. + * + * @param event The event. + */ + @HostListener('mouseover') + @HostListener('mouseout') + // @ts-ignore: The decorator refers to this method but TS thinks this method is not referred to + private _handleMouseOverOut(event: MouseEvent) { + const { selectorExpandedRow } = this.constructor as typeof BXTableExpandRow; + const { nextElementSibling } = this; + if (nextElementSibling?.matches(selectorExpandedRow)) { + (nextElementSibling as BXTableExpandedRow).highlighted = + event.type === 'mouseover'; + } + } + + /** + * Handles user-initiated toggle request of the expando button in this table row. + * + * @param expanded The new expanded state. + */ + private _handleUserInitiatedToggleExpando(expanded = !this.expanded) { + const init = { + bubbles: true, + cancelable: true, + composed: true, + detail: { + expanded, + }, + }; + if ( + this.dispatchEvent( + new CustomEvent( + ( + this.constructor as typeof BXTableExpandRow + ).eventBeforeExpandoToggle, + init + ) + ) + ) { + this.expanded = expanded; + this.dispatchEvent( + new CustomEvent( + (this.constructor as typeof BXTableExpandRow).eventExpandoToggle, + init + ) + ); + } + } + + protected _renderFirstCells() { + const { _handleClickExpando: handleClickExpando } = this; + return html` +
+ +
+ ${super._renderFirstCells()} + `; + } + + /** + * `true` if the table row should be expanded. + */ + @property({ type: Boolean, reflect: true }) + expanded = false; + + updated(changedProperties) { + if (changedProperties.has('expanded')) { + const { selectorExpandedRow } = this + .constructor as typeof BXTableExpandRow; + const { expanded, nextElementSibling } = this; + if (nextElementSibling?.matches(selectorExpandedRow)) { + (nextElementSibling as BXTableExpandedRow).expanded = expanded; + } + } + } + + /** + * A selector that will return the corresponding expanded row. + */ + static get selectorExpandedRow() { + return `${prefix}-table-expanded-row`; + } + + /** + * The name of the custom event fired before the expanded state this row is being toggled upon a user gesture. + * Cancellation of this event stops the user-initiated action of toggling the expanded state. + */ + static get eventBeforeExpandoToggle() { + return `${prefix}-table-row-expando-beingtoggled`; + } + + /** + * The name of the custom event fired after the expanded state this row is toggled upon a user gesture. + */ + static get eventExpandoToggle() { + return `${prefix}-table-row-expando-toggled`; + } + + static styles = styles; // `styles` here is a `CSSResult` generated by custom WebPack loader +} + +export default BXTableExpandRow; diff --git a/packages/carbon-web-components/src/components/data-table/table-expanded-row.ts b/packages/carbon-web-components/src/components/data-table/table-expanded-row.ts new file mode 100644 index 00000000000..7f0f72b2184 --- /dev/null +++ b/packages/carbon-web-components/src/components/data-table/table-expanded-row.ts @@ -0,0 +1,55 @@ +/** + * @license + * + * Copyright IBM Corp. 2020, 2022 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { html, property, customElement, LitElement } from 'lit-element'; +import settings from 'carbon-components/es/globals/js/settings'; +import styles from './data-table.scss'; + +const { prefix } = settings; + +/** + * Table row of collapsible details. + * + * @element bx-table-expanded-row + */ +@customElement(`${prefix}-table-expanded-row`) +class BXTableExpandedRow extends LitElement { + /** + * The colspan. + */ + @property({ type: Number, attribute: 'colspan' }) + colSpan = 1; + + /** + * `true` if the table row should be expanded. + */ + @property({ type: Boolean, reflect: true }) + expanded = false; + + /** + * `true` if the table row should be highlighted. + */ + @property({ type: Boolean, reflect: true }) + highlighted = false; + + render() { + const { colSpan } = this; + return html` +
+
+ +
+
- ${this.groupTitle} - ${this.groupTitle}