From 6a6d1064499a934b3ed708fd32a95d583a2021e1 Mon Sep 17 00:00:00 2001 From: Titani Date: Fri, 10 Apr 2026 14:25:07 -0400 Subject: [PATCH] fix(Toolbar filter): Fixed null exception in Toolbar filter --- .../src/components/Toolbar/ToolbarFilter.tsx | 25 +++++---- .../Toolbar/__tests__/ToolbarFilter.test.tsx | 54 +++++++++++++++++++ 2 files changed, 68 insertions(+), 11 deletions(-) create mode 100644 packages/react-core/src/components/Toolbar/__tests__/ToolbarFilter.test.tsx diff --git a/packages/react-core/src/components/Toolbar/ToolbarFilter.tsx b/packages/react-core/src/components/Toolbar/ToolbarFilter.tsx index 7284e853426..3b518c28af0 100644 --- a/packages/react-core/src/components/Toolbar/ToolbarFilter.tsx +++ b/packages/react-core/src/components/Toolbar/ToolbarFilter.tsx @@ -130,26 +130,29 @@ class ToolbarFilter extends Component { ) : null; if (!_isExpanded && this.state.isMounted) { + const collapsedLabelPortalTarget = labelGroupContentRef?.current?.firstElementChild ?? null; return ( {showToolbarItem && {children}} - {labelGroupContentRef?.current?.firstElementChild !== null && - ReactDOM.createPortal(labelGroup, labelGroupContentRef.current.firstElementChild)} + {collapsedLabelPortalTarget != null && ReactDOM.createPortal(labelGroup, collapsedLabelPortalTarget)} ); } return ( - {({ labelContainerRef }) => ( - - {showToolbarItem && {children}} - {labelContainerRef.current && ReactDOM.createPortal(labelGroup, labelContainerRef.current)} - {expandableLabelContainerRef && - expandableLabelContainerRef.current && - ReactDOM.createPortal(labelGroup, expandableLabelContainerRef.current)} - - )} + {({ labelContainerRef }) => { + const labelContainer = labelContainerRef?.current ?? null; + return ( + + {showToolbarItem && {children}} + {labelContainer != null && ReactDOM.createPortal(labelGroup, labelContainer)} + {expandableLabelContainerRef && + expandableLabelContainerRef.current && + ReactDOM.createPortal(labelGroup, expandableLabelContainerRef.current)} + + ); + }} ); } diff --git a/packages/react-core/src/components/Toolbar/__tests__/ToolbarFilter.test.tsx b/packages/react-core/src/components/Toolbar/__tests__/ToolbarFilter.test.tsx new file mode 100644 index 00000000000..4e37176b9b8 --- /dev/null +++ b/packages/react-core/src/components/Toolbar/__tests__/ToolbarFilter.test.tsx @@ -0,0 +1,54 @@ +import { createRef } from 'react'; +import { render, screen } from '@testing-library/react'; +import '@testing-library/jest-dom'; + +import { ToolbarContext } from '../ToolbarUtils'; +import { ToolbarFilter } from '../ToolbarFilter'; + +describe('ToolbarFilter', () => { + it('renders when ToolbarFilter is not under Toolbar or ToolbarContent (default context)', () => { + const deleteLabel = jest.fn(); + const deleteLabelGroup = jest.fn(); + + expect(() => + render( + + filter content + + ) + ).not.toThrow(); + + expect(screen.getByText('filter content')).toBeInTheDocument(); + }); + + it('does not throw when labelGroupContentRef.current is still null while collapsed (listed filters)', () => { + const labelGroupContentRef = createRef(); + expect(labelGroupContentRef.current).toBeNull(); + + expect(() => + render( + {}, + labelGroupContentRef, + updateNumberFilters: () => {}, + numberOfFilters: 0, + clearAllFilters: () => {} + }} + > + + filter content + + + ) + ).not.toThrow(); + + expect(screen.getByText('filter content')).toBeInTheDocument(); + }); +});