diff --git a/config/setupTests.js b/config/setupTests.js index 5cb2f97d..1c7ab00b 100644 --- a/config/setupTests.js +++ b/config/setupTests.js @@ -1,3 +1,10 @@ +/* eslint-disable no-undef */ import 'whatwg-fetch'; import 'babel-polyfill'; import '@testing-library/jest-dom'; + +global.ResizeObserver = jest.fn().mockImplementation(() => ({ + observe: jest.fn(), + unobserve: jest.fn(), + disconnect: jest.fn(), +})); \ No newline at end of file diff --git a/packages/module/patternfly-docs/content/extensions/component-groups/examples/ResponsiveActions/ResponsiveActionsExample.tsx b/packages/module/patternfly-docs/content/extensions/component-groups/examples/ResponsiveActions/ResponsiveActionsExample.tsx index 14522bc7..1e029336 100644 --- a/packages/module/patternfly-docs/content/extensions/component-groups/examples/ResponsiveActions/ResponsiveActionsExample.tsx +++ b/packages/module/patternfly-docs/content/extensions/component-groups/examples/ResponsiveActions/ResponsiveActionsExample.tsx @@ -3,15 +3,15 @@ import { ResponsiveAction } from '@patternfly/react-component-groups/dist/dynami import { ResponsiveActions } from '@patternfly/react-component-groups/dist/dynamic/ResponsiveActions'; export const TagCountDisabledExample: React.FunctionComponent = () => ( - + - Persistent Action + Persistent Action - Pinned Action + Pinned Action - Overflow Action + Overflow Action ); diff --git a/packages/module/src/ResponsiveActions/ResponsiveActions.tsx b/packages/module/src/ResponsiveActions/ResponsiveActions.tsx index 5d082204..0d05e74b 100644 --- a/packages/module/src/ResponsiveActions/ResponsiveActions.tsx +++ b/packages/module/src/ResponsiveActions/ResponsiveActions.tsx @@ -1,5 +1,10 @@ -import React, { useState } from 'react'; -import { Button, Dropdown, DropdownList, MenuToggle, OverflowMenu, OverflowMenuContent, OverflowMenuControl, OverflowMenuDropdownItem, OverflowMenuGroup, OverflowMenuItem, OverflowMenuProps } from '@patternfly/react-core'; +import React, { useState, useEffect } from 'react'; +import { + Button, Dropdown, DropdownList, MenuToggle, + OverflowMenu, OverflowMenuContent, OverflowMenuControl, + OverflowMenuDropdownItem, OverflowMenuGroup, OverflowMenuItem, + OverflowMenuProps, +} from '@patternfly/react-core'; import { EllipsisVIcon } from '@patternfly/react-icons'; import { ResponsiveActionProps } from '../ResponsiveAction'; @@ -10,12 +15,51 @@ export interface ResponsiveActionsProps extends Omit; } -export const ResponsiveActions: React.FunctionComponent = ({ ouiaId = 'ResponsiveActions', breakpoint = 'lg', children, ...props }: ResponsiveActionsProps) => { +const breakpoints = { + sm: 576, + md: 768, + lg: 992, + xl: 1200, + '2xl': 1450, +}; + +export const ResponsiveActions: React.FunctionComponent = ({ + ouiaId = 'ResponsiveActions', + breakpoint = 'lg', + children, + breakpointReference, + ...props +}: ResponsiveActionsProps) => { const [ isOpen, setIsOpen ] = useState(false); + const [ isBelowBreakpoint, setIsBelowBreakpoint ] = useState(false); + const currentBreakpoint = breakpoints[breakpoint]; + + useEffect(() => { + const referenceElement = breakpointReference?.current; + const observeSize = () => { + const elementWidth = referenceElement?.offsetWidth || window.innerWidth; + setIsBelowBreakpoint(elementWidth < currentBreakpoint); + }; + + const observer = new ResizeObserver(observeSize); + + if (referenceElement) { + observer.observe(referenceElement); + } else { + window.addEventListener('resize', observeSize); + observeSize(); + } + + return () => { + observer.disconnect(); + window.removeEventListener('resize', observeSize); + }; + }, [ breakpointReference, currentBreakpoint ]); - // separate persistent, pinned and collapsed actions const persistentActions: React.ReactNode[] = []; const pinnedActions: React.ReactNode[] = []; const dropdownItems: React.ReactNode[] = []; @@ -24,7 +68,7 @@ export const ResponsiveActions: React.FunctionComponent if (React.isValidElement(child)) { const { isPersistent, isPinned, key = index, children, onClick, ...actionProps } = child.props; - if (isPersistent || isPinned) { + if (isPersistent || (isPinned && !isBelowBreakpoint)) { (isPersistent ? persistentActions : pinnedActions).push( ); - } - if (!isPersistent) { + } else { dropdownItems.push( - + {children} ); @@ -45,20 +88,20 @@ export const ResponsiveActions: React.FunctionComponent return ( - {persistentActions.length > 0 ? ( + {persistentActions.length > 0 && ( {persistentActions} - ) : null} - {pinnedActions.length > 0 ? ( + )} + {pinnedActions.length > 0 && ( {pinnedActions} - ) : null} + )} {dropdownItems.length > 0 && ( ); }; -export default ResponsiveActions; \ No newline at end of file +export default ResponsiveActions;