diff --git a/.all-contributorsrc b/.all-contributorsrc index 3ad5829a13ef..35cfde183594 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -1290,6 +1290,14 @@ ] }, { + "login": "Nirajsah", + "name": "Niraj Sah", + "avatar_url": "https://avatars.githubusercontent.com/u/51414373?v=4", + "profile": "https://github.com/Nirajsah", + "contributions": [ + "code" + ] + }, "login": "allisonishida", "name": "Allison Ishida", "avatar_url": "https://avatars.githubusercontent.com/u/22247062?v=4", @@ -1306,6 +1314,15 @@ "contributions": [ "code" ] + }, + { + "login": "Tresau-IBM", + "name": "Tresau-IBM", + "avatar_url": "https://avatars.githubusercontent.com/u/148357638?v=4", + "profile": "https://github.com/Tresau-IBM", + "contributions": [ + "code" + ] } ], "commitConvention": "none" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e4efe9794a85..a4c73c38cdff 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1 - name: Use Node.js 20.x - uses: actions/setup-node@v3 + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #v4.0.0 with: node-version: '20.x' - name: Run yarn dedupe @@ -30,7 +30,7 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1 - name: Use Node.js 20.x - uses: actions/setup-node@v3 + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #v4.0.0 with: node-version: '20.x' - name: Install dependencies @@ -43,7 +43,7 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1 - name: Use Node.js 20.x - uses: actions/setup-node@v3 + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #v4.0.0 with: node-version: '20.x' - name: Install dependencies @@ -58,10 +58,11 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1 - name: Use Node.js 20.x - uses: actions/setup-node@v3 + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #v4.0.0 with: node-version: '20.x' - uses: actions/cache@v3 + if: github.event_name != 'merge_group' id: cache with: path: | @@ -84,10 +85,11 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1 - name: Use Node.js 20.x - uses: actions/setup-node@v3 + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #v4.0.0 with: node-version: '20.x' - uses: actions/cache@v3 + if: github.event_name != 'merge_group' id: cache with: path: | @@ -123,10 +125,11 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1 - name: Use Node.js 20.x - uses: actions/setup-node@v3 + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #v4.0.0 with: node-version: '20.x' - uses: actions/cache@v3 + if: github.event_name != 'merge_group' id: cache with: path: | @@ -182,10 +185,11 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1 - name: Use Node.js 20.x - uses: actions/setup-node@v3 + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #v4.0.0 with: node-version: '20.x' - uses: actions/cache@v3 + if: github.event_name != 'merge_group' id: cache with: path: | diff --git a/.github/workflows/deploy-packages.yml b/.github/workflows/deploy-packages.yml index 18e8784a1622..9288350ba4cf 100644 --- a/.github/workflows/deploy-packages.yml +++ b/.github/workflows/deploy-packages.yml @@ -21,7 +21,7 @@ jobs: repository: carbon-design-system/design-language-website ref: master - name: Use Node.js 20.x - uses: actions/setup-node@v3 + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #v4.0.0 with: node-version: '20.x' registry-url: 'https://registry.npmjs.org' @@ -63,7 +63,7 @@ jobs: repository: carbon-design-system/gatsby-theme-carbon ref: main - name: Use Node.js 20.x - uses: actions/setup-node@v3 + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #v4.0.0 with: node-version: '20.x' registry-url: 'https://registry.npmjs.org' diff --git a/.github/workflows/deploy-react-storybook.yml b/.github/workflows/deploy-react-storybook.yml index 0baf619a49ab..3eb69367b913 100644 --- a/.github/workflows/deploy-react-storybook.yml +++ b/.github/workflows/deploy-react-storybook.yml @@ -30,7 +30,7 @@ jobs: steps: - uses: actions/checkout@main - name: Use Node.js 20.x - uses: actions/setup-node@v3 + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #v4.0.0 with: node-version: '20.x' - name: Install dependencies diff --git a/.github/workflows/nightly-release.yml b/.github/workflows/nightly-release.yml index a69939ee0b4d..6a1eeb36a5aa 100644 --- a/.github/workflows/nightly-release.yml +++ b/.github/workflows/nightly-release.yml @@ -15,7 +15,7 @@ jobs: steps: - uses: actions/checkout@main - name: Use Node.js 20.x - uses: actions/setup-node@v3 + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #v4.0.0 with: node-version: '20.x' - name: Install dependencies diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ef5cdea9b49d..5d26ff03220e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,7 +21,7 @@ jobs: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1 - name: Use Node.js 20.x - uses: actions/setup-node@v3 + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #v4.0.0 with: node-version: '20.x' registry-url: 'https://registry.npmjs.org' diff --git a/.github/workflows/sync-generated-files.yml b/.github/workflows/sync-generated-files.yml index 88206645bc84..9a4e80f10ddf 100644 --- a/.github/workflows/sync-generated-files.yml +++ b/.github/workflows/sync-generated-files.yml @@ -9,7 +9,7 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1 - name: Use Node.js 20.x - uses: actions/setup-node@v3 + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #v4.0.0 with: node-version: '20.x' - name: Install dependencies diff --git a/.github/workflows/v10-ci.yml b/.github/workflows/v10-ci.yml index 8c123b218d5b..fde39a4411c5 100644 --- a/.github/workflows/v10-ci.yml +++ b/.github/workflows/v10-ci.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1 - name: Use Node.js 20.x - uses: actions/setup-node@v3 + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #v4.0.0 with: node-version: '20.x' - name: Run yarn dedupe @@ -29,7 +29,7 @@ jobs: with: ref: v10 - name: Use Node.js 20.x - uses: actions/setup-node@v3 + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #v4.0.0 with: node-version: '20.x' - name: Install dependencies @@ -44,7 +44,7 @@ jobs: with: ref: v10 - name: Use Node.js 20.x - uses: actions/setup-node@v3 + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #v4.0.0 with: node-version: '20.x' - name: Install dependencies @@ -61,7 +61,7 @@ jobs: with: ref: v10 - name: Use Node.js 20.x - uses: actions/setup-node@v3 + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #v4.0.0 with: node-version: '20.x' - uses: actions/cache@v3 @@ -89,7 +89,7 @@ jobs: with: ref: v10 - name: Use Node.js 20.x - uses: actions/setup-node@v3 + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #v4.0.0 with: node-version: '20.x' - uses: actions/cache@v3 diff --git a/.github/workflows/v10-deploy-react-storybook.yml b/.github/workflows/v10-deploy-react-storybook.yml index 0a92eb7116a5..0f2ecef9e2e4 100644 --- a/.github/workflows/v10-deploy-react-storybook.yml +++ b/.github/workflows/v10-deploy-react-storybook.yml @@ -19,7 +19,7 @@ jobs: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1 - name: Use Node.js 20.x - uses: actions/setup-node@v3 + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #v4.0.0 with: node-version: '20.x' - name: Install dependencies diff --git a/.github/workflows/v10-release.yml b/.github/workflows/v10-release.yml index 2ddec10b09a4..b1534733908d 100644 --- a/.github/workflows/v10-release.yml +++ b/.github/workflows/v10-release.yml @@ -19,7 +19,7 @@ jobs: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1 - name: Use Node.js 20.x - uses: actions/setup-node@v3 + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #v4.0.0 with: node-version: '20.x' registry-url: 'https://registry.npmjs.org' diff --git a/.github/workflows/version.yml b/.github/workflows/version.yml index 366f1583b827..f9b80def9310 100644 --- a/.github/workflows/version.yml +++ b/.github/workflows/version.yml @@ -32,7 +32,7 @@ jobs: with: fetch-depth: '0' - name: Use Node.js 20.x - uses: actions/setup-node@v3 + uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 #v4.0.0 with: node-version: '20.x' registry-url: 'https://registry.npmjs.org' diff --git a/.yarn/cache/@babel-code-frame-npm-7.22.13-2782581d20-22e342c807.zip b/.yarn/cache/@babel-code-frame-npm-7.22.13-2782581d20-22e342c807.zip new file mode 100644 index 000000000000..9ecb85a9916f Binary files /dev/null and b/.yarn/cache/@babel-code-frame-npm-7.22.13-2782581d20-22e342c807.zip differ diff --git a/.yarn/cache/@babel-code-frame-npm-7.22.5-b36f88d6f9-cfe804f518.zip b/.yarn/cache/@babel-code-frame-npm-7.22.5-b36f88d6f9-cfe804f518.zip deleted file mode 100644 index 998495e24d48..000000000000 Binary files a/.yarn/cache/@babel-code-frame-npm-7.22.5-b36f88d6f9-cfe804f518.zip and /dev/null differ diff --git a/.yarn/cache/@babel-generator-npm-7.22.9-d9fccf9328-7c9d2c58b8.zip b/.yarn/cache/@babel-generator-npm-7.22.9-d9fccf9328-7c9d2c58b8.zip deleted file mode 100644 index bab8838734ff..000000000000 Binary files a/.yarn/cache/@babel-generator-npm-7.22.9-d9fccf9328-7c9d2c58b8.zip and /dev/null differ diff --git a/.yarn/cache/@babel-generator-npm-7.23.0-08841c5369-8efe24adad.zip b/.yarn/cache/@babel-generator-npm-7.23.0-08841c5369-8efe24adad.zip new file mode 100644 index 000000000000..159e5218277d Binary files /dev/null and b/.yarn/cache/@babel-generator-npm-7.23.0-08841c5369-8efe24adad.zip differ diff --git a/.yarn/cache/@babel-helper-environment-visitor-npm-7.22.20-260909e014-d80ee98ff6.zip b/.yarn/cache/@babel-helper-environment-visitor-npm-7.22.20-260909e014-d80ee98ff6.zip new file mode 100644 index 000000000000..3d5f74720b29 Binary files /dev/null and b/.yarn/cache/@babel-helper-environment-visitor-npm-7.22.20-260909e014-d80ee98ff6.zip differ diff --git a/.yarn/cache/@babel-helper-environment-visitor-npm-7.22.5-7bc52eec61-248532077d.zip b/.yarn/cache/@babel-helper-environment-visitor-npm-7.22.5-7bc52eec61-248532077d.zip deleted file mode 100644 index 74536fc103df..000000000000 Binary files a/.yarn/cache/@babel-helper-environment-visitor-npm-7.22.5-7bc52eec61-248532077d.zip and /dev/null differ diff --git a/.yarn/cache/@babel-helper-function-name-npm-7.22.5-8a1a69b63d-6b1f6ce1b1.zip b/.yarn/cache/@babel-helper-function-name-npm-7.22.5-8a1a69b63d-6b1f6ce1b1.zip deleted file mode 100644 index e3b1350c5a4b..000000000000 Binary files a/.yarn/cache/@babel-helper-function-name-npm-7.22.5-8a1a69b63d-6b1f6ce1b1.zip and /dev/null differ diff --git a/.yarn/cache/@babel-helper-function-name-npm-7.23.0-ce38271242-e44542257b.zip b/.yarn/cache/@babel-helper-function-name-npm-7.23.0-ce38271242-e44542257b.zip new file mode 100644 index 000000000000..2458055dc686 Binary files /dev/null and b/.yarn/cache/@babel-helper-function-name-npm-7.23.0-ce38271242-e44542257b.zip differ diff --git a/.yarn/cache/@babel-helper-validator-identifier-npm-7.22.20-18305bb306-136412784d.zip b/.yarn/cache/@babel-helper-validator-identifier-npm-7.22.20-18305bb306-136412784d.zip new file mode 100644 index 000000000000..53d7fc0339c3 Binary files /dev/null and b/.yarn/cache/@babel-helper-validator-identifier-npm-7.22.20-18305bb306-136412784d.zip differ diff --git a/.yarn/cache/@babel-helper-validator-identifier-npm-7.22.5-4536624779-7f0f301134.zip b/.yarn/cache/@babel-helper-validator-identifier-npm-7.22.5-4536624779-7f0f301134.zip deleted file mode 100644 index 6156061a709f..000000000000 Binary files a/.yarn/cache/@babel-helper-validator-identifier-npm-7.22.5-4536624779-7f0f301134.zip and /dev/null differ diff --git a/.yarn/cache/@babel-highlight-npm-7.22.20-5de7aba88d-84bd034dca.zip b/.yarn/cache/@babel-highlight-npm-7.22.20-5de7aba88d-84bd034dca.zip new file mode 100644 index 000000000000..7c810e8b663d Binary files /dev/null and b/.yarn/cache/@babel-highlight-npm-7.22.20-5de7aba88d-84bd034dca.zip differ diff --git a/.yarn/cache/@babel-highlight-npm-7.22.5-3182ccc1fe-f61ae6de6e.zip b/.yarn/cache/@babel-highlight-npm-7.22.5-3182ccc1fe-f61ae6de6e.zip deleted file mode 100644 index ba4915a04c9b..000000000000 Binary files a/.yarn/cache/@babel-highlight-npm-7.22.5-3182ccc1fe-f61ae6de6e.zip and /dev/null differ diff --git a/.yarn/cache/@babel-parser-npm-7.22.7-7fbdf28552-02209ddbd4.zip b/.yarn/cache/@babel-parser-npm-7.22.7-7fbdf28552-02209ddbd4.zip deleted file mode 100644 index 1748e15f1272..000000000000 Binary files a/.yarn/cache/@babel-parser-npm-7.22.7-7fbdf28552-02209ddbd4.zip and /dev/null differ diff --git a/.yarn/cache/@babel-parser-npm-7.23.0-8a7b151672-453fdf8b9e.zip b/.yarn/cache/@babel-parser-npm-7.23.0-8a7b151672-453fdf8b9e.zip new file mode 100644 index 000000000000..d7543e4a61fe Binary files /dev/null and b/.yarn/cache/@babel-parser-npm-7.23.0-8a7b151672-453fdf8b9e.zip differ diff --git a/.yarn/cache/@babel-template-npm-7.22.15-0b464facb4-1f3e7dcd6c.zip b/.yarn/cache/@babel-template-npm-7.22.15-0b464facb4-1f3e7dcd6c.zip new file mode 100644 index 000000000000..499a48f47353 Binary files /dev/null and b/.yarn/cache/@babel-template-npm-7.22.15-0b464facb4-1f3e7dcd6c.zip differ diff --git a/.yarn/cache/@babel-template-npm-7.22.5-358c44dc9d-c574641016.zip b/.yarn/cache/@babel-template-npm-7.22.5-358c44dc9d-c574641016.zip deleted file mode 100644 index dc95158bfc62..000000000000 Binary files a/.yarn/cache/@babel-template-npm-7.22.5-358c44dc9d-c574641016.zip and /dev/null differ diff --git a/.yarn/cache/@babel-traverse-npm-7.22.8-98fbaaf7d8-a381369bc3.zip b/.yarn/cache/@babel-traverse-npm-7.22.8-98fbaaf7d8-a381369bc3.zip deleted file mode 100644 index b528dfa69616..000000000000 Binary files a/.yarn/cache/@babel-traverse-npm-7.22.8-98fbaaf7d8-a381369bc3.zip and /dev/null differ diff --git a/.yarn/cache/@babel-traverse-npm-7.23.2-4758feee42-26a1eea0dd.zip b/.yarn/cache/@babel-traverse-npm-7.23.2-4758feee42-26a1eea0dd.zip new file mode 100644 index 000000000000..07fe656495bf Binary files /dev/null and b/.yarn/cache/@babel-traverse-npm-7.23.2-4758feee42-26a1eea0dd.zip differ diff --git a/.yarn/cache/@babel-types-npm-7.22.5-d1e4264bef-c13a9c1dc7.zip b/.yarn/cache/@babel-types-npm-7.22.5-d1e4264bef-c13a9c1dc7.zip deleted file mode 100644 index 3676b26b904c..000000000000 Binary files a/.yarn/cache/@babel-types-npm-7.22.5-d1e4264bef-c13a9c1dc7.zip and /dev/null differ diff --git a/.yarn/cache/@babel-types-npm-7.23.0-332fd21daf-215fe04bd7.zip b/.yarn/cache/@babel-types-npm-7.23.0-332fd21daf-215fe04bd7.zip new file mode 100644 index 000000000000..318a0bc25d86 Binary files /dev/null and b/.yarn/cache/@babel-types-npm-7.23.0-332fd21daf-215fe04bd7.zip differ diff --git a/README.md b/README.md index 4c8a7b4f3040..59462a443f5f 100644 --- a/README.md +++ b/README.md @@ -258,8 +258,10 @@ check out our [Contributing Guide](/.github/CONTRIBUTING.md) and our
Aman Lajpal

💻 📖 +
Niraj Sah

💻
Allison Ishida

💻
Alex Lewitt

💻 +
Tresau-IBM

💻 diff --git a/e2e/components/Menu/Menu-test.avt.e2e.js b/e2e/components/Menu/Menu-test.avt.e2e.js new file mode 100644 index 000000000000..ecf249ecb777 --- /dev/null +++ b/e2e/components/Menu/Menu-test.avt.e2e.js @@ -0,0 +1,69 @@ +/** + * Copyright IBM Corp. 2023 + * + * 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 { expect, test } = require('@playwright/test'); +const { visitStory } = require('../../test-utils/storybook'); + +test.describe('Menu @avt', () => { + test('@avt-default-state', async ({ page }) => { + await visitStory(page, { + component: 'Menu', + id: 'components-menu--playground', + globals: { + theme: 'white', + }, + }); + await expect(page).toHaveNoACViolations('Menu @avt-default-state'); + }); + + test('@avt-keyboard-nav Menu', async ({ page }) => { + await visitStory(page, { + component: 'Menu', + id: 'components-menu--playground', + globals: { + theme: 'white', + }, + }); + + const firstItem = page.getByRole('menuitem', { name: 'Share with' }); + const LastItem = page.getByRole('menuitem', { name: 'Delete' }); + const nestedMenu = page.getByRole('menu', { name: 'Share with' }); + const nestedMenuItem = page + .getByRole('menuitemradio', { + name: 'None', + }) + .first(); + + await expect(firstItem).toBeVisible(); + await expect(LastItem).toBeVisible(); + await expect(nestedMenu).not.toBeVisible(); + await expect(firstItem).toBeFocused(); + + // Should go to last item when focused on the first item and arrow up is pressed + await page.keyboard.press('ArrowUp'); + await expect(LastItem).toBeFocused(); + + // Should open menu with ArrowRight and focus on first item + await page.keyboard.press('ArrowDown'); + await expect(firstItem).toBeFocused(); + await page.keyboard.press('ArrowRight'); + await expect(nestedMenu).toBeVisible(); + await expect(nestedMenuItem).toBeVisible(); + await expect(nestedMenuItem).toBeFocused(); + await expect(nestedMenuItem).not.toBeChecked(); + + // Should select item with enter key + await page.keyboard.press('Enter'); + await expect(nestedMenuItem).toBeChecked(); + + // Should close menu with ArrowLeft + await page.keyboard.press('ArrowLeft'); + await expect(nestedMenu).not.toBeVisible(); + }); +}); diff --git a/e2e/components/Menu/Menu-test.e2e.js b/e2e/components/Menu/Menu-test.e2e.js index cf3309d3dd24..7541bc740e50 100644 --- a/e2e/components/Menu/Menu-test.e2e.js +++ b/e2e/components/Menu/Menu-test.e2e.js @@ -7,9 +7,9 @@ 'use strict'; -const { expect, test } = require('@playwright/test'); +const { test } = require('@playwright/test'); const { themes } = require('../../test-utils/env'); -const { snapshotStory, visitStory } = require('../../test-utils/storybook'); +const { snapshotStory } = require('../../test-utils/storybook'); test.describe('Menu', () => { themes.forEach((theme) => { @@ -23,15 +23,4 @@ test.describe('Menu', () => { }); }); }); - - test('accessibility-checker @avt', async ({ page }) => { - await visitStory(page, { - component: 'Menu', - id: 'components-menu--playground', - globals: { - theme: 'white', - }, - }); - await expect(page).toHaveNoACViolations('Menu'); - }); }); diff --git a/e2e/components/Toggletip/Toggletip-test.avt.e2e.js b/e2e/components/Toggletip/Toggletip-test.avt.e2e.js new file mode 100644 index 000000000000..26525fc2519b --- /dev/null +++ b/e2e/components/Toggletip/Toggletip-test.avt.e2e.js @@ -0,0 +1,57 @@ +/** + * Copyright IBM Corp. 2016, 2023 + * + * 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'; + +import { expect, test } from '@playwright/test'; +import { visitStory } from '../../test-utils/storybook'; + +test.describe('Toggletip @avt', () => { + test('@avt-default-state Toggletip', async ({ page }) => { + await visitStory(page, { + component: 'Toggletip', + id: 'components-toggletip--default', + globals: { + theme: 'white', + }, + }); + await expect(page).toHaveNoACViolations('Toggletip'); + }); + + test('@avt-keyboard-nav Toggletip', async ({ page }) => { + await visitStory(page, { + component: 'Toggletip', + id: 'components-toggletip--default', + globals: { + theme: 'white', + }, + }); + + // Checking if the defaultOpen is working + await expect(page.locator('.cds--popover--open')).toBeVisible(); + + // Checking first Toggletip interaction + await page.keyboard.press('Tab'); + await expect(page.getByLabel('Show information').first()).toBeFocused(); + await page.keyboard.press('Enter'); + await expect(page.locator('.cds--popover--open')).toBeVisible(); + // Tabbing inside the popover + await page.keyboard.press('Tab'); + await expect(page.locator('.cds--link').first()).toBeFocused(); + await page.keyboard.press('Tab'); + await expect(page.getByRole('button', { name: 'Button' })).toBeFocused(); + await page.keyboard.press('Tab'); + await expect(page.locator('.cds--popover--open')).not.toBeVisible(); + + // Checking second Toggletip interaction and close on Escape key + await expect(page.getByLabel('Show information').last()).toBeFocused(); + await page.keyboard.press('Enter'); + await expect(page.locator('.cds--popover--open')).toBeVisible(); + await page.keyboard.press('Escape'); + await expect(page.locator('.cds--popover--open')).not.toBeVisible(); + }); +}); diff --git a/e2e/components/Toggletip/Toggletip-test.e2e.js b/e2e/components/Toggletip/Toggletip-test.e2e.js index df57ebbc70fb..b64f2a196073 100644 --- a/e2e/components/Toggletip/Toggletip-test.e2e.js +++ b/e2e/components/Toggletip/Toggletip-test.e2e.js @@ -7,9 +7,9 @@ 'use strict'; -const { expect, test } = require('@playwright/test'); -const { themes } = require('../../test-utils/env'); -const { snapshotStory, visitStory } = require('../../test-utils/storybook'); +import { test } from '@playwright/test'; +import { themes } from '../../test-utils/env'; +import { snapshotStory } from '../../test-utils/storybook'; test.describe('Toggletip', () => { themes.forEach((theme) => { @@ -23,15 +23,4 @@ test.describe('Toggletip', () => { }); }); }); - - test('accessibility-checker @avt', async ({ page }) => { - await visitStory(page, { - component: 'Toggletip', - id: 'components-toggletip--default', - globals: { - theme: 'white', - }, - }); - await expect(page).toHaveNoACViolations('Toggletip'); - }); }); diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap index 0e53df0816fd..9881e84aefae 100644 --- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap +++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap @@ -1054,6 +1054,9 @@ Map { "ComboBox" => Object { "$$typeof": Symbol(react.forward_ref), "propTypes": Object { + "allowCustomValue": Object { + "type": "bool", + }, "aria-label": Object { "type": "string", }, @@ -1945,6 +1948,7 @@ Map { }, }, "TableExpandRow": Object { + "$$typeof": Symbol(react.forward_ref), "propTypes": Object { "aria-controls": Object { "type": "string", @@ -1979,6 +1983,7 @@ Map { "type": "func", }, }, + "render": [Function], }, "TableExpandedRow": Object { "propTypes": Object { @@ -7557,6 +7562,7 @@ Map { }, }, "TableExpandRow" => Object { + "$$typeof": Symbol(react.forward_ref), "propTypes": Object { "aria-controls": Object { "type": "string", @@ -7591,6 +7597,7 @@ Map { "type": "func", }, }, + "render": [Function], }, "TableExpandedRow" => Object { "propTypes": Object { @@ -8889,6 +8896,7 @@ Map { }, }, "TreeNode" => Object { + "$$typeof": Symbol(react.forward_ref), "propTypes": Object { "active": Object { "args": Array [ @@ -8968,9 +8976,11 @@ Map { "type": "string", }, }, + "render": [Function], }, "TreeView" => Object { "TreeNode": Object { + "$$typeof": Symbol(react.forward_ref), "propTypes": Object { "active": Object { "args": Array [ @@ -9050,6 +9060,7 @@ Map { "type": "string", }, }, + "render": [Function], }, "propTypes": Object { "active": Object { diff --git a/packages/react/examples/drag-and-drop-file-uploader/yarn.lock b/packages/react/examples/drag-and-drop-file-uploader/yarn.lock index 7fa9fbd40dc6..5bfe3d79b573 100644 --- a/packages/react/examples/drag-and-drop-file-uploader/yarn.lock +++ b/packages/react/examples/drag-and-drop-file-uploader/yarn.lock @@ -31,6 +31,14 @@ dependencies: "@babel/highlight" "^7.18.6" +"@babel/code-frame@^7.22.13": + version "7.22.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" + integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== + dependencies: + "@babel/highlight" "^7.22.13" + chalk "^2.4.2" + "@babel/compat-data@^7.17.7", "@babel/compat-data@^7.18.8", "@babel/compat-data@^7.9.0": version "7.18.8" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.8.tgz#2483f565faca607b8535590e84e7de323f27764d" @@ -99,17 +107,6 @@ json5 "^2.2.1" semver "^6.3.0" -"@babel/generator@^7.1.3": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.1.3.tgz#2103ec9c42d9bdad9190a6ad5ff2d456fd7b8673" - integrity sha512-ZoCZGcfIJFJuZBqxcY9OjC1KW2lWK64qrX1o4UYL3yshVhwKFYgzpWZ0vvtGMNJdTlvkw0W+HR1VnYN8q3QPFQ== - dependencies: - "@babel/types" "^7.1.3" - jsesc "^2.5.1" - lodash "^4.17.10" - source-map "^0.5.0" - trim-right "^1.0.1" - "@babel/generator@^7.18.10", "@babel/generator@^7.6.0", "@babel/generator@^7.9.0": version "7.18.10" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.10.tgz#794f328bfabdcbaf0ebf9bf91b5b57b61fa77a2a" @@ -119,6 +116,16 @@ "@jridgewell/gen-mapping" "^0.3.2" jsesc "^2.5.1" +"@babel/generator@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420" + integrity sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g== + dependencies: + "@babel/types" "^7.23.0" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + "@babel/generator@^7.4.0": version "7.4.0" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.4.0.tgz#c230e79589ae7a729fd4631b9ded4dc220418196" @@ -208,6 +215,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + "@babel/helper-explode-assignable-expression@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz#41f8228ef0a6f1a036b8dfdfec7ce94f9a6bc096" @@ -215,15 +227,6 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-function-name@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" - integrity sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw== - dependencies: - "@babel/helper-get-function-arity" "^7.0.0" - "@babel/template" "^7.1.0" - "@babel/types" "^7.0.0" - "@babel/helper-function-name@^7.18.9": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz#940e6084a55dee867d33b4e487da2676365e86b0" @@ -232,12 +235,13 @@ "@babel/template" "^7.18.6" "@babel/types" "^7.18.9" -"@babel/helper-get-function-arity@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" - integrity sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ== +"@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== dependencies: - "@babel/types" "^7.0.0" + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" "@babel/helper-hoist-variables@^7.18.6": version "7.18.6" @@ -246,6 +250,13 @@ dependencies: "@babel/types" "^7.18.6" +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + "@babel/helper-member-expression-to-functions@^7.18.9": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz#1531661e8375af843ad37ac692c132841e2fd815" @@ -326,13 +337,6 @@ dependencies: "@babel/types" "^7.18.9" -"@babel/helper-split-export-declaration@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz#3aae285c0311c2ab095d997b8c9a94cad547d813" - integrity sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag== - dependencies: - "@babel/types" "^7.0.0" - "@babel/helper-split-export-declaration@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" @@ -340,23 +344,33 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-split-export-declaration@^7.4.0": - version "7.4.0" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.0.tgz#571bfd52701f492920d63b7f735030e9a3e10b55" - integrity sha512-7Cuc6JZiYShaZnybDmfwhY4UYHzI6rlqhWjaIqbsJGsIqPimEYy5uh3akSRLMg65LSdSEnJ8a8/bWQN6u2oMGw== +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== dependencies: - "@babel/types" "^7.4.0" + "@babel/types" "^7.22.5" "@babel/helper-string-parser@^7.18.10": version "7.18.10" resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz#181f22d28ebe1b3857fa575f5c290b1aaf659b56" integrity sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw== +"@babel/helper-string-parser@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" + integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== + "@babel/helper-validator-identifier@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + "@babel/helper-validator-option@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" @@ -399,7 +413,16 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.2", "@babel/parser@^7.1.3": +"@babel/highlight@^7.22.13": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" + integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" + js-tokens "^4.0.0" + +"@babel/parser@^7.0.0": version "7.1.3" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.3.tgz#2c92469bac2b7fbff810b67fca07bd138b48af77" integrity sha512-gqmspPZOMW3MIRb9HlrnbZHXI1/KHTOroBwN1NcLL6pWxzqzEKGvRTq0W/PxS45OtQGbaFikSQpkS5zbnsQm2w== @@ -409,6 +432,11 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.10.tgz#94b5f8522356e69e8277276adf67ed280c90ecc1" integrity sha512-TYk3OA0HKL6qNryUayb5UUEhM/rkOQozIBEA5ITXh5DWrSp0TlUQXMyZmnWxG/DizSWBeeQ0Zbc5z8UGaaqoeg== +"@babel/parser@^7.22.15", "@babel/parser@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" + integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== + "@babel/parser@^7.4.0", "@babel/parser@^7.4.3": version "7.4.3" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.4.3.tgz#eb3ac80f64aa101c907d4ce5406360fe75b7895b" @@ -1308,15 +1336,6 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.1.0": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.1.2.tgz#090484a574fef5a2d2d7726a674eceda5c5b5644" - integrity sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.1.2" - "@babel/types" "^7.1.2" - "@babel/template@^7.18.10", "@babel/template@^7.18.6", "@babel/template@^7.6.0", "@babel/template@^7.8.6": version "7.18.10" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" @@ -1326,6 +1345,15 @@ "@babel/parser" "^7.18.10" "@babel/types" "^7.18.10" +"@babel/template@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" + integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/parser" "^7.22.15" + "@babel/types" "^7.22.15" + "@babel/template@^7.4.0": version "7.4.0" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.0.tgz#12474e9c077bae585c5d835a95c0b0b790c25c8b" @@ -1335,53 +1363,23 @@ "@babel/parser" "^7.4.0" "@babel/types" "^7.4.0" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0": - version "7.1.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.1.4.tgz#f4f83b93d649b4b2c91121a9087fa2fa949ec2b4" - integrity sha512-my9mdrAIGdDiSVBuMjpn/oXYpva0/EZwWL3sm3Wcy/AVWO2eXnsoZruOT9jOGNRXU8KbCIu5zsKnXcAJ6PcV6Q== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.1.3" - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.0.0" - "@babel/parser" "^7.1.3" - "@babel/types" "^7.1.3" - debug "^3.1.0" - globals "^11.1.0" - lodash "^4.17.10" - -"@babel/traverse@^7.18.10", "@babel/traverse@^7.18.9", "@babel/traverse@^7.6.0", "@babel/traverse@^7.9.0": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.10.tgz#37ad97d1cb00efa869b91dd5d1950f8a6cf0cb08" - integrity sha512-J7ycxg0/K9XCtLyHf0cz2DqDihonJeIo+z+HEdRe9YuT8TY4A66i+Ab2/xZCEW7Ro60bPCBBfqqboHSamoV3+g== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.18.10" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.18.9" - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.18.10" - "@babel/types" "^7.18.10" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/traverse@^7.4.3": - version "7.4.3" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.4.3.tgz#1a01f078fc575d589ff30c0f71bf3c3d9ccbad84" - integrity sha512-HmA01qrtaCwwJWpSKpA948cBvU5BrmviAief/b3AVw936DtcdsTexlbyzNuDnthwhOQ37xshn7hvQaEQk7ISYQ== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.4.0" - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.4.0" - "@babel/parser" "^7.4.3" - "@babel/types" "^7.4.0" +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.18.10", "@babel/traverse@^7.18.9", "@babel/traverse@^7.4.3", "@babel/traverse@^7.6.0", "@babel/traverse@^7.9.0": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8" + integrity sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/generator" "^7.23.0" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.23.0" + "@babel/types" "^7.23.0" debug "^4.1.0" globals "^11.1.0" - lodash "^4.17.11" -"@babel/types@^7.0.0", "@babel/types@^7.1.2", "@babel/types@^7.1.3": +"@babel/types@^7.0.0": version "7.1.3" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.1.3.tgz#3a767004567060c2f40fca49a304712c525ee37d" integrity sha512-RpPOVfK+yatXyn8n4PB1NW6k9qjinrXrRR8ugBN8fD6hCy5RXI6PSbVqpOJBO9oSaY7Nom4ohj35feb0UR9hSA== @@ -1399,6 +1397,15 @@ "@babel/helper-validator-identifier" "^7.18.6" to-fast-properties "^2.0.0" +"@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb" + integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg== + dependencies: + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + "@babel/types@^7.4.0": version "7.4.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.4.0.tgz#670724f77d24cce6cc7d8cf64599d511d164894c" @@ -1737,6 +1744,11 @@ resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + "@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" @@ -1747,6 +1759,19 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== +"@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@^0.3.17": + version "0.3.20" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" + integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + "@jridgewell/trace-mapping@^0.3.9": version "0.3.14" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" @@ -4097,7 +4122,7 @@ debug@=3.1.0: dependencies: ms "2.0.0" -debug@^3.1.0, debug@^3.2.5, debug@^3.2.7: +debug@^3.2.5, debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== diff --git a/packages/react/examples/react-router/.yarn/install-state.gz b/packages/react/examples/react-router/.yarn/install-state.gz index 0eda591e4966..ef90e9c22e34 100644 Binary files a/packages/react/examples/react-router/.yarn/install-state.gz and b/packages/react/examples/react-router/.yarn/install-state.gz differ diff --git a/packages/react/examples/react-router/yarn.lock b/packages/react/examples/react-router/yarn.lock index 1a17d83954b8..ecc1850458e0 100644 --- a/packages/react/examples/react-router/yarn.lock +++ b/packages/react/examples/react-router/yarn.lock @@ -41,6 +41,16 @@ __metadata: languageName: node linkType: hard +"@babel/code-frame@npm:^7.22.13": + version: 7.22.13 + resolution: "@babel/code-frame@npm:7.22.13" + dependencies: + "@babel/highlight": ^7.22.13 + chalk: ^2.4.2 + checksum: 22e342c8077c8b77eeb11f554ecca2ba14153f707b85294fcf6070b6f6150aae88a7b7436dd88d8c9289970585f3fe5b9b941c5aa3aa26a6d5a8ef3f292da058 + languageName: node + linkType: hard + "@babel/compat-data@npm:^7.12.1, @babel/compat-data@npm:^7.13.11, @babel/compat-data@npm:^7.14.5, @babel/compat-data@npm:^7.14.7": version: 7.14.7 resolution: "@babel/compat-data@npm:7.14.7" @@ -106,14 +116,15 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.20.7": - version: 7.20.7 - resolution: "@babel/generator@npm:7.20.7" +"@babel/generator@npm:^7.23.0": + version: 7.23.0 + resolution: "@babel/generator@npm:7.23.0" dependencies: - "@babel/types": ^7.20.7 + "@babel/types": ^7.23.0 "@jridgewell/gen-mapping": ^0.3.2 + "@jridgewell/trace-mapping": ^0.3.17 jsesc: ^2.5.1 - checksum: 84b6983ffdb50c80c1c2e3f3c32617a7133d8effd1065f3e0f9bba188a7d54ab42a4dd5e42b61b843c65f9dd1aa870036ff0f848ebd42707aaa8a2b6d31d04f5 + checksum: 8efe24adad34300f1f8ea2add420b28171a646edc70f2a1b3e1683842f23b8b7ffa7e35ef0119294e1901f45bfea5b3dc70abe1f10a1917ccdfb41bed69be5f1 languageName: node linkType: hard @@ -230,6 +241,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-environment-visitor@npm:^7.22.20": + version: 7.22.20 + resolution: "@babel/helper-environment-visitor@npm:7.22.20" + checksum: d80ee98ff66f41e233f36ca1921774c37e88a803b2f7dca3db7c057a5fea0473804db9fb6729e5dbfd07f4bed722d60f7852035c2c739382e84c335661590b69 + languageName: node + linkType: hard + "@babel/helper-explode-assignable-expression@npm:^7.14.5": version: 7.14.5 resolution: "@babel/helper-explode-assignable-expression@npm:7.14.5" @@ -260,6 +278,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-function-name@npm:^7.23.0": + version: 7.23.0 + resolution: "@babel/helper-function-name@npm:7.23.0" + dependencies: + "@babel/template": ^7.22.15 + "@babel/types": ^7.23.0 + checksum: e44542257b2d4634a1f979244eb2a4ad8e6d75eb6761b4cfceb56b562f7db150d134bc538c8e6adca3783e3bc31be949071527aa8e3aab7867d1ad2d84a26e10 + languageName: node + linkType: hard + "@babel/helper-get-function-arity@npm:^7.14.5": version: 7.14.5 resolution: "@babel/helper-get-function-arity@npm:7.14.5" @@ -278,12 +306,12 @@ __metadata: languageName: node linkType: hard -"@babel/helper-hoist-variables@npm:^7.18.6": - version: 7.18.6 - resolution: "@babel/helper-hoist-variables@npm:7.18.6" +"@babel/helper-hoist-variables@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-hoist-variables@npm:7.22.5" dependencies: - "@babel/types": ^7.18.6 - checksum: fd9c35bb435fda802bf9ff7b6f2df06308a21277c6dec2120a35b09f9de68f68a33972e2c15505c1a1a04b36ec64c9ace97d4a9e26d6097b76b4396b7c5fa20f + "@babel/types": ^7.22.5 + checksum: 394ca191b4ac908a76e7c50ab52102669efe3a1c277033e49467913c7ed6f7c64d7eacbeabf3bed39ea1f41731e22993f763b1edce0f74ff8563fd1f380d92cc languageName: node linkType: hard @@ -444,6 +472,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-split-export-declaration@npm:^7.22.6": + version: 7.22.6 + resolution: "@babel/helper-split-export-declaration@npm:7.22.6" + dependencies: + "@babel/types": ^7.22.5 + checksum: e141cace583b19d9195f9c2b8e17a3ae913b7ee9b8120246d0f9ca349ca6f03cb2c001fd5ec57488c544347c0bb584afec66c936511e447fd20a360e591ac921 + languageName: node + linkType: hard + "@babel/helper-string-parser@npm:^7.19.4": version: 7.19.4 resolution: "@babel/helper-string-parser@npm:7.19.4" @@ -451,6 +488,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-string-parser@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-string-parser@npm:7.22.5" + checksum: 836851ca5ec813077bbb303acc992d75a360267aa3b5de7134d220411c852a6f17de7c0d0b8c8dcc0f567f67874c00f4528672b2a4f1bc978a3ada64c8c78467 + languageName: node + linkType: hard + "@babel/helper-validator-identifier@npm:^7.14.5": version: 7.14.5 resolution: "@babel/helper-validator-identifier@npm:7.14.5" @@ -465,6 +509,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-identifier@npm:^7.22.20": + version: 7.22.20 + resolution: "@babel/helper-validator-identifier@npm:7.22.20" + checksum: 136412784d9428266bcdd4d91c32bcf9ff0e8d25534a9d94b044f77fe76bc50f941a90319b05aafd1ec04f7d127cd57a179a3716009ff7f3412ef835ada95bdc + languageName: node + linkType: hard + "@babel/helper-validator-option@npm:^7.12.1, @babel/helper-validator-option@npm:^7.14.5": version: 7.14.5 resolution: "@babel/helper-validator-option@npm:7.14.5" @@ -517,7 +568,18 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.12.3, @babel/parser@npm:^7.12.5, @babel/parser@npm:^7.14.5, @babel/parser@npm:^7.14.6, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.7.0": +"@babel/highlight@npm:^7.22.13": + version: 7.22.20 + resolution: "@babel/highlight@npm:7.22.20" + dependencies: + "@babel/helper-validator-identifier": ^7.22.20 + chalk: ^2.4.2 + js-tokens: ^4.0.0 + checksum: 84bd034dca309a5e680083cd827a766780ca63cef37308404f17653d32366ea76262bd2364b2d38776232f2d01b649f26721417d507e8b4b6da3e4e739f6d134 + languageName: node + linkType: hard + +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.12.3, @babel/parser@npm:^7.12.5, @babel/parser@npm:^7.14.5, @babel/parser@npm:^7.14.6, @babel/parser@npm:^7.7.0": version: 7.14.7 resolution: "@babel/parser@npm:7.14.7" bin: @@ -535,6 +597,15 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.22.15, @babel/parser@npm:^7.23.0": + version: 7.23.0 + resolution: "@babel/parser@npm:7.23.0" + bin: + parser: ./bin/babel-parser.js + checksum: 453fdf8b9e2c2b7d7b02139e0ce003d1af21947bbc03eb350fb248ee335c9b85e4ab41697ddbdd97079698de825a265e45a0846bb2ed47a2c7c1df833f42a354 + languageName: node + linkType: hard + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.14.5": version: 7.14.5 resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.14.5" @@ -1809,38 +1880,32 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.1.0, @babel/traverse@npm:^7.12.1, @babel/traverse@npm:^7.12.5, @babel/traverse@npm:^7.13.0, @babel/traverse@npm:^7.14.5, @babel/traverse@npm:^7.7.0": - version: 7.14.7 - resolution: "@babel/traverse@npm:7.14.7" +"@babel/template@npm:^7.22.15": + version: 7.22.15 + resolution: "@babel/template@npm:7.22.15" dependencies: - "@babel/code-frame": ^7.14.5 - "@babel/generator": ^7.14.5 - "@babel/helper-function-name": ^7.14.5 - "@babel/helper-hoist-variables": ^7.14.5 - "@babel/helper-split-export-declaration": ^7.14.5 - "@babel/parser": ^7.14.7 - "@babel/types": ^7.14.5 - debug: ^4.1.0 - globals: ^11.1.0 - checksum: 11e9162e46bdd6daef8691facbf5c47838f6e312ac775be35c40353c77887338d1b9ce497211d2ae96628a9230551f03eb3df49b4ca53b6f668082f2c157d1a0 + "@babel/code-frame": ^7.22.13 + "@babel/parser": ^7.22.15 + "@babel/types": ^7.22.15 + checksum: 1f3e7dcd6c44f5904c184b3f7fe280394b191f2fed819919ffa1e529c259d5b197da8981b6ca491c235aee8dbad4a50b7e31304aa531271cb823a4a24a0dd8fd languageName: node linkType: hard -"@babel/traverse@npm:^7.20.7": - version: 7.20.12 - resolution: "@babel/traverse@npm:7.20.12" +"@babel/traverse@npm:^7.1.0, @babel/traverse@npm:^7.12.1, @babel/traverse@npm:^7.12.5, @babel/traverse@npm:^7.13.0, @babel/traverse@npm:^7.14.5, @babel/traverse@npm:^7.20.7, @babel/traverse@npm:^7.7.0": + version: 7.23.2 + resolution: "@babel/traverse@npm:7.23.2" dependencies: - "@babel/code-frame": ^7.18.6 - "@babel/generator": ^7.20.7 - "@babel/helper-environment-visitor": ^7.18.9 - "@babel/helper-function-name": ^7.19.0 - "@babel/helper-hoist-variables": ^7.18.6 - "@babel/helper-split-export-declaration": ^7.18.6 - "@babel/parser": ^7.20.7 - "@babel/types": ^7.20.7 + "@babel/code-frame": ^7.22.13 + "@babel/generator": ^7.23.0 + "@babel/helper-environment-visitor": ^7.22.20 + "@babel/helper-function-name": ^7.23.0 + "@babel/helper-hoist-variables": ^7.22.5 + "@babel/helper-split-export-declaration": ^7.22.6 + "@babel/parser": ^7.23.0 + "@babel/types": ^7.23.0 debug: ^4.1.0 globals: ^11.1.0 - checksum: d758b355ab4f1e87984524b67785fa23d74e8a45d2ceb8bcf4d5b2b0cd15ee160db5e68c7078808542805774ca3802e2eafb1b9638afa4cd7f9ecabd0ca7fd56 + checksum: 26a1eea0dde41ab99dde8b9773a013a0dc50324e5110a049f5d634e721ff08afffd54940b3974a20308d7952085ac769689369e9127dea655f868c0f6e1ab35d languageName: node linkType: hard @@ -1865,6 +1930,17 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.22.15, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0": + version: 7.23.0 + resolution: "@babel/types@npm:7.23.0" + dependencies: + "@babel/helper-string-parser": ^7.22.5 + "@babel/helper-validator-identifier": ^7.22.20 + to-fast-properties: ^2.0.0 + checksum: 215fe04bd7feef79eeb4d33374b39909ce9cad1611c4135a4f7fdf41fe3280594105af6d7094354751514625ea92d0875aba355f53e86a92600f290e77b0e604 + languageName: node + linkType: hard + "@bcoe/v8-coverage@npm:^0.2.3": version: 0.2.3 resolution: "@bcoe/v8-coverage@npm:0.2.3" @@ -2248,6 +2324,13 @@ __metadata: languageName: node linkType: hard +"@jridgewell/resolve-uri@npm:^3.1.0": + version: 3.1.1 + resolution: "@jridgewell/resolve-uri@npm:3.1.1" + checksum: f5b441fe7900eab4f9155b3b93f9800a916257f4e8563afbcd3b5a5337b55e52bd8ae6735453b1b745457d9f6cdb16d74cd6220bbdd98cf153239e13f6cbb653 + languageName: node + linkType: hard + "@jridgewell/set-array@npm:^1.0.1": version: 1.1.2 resolution: "@jridgewell/set-array@npm:1.1.2" @@ -2262,6 +2345,23 @@ __metadata: languageName: node linkType: hard +"@jridgewell/sourcemap-codec@npm:^1.4.14": + version: 1.4.15 + resolution: "@jridgewell/sourcemap-codec@npm:1.4.15" + checksum: b881c7e503db3fc7f3c1f35a1dd2655a188cc51a3612d76efc8a6eb74728bef5606e6758ee77423e564092b4a518aba569bbb21c9bac5ab7a35b0c6ae7e344c8 + languageName: node + linkType: hard + +"@jridgewell/trace-mapping@npm:^0.3.17": + version: 0.3.20 + resolution: "@jridgewell/trace-mapping@npm:0.3.20" + dependencies: + "@jridgewell/resolve-uri": ^3.1.0 + "@jridgewell/sourcemap-codec": ^1.4.14 + checksum: cd1a7353135f385909468ff0cf20bdd37e59f2ee49a13a966dedf921943e222082c583ade2b579ff6cd0d8faafcb5461f253e1bf2a9f48fec439211fdbe788f5 + languageName: node + linkType: hard + "@jridgewell/trace-mapping@npm:^0.3.9": version: 0.3.17 resolution: "@jridgewell/trace-mapping@npm:0.3.17" diff --git a/packages/react/src/components/Breadcrumb/Breadcrumb.Skeleton.js b/packages/react/src/components/Breadcrumb/Breadcrumb.Skeleton.tsx similarity index 78% rename from packages/react/src/components/Breadcrumb/Breadcrumb.Skeleton.js rename to packages/react/src/components/Breadcrumb/Breadcrumb.Skeleton.tsx index 75980d815ae8..2e1540405ff1 100644 --- a/packages/react/src/components/Breadcrumb/Breadcrumb.Skeleton.js +++ b/packages/react/src/components/Breadcrumb/Breadcrumb.Skeleton.tsx @@ -10,6 +10,14 @@ import React from 'react'; import cx from 'classnames'; import { usePrefix } from '../../internal/usePrefix'; +export interface BreadcrumbSkeletonProps + extends React.HTMLAttributes { + /** + * Specify an optional className to add. + */ + className?: string; +} + function Item() { const prefix = usePrefix(); @@ -20,7 +28,7 @@ function Item() { ); } -function BreadcrumbSkeleton({ className, ...rest }) { +function BreadcrumbSkeleton({ className, ...rest }: BreadcrumbSkeletonProps) { const prefix = usePrefix(); const classes = cx(`${prefix}--breadcrumb`, `${prefix}--skeleton`, className); diff --git a/packages/react/src/components/Breadcrumb/Breadcrumb.js b/packages/react/src/components/Breadcrumb/Breadcrumb.js deleted file mode 100644 index 0aeafe22b21c..000000000000 --- a/packages/react/src/components/Breadcrumb/Breadcrumb.js +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright IBM Corp. 2016, 2023 - * - * 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 PropTypes from 'prop-types'; -import React from 'react'; -import cx from 'classnames'; -import { usePrefix } from '../../internal/usePrefix'; - -const Breadcrumb = React.forwardRef(function Breadcrumb( - { - 'aria-label': ariaLabel, - children, - className: customClassNameNav, - noTrailingSlash, - ...rest - }, - ref -) { - const prefix = usePrefix(); - const className = cx({ - [`${prefix}--breadcrumb`]: true, - [`${prefix}--breadcrumb--no-trailing-slash`]: noTrailingSlash, - }); - - return ( - - ); -}); - -Breadcrumb.displayName = 'Breadcrumb'; -Breadcrumb.propTypes = { - /** - * Specify the label for the breadcrumb container - */ - 'aria-label': PropTypes.string, - - /** - * Pass in the BreadcrumbItem's for your Breadcrumb - */ - children: PropTypes.node, - - /** - * Specify an optional className to be applied to the container node - */ - className: PropTypes.string, - - /** - * Optional prop to omit the trailing slash for the breadcrumbs - */ - noTrailingSlash: PropTypes.bool, -}; - -export default Breadcrumb; diff --git a/packages/react/src/components/Breadcrumb/Breadcrumb.tsx b/packages/react/src/components/Breadcrumb/Breadcrumb.tsx new file mode 100644 index 000000000000..7b1e11a76919 --- /dev/null +++ b/packages/react/src/components/Breadcrumb/Breadcrumb.tsx @@ -0,0 +1,82 @@ +/** + * Copyright IBM Corp. 2016, 2023 + * + * 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 PropTypes from 'prop-types'; +import React, { PropsWithChildren } from 'react'; +import cx from 'classnames'; +import { usePrefix } from '../../internal/usePrefix'; +import { ForwardRefReturn } from '../../types/common'; + +export interface BreadcrumbProps extends React.HTMLAttributes { + /** + * Specify the label for the breadcrumb container + */ + 'aria-label'?: string; + + /** + * Specify an optional className to be applied to the container node + */ + className?: string; + + /** + * Optional prop to omit the trailing slash for the breadcrumbs + */ + noTrailingSlash?: boolean; +} + +const Breadcrumb: ForwardRefReturn = + React.forwardRef(function Breadcrumb( + { + 'aria-label': ariaLabel, + children, + className: customClassNameNav, + noTrailingSlash, + ...rest + }: PropsWithChildren, + ref: React.Ref + ) { + const prefix = usePrefix(); + const className = cx({ + [`${prefix}--breadcrumb`]: true, + [`${prefix}--breadcrumb--no-trailing-slash`]: noTrailingSlash, + }); + + return ( + + ); + }); + +Breadcrumb.displayName = 'Breadcrumb'; +Breadcrumb.propTypes = { + /** + * Specify the label for the breadcrumb container + */ + 'aria-label': PropTypes.string, + + /** + * Pass in the BreadcrumbItem's for your Breadcrumb + */ + children: PropTypes.node, + + /** + * Specify an optional className to be applied to the container node + */ + className: PropTypes.string, + + /** + * Optional prop to omit the trailing slash for the breadcrumbs + */ + noTrailingSlash: PropTypes.bool, +}; + +export default Breadcrumb; diff --git a/packages/react/src/components/Breadcrumb/BreadcrumbItem.js b/packages/react/src/components/Breadcrumb/BreadcrumbItem.js deleted file mode 100644 index 18b3e8eb960e..000000000000 --- a/packages/react/src/components/Breadcrumb/BreadcrumbItem.js +++ /dev/null @@ -1,106 +0,0 @@ -/** - * Copyright IBM Corp. 2016, 2023 - * - * 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 PropTypes from 'prop-types'; -import React from 'react'; -import cx from 'classnames'; -import Link from '../Link'; -import { OverflowMenuHorizontal } from '@carbon/icons-react'; -import { usePrefix } from '../../internal/usePrefix'; -import { Text } from '../Text'; - -const BreadcrumbItem = React.forwardRef(function BreadcrumbItem( - { - 'aria-current': ariaCurrent, - children, - className: customClassName, - href, - isCurrentPage, - ...rest - }, - ref -) { - const prefix = usePrefix(); - const className = cx({ - [`${prefix}--breadcrumb-item`]: true, - // We set the current class only if `isCurrentPage` is passed in and we do - // not have an `aria-current="page"` set for the breadcrumb item - [`${prefix}--breadcrumb-item--current`]: - isCurrentPage && ariaCurrent !== 'page', - [customClassName]: !!customClassName, - }); - - if ( - children.type && - children.type.displayName !== undefined && - children.type.displayName.includes('OverflowMenu') - ) { - const horizontalOverflowIcon = ( - - ); - return ( -
  • - {React.cloneElement(children, { - menuOptionsClass: `${prefix}--breadcrumb-menu-options`, - menuOffset: { top: 10, left: 59 }, - renderIcon: () => horizontalOverflowIcon, - })} -
  • - ); - } - - if (typeof children === 'string') { - return ( -
  • - {href ? ( - - {children} - - ) : ( - {children} - )} -
  • - ); - } - - return ( -
  • - {React.cloneElement(children, { - 'aria-current': ariaCurrent, - className: cx(`${prefix}--link`, children.props.className), - })} -
  • - ); -}); - -BreadcrumbItem.displayName = 'BreadcrumbItem'; - -BreadcrumbItem.propTypes = { - 'aria-current': PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), - - /** - * Pass in content that will be inside of the BreadcrumbItem - */ - children: PropTypes.node, - - /** - * Specify an optional className to be applied to the container node - */ - className: PropTypes.string, - - /** - * Optional string representing the link location for the BreadcrumbItem - */ - href: PropTypes.string, - - /** - * Provide if this breadcrumb item represents the current page - */ - isCurrentPage: PropTypes.bool, -}; - -export default BreadcrumbItem; diff --git a/packages/react/src/components/Breadcrumb/BreadcrumbItem.tsx b/packages/react/src/components/Breadcrumb/BreadcrumbItem.tsx new file mode 100644 index 000000000000..f1207286cb17 --- /dev/null +++ b/packages/react/src/components/Breadcrumb/BreadcrumbItem.tsx @@ -0,0 +1,130 @@ +/** + * Copyright IBM Corp. 2016, 2023 + * + * 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 PropTypes from 'prop-types'; +import React, { AriaAttributes, PropsWithChildren } from 'react'; +import cx from 'classnames'; +import Link from '../Link'; +import { OverflowMenuHorizontal } from '@carbon/icons-react'; +import { usePrefix } from '../../internal/usePrefix'; +import { ForwardRefReturn } from '../../types/common'; +import { Text } from '../Text'; + +export interface BreadcrumbItemProps + extends React.HTMLAttributes { + 'aria-current'?: AriaAttributes['aria-current']; + + /** + * Specify an optional className to be applied to the container node + */ + className?: string; + + /** + * Optional string representing the link location for the BreadcrumbItem + */ + href?: string; + + /** + * Provide if this breadcrumb item represents the current page + */ + isCurrentPage?: boolean; +} + +const BreadcrumbItem: ForwardRefReturn = + React.forwardRef(function BreadcrumbItem( + { + 'aria-current': ariaCurrent, + children, + className: customClassName = '', + href, + isCurrentPage, + ...rest + }: PropsWithChildren, + ref: React.Ref + ) { + const prefix = usePrefix(); + const className = cx({ + [`${prefix}--breadcrumb-item`]: true, + // We set the current class only if `isCurrentPage` is passed in and we do + // not have an `aria-current="page"` set for the breadcrumb item + [`${prefix}--breadcrumb-item--current`]: + isCurrentPage && ariaCurrent !== 'page', + [customClassName]: !!customClassName, + }); + + const child = children as React.FunctionComponentElement; + if ( + child.type && + child.type.displayName !== undefined && + child.type.displayName.includes('OverflowMenu') + ) { + const horizontalOverflowIcon = ( + + ); + return ( +
  • + {React.cloneElement(child, { + menuOptionsClass: `${prefix}--breadcrumb-menu-options`, + menuOffset: { top: 10, left: 59 }, + renderIcon: () => horizontalOverflowIcon, + })} +
  • + ); + } + + if (typeof children === 'string') { + return ( +
  • + {href ? ( + + {children} + + ) : ( + {children} + )} +
  • + ); + } + + return ( +
  • + {React.cloneElement(child, { + 'aria-current': ariaCurrent, + className: cx(`${prefix}--link`, child.props.className), + })} +
  • + ); + }); + +BreadcrumbItem.displayName = 'BreadcrumbItem'; + +BreadcrumbItem.propTypes = { + // @ts-expect-error - v12 TODO: BREAKING: This should match AriaAttributes['aria-current'] + 'aria-current': PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), + + /** + * Pass in content that will be inside of the BreadcrumbItem + */ + children: PropTypes.node, + + /** + * Specify an optional className to be applied to the container node + */ + className: PropTypes.string, + + /** + * Optional string representing the link location for the BreadcrumbItem + */ + href: PropTypes.string, + + /** + * Provide if this breadcrumb item represents the current page + */ + isCurrentPage: PropTypes.bool, +}; + +export default BreadcrumbItem; diff --git a/packages/react/src/components/ComboBox/ComboBox-test.js b/packages/react/src/components/ComboBox/ComboBox-test.js index 36e0d8ee8374..dca836a0b8c8 100644 --- a/packages/react/src/components/ComboBox/ComboBox-test.js +++ b/packages/react/src/components/ComboBox/ComboBox-test.js @@ -101,6 +101,21 @@ describe('ComboBox', () => { }); }); + it('should retain value if custom value is entered and `allowCustomValue` is set', async () => { + render(); + + expect(findInputNode()).toHaveDisplayValue(''); + + await userEvent.type(findInputNode(), 'Apple'); + // Should close menu and keep value in input, even though it is not in the item list + await userEvent.keyboard('[Enter]'); + assertMenuClosed(); + expect(findInputNode()).toHaveDisplayValue('Apple'); + // Should retain value on blur + await userEvent.keyboard('[Tab]'); + expect(findInputNode()).toHaveDisplayValue('Apple'); + }); + describe('should display initially selected item found in `initialSelectedItem`', () => { it('using an object type for the `initialSelectedItem` prop', () => { render( diff --git a/packages/react/src/components/ComboBox/ComboBox.mdx b/packages/react/src/components/ComboBox/ComboBox.mdx index 956c9dcacdcf..06fae50fa306 100644 --- a/packages/react/src/components/ComboBox/ComboBox.mdx +++ b/packages/react/src/components/ComboBox/ComboBox.mdx @@ -21,6 +21,7 @@ import ComboBox from '../ComboBox'; - [itemToElement](#itemtoelement) - [itemToString](#itemtostring) - [shouldFilterItem](#shouldfilteritem) +- [allowCustomValue](#allowcustomvalue) - [With Layer](#with-layer) - [Feedback](#feedback) @@ -147,6 +148,19 @@ const filterItems = (menu) => { />; ``` +## `allowCustomValue` + +By default, if text is entered into the `Combobox` and it does not match an +item, it will be cleared on blur. However, you can change this behavior by +passing in the `allowCustomValue` prop. This will allow a user to close the menu +and accept a custom value by pressing `Enter` as well as retain the value on +blur. The `inputValue` is provided as a second argument to the `onChange` +callback. + +```js +{selectedItem: undefined, inputValue: 'Apple'} +``` + ## With Layer diff --git a/packages/react/src/components/ComboBox/ComboBox.stories.js b/packages/react/src/components/ComboBox/ComboBox.stories.js index dc6197a1d912..b987255bf215 100644 --- a/packages/react/src/components/ComboBox/ComboBox.stories.js +++ b/packages/react/src/components/ComboBox/ComboBox.stories.js @@ -79,6 +79,32 @@ export const Default = () => ( ); +export const AllowCustomValue = () => { + const filterItems = (menu) => { + return menu?.item?.toLowerCase().includes(menu?.inputValue?.toLowerCase()); + }; + return ( +
    + { + console.log(e); + }} + id="carbon-combobox" + items={['Apple', 'Orange', 'Banana', 'Pineapple', 'Raspberry', 'Lime']} + downshiftProps={{ + onStateChange: () => { + console.log('the state has changed'); + }, + }} + titleText="ComboBox title" + helperText="Combobox helper text" + /> +
    + ); +}; + export const _WithLayer = () => ( {(layer) => ( diff --git a/packages/react/src/components/ComboBox/ComboBox.tsx b/packages/react/src/components/ComboBox/ComboBox.tsx index 61914df39043..00060d69c922 100644 --- a/packages/react/src/components/ComboBox/ComboBox.tsx +++ b/packages/react/src/components/ComboBox/ComboBox.tsx @@ -55,6 +55,7 @@ const { clickButton, blurButton, changeInput, + blurInput, } = Downshift.stateChangeTypes; const defaultItemToString = (item: ItemType | null) => { @@ -127,13 +128,20 @@ const getInstanceId = setupGetInstanceId(); type ExcludedAttributes = 'id' | 'onChange' | 'onClick' | 'type' | 'size'; interface OnChangeData { - selectedItem: ItemType | null; + selectedItem: ItemType | null | undefined; + inputValue?: string | null; } type ItemToStringHandler = (item: ItemType | null) => string; export interface ComboBoxProps extends Omit, ExcludedAttributes> { + /** + * Specify whether or not the ComboBox should allow a value that is + * not in the list to be entered in the input + */ + allowCustomValue?: boolean; + /** * Specify a label to be read by screen readers on the container node * 'aria-label' of the ListBox component. @@ -329,6 +337,7 @@ const ComboBox = forwardRef( translateWithId, warn, warnText, + allowCustomValue = false, ...rest } = props; const prefix = usePrefix(); @@ -447,6 +456,14 @@ const ComboBox = forwardRef( case changeInput: updateHighlightedIndex(getHighlightedIndex(changes)); break; + case blurInput: + if (allowCustomValue) { + setInputValue(inputValue); + if (onChange) { + onChange({ selectedItem, inputValue }); + } + } + break; } }; @@ -571,8 +588,18 @@ const ComboBox = forwardRef( event.stopPropagation(); } - if (match(event, keys.Enter) && !inputValue) { + if ( + match(event, keys.Enter) && + (!inputValue || allowCustomValue) + ) { toggleMenu(); + + // Since `onChange` does not normally fire when the menu is closed, we should + // manually fire it when `allowCustomValue` is provided, the menu is closing, + // and there is a value. + if (allowCustomValue && isOpen && inputValue) { + onChange({ selectedItem, inputValue }); + } } if (match(event, keys.Escape) && inputValue) { @@ -744,6 +771,12 @@ const ComboBox = forwardRef( ComboBox.displayName = 'ComboBox'; ComboBox.propTypes = { + /** + * Specify whether or not the ComboBox should allow a value that is + * not in the list to be entered in the input + */ + allowCustomValue: PropTypes.bool, + /** * 'aria-label' of the ListBox component. * Specify a label to be read by screen readers on the container node diff --git a/packages/react/src/components/ContentSwitcher/ContentSwitcher.tsx b/packages/react/src/components/ContentSwitcher/ContentSwitcher.tsx index 3f3129543476..384b978973d2 100644 --- a/packages/react/src/components/ContentSwitcher/ContentSwitcher.tsx +++ b/packages/react/src/components/ContentSwitcher/ContentSwitcher.tsx @@ -56,7 +56,7 @@ export interface ContentSwitcherProps /** * Choose whether or not to automatically change selection on focus */ - selectionMode: 'automatic' | 'manual'; + selectionMode?: 'automatic' | 'manual'; /** * Specify the size of the Content Switcher. Currently supports either `sm`, 'md' (default) or 'lg` as an option. diff --git a/packages/react/src/components/DataTable/TableExpandRow.tsx b/packages/react/src/components/DataTable/TableExpandRow.tsx index 9c2e604a76a6..24356f76cc2f 100644 --- a/packages/react/src/components/DataTable/TableExpandRow.tsx +++ b/packages/react/src/components/DataTable/TableExpandRow.tsx @@ -54,66 +54,73 @@ interface TableExpandRowProps extends PropsWithChildren { onExpand: MouseEventHandler; } -const TableExpandRow = ({ - ['aria-controls']: ariaControls, - ['aria-label']: ariaLabel, - ariaLabel: deprecatedAriaLabel, - className: rowClassName, - children, - isExpanded, - onExpand, - expandIconDescription, - isSelected, - expandHeader = 'expand', - ...rest -}: TableExpandRowProps) => { - const prefix = usePrefix(); - const className = cx( +const TableExpandRow = React.forwardRef( + ( { - [`${prefix}--parent-row`]: true, - [`${prefix}--expandable-row`]: isExpanded, - [`${prefix}--data-table--selected`]: isSelected, - }, - rowClassName - ); - const previousValue = isExpanded ? 'collapsed' : undefined; - - return ( - - - - - {children} - - ); -}; + ['aria-controls']: ariaControls, + ['aria-label']: ariaLabel, + ariaLabel: deprecatedAriaLabel, + className: rowClassName, + children, + isExpanded, + onExpand, + expandIconDescription, + isSelected, + expandHeader = 'expand', + ...rest + }: TableExpandRowProps, + ref: React.Ref + ) => { + const prefix = usePrefix(); + const className = cx( + { + [`${prefix}--parent-row`]: true, + [`${prefix}--expandable-row`]: isExpanded, + [`${prefix}--data-table--selected`]: isSelected, + }, + rowClassName + ); + const previousValue = isExpanded ? 'collapsed' : undefined; + + return ( + + + + + {children} + + ); + } +); TableExpandRow.propTypes = { /** * Space separated list of one or more ID values referencing the TableExpandedRow(s) being controlled by the TableExpandRow * TODO: make this required in v12 */ + /**@ts-ignore*/ ['aria-controls']: PropTypes.string, /** * Specify the string read by a voice reader when the expand trigger is * focused */ + /**@ts-ignore*/ ['aria-label']: PropTypes.string, /** @@ -152,4 +159,5 @@ TableExpandRow.propTypes = { onExpand: PropTypes.func.isRequired, }; +TableExpandRow.displayName = 'TableExpandRow'; export default TableExpandRow; diff --git a/packages/react/src/components/Dropdown/Dropdown.tsx b/packages/react/src/components/Dropdown/Dropdown.tsx index 4284fc96c448..25206b4a6b24 100644 --- a/packages/react/src/components/Dropdown/Dropdown.tsx +++ b/packages/react/src/components/Dropdown/Dropdown.tsx @@ -184,7 +184,9 @@ export interface DropdownProps * An optional callback to render the currently selected item as a react element instead of only * as a string. */ - renderSelectedItem?(item: ItemType): string; + renderSelectedItem?( + item: ItemType + ): React.JSXElementConstructor | null; /** * In the case you want to control the dropdown selection entirely. diff --git a/packages/react/src/components/Slug/Slug.stories.js b/packages/react/src/components/Slug/Slug.stories.js index 5c2c7c4722b4..7a677b3a6dca 100644 --- a/packages/react/src/components/Slug/Slug.stories.js +++ b/packages/react/src/components/Slug/Slug.stories.js @@ -9,8 +9,10 @@ import React from 'react'; -import Slug from '.'; +import { Slug, SlugContent, SlugActions } from '.'; +import { View, FolderOpen, Folders } from '@carbon/icons-react'; import Button from '../Button'; +import { IconButton } from '../IconButton'; import mdx from './Slug.mdx'; import './slug-story.scss'; @@ -44,69 +46,225 @@ const content = AI was used to generate this content; export const Default = () => ( <>
    - - - - - - - + + {aiContent} + + + {aiContent} + + + + {aiContent} + + + + + + + + + + + + + + + + + {aiContent} + + + + + + + + + + + + + + + + + {aiContent} + + + + + + + + + + + + + + + + + {aiContent} + + + + + + + + + + + + + + + + + {aiContent} + + + + + + + + + + + + + +
    - - - + + {content} + + + {content} + + + {content} +
    - - - + + + {aiContent} + + + + + + + + + + + + + + + + + {aiContent} + + + + + + + + + + + + + + + + + {aiContent} + + + + + + + + + + + + + +
    - - - + + + {aiContent} + + + + + + + + + + + + + + + + + {aiContent} + + + + + + + + + + + + + + + + + {aiContent} + + + + + + + + + + + + + +
    - - - + + {content} + + + {content} + + + {content} +
    ( kind="inline" dotType="hollow" size="sm" - aiTextLabel="Text goes here" - slugContent={content} - /> + aiTextLabel="Text goes here"> + {content} + + aiTextLabel="Text goes here"> + {content} + + aiTextLabel="Text goes here"> + {content} +
    ); -export const Playground = (args) => ( - <> -
    - -
    - - - -); +export const Playground = (args) => { + const { kind, dotType, showSlugActions = true } = args; + + let renderedContent; + if (kind === 'hollow' || dotType === 'hollow') { + renderedContent = content; + } else { + renderedContent = ( + <> +
    +

    AI Explained

    +

    84%

    +

    Confidence score

    +

    + Lorem ipsum dolor sit amet, di os consectetur adipiscing elit, sed + do eiusmod tempor incididunt ut fsil labore et dolore magna aliqua. +

    +
    +

    Model type

    +

    Foundation model

    +
    + {showSlugActions && ( + + + + + + + + + + + + + )} + + ); + } + + return ( + <> +
    + + {renderedContent} + +
    + + + + ); +}; + +Playground.argTypes = { + showSlugActions: { + control: { + type: 'boolean', + }, + description: 'Playground only - toggle to show the callout toolbar', + }, +}; diff --git a/packages/react/src/components/Slug/index.js b/packages/react/src/components/Slug/index.js index b93fe751c330..8e4be8cfbb37 100644 --- a/packages/react/src/components/Slug/index.js +++ b/packages/react/src/components/Slug/index.js @@ -4,7 +4,191 @@ * 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 Slug from './Slug'; -export default Slug; -export { Slug }; +import cx from 'classnames'; +import PropTypes from 'prop-types'; +import React from 'react'; + +import { usePrefix } from '../../internal/usePrefix'; +import { + Toggletip, + ToggletipButton, + ToggletipContent, + ToggletipActions, +} from '../Toggletip'; + +export const SlugContent = React.forwardRef(function SlugContent( + { children, className }, + ref +) { + const prefix = usePrefix(); + + const slugContentClasses = cx(className, { + [`${prefix}--slug-content`]: true, + }); + + return ( + + {children} + + ); +}); + +SlugContent.propTypes = { + /** + * Specify the content you want rendered inside the slug ToggleTip + */ + children: PropTypes.node, + + /** + * Specify an optional className to be added to the AI slug callout + */ + className: PropTypes.string, +}; + +export const SlugActions = React.forwardRef(function SlugActions( + { children, className }, + ref +) { + const prefix = usePrefix(); + + const slugActionBarClasses = cx(className, { + [`${prefix}--slug-actions`]: true, + }); + + return ( + + {children} + + ); +}); + +SlugActions.propTypes = { + /** + * Specify the content you want rendered inside the slug callout toolbar + */ + children: PropTypes.node, + + /** + * Specify an optional className to be added to the AI slug toolbar + */ + className: PropTypes.string, +}; + +export const Slug = React.forwardRef(function Slug( + { + aiText = 'AI', + aiTextLabel, + align, + autoAlign = false, + className, + dotType, + kind, + size = 'xs', + children, + }, + ref +) { + const prefix = usePrefix(); + + const slugClasses = cx(className, { + [`${prefix}--slug`]: true, + [`${prefix}--slug--hollow`]: kind === 'hollow' || dotType === 'hollow', + // Need to come up with a better name; explainable? + // Need to be able to target the non-hollow variant another way + // other than using `:not` all over the styles + [`${prefix}--slug--enabled`]: kind !== 'hollow' && dotType !== 'hollow', + }); + + const slugButtonClasses = cx({ + [`${prefix}--slug__button`]: true, + [`${prefix}--slug__button--${size}`]: size, + [`${prefix}--slug__button--${kind}`]: kind, + [`${prefix}--slug__button--inline-with-content`]: + kind === 'inline' && aiTextLabel, + }); + + return ( +
    + + + {aiText} + {aiTextLabel && ( + + {aiTextLabel} + + )} + + {children} + +
    + ); +}); + +Slug.propTypes = { + /** + * Specify the correct translation of the AI text + */ + aiText: PropTypes.string, + + /** + * Specify additional text to be rendered next to the AI label in the inline variant + */ + aiTextLabel: PropTypes.string, + + /** + * Specify how the popover should align with the button + */ + align: PropTypes.oneOf([ + 'top', + 'top-left', + 'top-right', + + 'bottom', + 'bottom-left', + 'bottom-right', + + 'left', + 'left-bottom', + 'left-top', + + 'right', + 'right-bottom', + 'right-top', + ]), + + /** + * Will auto-align the popover on first render if it is not visible. This prop is currently experimental and is subject to future changes. + */ + autoAlign: PropTypes.bool, + + /** + * Specify the content you want rendered inside the slug ToggleTip + */ + children: PropTypes.node, + + /** + * Specify an optional className to be added to the AI slug + */ + className: PropTypes.string, + + /** + * Specify the type of dot that should be rendered in front of the inline variant + */ + dotType: PropTypes.oneOf(['default', 'hollow']), + + /** + * Specify the type of Slug, from the following list of types: + */ + kind: PropTypes.oneOf(['default', 'hollow', 'inline']), + + /** + * Specify the size of the button, from the following list of sizes: + */ + size: PropTypes.oneOf(['mini', '2xs', 'xs', 'sm', 'md', 'lg', 'xl']), + + /** + * Specify the content you want rendered inside the slug ToggleTip + */ + slugContent: PropTypes.node, +}; diff --git a/packages/react/src/components/TreeView/TreeNode.js b/packages/react/src/components/TreeView/TreeNode.js index b29a85c77f15..14852225d747 100644 --- a/packages/react/src/components/TreeView/TreeNode.js +++ b/packages/react/src/components/TreeView/TreeNode.js @@ -13,212 +13,220 @@ import { keys, match, matches } from '../../internal/keyboard'; import uniqueId from '../../tools/uniqueId'; import { usePrefix } from '../../internal/usePrefix'; -export default function TreeNode({ - active, - children, - className, - depth, - disabled, - isExpanded, - label, - onNodeFocusEvent, - onSelect: onNodeSelect, - onToggle, - onTreeSelect, - renderIcon: Icon, - selected, - value, - ...rest -}) { - const { current: id } = useRef(rest.id || uniqueId()); - const [expanded, setExpanded] = useState(isExpanded); - const currentNode = useRef(null); - const currentNodeLabel = useRef(null); - const prefix = usePrefix(); - const nodesWithProps = React.Children.map(children, (node) => { - if (React.isValidElement(node)) { - return React.cloneElement(node, { - active, - depth: depth + 1, - disabled, - onTreeSelect, - selected, - tabIndex: (!node.props.disabled && -1) || null, - }); - } - }); - const isActive = active === id; - const isSelected = selected.includes(id); - const treeNodeClasses = classNames(className, `${prefix}--tree-node`, { - [`${prefix}--tree-node--active`]: isActive, - [`${prefix}--tree-node--disabled`]: disabled, - [`${prefix}--tree-node--selected`]: isSelected, - [`${prefix}--tree-node--with-icon`]: Icon, - [`${prefix}--tree-leaf-node`]: !children, - [`${prefix}--tree-parent-node`]: children, - }); - const toggleClasses = classNames(`${prefix}--tree-parent-node__toggle-icon`, { - [`${prefix}--tree-parent-node__toggle-icon--expanded`]: expanded, - }); - function handleToggleClick(event) { - if (disabled) { - return; - } - onToggle?.(event, { id, isExpanded: !expanded, label, value }); - setExpanded(!expanded); - } - function handleClick(event) { - event.stopPropagation(); - if (!disabled) { - onTreeSelect?.(event, { id, label, value }); - onNodeSelect?.(event, { id, label, value }); - rest?.onClick?.(event); - } - } - function handleKeyDown(event) { - if (disabled) { - return; +const TreeNode = React.forwardRef( + ( + { + active, + children, + className, + depth, + disabled, + isExpanded, + label, + onNodeFocusEvent, + onSelect: onNodeSelect, + onToggle, + onTreeSelect, + renderIcon: Icon, + selected, + value, + ...rest + }, + ref + ) => { + const { current: id } = useRef(rest.id || uniqueId()); + const [expanded, setExpanded] = useState(isExpanded); + const currentNode = useRef(null); + const currentNodeLabel = useRef(null); + const prefix = usePrefix(); + const nodesWithProps = React.Children.map(children, (node) => { + if (React.isValidElement(node)) { + return React.cloneElement(node, { + active, + depth: depth + 1, + disabled, + onTreeSelect, + selected, + tabIndex: (!node.props.disabled && -1) || null, + }); + } + }); + const isActive = active === id; + const isSelected = selected.includes(id); + const treeNodeClasses = classNames(className, `${prefix}--tree-node`, { + [`${prefix}--tree-node--active`]: isActive, + [`${prefix}--tree-node--disabled`]: disabled, + [`${prefix}--tree-node--selected`]: isSelected, + [`${prefix}--tree-node--with-icon`]: Icon, + [`${prefix}--tree-leaf-node`]: !children, + [`${prefix}--tree-parent-node`]: children, + }); + const toggleClasses = classNames( + `${prefix}--tree-parent-node__toggle-icon`, + { + [`${prefix}--tree-parent-node__toggle-icon--expanded`]: expanded, + } + ); + function handleToggleClick(event) { + if (disabled) { + return; + } + onToggle?.(event, { id, isExpanded: !expanded, label, value }); + setExpanded(!expanded); } - if (matches(event, [keys.ArrowLeft, keys.ArrowRight, keys.Enter])) { + function handleClick(event) { event.stopPropagation(); + if (!disabled) { + onTreeSelect?.(event, { id, label, value }); + onNodeSelect?.(event, { id, label, value }); + rest?.onClick?.(event); + } } - if (match(event, keys.ArrowLeft)) { - const findParentTreeNode = (node) => { - if (node.classList.contains(`${prefix}--tree-parent-node`)) { - return node; + function handleKeyDown(event) { + if (disabled) { + return; + } + if (matches(event, [keys.ArrowLeft, keys.ArrowRight, keys.Enter])) { + event.stopPropagation(); + } + if (match(event, keys.ArrowLeft)) { + const findParentTreeNode = (node) => { + if (node.classList.contains(`${prefix}--tree-parent-node`)) { + return node; + } + if (node.classList.contains(`${prefix}--tree`)) { + return null; + } + return findParentTreeNode(node.parentNode); + }; + if (children && expanded) { + onToggle?.(event, { id, isExpanded: false, label, value }); + setExpanded(false); + } else { + /** + * When focus is on a leaf node or a closed parent node, move focus to + * its parent node (unless its depth is level 1) + */ + findParentTreeNode(currentNode.current.parentNode)?.focus(); } - if (node.classList.contains(`${prefix}--tree`)) { - return null; + } + if (children && match(event, keys.ArrowRight)) { + if (expanded) { + /** + * When focus is on an expanded parent node, move focus to the first + * child node + */ + currentNode.current.lastChild.firstChild.focus(); + } else { + onToggle?.(event, { id, isExpanded: true, label, value }); + setExpanded(true); } - return findParentTreeNode(node.parentNode); - }; - if (children && expanded) { - onToggle?.(event, { id, isExpanded: false, label, value }); - setExpanded(false); - } else { - /** - * When focus is on a leaf node or a closed parent node, move focus to - * its parent node (unless its depth is level 1) - */ - findParentTreeNode(currentNode.current.parentNode)?.focus(); } - } - if (children && match(event, keys.ArrowRight)) { - if (expanded) { - /** - * When focus is on an expanded parent node, move focus to the first - * child node - */ - currentNode.current.lastChild.firstChild.focus(); - } else { - onToggle?.(event, { id, isExpanded: true, label, value }); - setExpanded(true); + if (matches(event, [keys.Enter, keys.Space])) { + event.preventDefault(); + handleClick(event); } + rest?.onKeyDown?.(event); } - if (matches(event, [keys.Enter, keys.Space])) { - event.preventDefault(); - handleClick(event); - } - rest?.onKeyDown?.(event); - } - function handleFocusEvent(event) { - if (event.type === 'blur') { - rest?.onBlur?.(event); - } - if (event.type === 'focus') { - rest?.onFocus?.(event); - } - onNodeFocusEvent?.(event); - } - - useEffect(() => { - /** - * Negative margin shifts node to align with the left side boundary of the - * tree - * Dynamically calculate padding to recreate tree node indentation - * - parent nodes with icon have (depth + 1rem + depth * 0.5) left padding - * - parent nodes have (depth + 1rem) left padding - * - leaf nodes have (depth + 2.5rem) left padding without icons (because - * of expand icon + spacing) - * - leaf nodes have (depth + 2rem + depth * 0.5) left padding with icons (because of - * reduced spacing between the expand icon and the node icon + label) - */ - const calcOffset = () => { - // parent node with icon - if (children && Icon) { - return depth + 1 + depth * 0.5; - } - // parent node without icon - if (children) { - return depth + 1; + function handleFocusEvent(event) { + if (event.type === 'blur') { + rest?.onBlur?.(event); } - // leaf node with icon - if (Icon) { - return depth + 2 + depth * 0.5; + if (event.type === 'focus') { + rest?.onFocus?.(event); } - // leaf node without icon - return depth + 2.5; - }; - - if (currentNodeLabel.current) { - currentNodeLabel.current.style.marginInlineStart = `-${calcOffset()}rem`; - currentNodeLabel.current.style.paddingInlineStart = `${calcOffset()}rem`; + onNodeFocusEvent?.(event); } - // sync props and state - setExpanded(isExpanded); - }, [children, depth, Icon, isExpanded]); + useEffect(() => { + /** + * Negative margin shifts node to align with the left side boundary of the + * tree + * Dynamically calculate padding to recreate tree node indentation + * - parent nodes with icon have (depth + 1rem + depth * 0.5) left padding + * - parent nodes have (depth + 1rem) left padding + * - leaf nodes have (depth + 2.5rem) left padding without icons (because + * of expand icon + spacing) + * - leaf nodes have (depth + 2rem + depth * 0.5) left padding with icons (because of + * reduced spacing between the expand icon and the node icon + label) + */ + const calcOffset = () => { + // parent node with icon + if (children && Icon) { + return depth + 1 + depth * 0.5; + } + // parent node without icon + if (children) { + return depth + 1; + } + // leaf node with icon + if (Icon) { + return depth + 2 + depth * 0.5; + } + // leaf node without icon + return depth + 2.5; + }; + + if (currentNodeLabel.current) { + currentNodeLabel.current.style.marginInlineStart = `-${calcOffset()}rem`; + currentNodeLabel.current.style.paddingInlineStart = `${calcOffset()}rem`; + } - const treeNodeProps = { - ...rest, - ['aria-current']: isActive || null, - ['aria-selected']: disabled ? null : isSelected, - ['aria-disabled']: disabled, - className: treeNodeClasses, - id, - onBlur: handleFocusEvent, - onClick: handleClick, - onFocus: handleFocusEvent, - onKeyDown: handleKeyDown, - ref: currentNode, - role: 'treeitem', - }; + // sync props and state + setExpanded(isExpanded); + }, [children, depth, Icon, isExpanded]); - if (!children) { + const treeNodeProps = { + ...rest, + ['aria-current']: isActive || null, + ['aria-selected']: disabled ? null : isSelected, + ['aria-disabled']: disabled, + className: treeNodeClasses, + id, + onBlur: handleFocusEvent, + onClick: handleClick, + onFocus: handleFocusEvent, + onKeyDown: handleKeyDown, + ref: currentNode, + role: 'treeitem', + }; + + if (!children) { + return ( +
  • +
    + {Icon && } + {label} +
    +
  • + ); + } return ( -
  • + // eslint-disable-next-line jsx-a11y/role-supports-aria-props +
  • - {Icon && } - {label} + {/* https://github.com/carbon-design-system/carbon/pull/6008#issuecomment-675738670 */} + {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */} + + + + + {Icon && } + {label} +
    + {expanded && ( +
      + {nodesWithProps} +
    + )}
  • ); } - return ( - // eslint-disable-next-line jsx-a11y/role-supports-aria-props -
  • -
    - {/* https://github.com/carbon-design-system/carbon/pull/6008#issuecomment-675738670 */} - {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */} - - - - - {Icon && } - {label} - -
    - {expanded && ( -
      - {nodesWithProps} -
    - )} -
  • - ); -} +); TreeNode.propTypes = { /** @@ -294,3 +302,6 @@ TreeNode.propTypes = { */ value: PropTypes.string, }; + +TreeNode.displayName = 'TreeNode'; +export default TreeNode; diff --git a/packages/react/src/components/UIShell/SideNavMenu.js b/packages/react/src/components/UIShell/SideNavMenu.js deleted file mode 100644 index 3595eea19b3d..000000000000 --- a/packages/react/src/components/UIShell/SideNavMenu.js +++ /dev/null @@ -1,172 +0,0 @@ -/** - * Copyright IBM Corp. 2016, 2023 - * - * 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 { ChevronDown } from '@carbon/icons-react'; -import cx from 'classnames'; -import PropTypes from 'prop-types'; -import React, { useContext, useState } from 'react'; -import SideNavIcon from './SideNavIcon'; -import { keys, match } from '../../internal/keyboard'; -import { usePrefix } from '../../internal/usePrefix'; -import { SideNavContext } from './SideNav'; - -const SideNavMenu = React.forwardRef(function SideNavMenu(props, ref) { - const { - className: customClassName, - children, - defaultExpanded = false, - isActive = false, - large = false, - renderIcon: IconElement, - isSideNavExpanded, - tabIndex, - title, - } = props; - const isRail = useContext(SideNavContext); - const prefix = usePrefix(); - const [isExpanded, setIsExpanded] = useState(defaultExpanded); - const [prevExpanded, setPrevExpanded] = useState(defaultExpanded); - const className = cx({ - [`${prefix}--side-nav__item`]: true, - [`${prefix}--side-nav__item--active`]: - isActive || (hasActiveChild(children) && !isExpanded), - [`${prefix}--side-nav__item--icon`]: IconElement, - [`${prefix}--side-nav__item--large`]: large, - [customClassName]: !!customClassName, - }); - - if (isSideNavExpanded === false && isExpanded === true) { - setIsExpanded(false); - setPrevExpanded(true); - } else if (isSideNavExpanded === true && prevExpanded === true) { - setIsExpanded(true); - setPrevExpanded(false); - } - - return ( - // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -
  • { - if (match(event, keys.Escape)) { - setIsExpanded(false); - } - }}> - -
      {children}
    -
  • - ); -}); -SideNavMenu.displayName = 'SideNavMenu'; -SideNavMenu.propTypes = { - /** - * Provide 's inside of the `SideNavMenu` - */ - children: PropTypes.node, - - /** - * Provide an optional class to be applied to the containing node - */ - className: PropTypes.string, - - /** - * Specify whether the menu should default to expanded. By default, it will - * be closed. - */ - defaultExpanded: PropTypes.bool, - - /** - * Specify whether the `SideNavMenu` is "active". `SideNavMenu` should be - * considered active if one of its menu items are a link for the current - * page. - */ - isActive: PropTypes.bool, - - /** - * Property to indicate if the side nav container is open (or not). Use to - * keep local state and styling in step with the SideNav expansion state. - */ - isSideNavExpanded: PropTypes.bool, - - /** - * Specify if this is a large variation of the SideNavMenu - */ - large: PropTypes.bool, - - /** - * Pass in a custom icon to render next to the `SideNavMenu` title - */ - renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), - - /** - * Optional prop to specify the tabIndex of the button. If undefined, it will be applied default validation - */ - tabIndex: PropTypes.number, - - /** - * Provide the text for the overall menu name - */ - title: PropTypes.string.isRequired, -}; - -function hasActiveChild(children) { - // if we have children, either a single or multiple, find if it is active - if (Array.isArray(children)) { - return children.some((child) => { - if (!child.props) { - return false; - } - - if (child.props.isActive === true) { - return true; - } - - if (child.props['aria-current']) { - return true; - } - - return false; - }); - } - - if (children.props) { - if (children.props.isActive === true || children.props['aria-current']) { - return true; - } - } - - return false; -} - -export default SideNavMenu; -export { SideNavMenu }; diff --git a/packages/react/src/components/UIShell/SideNavMenu.tsx b/packages/react/src/components/UIShell/SideNavMenu.tsx index cfee364113fa..bcdb6869fe1f 100644 --- a/packages/react/src/components/UIShell/SideNavMenu.tsx +++ b/packages/react/src/components/UIShell/SideNavMenu.tsx @@ -132,9 +132,7 @@ const SideNavMenu = React.forwardRef( )} - - {title} - + {title} diff --git a/packages/react/src/components/UIShell/SideNavMenuItem.js b/packages/react/src/components/UIShell/SideNavMenuItem.js deleted file mode 100644 index 352732ec7de6..000000000000 --- a/packages/react/src/components/UIShell/SideNavMenuItem.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright IBM Corp. 2016, 2023 - * - * 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 cx from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; -import SideNavLinkText from './SideNavLinkText'; -import Link from './Link'; -import { usePrefix } from '../../internal/usePrefix'; - -const SideNavMenuItem = React.forwardRef(function SideNavMenuItem(props, ref) { - const prefix = usePrefix(); - const { children, className: customClassName, isActive, ...rest } = props; - const className = cx(`${prefix}--side-nav__menu-item`, customClassName); - const linkClassName = cx({ - [`${prefix}--side-nav__link`]: true, - [`${prefix}--side-nav__link--current`]: isActive, - }); - - return ( -
  • - - {children} - -
  • - ); -}); - -SideNavMenuItem.displayName = 'SideNavMenuItem'; -SideNavMenuItem.propTypes = { - /** - * Specify the children to be rendered inside of the `SideNavMenuItem` - */ - children: PropTypes.node, - - /** - * Provide an optional class to be applied to the containing node - */ - className: PropTypes.string, - - /** - * Optionally specify whether the link is "active". An active link is one that - * has an href that is the same as the current page. Can also pass in - * `aria-current="page"`, as well. - */ - isActive: PropTypes.bool, -}; - -export default SideNavMenuItem; diff --git a/packages/react/src/components/UIShell/SideNavMenuItem.tsx b/packages/react/src/components/UIShell/SideNavMenuItem.tsx new file mode 100644 index 000000000000..322971d3638d --- /dev/null +++ b/packages/react/src/components/UIShell/SideNavMenuItem.tsx @@ -0,0 +1,74 @@ +/** + * Copyright IBM Corp. 2016, 2023 + * + * 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 cx from 'classnames'; +import PropTypes from 'prop-types'; +import React, { ElementType, ForwardedRef, HTMLAttributes, Ref } from 'react'; +import SideNavLinkText from './SideNavLinkText'; +import Link from './Link'; +import { usePrefix } from '../../internal/usePrefix'; + +interface SideNavMenuItemProps extends HTMLAttributes { + /** + * Specify the children to be rendered inside of the `SideNavMenuItem` + */ + children?: React.ReactNode; + + /** + * Provide an optional class to be applied to the containing node + */ + className?: string; + + /** + * Optionally specify whether the link is "active". An active link is one that + * has an href that is the same as the current page. Can also pass in + * `aria-current="page"`, as well. + */ + isActive?: boolean; +} + +const SideNavMenuItem = React.forwardRef( + function SideNavMenuItem(props, ref: ForwardedRef) { + const prefix = usePrefix(); + const { children, className: customClassName, isActive, ...rest } = props; + const className = cx(`${prefix}--side-nav__menu-item`, customClassName); + const linkClassName = cx({ + [`${prefix}--side-nav__link`]: true, + [`${prefix}--side-nav__link--current`]: isActive, + }); + + return ( +
  • + }> + {children} + +
  • + ); + } +); + +SideNavMenuItem.displayName = 'SideNavMenuItem'; +SideNavMenuItem.propTypes = { + /** + * Specify the children to be rendered inside of the `SideNavMenuItem` + */ + children: PropTypes.node, + + /** + * Provide an optional class to be applied to the containing node + */ + className: PropTypes.string, + + /** + * Optionally specify whether the link is "active". An active link is one that + * has an href that is the same as the current page. Can also pass in + * `aria-current="page"`, as well. + */ + isActive: PropTypes.bool, +}; + +export default SideNavMenuItem; diff --git a/packages/react/src/index.js b/packages/react/src/index.js index 14e20ee01f13..774125a677ff 100644 --- a/packages/react/src/index.js +++ b/packages/react/src/index.js @@ -298,4 +298,8 @@ export { DefinitionTooltip } from './components/Tooltip/DefinitionTooltip'; export { GlobalTheme, Theme, useTheme } from './components/Theme'; export { usePrefix } from './internal/usePrefix'; export { useIdPrefix } from './internal/useIdPrefix'; -export { Slug as unstable__Slug } from './components/Slug'; +export { + Slug as unstable__Slug, + SlugContent as unstable__SlugContent, + SlugActions as unstable__SlugActions, +} from './components/Slug'; diff --git a/packages/styles/scss/components/slider/_slider.scss b/packages/styles/scss/components/slider/_slider.scss index 67ff6f1f6c60..212a6c8fca27 100644 --- a/packages/styles/scss/components/slider/_slider.scss +++ b/packages/styles/scss/components/slider/_slider.scss @@ -146,7 +146,7 @@ block-size: convert.to-rem(2px); content: ''; inline-size: convert.to-rem(6px); - inset-block-start: calc(50% - #{convert.to-rem(2px) / 2}); + inset-block-start: calc(50% - #{convert.to-rem(2px) * 0.5}); inset-inline-end: 0; } diff --git a/packages/styles/scss/components/slug/_slug.scss b/packages/styles/scss/components/slug/_slug.scss index fd625e4a4f0f..21fde4e37099 100644 --- a/packages/styles/scss/components/slug/_slug.scss +++ b/packages/styles/scss/components/slug/_slug.scss @@ -309,7 +309,7 @@ $sizes: ( } // Slug callout styles - .#{$prefix}--slug.#{$prefix}--slug--enabled .#{$prefix}--popover-content { + .#{$prefix}--slug.#{$prefix}--slug--enabled .#{$prefix}--slug-content { border: 1px solid $border-subtle; border-radius: 16px; // 84px seems to make this fully opaque? @@ -334,13 +334,44 @@ $sizes: ( min-inline-size: convert.to-rem(280px); } - .#{$prefix}--slug.#{$prefix}--slug--enabled .#{$prefix}--popover-caret { + .#{$prefix}--slug.#{$prefix}--slug--enabled + > .#{$prefix}--toggletip + > .#{$prefix}--popover + > .#{$prefix}--popover-caret { background: $border-subtle; } .#{$prefix}--slug.#{$prefix}--slug--enabled .#{$prefix}--toggletip-content { + // This sets the max size to the size of the action bar with 3 buttons + max-inline-size: convert.to-rem(334px); padding-block-end: convert.to-rem(80px); padding-block-start: convert.to-rem(32px); padding-inline: convert.to-rem(32px); } + + .#{$prefix}--slug.#{$prefix}--slug--enabled .#{$prefix}--slug-actions { + position: absolute; + justify-content: flex-end; + background: $layer-accent; + border-end-end-radius: convert.to-rem(15px); + border-end-start-radius: convert.to-rem(15px); + column-gap: 0; + inline-size: 100%; + inset-block-end: 0; + inset-inline-end: 0; + } + + .#{$prefix}--slug.#{$prefix}--slug--enabled + .#{$prefix}--slug-actions + .#{$prefix}--btn:focus { + border-color: $focus; + box-shadow: inset 0 0 0 1px $focus, inset 0 0 0 2px $background; + } + + .#{$prefix}--slug.#{$prefix}--slug--enabled + .#{$prefix}--slug-actions + .#{$prefix}--btn--primary { + order: 1; + border-end-end-radius: convert.to-rem(16px); + } } diff --git a/yarn.lock b/yarn.lock index 9cd9584370a7..ab018e86bac6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -78,12 +78,13 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.22.5, @babel/code-frame@npm:^7.8.3": - version: 7.22.5 - resolution: "@babel/code-frame@npm:7.22.5" +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.22.13, @babel/code-frame@npm:^7.22.5, @babel/code-frame@npm:^7.8.3": + version: 7.22.13 + resolution: "@babel/code-frame@npm:7.22.13" dependencies: - "@babel/highlight": ^7.22.5 - checksum: cfe804f518f53faaf9a1d3e0f9f74127ab9a004912c3a16fda07fb6a633393ecb9918a053cb71804204c1b7ec3d49e1699604715e2cfb0c9f7bc4933d324ebb6 + "@babel/highlight": ^7.22.13 + chalk: ^2.4.2 + checksum: 22e342c8077c8b77eeb11f554ecca2ba14153f707b85294fcf6070b6f6150aae88a7b7436dd88d8c9289970585f3fe5b9b941c5aa3aa26a6d5a8ef3f292da058 languageName: node linkType: hard @@ -131,15 +132,15 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.12.11, @babel/generator@npm:^7.18.2, @babel/generator@npm:^7.22.0, @babel/generator@npm:^7.22.7, @babel/generator@npm:^7.22.9, @babel/generator@npm:^7.7.2": - version: 7.22.9 - resolution: "@babel/generator@npm:7.22.9" +"@babel/generator@npm:^7.12.11, @babel/generator@npm:^7.18.2, @babel/generator@npm:^7.22.0, @babel/generator@npm:^7.22.9, @babel/generator@npm:^7.23.0, @babel/generator@npm:^7.7.2": + version: 7.23.0 + resolution: "@babel/generator@npm:7.23.0" dependencies: - "@babel/types": ^7.22.5 + "@babel/types": ^7.23.0 "@jridgewell/gen-mapping": ^0.3.2 "@jridgewell/trace-mapping": ^0.3.17 jsesc: ^2.5.1 - checksum: 7c9d2c58b8d5ac5e047421a6ab03ec2ff5d9a5ff2c2212130a0055e063ac349e0b19d435537d6886c999771aef394832e4f54cd9fc810100a7f23d982f6af06b + checksum: 8efe24adad34300f1f8ea2add420b28171a646edc70f2a1b3e1683842f23b8b7ffa7e35ef0119294e1901f45bfea5b3dc70abe1f10a1917ccdfb41bed69be5f1 languageName: node linkType: hard @@ -239,20 +240,20 @@ __metadata: languageName: node linkType: hard -"@babel/helper-environment-visitor@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/helper-environment-visitor@npm:7.22.5" - checksum: 248532077d732a34cd0844eb7b078ff917c3a8ec81a7f133593f71a860a582f05b60f818dc5049c2212e5baa12289c27889a4b81d56ef409b4863db49646c4b1 +"@babel/helper-environment-visitor@npm:^7.22.20, @babel/helper-environment-visitor@npm:^7.22.5": + version: 7.22.20 + resolution: "@babel/helper-environment-visitor@npm:7.22.20" + checksum: d80ee98ff66f41e233f36ca1921774c37e88a803b2f7dca3db7c057a5fea0473804db9fb6729e5dbfd07f4bed722d60f7852035c2c739382e84c335661590b69 languageName: node linkType: hard -"@babel/helper-function-name@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/helper-function-name@npm:7.22.5" +"@babel/helper-function-name@npm:^7.22.5, @babel/helper-function-name@npm:^7.23.0": + version: 7.23.0 + resolution: "@babel/helper-function-name@npm:7.23.0" dependencies: - "@babel/template": ^7.22.5 - "@babel/types": ^7.22.5 - checksum: 6b1f6ce1b1f4e513bf2c8385a557ea0dd7fa37971b9002ad19268ca4384bbe90c09681fe4c076013f33deabc63a53b341ed91e792de741b4b35e01c00238177a + "@babel/template": ^7.22.15 + "@babel/types": ^7.23.0 + checksum: e44542257b2d4634a1f979244eb2a4ad8e6d75eb6761b4cfceb56b562f7db150d134bc538c8e6adca3783e3bc31be949071527aa8e3aab7867d1ad2d84a26e10 languageName: node linkType: hard @@ -374,10 +375,10 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/helper-validator-identifier@npm:7.22.5" - checksum: 7f0f30113474a28298c12161763b49de5018732290ca4de13cdaefd4fd0d635a6fe3f6686c37a02905fb1e64f21a5ee2b55140cf7b070e729f1bd66866506aea +"@babel/helper-validator-identifier@npm:^7.22.20, @babel/helper-validator-identifier@npm:^7.22.5": + version: 7.22.20 + resolution: "@babel/helper-validator-identifier@npm:7.22.20" + checksum: 136412784d9428266bcdd4d91c32bcf9ff0e8d25534a9d94b044f77fe76bc50f941a90319b05aafd1ec04f7d127cd57a179a3716009ff7f3412ef835ada95bdc languageName: node linkType: hard @@ -410,14 +411,14 @@ __metadata: languageName: node linkType: hard -"@babel/highlight@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/highlight@npm:7.22.5" +"@babel/highlight@npm:^7.22.13": + version: 7.22.20 + resolution: "@babel/highlight@npm:7.22.20" dependencies: - "@babel/helper-validator-identifier": ^7.22.5 - chalk: ^2.0.0 + "@babel/helper-validator-identifier": ^7.22.20 + chalk: ^2.4.2 js-tokens: ^4.0.0 - checksum: f61ae6de6ee0ea8d9b5bcf2a532faec5ab0a1dc0f7c640e5047fc61630a0edb88b18d8c92eb06566d30da7a27db841aca11820ecd3ebe9ce514c9350fbed39c4 + checksum: 84bd034dca309a5e680083cd827a766780ca63cef37308404f17653d32366ea76262bd2364b2d38776232f2d01b649f26721417d507e8b4b6da3e4e739f6d134 languageName: node linkType: hard @@ -439,12 +440,12 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.13.16, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.22.0, @babel/parser@npm:^7.22.5, @babel/parser@npm:^7.22.7": - version: 7.22.7 - resolution: "@babel/parser@npm:7.22.7" +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.13.16, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.22.0, @babel/parser@npm:^7.22.15, @babel/parser@npm:^7.22.7, @babel/parser@npm:^7.23.0": + version: 7.23.0 + resolution: "@babel/parser@npm:7.23.0" bin: parser: ./bin/babel-parser.js - checksum: 02209ddbd445831ee8bf966fdf7c29d189ed4b14343a68eb2479d940e7e3846340d7cc6bd654a5f3d87d19dc84f49f50a58cf9363bee249dc5409ff3ba3dab54 + checksum: 453fdf8b9e2c2b7d7b02139e0ce003d1af21947bbc03eb350fb248ee335c9b85e4ab41697ddbdd97079698de825a265e45a0846bb2ed47a2c7c1df833f42a354 languageName: node linkType: hard @@ -1756,43 +1757,43 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.16.7, @babel/template@npm:^7.22.5, @babel/template@npm:^7.3.3": - version: 7.22.5 - resolution: "@babel/template@npm:7.22.5" +"@babel/template@npm:^7.16.7, @babel/template@npm:^7.22.15, @babel/template@npm:^7.22.5, @babel/template@npm:^7.3.3": + version: 7.22.15 + resolution: "@babel/template@npm:7.22.15" dependencies: - "@babel/code-frame": ^7.22.5 - "@babel/parser": ^7.22.5 - "@babel/types": ^7.22.5 - checksum: c5746410164039aca61829cdb42e9a55410f43cace6f51ca443313f3d0bdfa9a5a330d0b0df73dc17ef885c72104234ae05efede37c1cc8a72dc9f93425977a3 + "@babel/code-frame": ^7.22.13 + "@babel/parser": ^7.22.15 + "@babel/types": ^7.22.15 + checksum: 1f3e7dcd6c44f5904c184b3f7fe280394b191f2fed819919ffa1e529c259d5b197da8981b6ca491c235aee8dbad4a50b7e31304aa531271cb823a4a24a0dd8fd languageName: node linkType: hard "@babel/traverse@npm:^7.1.6, @babel/traverse@npm:^7.22.0, @babel/traverse@npm:^7.22.6, @babel/traverse@npm:^7.22.8, @babel/traverse@npm:^7.7.2": - version: 7.22.8 - resolution: "@babel/traverse@npm:7.22.8" + version: 7.23.2 + resolution: "@babel/traverse@npm:7.23.2" dependencies: - "@babel/code-frame": ^7.22.5 - "@babel/generator": ^7.22.7 - "@babel/helper-environment-visitor": ^7.22.5 - "@babel/helper-function-name": ^7.22.5 + "@babel/code-frame": ^7.22.13 + "@babel/generator": ^7.23.0 + "@babel/helper-environment-visitor": ^7.22.20 + "@babel/helper-function-name": ^7.23.0 "@babel/helper-hoist-variables": ^7.22.5 "@babel/helper-split-export-declaration": ^7.22.6 - "@babel/parser": ^7.22.7 - "@babel/types": ^7.22.5 + "@babel/parser": ^7.23.0 + "@babel/types": ^7.23.0 debug: ^4.1.0 globals: ^11.1.0 - checksum: a381369bc3eedfd13ed5fef7b884657f1c29024ea7388198149f0edc34bd69ce3966e9f40188d15f56490a5e12ba250ccc485f2882b53d41b054fccefb233e33 + checksum: 26a1eea0dde41ab99dde8b9773a013a0dc50324e5110a049f5d634e721ff08afffd54940b3974a20308d7952085ac769689369e9127dea655f868c0f6e1ab35d languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.12.6, @babel/types@npm:^7.18.4, @babel/types@npm:^7.2.0, @babel/types@npm:^7.22.0, @babel/types@npm:^7.22.5, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": - version: 7.22.5 - resolution: "@babel/types@npm:7.22.5" +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.12.6, @babel/types@npm:^7.18.4, @babel/types@npm:^7.2.0, @babel/types@npm:^7.22.0, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": + version: 7.23.0 + resolution: "@babel/types@npm:7.23.0" dependencies: "@babel/helper-string-parser": ^7.22.5 - "@babel/helper-validator-identifier": ^7.22.5 + "@babel/helper-validator-identifier": ^7.22.20 to-fast-properties: ^2.0.0 - checksum: c13a9c1dc7d2d1a241a2f8363540cb9af1d66e978e8984b400a20c4f38ba38ca29f06e26a0f2d49a70bad9e57615dac09c35accfddf1bb90d23cd3e0a0bab892 + checksum: 215fe04bd7feef79eeb4d33374b39909ce9cad1611c4135a4f7fdf41fe3280594105af6d7094354751514625ea92d0875aba355f53e86a92600f290e77b0e604 languageName: node linkType: hard @@ -10878,7 +10879,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^2.0.0, chalk@npm:^2.4.1, chalk@npm:^2.4.2": +"chalk@npm:^2.4.1, chalk@npm:^2.4.2": version: 2.4.2 resolution: "chalk@npm:2.4.2" dependencies: