Skip to content

Commit ee80e20

Browse files
committed
fix: hide actions dropdown when empty
1 parent d8af989 commit ee80e20

File tree

3 files changed

+67
-17
lines changed

3 files changed

+67
-17
lines changed

config/setupTests.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
/* eslint-disable no-undef */
12
import 'whatwg-fetch';
23
import 'babel-polyfill';
34
import '@testing-library/jest-dom';
5+
6+
global.ResizeObserver = jest.fn().mockImplementation(() => ({
7+
observe: jest.fn(),
8+
unobserve: jest.fn(),
9+
disconnect: jest.fn(),
10+
}));

packages/module/patternfly-docs/content/extensions/component-groups/examples/ResponsiveActions/ResponsiveActionsExample.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ import { ResponsiveAction } from '@patternfly/react-component-groups/dist/dynami
33
import { ResponsiveActions } from '@patternfly/react-component-groups/dist/dynamic/ResponsiveActions';
44

55
export const TagCountDisabledExample: React.FunctionComponent = () => (
6-
<ResponsiveActions breakpoint="lg">
6+
<ResponsiveActions breakpoint="md">
77
<ResponsiveAction isPersistent>
8-
Persistent Action
8+
Persistent Action
99
</ResponsiveAction>
1010
<ResponsiveAction isPinned variant='secondary'>
11-
Pinned Action
11+
Pinned Action
1212
</ResponsiveAction>
1313
<ResponsiveAction>
14-
Overflow Action
14+
Overflow Action
1515
</ResponsiveAction>
1616
</ResponsiveActions>
1717
);

packages/module/src/ResponsiveActions/ResponsiveActions.tsx

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1-
import React, { useState } from 'react';
2-
import { Button, Dropdown, DropdownList, MenuToggle, OverflowMenu, OverflowMenuContent, OverflowMenuControl, OverflowMenuDropdownItem, OverflowMenuGroup, OverflowMenuItem, OverflowMenuProps } from '@patternfly/react-core';
1+
import React, { useState, useEffect } from 'react';
2+
import {
3+
Button, Dropdown, DropdownList, MenuToggle,
4+
OverflowMenu, OverflowMenuContent, OverflowMenuControl,
5+
OverflowMenuDropdownItem, OverflowMenuGroup, OverflowMenuItem,
6+
OverflowMenuProps,
7+
} from '@patternfly/react-core';
38
import { EllipsisVIcon } from '@patternfly/react-icons';
49
import { ResponsiveActionProps } from '../ResponsiveAction';
510

@@ -10,12 +15,51 @@ export interface ResponsiveActionsProps extends Omit<OverflowMenuProps, 'ref' |
1015
ouiaId?: string;
1116
/** Child actions to be displayed */
1217
children: React.ReactNode;
18+
/** Reference element for breakpoint calculations */
19+
breakpointReference?: React.RefObject<HTMLElement>;
1320
}
1421

15-
export const ResponsiveActions: React.FunctionComponent<ResponsiveActionsProps> = ({ ouiaId = 'ResponsiveActions', breakpoint = 'lg', children, ...props }: ResponsiveActionsProps) => {
22+
const breakpoints = {
23+
sm: 576,
24+
md: 768,
25+
lg: 992,
26+
xl: 1200,
27+
'2xl': 1450,
28+
};
29+
30+
export const ResponsiveActions: React.FunctionComponent<ResponsiveActionsProps> = ({
31+
ouiaId = 'ResponsiveActions',
32+
breakpoint = 'lg',
33+
children,
34+
breakpointReference,
35+
...props
36+
}: ResponsiveActionsProps) => {
1637
const [ isOpen, setIsOpen ] = useState(false);
38+
const [ isBelowBreakpoint, setIsBelowBreakpoint ] = useState(false);
39+
const currentBreakpoint = breakpoints[breakpoint];
40+
41+
useEffect(() => {
42+
const referenceElement = breakpointReference?.current;
43+
const observeSize = () => {
44+
const elementWidth = referenceElement?.offsetWidth || window.innerWidth;
45+
setIsBelowBreakpoint(elementWidth < currentBreakpoint);
46+
};
47+
48+
const observer = new ResizeObserver(observeSize);
49+
50+
if (referenceElement) {
51+
observer.observe(referenceElement);
52+
} else {
53+
window.addEventListener('resize', observeSize);
54+
observeSize();
55+
}
56+
57+
return () => {
58+
observer.disconnect();
59+
window.removeEventListener('resize', observeSize);
60+
};
61+
}, [ breakpointReference, currentBreakpoint ]);
1762

18-
// separate persistent, pinned and collapsed actions
1963
const persistentActions: React.ReactNode[] = [];
2064
const pinnedActions: React.ReactNode[] = [];
2165
const dropdownItems: React.ReactNode[] = [];
@@ -24,18 +68,17 @@ export const ResponsiveActions: React.FunctionComponent<ResponsiveActionsProps>
2468
if (React.isValidElement<ResponsiveActionProps>(child)) {
2569
const { isPersistent, isPinned, key = index, children, onClick, ...actionProps } = child.props;
2670

27-
if (isPersistent || isPinned) {
71+
if (isPersistent || (isPinned && !isBelowBreakpoint)) {
2872
(isPersistent ? persistentActions : pinnedActions).push(
2973
<OverflowMenuItem key={key} isPersistent={isPersistent}>
3074
<Button onClick={onClick} ouiaId={`${ouiaId}-action-${key}`} {...actionProps}>
3175
{children}
3276
</Button>
3377
</OverflowMenuItem>
3478
);
35-
}
36-
if (!isPersistent) {
79+
} else {
3780
dropdownItems.push(
38-
<OverflowMenuDropdownItem key={key} onClick={onClick} isShared={isPinned} ouiaId={`${ouiaId}-action-${key}`}>
81+
<OverflowMenuDropdownItem key={key} onClick={onClick} ouiaId={`${ouiaId}-action-${key}`}>
3982
{children}
4083
</OverflowMenuDropdownItem>
4184
);
@@ -45,20 +88,20 @@ export const ResponsiveActions: React.FunctionComponent<ResponsiveActionsProps>
4588

4689
return (
4790
<OverflowMenu breakpoint={breakpoint} data-ouia-component-id={`${ouiaId}-menu`} {...props}>
48-
{persistentActions.length > 0 ? (
91+
{persistentActions.length > 0 && (
4992
<OverflowMenuContent isPersistent data-ouia-component-id={`${ouiaId}-menu-persistent-content`}>
5093
<OverflowMenuGroup groupType="button" data-ouia-component-id={`${ouiaId}-menu-persistent-group`} isPersistent>
5194
{persistentActions}
5295
</OverflowMenuGroup>
5396
</OverflowMenuContent>
54-
) : null}
55-
{pinnedActions.length > 0 ? (
97+
)}
98+
{pinnedActions.length > 0 && (
5699
<OverflowMenuContent data-ouia-component-id={`${ouiaId}-menu-pinned-content`}>
57100
<OverflowMenuGroup groupType="button" data-ouia-component-id={`${ouiaId}-menu-pinned-group`}>
58101
{pinnedActions}
59102
</OverflowMenuGroup>
60103
</OverflowMenuContent>
61-
) : null}
104+
)}
62105
{dropdownItems.length > 0 && (
63106
<OverflowMenuControl hasAdditionalOptions data-ouia-component-id={`${ouiaId}-menu-control`}>
64107
<Dropdown
@@ -89,4 +132,4 @@ export const ResponsiveActions: React.FunctionComponent<ResponsiveActionsProps>
89132
);
90133
};
91134

92-
export default ResponsiveActions;
135+
export default ResponsiveActions;

0 commit comments

Comments
 (0)