Skip to content

Commit 0811452

Browse files
feat(Dropdown): Add optional container with ouiaId (#12022)
* feat(Dropdown): Add optional container with ouiaId Container component can be customized via a prop as well. Container does not render if containerOuiaId is not used, so as not to break existing consumers. * Update packages/react-core/src/components/Dropdown/__tests__/Dropdown.test.tsx Co-authored-by: Eric Olkowski <70952936+thatblindgeye@users.noreply.github.com> --------- Co-authored-by: Eric Olkowski <70952936+thatblindgeye@users.noreply.github.com>
1 parent 07c2bbf commit 0811452

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

packages/react-core/src/components/Dropdown/Dropdown.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ export interface DropdownProps extends MenuProps, OUIAProps {
4848
ouiaId?: number | string;
4949
/** 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. */
5050
ouiaSafe?: boolean;
51+
/** When applied, wraps dropdown in a container with a data-ouia-component-id.*/
52+
containerOuiaId?: number | string;
53+
/** 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. */
54+
containerOuiaSafe?: boolean;
55+
/** Sets the base component to render for the container. Defaults to <span> */
56+
containerComponent?: React.ReactNode;
5157
/** z-index of the dropdown menu */
5258
zIndex?: number;
5359
/** Additional properties to pass to the Popper */
@@ -86,11 +92,16 @@ const DropdownBase: React.FunctionComponent<DropdownProps> = ({
8692
shouldFocusFirstItemOnOpen = false,
8793
shouldPreventScrollOnItemFocus = true,
8894
focusTimeoutDelay = 0,
95+
containerOuiaId,
96+
containerOuiaSafe = true,
97+
containerComponent = 'span',
8998
...props
9099
}: DropdownProps) => {
91100
const localMenuRef = useRef<HTMLDivElement>(undefined);
92101
const localToggleRef = useRef<HTMLButtonElement>(undefined);
93102
const ouiaProps = useOUIAProps(Dropdown.displayName, ouiaId, ouiaSafe);
103+
const ContainerComponent = containerComponent as any;
104+
const containerOuiaProps = useOUIAProps('Dropdown container', containerOuiaId, containerOuiaSafe);
94105

95106
const menuRef = (innerRef as React.RefObject<HTMLDivElement | null>) || localMenuRef;
96107
const toggleRef =
@@ -185,7 +196,8 @@ const DropdownBase: React.FunctionComponent<DropdownProps> = ({
185196
</MenuContent>
186197
</Menu>
187198
);
188-
return (
199+
200+
const popper = (
189201
<Popper
190202
trigger={typeof toggle === 'function' ? toggle(toggleRef) : toggle.toggleNode}
191203
triggerRef={toggleRef}
@@ -196,6 +208,8 @@ const DropdownBase: React.FunctionComponent<DropdownProps> = ({
196208
{...popperProps}
197209
/>
198210
);
211+
212+
return containerOuiaId ? <ContainerComponent {...containerOuiaProps}>{popper}</ContainerComponent> : popper;
199213
};
200214

201215
export const Dropdown = forwardRef((props: DropdownProps, ref: React.Ref<any>) => (

packages/react-core/src/components/Dropdown/__tests__/Dropdown.test.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,32 @@ test('onOpenChange is called when passed and user presses esc key', async () =>
201201
expect(onOpenChange).toBeCalledTimes(1);
202202
});
203203

204+
test('applies containerOuiaId to parent element', () => {
205+
render(
206+
<Dropdown containerOuiaId="test-dropdown" toggle={(toggleRef) => toggle(toggleRef)}>
207+
{dropdownChildren}
208+
</Dropdown>
209+
);
210+
211+
const dropdownToggle = screen.getByRole('button', { name: 'Dropdown' });
212+
const dropdownParent = dropdownToggle?.parentNode?.parentNode;
213+
expect(dropdownParent).toHaveAttribute('data-ouia-component-id', 'test-dropdown');
214+
expect(dropdownParent).toHaveAttribute('data-ouia-component-type', 'PF6/Dropdown container');
215+
expect(dropdownParent?.tagName).toBe('SPAN');
216+
});
217+
218+
test('Renders with custom container element when containerComponent is passed', () => {
219+
render(
220+
<Dropdown containerOuiaId="test-dropdown" containerComponent="div" toggle={(toggleRef) => toggle(toggleRef)}>
221+
{dropdownChildren}
222+
</Dropdown>
223+
);
224+
225+
const dropdownToggle = screen.getByRole('button', { name: 'Dropdown' });
226+
const dropdownParent = dropdownToggle?.parentNode?.parentNode;
227+
expect(dropdownParent?.tagName).toBe('DIV');
228+
});
229+
204230
test('match snapshot', () => {
205231
const { asFragment } = render(
206232
<Dropdown

0 commit comments

Comments
 (0)