diff --git a/packages/react-core/src/components/Dropdown/Dropdown.tsx b/packages/react-core/src/components/Dropdown/Dropdown.tsx index 9ad39d49477..c1e4210cff4 100644 --- a/packages/react-core/src/components/Dropdown/Dropdown.tsx +++ b/packages/react-core/src/components/Dropdown/Dropdown.tsx @@ -63,6 +63,12 @@ export interface DropdownProps extends MenuProps, OUIAProps { ouiaId?: number | string; /** Set the value of data-ouia-safe. Only set to true when the component is in a static state, i.e. no animations are occurring. At all other times, this value must be false. */ ouiaSafe?: boolean; + /** When applied, wraps dropdown in a container with a data-ouia-component-id.*/ + containerOuiaId?: number | string; + /** Set the value of data-ouia-safe for the container when containerOuiaId is applied. Only set to true when the component is in a static state, i.e. no animations are occurring. At all other times, this value must be false. */ + containerOuiaSafe?: boolean; + /** Sets the base component to render for the container. Defaults to */ + containerComponent?: React.ReactNode; /** z-index of the dropdown menu */ zIndex?: number; /** Additional properties to pass to the Popper */ @@ -101,11 +107,16 @@ const DropdownBase: React.FunctionComponent = ({ shouldFocusFirstItemOnOpen = false, shouldPreventScrollOnItemFocus = true, focusTimeoutDelay = 0, + containerOuiaId, + containerOuiaSafe = true, + containerComponent = 'span', ...props }: DropdownProps) => { const localMenuRef = useRef(undefined); const localToggleRef = useRef(undefined); const ouiaProps = useOUIAProps(Dropdown.displayName, ouiaId, ouiaSafe); + const ContainerComponent = containerComponent as any; + const containerOuiaProps = useOUIAProps('Dropdown container', containerOuiaId, containerOuiaSafe); const menuRef = (innerRef as React.RefObject) || localMenuRef; const toggleRef = @@ -200,7 +211,8 @@ const DropdownBase: React.FunctionComponent = ({ ); - return ( + + const popper = ( = ({ {...popperProps} /> ); + + return containerOuiaId ? {popper} : popper; }; export const Dropdown = forwardRef((props: DropdownProps, ref: React.Ref) => ( diff --git a/packages/react-core/src/components/Dropdown/__tests__/Dropdown.test.tsx b/packages/react-core/src/components/Dropdown/__tests__/Dropdown.test.tsx index 73e6d5068d5..b8b78399fe5 100644 --- a/packages/react-core/src/components/Dropdown/__tests__/Dropdown.test.tsx +++ b/packages/react-core/src/components/Dropdown/__tests__/Dropdown.test.tsx @@ -201,6 +201,32 @@ test('onOpenChange is called when passed and user presses esc key', async () => expect(onOpenChange).toBeCalledTimes(1); }); +test('applies containerOuiaId to parent element', () => { + render( + toggle(toggleRef)}> + {dropdownChildren} + + ); + + const dropdownToggle = screen.getByRole('button', { name: 'Dropdown' }); + const dropdownParent = dropdownToggle?.parentNode?.parentNode; + expect(dropdownParent).toHaveAttribute('data-ouia-component-id', 'test-dropdown'); + expect(dropdownParent).toHaveAttribute('data-ouia-component-type', 'PF6/Dropdown container'); + expect(dropdownParent?.tagName).toBe('SPAN'); +}); + +test('Renders with custom container element when containerComponent is passed', () => { + render( + toggle(toggleRef)}> + {dropdownChildren} + + ); + + const dropdownToggle = screen.getByRole('button', { name: 'Dropdown' }); + const dropdownParent = dropdownToggle?.parentNode?.parentNode; + expect(dropdownParent?.tagName).toBe('DIV'); +}); + test('match snapshot', () => { const { asFragment } = render(