From 95d5b2537e870e762c8527082d4de9778d01442a Mon Sep 17 00:00:00 2001 From: Michail Yasonik Date: Wed, 20 Jan 2021 14:13:20 -0500 Subject: [PATCH 1/3] adding more pages to a11y testing --- CHANGELOG.md | 5 ++- package.json | 6 +-- scripts/a11y-testing.js | 17 +++----- src-docs/src/views/button/button_ghost.js | 2 +- src-docs/src/views/button/button_group.js | 10 +++-- src-docs/src/views/side_nav/side_nav.js | 1 + .../src/views/side_nav/side_nav_complex.js | 1 + .../src/views/side_nav/side_nav_force_open.js | 1 + .../views/utility_classes/utility_classes.js | 13 +++--- .../tabs/__snapshots__/tabs.test.tsx.snap | 16 +++++-- src/components/tabs/tabs.test.tsx | 10 +++-- src/components/tabs/tabs.tsx | 2 + .../__snapshots__/tree_view.test.tsx.snap | 31 +++++++------ src/components/tree_view/tree_view.tsx | 18 +++++--- yarn.lock | 43 +++++++++++-------- 15 files changed, 102 insertions(+), 74 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 595ad48e49d..269524e85ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ ## [`master`](https://github.com/elastic/eui/tree/master) -No public interface changes since `31.2.0`. +**Bug Fixes** + +- Fixed id usage throughout `EuiTreeView` to respect custom ids and stop conflicts in generated ids ([#]()) +- Stopped rendering an empty tab container in `EuiTabs` if no tabs are passed in ([#]()) ## [`31.2.0`](https://github.com/elastic/eui/tree/v31.2.0) diff --git a/package.json b/package.json index 6f1c3cc1a4e..a4ffcacbe24 100644 --- a/package.json +++ b/package.json @@ -115,8 +115,8 @@ "@typescript-eslint/parser": "^4.8.1", "argparse": "^2.0.1", "autoprefixer": "^9.8.6", - "axe-core": "^4.0.1", - "axe-puppeteer": "^1.1.0", + "axe-core": "^4.1.1", + "axe-puppeteer": "^1.1.1", "babel-core": "7.0.0-bridge.0", "babel-eslint": "^10.1.0", "babel-jest": "^24.1.0", @@ -179,7 +179,7 @@ "prettier-stylelint": "^0.4.2", "prompt": "^1.0.0", "prop-types": "^15.6.0", - "puppeteer": "^5.3.0", + "puppeteer": "^5.5.0", "raw-loader": "^4.0.1", "react": "^16.12.0", "react-docgen-typescript": "^1.20.5", diff --git a/scripts/a11y-testing.js b/scripts/a11y-testing.js index 39c9f5378b1..869d81a0424 100644 --- a/scripts/a11y-testing.js +++ b/scripts/a11y-testing.js @@ -24,9 +24,6 @@ const { AxePuppeteer } = require('axe-puppeteer'); const docsPages = async (root, page) => { const pagesToSkip = [ `${root}#/layout/resizable-container`, - `${root}#/navigation/button`, - `${root}#/navigation/tree-view`, - `${root}#/navigation/side-nav`, `${root}#/tabular-content/tables`, `${root}#/tabular-content/in-memory-tables`, `${root}#/display/aspect-ratio`, @@ -42,21 +39,19 @@ const docsPages = async (root, page) => { `${root}#/forms/super-date-picker`, `${root}#/elastic-charts/creating-charts`, `${root}#/elastic-charts/part-to-whole-comparisons`, - `${root}#/utilities/css-utility-classes`, - `${root}#/utilities/focus-trap`, ]; return [ root, - ...(await page.$$eval('nav a', anchors => anchors.map(a => a.href))), - ].filter(link => !pagesToSkip.includes(link)); + ...(await page.$$eval('nav a', (anchors) => anchors.map((a) => a.href))), + ].filter((link) => !pagesToSkip.includes(link)); }; -const printResult = result => +const printResult = (result) => console.log(`[${result.id}]: ${result.description} Help: ${chalk.blue(result.helpUrl)} Elements: - - ${result.nodes.map(node => node.target).join('\n - ')}`); + - ${result.nodes.map((node) => node.target).join('\n - ')}`); (async () => { let totalViolationsCount = 0; @@ -114,7 +109,7 @@ const printResult = result => console.log(chalk.red(`Errors on ${pageName}`)); } - violations.forEach(result => { + violations.forEach((result) => { printResult(result); }); } @@ -136,4 +131,4 @@ Firefox: https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/`); } else { console.log(chalk.green('axe found no accessibility errors!')); } -})().catch(e => console.error(e)); +})().catch((e) => console.error(e)); diff --git a/src-docs/src/views/button/button_ghost.js b/src-docs/src/views/button/button_ghost.js index 95413ec09ab..a8519ab6ec8 100644 --- a/src-docs/src/views/button/button_ghost.js +++ b/src-docs/src/views/button/button_ghost.js @@ -19,7 +19,7 @@ export default () => { return ( diff --git a/src-docs/src/views/button/button_group.js b/src-docs/src/views/button/button_group.js index 1d35a5980c1..0492f8cfae2 100644 --- a/src-docs/src/views/button/button_group.js +++ b/src-docs/src/views/button/button_group.js @@ -121,6 +121,10 @@ export default () => { }, ]; + const toggleButtonsIconsMultiCompressed = toggleButtonsIconsMulti.map( + (config) => ({ ...config, id: `${config.id}-compressed` }) + ); + const [toggleIdSelected, setToggleIdSelected] = useState(`${idPrefix}1`); const [toggleIdDisabled, setToggleIdDisabled] = useState(`${idPrefix}4`); const [toggleIdToSelectedMap, setToggleIdToSelectedMap] = useState({ @@ -137,7 +141,7 @@ export default () => { setToggleIconIdToSelectedMapIcon, ] = useState({}); const [toggleCompressedIdSelected, setToggleCompressedIdSelected] = useState( - `${idPrefix2}4` + `${idPrefix2}4-compressed` ); const onChange = (optionId) => { @@ -268,9 +272,9 @@ export default () => { onChangeIconsMultiIcons(id)} type="multi" diff --git a/src-docs/src/views/side_nav/side_nav.js b/src-docs/src/views/side_nav/side_nav.js index 6f76d7ad650..0ff3bb53875 100644 --- a/src-docs/src/views/side_nav/side_nav.js +++ b/src-docs/src/views/side_nav/side_nav.js @@ -41,6 +41,7 @@ export default () => { return ( toggleOpenOnMobile()} isOpenOnMobile={isSideNavOpenOnMobile} diff --git a/src-docs/src/views/side_nav/side_nav_complex.js b/src-docs/src/views/side_nav/side_nav_complex.js index cadf47c35b9..f6dce49d9f7 100644 --- a/src-docs/src/views/side_nav/side_nav_complex.js +++ b/src-docs/src/views/side_nav/side_nav_complex.js @@ -70,6 +70,7 @@ export default () => { return ( { return ( ( -

Display

+

Display

.eui-displayBlock @@ -42,7 +42,7 @@ export default () => ( -

Text

+

Text

@@ -105,7 +105,7 @@ export default () => ( -

Overflows

+

Overflows

( padding: 0, }}>
@@ -155,7 +156,7 @@ export default () => (
-

Vertical alignment

+

Vertical alignment

@@ -190,7 +191,7 @@ export default () => ( -

Responsive

+

Responsive

.eui-hideFor--xs @@ -212,7 +213,7 @@ export default () => ( -
Modifiers
+

Modifiers

The .eui-showFor--[size] classes will force display of{' '} inline when showing the element. You can modify this diff --git a/src/components/tabs/__snapshots__/tabs.test.tsx.snap b/src/components/tabs/__snapshots__/tabs.test.tsx.snap index a26365cc353..e381dc96448 100644 --- a/src/components/tabs/__snapshots__/tabs.test.tsx.snap +++ b/src/components/tabs/__snapshots__/tabs.test.tsx.snap @@ -4,21 +4,27 @@ exports[`EuiTabs props display can be condensed 1`] = `

+> + children +
`; exports[`EuiTabs props expand is rendered 1`] = `
+> + children +
`; exports[`EuiTabs props size can be small 1`] = `
+> + children +
`; exports[`EuiTabs renders 1`] = ` @@ -27,5 +33,7 @@ exports[`EuiTabs renders 1`] = ` class="euiTabs testClass1 testClass2" data-test-subj="test subject string" role="tablist" -/> +> + children +
`; diff --git a/src/components/tabs/tabs.test.tsx b/src/components/tabs/tabs.test.tsx index e6f932c0149..062e688b483 100644 --- a/src/components/tabs/tabs.test.tsx +++ b/src/components/tabs/tabs.test.tsx @@ -25,7 +25,7 @@ import { EuiTabs } from './tabs'; describe('EuiTabs', () => { test('renders', () => { - const component = ; + const component = children; expect(render(component)).toMatchSnapshot(); }); @@ -33,21 +33,23 @@ describe('EuiTabs', () => { describe('props', () => { describe('size', () => { test('can be small', () => { - const component = render(); + const component = render(children); expect(component).toMatchSnapshot(); }); }); describe('display', () => { test('can be condensed', () => { - const component = render(); + const component = render( + children + ); expect(component).toMatchSnapshot(); }); }); describe('expand', () => { test('is rendered', () => { - const component = render(); + const component = render(children); expect(component).toMatchSnapshot(); }); }); diff --git a/src/components/tabs/tabs.tsx b/src/components/tabs/tabs.tsx index ff9ba5eb885..c5b246d502c 100644 --- a/src/components/tabs/tabs.tsx +++ b/src/components/tabs/tabs.tsx @@ -86,6 +86,8 @@ export const EuiTabs = forwardRef>( className ); + if (!children) return <>; + return (
{children} diff --git a/src/components/tree_view/__snapshots__/tree_view.test.tsx.snap b/src/components/tree_view/__snapshots__/tree_view.test.tsx.snap index cd592f844db..dfe546ec80a 100644 --- a/src/components/tree_view/__snapshots__/tree_view.test.tsx.snap +++ b/src/components/tree_view/__snapshots__/tree_view.test.tsx.snap @@ -21,11 +21,11 @@ exports[`EuiTreeView is rendered 1`] = ` class="euiTreeView__node euiTreeView__node--expanded" >
  • @@ -140,11 +139,11 @@ exports[`EuiTreeView is rendered 1`] = ` class="euiTreeView__node" >
    diff --git a/src/components/tree_view/tree_view.tsx b/src/components/tree_view/tree_view.tsx index 4c4a066cbb8..440bb9a1adc 100644 --- a/src/components/tree_view/tree_view.tsx +++ b/src/components/tree_view/tree_view.tsx @@ -28,7 +28,6 @@ import { keys, htmlIdGenerator } from '../../services'; import { EuiInnerText } from '../inner_text'; const EuiTreeViewContext = createContext(''); -const treeIdGenerator = htmlIdGenerator('euiTreeView'); function hasAriaLabel( x: HTMLAttributes @@ -109,6 +108,7 @@ export type EuiTreeViewProps = Omit< ({ 'aria-label': string } | { 'aria-labelledby': string }); export class EuiTreeView extends Component { + treeIdGenerator = htmlIdGenerator('euiTreeView'); static contextType = EuiTreeViewContext; isNested: boolean = !!this.context; state: EuiTreeViewState = { @@ -124,7 +124,9 @@ export class EuiTreeView extends Component { ) .filter((x) => x != null), activeItem: '', - treeID: this.context || treeIdGenerator(), + treeID: + this.props.id ?? + (this.context === '' ? this.treeIdGenerator() : this.context), expandChildNodes: this.props.expandByDefault || false, }; @@ -273,11 +275,15 @@ export class EuiTreeView extends Component { )}
      {items.map((node, index) => { - const buttonId = `${this.state.treeID}--${index}--node`; + const buttonId = + node.id ?? `${this.state.treeID}--${this.treeIdGenerator()}`; + const wrappingId = `euiNestedTreeView-${ + this.state.treeID + }--${this.treeIdGenerator()}`; return ( {
    • this.onChildrenKeydown(event, index) }> diff --git a/yarn.lock b/yarn.lock index d41ce280d89..c0c14eff504 100755 --- a/yarn.lock +++ b/yarn.lock @@ -2772,15 +2772,15 @@ axe-core@^3.5.3, axe-core@^3.5.4: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-3.5.5.tgz#84315073b53fa3c0c51676c588d59da09a192227" integrity sha512-5P0QZ6J5xGikH780pghEdbEKijCTrruK9KxtPZCFWUpef0f6GipO+xEZ5GKCb020mmqgbiNO6TcA55CriL784Q== -axe-core@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.0.1.tgz#e337c2ed1e6fe73920166d8b0b0b352e1b50d8ae" - integrity sha512-OSCABHvSNDleKqJP7DUwEBvMVbr/gtOj2vCDoKKz967fxe9WqtCZLo3IRNOO2fJcu+eSFsu8aAToHfIY7sPLaw== +axe-core@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.1.1.tgz#70a7855888e287f7add66002211a423937063eaf" + integrity sha512-5Kgy8Cz6LPC9DJcNb3yjAXTu3XihQgEdnIg50c//zOC/MyLP0Clg+Y8Sh9ZjjnvBrDZU4DgXS9C3T9r4/scGZQ== -axe-puppeteer@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/axe-puppeteer/-/axe-puppeteer-1.1.0.tgz#efcf0666a7d8fefec6930b4b6ec3476c403d1b91" - integrity sha512-VS17Y1rDQe6A0PdeTPxwOSBfmOdj6efgxyre9cN1du1snnVilczSDtQsgifBKBlzoL/3DKfGpgIi+N+zrzODOg== +axe-puppeteer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/axe-puppeteer/-/axe-puppeteer-1.1.1.tgz#e95f46e069d84d388cdc9fc0630cf2b2e78b1100" + integrity sha512-bU7dt3zlXrlTmaBsudeACEkQ0O4a5LNxRCdA1Qfph4mqx/DewybPCrlyDqJlHXb/W7ZSodE1fMmC+MgRLizxuQ== dependencies: axe-core "^3.5.3" @@ -5086,10 +5086,10 @@ detect-node@^2.0.4: resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== -devtools-protocol@0.0.799653: - version "0.0.799653" - resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.799653.tgz#86fc95ce5bf4fdf4b77a58047ba9d2301078f119" - integrity sha512-t1CcaZbvm8pOlikqrsIM9GOa7Ipp07+4h/q9u0JXBWjPCjHdBl9KkddX87Vv9vBHoBGtwV79sYQNGnQM6iS5gg== +devtools-protocol@0.0.818844: + version "0.0.818844" + resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.818844.tgz#d1947278ec85b53e4c8ca598f607a28fa785ba9e" + integrity sha512-AD1hi7iVJ8OD0aMLQU5VK0XH9LDlA1+BcPIgrAxPfaibx2DbWucuyOhc4oyQCbnvDDO68nN6/LcKfqTP343Jjg== diff-match-patch@^1.0.4: version "1.0.4" @@ -10475,7 +10475,7 @@ mime@1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mime@^2.0.3, mime@^2.4.4: +mime@^2.4.4: version "2.4.6" resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.6.tgz#e5b407c90db442f2beb5b162373d07b69affa4d1" integrity sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA== @@ -10890,6 +10890,11 @@ node-fetch-npm@^2.0.2: json-parse-better-errors "^1.0.0" safe-buffer "^5.1.1" +node-fetch@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + node-forge@^0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" @@ -12881,16 +12886,16 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -puppeteer@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-5.3.0.tgz#0abf83d0f2d1273baf2b56885a813f8052903e33" - integrity sha512-GjqMk5GRro3TO0sw3QMsF1H7n+/jaK2OW45qMvqjYUyJ7y4oA//9auy969HHhTG3HZXaMxY/NWXF/NXlAFIvtw== +puppeteer@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-5.5.0.tgz#331a7edd212ca06b4a556156435f58cbae08af00" + integrity sha512-OM8ZvTXAhfgFA7wBIIGlPQzvyEETzDjeRa4mZRCRHxYL+GNH5WAuYUQdja3rpWZvkX/JKqmuVgbsxDNsDFjMEg== dependencies: debug "^4.1.0" - devtools-protocol "0.0.799653" + devtools-protocol "0.0.818844" extract-zip "^2.0.0" https-proxy-agent "^4.0.0" - mime "^2.0.3" + node-fetch "^2.6.1" pkg-dir "^4.2.0" progress "^2.0.1" proxy-from-env "^1.0.0" From c1574656bc13f9a0c7ae81dfff21c075c3775935 Mon Sep 17 00:00:00 2001 From: Michail Yasonik Date: Wed, 20 Jan 2021 14:43:24 -0500 Subject: [PATCH 2/3] changelog --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04d6f284a40..4256a866b16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,8 @@ No public interface changes since `31.3.0`. **Bug Fixes** -- Fixed id usage throughout `EuiTreeView` to respect custom ids and stop conflicts in generated ids ([#]()) -- Stopped rendering an empty tab container in `EuiTabs` if no tabs are passed in ([#]()) +- Fixed id usage throughout `EuiTreeView` to respect custom ids and stop conflicts in generated ids ([#4435](https://github.com/elastic/eui/pull/4435)) +- Stopped rendering an empty tab container in `EuiTabs` if no tabs are passed in ([#4435](https://github.com/elastic/eui/pull/4435)) ## [`31.2.0`](https://github.com/elastic/eui/tree/v31.2.0) From 0365a6ca75c11780510d7ace3498aac3dc1f7fa5 Mon Sep 17 00:00:00 2001 From: Michail Yasonik Date: Wed, 27 Jan 2021 13:52:29 -0500 Subject: [PATCH 3/3] implementing PR feedback --- CHANGELOG.md | 7 ++--- src/components/tabs/tabs.tsx | 8 ++++-- .../__snapshots__/tree_view.test.tsx.snap | 20 ++++++------- src/components/tree_view/tree_view.tsx | 28 +++++++++++++------ 4 files changed, 37 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b0f9bf76ae0..7cb894435d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ **Bug fixes** - Fixed heights of `append` and `prepend` in `EuiComboBox` ([#4410](https://github.com/elastic/eui/pull/4410)) +- Fixed `id` usage throughout `EuiTreeView` to respect custom ids and stop conflicts in generated ids ([#4435](https://github.com/elastic/eui/pull/4435)) +- Fixed `EuiTabs` `role` if no tabs are passed in ([#4435](https://github.com/elastic/eui/pull/4435)) ## [`31.3.0`](https://github.com/elastic/eui/tree/v31.3.0) @@ -13,11 +15,6 @@ - Added a `textSize` prop to `EuiHealth` ([#4420](https://github.com/elastic/eui/pull/4420)) - Removed selected item of `EuiSelect` when `hasNoInitialSelection=true` and value reset to `undefined` ([#4428](https://github.com/elastic/eui/pull/4428)) -**Bug Fixes** - -- Fixed id usage throughout `EuiTreeView` to respect custom ids and stop conflicts in generated ids ([#4435](https://github.com/elastic/eui/pull/4435)) -- Stopped rendering an empty tab container in `EuiTabs` if no tabs are passed in ([#4435](https://github.com/elastic/eui/pull/4435)) - ## [`31.2.0`](https://github.com/elastic/eui/tree/v31.2.0) - Added support for adjusting `buffer` for individual window sides of `EuiPopover`. ([#4417](https://github.com/elastic/eui/pull/4417)) diff --git a/src/components/tabs/tabs.tsx b/src/components/tabs/tabs.tsx index c5b246d502c..b4273ce95c1 100644 --- a/src/components/tabs/tabs.tsx +++ b/src/components/tabs/tabs.tsx @@ -86,10 +86,12 @@ export const EuiTabs = forwardRef>( className ); - if (!children) return <>; - return ( -
      +
      {children}
      ); diff --git a/src/components/tree_view/__snapshots__/tree_view.test.tsx.snap b/src/components/tree_view/__snapshots__/tree_view.test.tsx.snap index dfe546ec80a..61b3589396a 100644 --- a/src/components/tree_view/__snapshots__/tree_view.test.tsx.snap +++ b/src/components/tree_view/__snapshots__/tree_view.test.tsx.snap @@ -21,7 +21,7 @@ exports[`EuiTreeView is rendered 1`] = ` class="euiTreeView__node euiTreeView__node--expanded" >
    @@ -139,7 +139,7 @@ exports[`EuiTreeView is rendered 1`] = ` class="euiTreeView__node" >
    diff --git a/src/components/tree_view/tree_view.tsx b/src/components/tree_view/tree_view.tsx index 440bb9a1adc..b081c79778b 100644 --- a/src/components/tree_view/tree_view.tsx +++ b/src/components/tree_view/tree_view.tsx @@ -35,6 +35,14 @@ function hasAriaLabel( return x.hasOwnProperty('aria-label'); } +function getTreeId( + propId: string | undefined, + contextId: string, + idGenerator: Function +) { + return propId ?? (contextId === '' ? idGenerator() : contextId); +} + export interface Node { /** An array of EuiTreeViewNodes to render as children */ @@ -124,12 +132,19 @@ export class EuiTreeView extends Component { ) .filter((x) => x != null), activeItem: '', - treeID: - this.props.id ?? - (this.context === '' ? this.treeIdGenerator() : this.context), + treeID: getTreeId(this.props.id, this.context, this.treeIdGenerator), expandChildNodes: this.props.expandByDefault || false, }; + componentDidUpdate(prevProps: EuiTreeViewProps) { + if (this.props.id !== prevProps.id) { + // eslint-disable-next-line react/no-did-update-set-state + this.setState({ + treeID: getTreeId(this.props.id, this.context, this.treeIdGenerator), + }); + } + } + buttonRef: Array = []; setButtonRef = ( @@ -279,11 +294,8 @@ export class EuiTreeView extends Component { aria-describedby={!this.isNested ? instructionsId : undefined} {...rest}> {items.map((node, index) => { - const buttonId = - node.id ?? `${this.state.treeID}--${this.treeIdGenerator()}`; - const wrappingId = `euiNestedTreeView-${ - this.state.treeID - }--${this.treeIdGenerator()}`; + const buttonId = node.id; + const wrappingId = this.treeIdGenerator(buttonId); return (