From 3dc4a27b57c188aac8626b479e4ce7aca49707fb Mon Sep 17 00:00:00 2001 From: Taylor Jones Date: Thu, 5 Sep 2024 17:03:59 -0500 Subject: [PATCH] fix(toggletip): prevent ref error (#17225) Co-authored-by: Gururaj J <89023023+Gururajj77@users.noreply.github.com> Co-authored-by: Nikhil Tomar <63502271+2nikhiltom@users.noreply.github.com> Co-authored-by: kennylam <909118+kennylam@users.noreply.github.com> --- .../react/src/components/Popover/index.tsx | 22 +++++++++++--- .../Toggletip/__tests__/Toggletip-test.js | 29 ++++++++++++++++++- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/packages/react/src/components/Popover/index.tsx b/packages/react/src/components/Popover/index.tsx index 8a2fc27dd12c..b71854c40d50 100644 --- a/packages/react/src/components/Popover/index.tsx +++ b/packages/react/src/components/Popover/index.tsx @@ -356,12 +356,26 @@ export const Popover: PopoverComponent = React.forwardRef( const mappedChildren = React.Children.map(children, (child) => { const item = child as any; + const displayName = item?.type?.displayName; + + /** + * Only trigger elements (button) or trigger components (ToggletipButton) should be + * cloned because these will be decorated with a trigger-specific className and ref. + * + * There are also some specific components that should not be cloned when autoAlign + * is on, even if they are a trigger element. + */ + const isTriggerElement = item?.type === 'button'; + const isTriggerComponent = + autoAlign && displayName && ['ToggletipButton'].includes(displayName); + const isAllowedTriggerComponent = + autoAlign && + displayName && + !['ToggletipContent', 'PopoverContent'].includes(displayName); if ( - (item?.type === 'button' || - (autoAlign && item?.type?.displayName !== 'PopoverContent') || - (autoAlign && item?.type?.displayName === 'ToggletipButton')) && - React.isValidElement(item) + React.isValidElement(item) && + (isTriggerElement || isTriggerComponent || isAllowedTriggerComponent) ) { const className = (item?.props as any)?.className; const ref = (item?.props as any).ref; diff --git a/packages/react/src/components/Toggletip/__tests__/Toggletip-test.js b/packages/react/src/components/Toggletip/__tests__/Toggletip-test.js index 3505fd573ba0..f592c8642968 100644 --- a/packages/react/src/components/Toggletip/__tests__/Toggletip-test.js +++ b/packages/react/src/components/Toggletip/__tests__/Toggletip-test.js @@ -7,7 +7,13 @@ const prefix = 'cds'; import React, { forwardRef } from 'react'; import { fireEvent, render, screen } from '@testing-library/react'; -import { Toggletip, ToggletipButton } from '..'; +import { + Toggletip, + ToggletipButton, + ToggletipContent, + ToggletipActions, +} from '..'; +import { Information } from '@carbon/react/icons'; import userEvent from '@testing-library/user-event'; describe('Toggletip', () => { @@ -175,5 +181,26 @@ describe('Toggletip', () => { ); expect(container.firstChild).not.toHaveClass(`${prefix}--popover--open`); }); + + describe('autoAlign', () => { + it('should render without errors when composed with ToggletipButton, ToggletipContent, ToggletipActions', async () => { + render( +
+ + + + + +

Test content

+ + Link + + +
+
+
+ ); + }); + }); }); });