diff --git a/packages/module/src/ResponsiveActions/ResponsiveActions.test.tsx b/packages/module/src/ResponsiveActions/ResponsiveActions.test.tsx
index f3c29fec..a573e99b 100644
--- a/packages/module/src/ResponsiveActions/ResponsiveActions.test.tsx
+++ b/packages/module/src/ResponsiveActions/ResponsiveActions.test.tsx
@@ -1,4 +1,4 @@
-import { render } from '@testing-library/react';
+import { render, screen } from '@testing-library/react';
import ResponsiveActions from './ResponsiveActions';
import ResponsiveAction from '../ResponsiveAction';
@@ -56,5 +56,71 @@ describe('ResponsiveActions component', () => {
expect(buttons).toHaveLength(2);
expect(container).toMatchSnapshot();
});
+
+ test('ResponsiveActions with all dropdown items disabled should disable kebab', () => {
+ render(
+
+ Disabled action 1
+ Disabled action 2
+ );
+
+ const kebabToggle = screen.getByRole('button', { name: /actions overflow menu/i });
+ expect(kebabToggle).toBeDisabled();
+ });
+
+ test('ResponsiveActions with some enabled dropdown items should not disable kebab', () => {
+ render(
+
+ Disabled action
+ Enabled action
+ );
+
+ const kebabToggle = screen.getByRole('button', { name: /actions overflow menu/i });
+ expect(kebabToggle).toBeEnabled();
+ });
+
+ test('ResponsiveActions with enabled pinned item and disabled regular item should disable kebab above breakpoint', () => {
+ render(
+
+ Enabled pinned action
+ Disabled regular action
+ );
+
+ const kebabToggle = screen.getByRole('button', { name: /actions overflow menu/i });
+ expect(kebabToggle).toBeDisabled();
+ });
+
+ test('ResponsiveActions with enabled pinned item and enabled regular item should not disable kebab', () => {
+ render(
+
+ Enabled pinned action
+ Enabled regular action
+ );
+
+ const kebabToggle = screen.getByRole('button', { name: /actions overflow menu/i });
+ expect(kebabToggle).toBeEnabled();
+ });
+
+ test('ResponsiveActions with all dropdown items disabled including pinned should disable kebab', () => {
+ render(
+
+ Disabled pinned action
+ Disabled action
+ );
+
+ const kebabToggle = screen.getByRole('button', { name: /actions overflow menu/i });
+ expect(kebabToggle).toBeDisabled();
+ });
+
+ test('ResponsiveActions with only persistent items should not render kebab', () => {
+ const { container } = render(
+
+ Persistent action
+ );
+
+ // Should not have kebab when only persistent items exist
+ const kebabToggle = container.querySelector('[data-ouia-component-id="ResponsiveActions-menu-dropdown-toggle"]');
+ expect(kebabToggle).toBeNull();
+ });
});
});
\ No newline at end of file
diff --git a/packages/module/src/ResponsiveActions/ResponsiveActions.tsx b/packages/module/src/ResponsiveActions/ResponsiveActions.tsx
index a7e1c5f7..54714c6e 100644
--- a/packages/module/src/ResponsiveActions/ResponsiveActions.tsx
+++ b/packages/module/src/ResponsiveActions/ResponsiveActions.tsx
@@ -1,8 +1,9 @@
import type { ReactNode, FunctionComponent } from 'react';
-import { Children, isValidElement, useState } from 'react';
+import { Children, isValidElement, useState, useContext } 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';
+import { OverflowMenuContext } from '@patternfly/react-core/dist/esm/components/OverflowMenu/OverflowMenuContext';
/** extends OverflowMenuProps */
export interface ResponsiveActionsProps extends Omit {
@@ -14,13 +15,62 @@ export interface ResponsiveActionsProps extends Omit = ({ ouiaId = 'ResponsiveActions', breakpoint = 'lg', children, ...props }: ResponsiveActionsProps) => {
+const ResponsiveActionsDropdown: FunctionComponent<{
+ ouiaId: string;
+ dropdownItems: ReactNode[];
+ pinnedItemsDisabled: boolean[];
+ regularItemsDisabled: boolean[];
+}> = ({ ouiaId, dropdownItems, pinnedItemsDisabled, regularItemsDisabled }) => {
const [ isOpen, setIsOpen ] = useState(false);
+ const { isBelowBreakpoint } = useContext(OverflowMenuContext);
+
+ const isKebabDisabled = (() => {
+ const allPinnedDisabled = pinnedItemsDisabled.length > 0 && pinnedItemsDisabled.every(disabled => disabled);
+ const allRegularDisabled = regularItemsDisabled.length > 0 && regularItemsDisabled.every(disabled => disabled);
+
+ if (isBelowBreakpoint) {
+ return (pinnedItemsDisabled.length > 0 || regularItemsDisabled.length > 0) &&
+ (pinnedItemsDisabled.length === 0 || allPinnedDisabled) &&
+ (regularItemsDisabled.length === 0 || allRegularDisabled);
+ } else {
+ return allRegularDisabled;
+ }
+ })();
+
+ return (
+ setIsOpen(false)}
+ toggle={(toggleRef) => (
+ }
+ onClick={() => setIsOpen(!isOpen)}
+ isExpanded={isOpen}
+ isDisabled={isKebabDisabled}
+ />
+ )}
+ isOpen={isOpen}
+ onOpenChange={setIsOpen}
+ >
+
+ {dropdownItems}
+
+
+ );
+};
+
+export const ResponsiveActions: FunctionComponent = ({ ouiaId = 'ResponsiveActions', breakpoint = 'lg', children, ...props }: ResponsiveActionsProps) => {
// separate persistent, pinned and collapsed actions
const persistentActions: ReactNode[] = [];
const pinnedActions: ReactNode[] = [];
const dropdownItems: ReactNode[] = [];
+ const pinnedItemsDisabled: boolean[] = [];
+ const regularItemsDisabled: boolean[] = [];
let hasRegularActions = false;
Children.forEach(children, (child, index) => {
@@ -37,7 +87,6 @@ export const ResponsiveActions: FunctionComponent = ({ o
);
} else {
- // Track if there are any regular (non-persistent, non-pinned) actions
hasRegularActions = true;
}
@@ -47,6 +96,11 @@ export const ResponsiveActions: FunctionComponent = ({ o
{children}
);
+ if (isPinned) {
+ pinnedItemsDisabled.push(!!actionProps.isDisabled);
+ } else {
+ regularItemsDisabled.push(!!actionProps.isDisabled);
+ }
}
}
});
@@ -74,27 +128,12 @@ export const ResponsiveActions: FunctionComponent = ({ o
) : null}
{dropdownItems.length > 0 && (
- setIsOpen(false)}
- toggle={(toggleRef) => (
- }
- onClick={() => setIsOpen(!isOpen)}
- isExpanded={isOpen}
- />
- )}
- isOpen={isOpen}
- onOpenChange={setIsOpen}
- >
-
- {dropdownItems}
-
-
+
)}