diff --git a/packages/module/src/ResponsiveActions/ResponsiveActions.test.tsx b/packages/module/src/ResponsiveActions/ResponsiveActions.test.tsx
index f3c29fec..41f2bfae 100644
--- a/packages/module/src/ResponsiveActions/ResponsiveActions.test.tsx
+++ b/packages/module/src/ResponsiveActions/ResponsiveActions.test.tsx
@@ -56,5 +56,82 @@ describe('ResponsiveActions component', () => {
expect(buttons).toHaveLength(2);
expect(container).toMatchSnapshot();
});
+
+ test('ResponsiveActions with all dropdown items disabled should disable kebab', () => {
+ const { container } = render(
+
+ Disabled action 1
+ Disabled action 2
+ );
+
+ // Kebab toggle should be disabled when all dropdown items are disabled
+ const kebabToggle = container.querySelector('[data-ouia-component-id="ResponsiveActions-menu-dropdown-toggle"]');
+ expect(kebabToggle).toHaveAttribute('disabled');
+ expect(container).toMatchSnapshot();
+ });
+
+ test('ResponsiveActions with some enabled dropdown items should not disable kebab', () => {
+ const { container } = render(
+
+ Disabled action
+ Enabled action
+ );
+
+ // Kebab toggle should be enabled when at least one dropdown item is enabled
+ const kebabToggle = container.querySelector('[data-ouia-component-id="ResponsiveActions-menu-dropdown-toggle"]');
+ expect(kebabToggle).not.toHaveAttribute('disabled');
+ expect(container).toMatchSnapshot();
+ });
+
+ test('ResponsiveActions with enabled pinned item and disabled regular item should disable kebab above breakpoint', () => {
+ const { container } = render(
+
+ Enabled pinned action
+ Disabled regular action
+ );
+
+ // Above breakpoint: pinned items show as buttons, so kebab is disabled if regular items are disabled
+ // (When resized below breakpoint, the pinned item moves into kebab and it becomes enabled)
+ const kebabToggle = container.querySelector('[data-ouia-component-id="ResponsiveActions-menu-dropdown-toggle"]');
+ expect(kebabToggle).toHaveAttribute('disabled');
+ expect(container).toMatchSnapshot();
+ });
+
+ test('ResponsiveActions with enabled pinned item and enabled regular item should not disable kebab', () => {
+ const { container } = render(
+
+ Enabled pinned action
+ Enabled regular action
+ );
+
+ // Kebab should be enabled because there's an enabled regular action
+ const kebabToggle = container.querySelector('[data-ouia-component-id="ResponsiveActions-menu-dropdown-toggle"]');
+ expect(kebabToggle).not.toHaveAttribute('disabled');
+ expect(container).toMatchSnapshot();
+ });
+
+ test('ResponsiveActions with all dropdown items disabled including pinned should disable kebab', () => {
+ const { container } = render(
+
+ Disabled pinned action
+ Disabled action
+ );
+
+ // Kebab toggle should be disabled when all dropdown items (including pinned) are disabled
+ const kebabToggle = container.querySelector('[data-ouia-component-id="ResponsiveActions-menu-dropdown-toggle"]');
+ expect(kebabToggle).toHaveAttribute('disabled');
+ expect(container).toMatchSnapshot();
+ });
+
+ 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..53ce101b 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,68 @@ export interface ResponsiveActionsProps extends Omit = ({ ouiaId = 'ResponsiveActions', breakpoint = 'lg', children, ...props }: ResponsiveActionsProps) => {
+// Inner component that has access to OverflowMenuContext
+const ResponsiveActionsDropdown: FunctionComponent<{
+ ouiaId: string;
+ dropdownItems: ReactNode[];
+ pinnedItemsDisabled: boolean[];
+ regularItemsDisabled: boolean[];
+}> = ({ ouiaId, dropdownItems, pinnedItemsDisabled, regularItemsDisabled }) => {
const [ isOpen, setIsOpen ] = useState(false);
+ const { isBelowBreakpoint } = useContext(OverflowMenuContext);
+
+ // Determine if kebab should be disabled based on breakpoint
+ const isKebabDisabled = (() => {
+ const allPinnedDisabled = pinnedItemsDisabled.length > 0 && pinnedItemsDisabled.every(disabled => disabled);
+ const allRegularDisabled = regularItemsDisabled.length > 0 && regularItemsDisabled.every(disabled => disabled);
+
+ if (isBelowBreakpoint) {
+ // Below breakpoint: pinned items are IN the dropdown, so check all dropdown items
+ // Disabled only if both pinned AND regular items exist and are all disabled
+ return (pinnedItemsDisabled.length > 0 || regularItemsDisabled.length > 0) &&
+ (pinnedItemsDisabled.length === 0 || allPinnedDisabled) &&
+ (regularItemsDisabled.length === 0 || allRegularDisabled);
+ } else {
+ // Above breakpoint: pinned items are shown as buttons, only check regular items
+ // Disabled only if there are regular items and they're all disabled
+ 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) => {
@@ -47,6 +103,12 @@ export const ResponsiveActions: FunctionComponent = ({ o
{children}
);
+ // Track disabled state separately for pinned vs regular items
+ if (isPinned) {
+ pinnedItemsDisabled.push(!!actionProps.isDisabled);
+ } else {
+ regularItemsDisabled.push(!!actionProps.isDisabled);
+ }
}
}
});
@@ -74,27 +136,12 @@ export const ResponsiveActions: FunctionComponent = ({ o
) : null}
{dropdownItems.length > 0 && (
- setIsOpen(false)}
- toggle={(toggleRef) => (
- }
- onClick={() => setIsOpen(!isOpen)}
- isExpanded={isOpen}
- />
- )}
- isOpen={isOpen}
- onOpenChange={setIsOpen}
- >
-
- {dropdownItems}
-
-
+
)}
diff --git a/packages/module/src/ResponsiveActions/__snapshots__/ResponsiveActions.test.tsx.snap b/packages/module/src/ResponsiveActions/__snapshots__/ResponsiveActions.test.tsx.snap
index 7527af80..d8100a72 100644
--- a/packages/module/src/ResponsiveActions/__snapshots__/ResponsiveActions.test.tsx.snap
+++ b/packages/module/src/ResponsiveActions/__snapshots__/ResponsiveActions.test.tsx.snap
@@ -100,6 +100,270 @@ exports[`ResponsiveActions component should render correctly ResponsiveActions 1
`;
+exports[`ResponsiveActions component should render correctly ResponsiveActions with all dropdown items disabled including pinned should disable kebab 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`ResponsiveActions component should render correctly ResponsiveActions with all dropdown items disabled should disable kebab 1`] = `
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`ResponsiveActions component should render correctly ResponsiveActions with enabled pinned item and disabled regular item should disable kebab above breakpoint 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`ResponsiveActions component should render correctly ResponsiveActions with enabled pinned item and enabled regular item should not disable kebab 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
exports[`ResponsiveActions component should render correctly ResponsiveActions with mix of isPersistent and isPinned actions 1`] = `
`;
+
+exports[`ResponsiveActions component should render correctly ResponsiveActions with some enabled dropdown items should not disable kebab 1`] = `
+