Skip to content

feat(Toolbar,OverflowMenu): support responsive height vis breakpoints#12347

Open
kmcfaul wants to merge 5 commits intopatternfly:mainfrom
kmcfaul:responsive-heights
Open

feat(Toolbar,OverflowMenu): support responsive height vis breakpoints#12347
kmcfaul wants to merge 5 commits intopatternfly:mainfrom
kmcfaul:responsive-heights

Conversation

@kmcfaul
Copy link
Copy Markdown
Contributor

@kmcfaul kmcfaul commented Apr 10, 2026

What: Closes #12335

Needs patternfly/patternfly#8295 to be pulled in when merged for styling

  • Adds visibilityAtHeight props to ToolbarItem, ToolbarGroup, ToolbarContent that allows visibility to be changed based on specific height breakpoints
  • Adds isVertical to OverflowMenu that changes the layout orientation for vertical toolbars/elements that use OverflowMenu
  • Adds examples for Toolbar and OverflowMenu

Some notes:
I changed the OverflowMenu container example to full page to allow enough height for the breakpoint to change.
I also added a warning for vertical OverflowMenus that the sm breakpoint won't do anything (it evaluates to 0 from the token and cannot be calc'd - in practice sm means that something is always visible/above the breakpoint for OverflowMenu).

Summary by CodeRabbit

  • New Features

    • Vertical orientation support for OverflowMenu with height-based breakpoint behavior
    • Added height-based visibility controls (visibilityAtHeight) for ToolbarContent/Group/Item
  • Documentation

    • New examples showing vertical and height-based OverflowMenu and a vertical Toolbar
    • Clarified breakpoint wording in related docs
  • Chores

    • Bumped PatternFly dev dependency versions across packages

@kmcfaul kmcfaul marked this pull request as draft April 10, 2026 17:13
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 10, 2026

Walkthrough

Adds height-responsive behavior: OverflowMenu gains an isVertical prop and uses height-based breakpoint evaluation when vertical; ToolbarContent/ToolbarGroup/ToolbarItem gain visibilityAtHeight to control visibility by height breakpoints. New vertical/height examples and docs added; several devDependency version bumps included.

Changes

Cohort / File(s) Summary
OverflowMenu Core
packages/react-core/src/components/OverflowMenu/OverflowMenu.tsx
Added optional isVertical?: boolean (default false); split resize handling into handleResizeWidth and handleResizeHeight; added height breakpoint evaluation using globalHeightBreakpoints and container/client height; added runtime warnings/errors for invalid height breakpoints; exclude isVertical from spread props and apply styles.modifiers.vertical when set.
OverflowMenu Examples & Docs
packages/react-core/src/components/OverflowMenu/examples/OverflowMenu.md, packages/react-core/src/components/OverflowMenu/examples/OverflowMenuSimpleVertical.tsx, packages/react-core/src/components/OverflowMenu/examples/OverflowMenuBreakpointOnContainerHeight.tsx
Added vertical/height-focused examples and clarified existing example heading to indicate width-based container breakpoints.
Toolbar Core
packages/react-core/src/components/Toolbar/ToolbarContent.tsx, packages/react-core/src/components/Toolbar/ToolbarGroup.tsx, packages/react-core/src/components/Toolbar/ToolbarItem.tsx
Added visibilityAtHeight prop to components; clarified visibility JSDoc to specify width breakpoints; components now consume height and getVerticalBreakpoint from PageContext and apply height-driven modifiers via formatBreakpointMods(..., getVerticalBreakpoint(height), true).
Toolbar Examples & Docs
packages/react-core/src/components/Toolbar/examples/Toolbar.md, packages/react-core/src/components/Toolbar/examples/ToolbarVertical.tsx
Added docs describing vertical toolbars and visibilityAtHeight; added a vertical toolbar example demonstrating isVertical and height-based visibility behavior.
DevDependency bumps
packages/react-core/package.json, packages/react-docs/package.json, packages/react-icons/package.json, packages/react-styles/package.json, packages/react-tokens/package.json
Bumped @patternfly/patternfly devDependency from 6.5.0-prerelease.67 to 6.5.0-prerelease.68 across packages.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Window
participant OverflowMenu
participant PageContext
Note over Window,OverflowMenu: Resize or container size change triggers evaluation
Window->>OverflowMenu: emit resize (width or height)
OverflowMenu->>PageContext: request breakpoints (getBreakpoint / getVerticalBreakpoint) and sizes
PageContext-->>OverflowMenu: return breakpoint thresholds
OverflowMenu->>OverflowMenu: select handleResizeWidth or handleResizeHeight based on isVertical
OverflowMenu->>OverflowMenu: compare client/container size to breakpoint, update expanded/collapsed state

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • mcoker
  • thatblindgeye
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main changes: adding support for responsive height-based visibility breakpoints to both Toolbar and OverflowMenu components.
Linked Issues check ✅ Passed All coding objectives from issue #12335 are met: visibilityAtHeight props added to Toolbar components [ToolbarItem, ToolbarGroup, ToolbarContent], isVertical prop added to OverflowMenu with documentation updates, and examples demonstrating both features are provided.
Out of Scope Changes check ✅ Passed All changes are within scope; they address responsive height breakpoints and vertical OverflowMenu orientation as specified in issue #12335. Package version bumps for @patternfly/patternfly align with the styling requirement mentioned in PR objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@patternfly-build
Copy link
Copy Markdown
Collaborator

patternfly-build commented Apr 10, 2026

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/react-core/src/components/OverflowMenu/OverflowMenu.tsx (1)

63-72: ⚠️ Potential issue | 🟠 Major

Recompute the breakpoint when isVertical or breakpoint props change.

handleResize() branches on isVertical (lines 79–86) to use either height or width calculations, but componentDidUpdate() only reruns the calculation when breakpointRef changes. Flipping isVertical after mount or changing the breakpoint prop leaves isBelowBreakpoint stale until a resize event fires.

Suggested fix
  componentDidUpdate(prevProps: Readonly<OverflowMenuProps>, prevState: Readonly<OverflowMenuState>): void {
    const reference = this.props.breakpointReference ? this.getBreakpointRef() : undefined;

    if (prevState.breakpointRef !== reference) {
      // To remove any previous observer/event listener from componentDidMount before adding a new one
      this.observer();
      this.setState({ breakpointRef: reference });
      this.observer = getResizeObserver(reference, this.handleResizeWithDelay);
      this.handleResize();
+    } else if (
+      prevProps.isVertical !== this.props.isVertical ||
+      prevProps.breakpoint !== this.props.breakpoint
+    ) {
+      this.handleResize();
     }
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-core/src/components/OverflowMenu/OverflowMenu.tsx` around
lines 63 - 72, componentDidUpdate currently only reacts to breakpointRef changes
and so flipping isVertical or changing breakpoint leaves isBelowBreakpoint
stale; update componentDidUpdate (in OverflowMenu) to also detect prop changes
(prevProps.isVertical !== this.props.isVertical || prevProps.breakpoint !==
this.props.breakpoint) and when they change recompute the reference if needed
(use this.getBreakpointRef() like you do when computing reference) and call
this.handleResize() (and reattach observer if the breakpointReference-related
ref changed using this.observer = getResizeObserver(...)). Ensure you still call
this.observer() to cleanup and setState/update breakpointRef when the
breakpointReference-derived ref changes, but always invoke handleResize() when
isVertical or breakpoint props change so isBelowBreakpoint is updated
immediately.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@packages/react-core/src/components/OverflowMenu/examples/OverflowMenuBreakpointOnContainerHeight.tsx`:
- Around line 63-64: The displayed label text is wrong: in
OverflowMenuBreakpointOnContainerHeight.tsx update the span with id
"overflowMenu-hasBreakpointOnContainer-height-slider-label" (and any adjacent
text) from "Current container width" to "Current container height" (and ensure
any related aria/accessible labels or variables referencing containerHeight
reflect "height" consistently); keep the existing id and variable
containerHeight unchanged.
- Line 78: The example is using height-based breakpoint props but never toggles
OverflowMenu to vertical mode; update the <OverflowMenu> instance (the one with
props breakpointReference={containerRef} breakpoint="sm") to also pass
isVertical so OverflowMenu uses clientHeight for breakpoints, and change the
slider label text currently reading "Current container width" (around the slider
at line ~63) to "Current container height" so the UI and docs match the
height-based example.

In `@packages/react-core/src/components/Toolbar/examples/ToolbarVertical.tsx`:
- Around line 20-29: The example uses width-based props but should use height
breakpoints: replace the width-based visibility props with height-aware ones by
changing ToolbarGroup's visibility to visibilityAtHeight and each ToolbarItem's
visibility to visibilityAtHeight (i.e., keep the same breakpoint keys/values but
use visibilityAtHeight on ToolbarGroup and the two ToolbarItem instances with
lg/md/default as shown); update any prop names in ToolbarGroup and ToolbarItem
to visibilityAtHeight so the example demonstrates height breakpoints correctly.

---

Outside diff comments:
In `@packages/react-core/src/components/OverflowMenu/OverflowMenu.tsx`:
- Around line 63-72: componentDidUpdate currently only reacts to breakpointRef
changes and so flipping isVertical or changing breakpoint leaves
isBelowBreakpoint stale; update componentDidUpdate (in OverflowMenu) to also
detect prop changes (prevProps.isVertical !== this.props.isVertical ||
prevProps.breakpoint !== this.props.breakpoint) and when they change recompute
the reference if needed (use this.getBreakpointRef() like you do when computing
reference) and call this.handleResize() (and reattach observer if the
breakpointReference-related ref changed using this.observer =
getResizeObserver(...)). Ensure you still call this.observer() to cleanup and
setState/update breakpointRef when the breakpointReference-derived ref changes,
but always invoke handleResize() when isVertical or breakpoint props change so
isBelowBreakpoint is updated immediately.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4109d74c-080f-4724-9a72-c5cccf04a3cd

📥 Commits

Reviewing files that changed from the base of the PR and between 911223a and 08742ba.

📒 Files selected for processing (9)
  • packages/react-core/src/components/OverflowMenu/OverflowMenu.tsx
  • packages/react-core/src/components/OverflowMenu/examples/OverflowMenu.md
  • packages/react-core/src/components/OverflowMenu/examples/OverflowMenuBreakpointOnContainerHeight.tsx
  • packages/react-core/src/components/OverflowMenu/examples/OverflowMenuSimpleVertical.tsx
  • packages/react-core/src/components/Toolbar/ToolbarContent.tsx
  • packages/react-core/src/components/Toolbar/ToolbarGroup.tsx
  • packages/react-core/src/components/Toolbar/ToolbarItem.tsx
  • packages/react-core/src/components/Toolbar/examples/Toolbar.md
  • packages/react-core/src/components/Toolbar/examples/ToolbarVertical.tsx

@kmcfaul kmcfaul force-pushed the responsive-heights branch from 08742ba to fdd97ac Compare April 13, 2026 15:58
@kmcfaul kmcfaul marked this pull request as ready for review April 13, 2026 15:58
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/react-core/src/components/OverflowMenu/OverflowMenu.tsx`:
- Line 8: The import in OverflowMenu.tsx uses an absolute path for PickOptional
which is inconsistent with the project's relative import convention; change the
import of PickOptional to use the same relative path style as other helpers
(e.g., adjust the import statement referencing PickOptional in OverflowMenu.tsx
to the appropriate relative path such as ../../helpers or
../../helpers/typeUtils to match nearby files).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 545c30bc-6141-4039-bbd5-f785f11951ee

📥 Commits

Reviewing files that changed from the base of the PR and between 08742ba and fdd97ac.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (14)
  • packages/react-core/package.json
  • packages/react-core/src/components/OverflowMenu/OverflowMenu.tsx
  • packages/react-core/src/components/OverflowMenu/examples/OverflowMenu.md
  • packages/react-core/src/components/OverflowMenu/examples/OverflowMenuBreakpointOnContainerHeight.tsx
  • packages/react-core/src/components/OverflowMenu/examples/OverflowMenuSimpleVertical.tsx
  • packages/react-core/src/components/Toolbar/ToolbarContent.tsx
  • packages/react-core/src/components/Toolbar/ToolbarGroup.tsx
  • packages/react-core/src/components/Toolbar/ToolbarItem.tsx
  • packages/react-core/src/components/Toolbar/examples/Toolbar.md
  • packages/react-core/src/components/Toolbar/examples/ToolbarVertical.tsx
  • packages/react-docs/package.json
  • packages/react-icons/package.json
  • packages/react-styles/package.json
  • packages/react-tokens/package.json
✅ Files skipped from review due to trivial changes (7)
  • packages/react-docs/package.json
  • packages/react-tokens/package.json
  • packages/react-core/package.json
  • packages/react-icons/package.json
  • packages/react-styles/package.json
  • packages/react-core/src/components/OverflowMenu/examples/OverflowMenu.md
  • packages/react-core/src/components/Toolbar/examples/Toolbar.md
🚧 Files skipped from review as they are similar to previous changes (5)
  • packages/react-core/src/components/Toolbar/examples/ToolbarVertical.tsx
  • packages/react-core/src/components/Toolbar/ToolbarGroup.tsx
  • packages/react-core/src/components/Toolbar/ToolbarContent.tsx
  • packages/react-core/src/components/OverflowMenu/examples/OverflowMenuSimpleVertical.tsx
  • packages/react-core/src/components/Toolbar/ToolbarItem.tsx

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/react-core/src/components/OverflowMenu/OverflowMenu.tsx (1)

79-116: Clean refactor with symmetric width/height handling.

The dispatch logic and handleResizeHeight implementation are well-structured. One edge case to consider: if isVertical changes dynamically after mount, isBelowBreakpoint won't recalculate until the next resize event occurs since componentDidUpdate only checks for breakpointRef changes.

If dynamic isVertical switching is a supported use case, consider adding a check in componentDidUpdate:

♻️ Optional enhancement
 componentDidUpdate(prevProps: Readonly<OverflowMenuProps>, prevState: Readonly<OverflowMenuState>): void {
   const reference = this.props.breakpointReference ? this.getBreakpointRef() : undefined;

-  if (prevState.breakpointRef !== reference) {
+  if (prevState.breakpointRef !== reference || prevProps.isVertical !== this.props.isVertical) {
     // To remove any previous observer/event listener from componentDidMount before adding a new one
     this.observer();
     this.setState({ breakpointRef: reference });
     this.observer = getResizeObserver(reference, this.handleResizeWithDelay);
     this.handleResize();
   }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-core/src/components/OverflowMenu/OverflowMenu.tsx` around
lines 79 - 116, If isVertical can change at runtime, componentDidUpdate should
also detect a change in this.props.isVertical (compare prevProps.isVertical !==
this.props.isVertical) and trigger a recalculation of isBelowBreakpoint by
calling handleResize (or the appropriate handler: handleResizeWidth /
handleResizeHeight) so the state updates immediately when orientation switches;
update componentDidUpdate to include this check and call the same resize logic
used on window resize to keep isBelowBreakpoint in sync.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/react-core/src/components/OverflowMenu/OverflowMenu.tsx`:
- Around line 79-116: If isVertical can change at runtime, componentDidUpdate
should also detect a change in this.props.isVertical (compare
prevProps.isVertical !== this.props.isVertical) and trigger a recalculation of
isBelowBreakpoint by calling handleResize (or the appropriate handler:
handleResizeWidth / handleResizeHeight) so the state updates immediately when
orientation switches; update componentDidUpdate to include this check and call
the same resize logic used on window resize to keep isBelowBreakpoint in sync.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9ae93b45-9e22-4e8d-ad26-fc74e2687dce

📥 Commits

Reviewing files that changed from the base of the PR and between fdd97ac and 179cd4a.

📒 Files selected for processing (3)
  • packages/react-core/src/components/OverflowMenu/OverflowMenu.tsx
  • packages/react-core/src/components/OverflowMenu/examples/OverflowMenuBreakpointOnContainerHeight.tsx
  • packages/react-core/src/components/Toolbar/examples/ToolbarVertical.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/react-core/src/components/Toolbar/examples/ToolbarVertical.tsx
  • packages/react-core/src/components/OverflowMenu/examples/OverflowMenuBreakpointOnContainerHeight.tsx

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/react-core/src/components/Toolbar/examples/ToolbarVertical.tsx`:
- Around line 16-18: The example's label for ToolbarItem is inconsistent with
its visibilityAtHeight config: the prop visibilityAtHeight={{ default: 'hidden',
lg: 'visible' }} makes the item visible at the lg breakpoint, but the text says
"visible above md breakpoint." Update either the prop on the ToolbarItem or the
label text so they match; e.g., change the label to "Item 6 (visible at lg
breakpoint)" or change the visibilityAtHeight value to reflect "above md" (e.g.,
make it visible at md) — locate the ToolbarItem instance with the
visibilityAtHeight prop to apply the fix.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5aabe15c-53ba-4d84-aa22-9028e87159c8

📥 Commits

Reviewing files that changed from the base of the PR and between 179cd4a and be35ea3.

📒 Files selected for processing (4)
  • packages/react-core/src/components/OverflowMenu/OverflowMenu.tsx
  • packages/react-core/src/components/OverflowMenu/examples/OverflowMenu.md
  • packages/react-core/src/components/OverflowMenu/examples/OverflowMenuBreakpointOnContainerHeight.tsx
  • packages/react-core/src/components/Toolbar/examples/ToolbarVertical.tsx
✅ Files skipped from review due to trivial changes (1)
  • packages/react-core/src/components/OverflowMenu/examples/OverflowMenu.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/react-core/src/components/OverflowMenu/examples/OverflowMenuBreakpointOnContainerHeight.tsx

Comment on lines +16 to +18
<ToolbarItem visibilityAtHeight={{ default: 'hidden', lg: 'visible' }}>
Item 6 (visible above md breakpoint)
</ToolbarItem>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Item 6 description conflicts with its breakpoint config.

Line 16 makes Item 6 visible at lg, but Line 17 says “visible above md breakpoint.” Please align the label (or the prop) so the example isn’t misleading.

Suggested fix (label aligned to current behavior)
-        <ToolbarItem visibilityAtHeight={{ default: 'hidden', lg: 'visible' }}>
-          Item 6 (visible above md breakpoint)
+        <ToolbarItem visibilityAtHeight={{ default: 'hidden', lg: 'visible' }}>
+          Item 6 (visible above lg breakpoint)
         </ToolbarItem>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<ToolbarItem visibilityAtHeight={{ default: 'hidden', lg: 'visible' }}>
Item 6 (visible above md breakpoint)
</ToolbarItem>
<ToolbarItem visibilityAtHeight={{ default: 'hidden', lg: 'visible' }}>
Item 6 (visible above lg breakpoint)
</ToolbarItem>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-core/src/components/Toolbar/examples/ToolbarVertical.tsx`
around lines 16 - 18, The example's label for ToolbarItem is inconsistent with
its visibilityAtHeight config: the prop visibilityAtHeight={{ default: 'hidden',
lg: 'visible' }} makes the item visible at the lg breakpoint, but the text says
"visible above md breakpoint." Update either the prop on the ToolbarItem or the
label text so they match; e.g., change the label to "Item 6 (visible at lg
breakpoint)" or change the visibilityAtHeight value to reflect "above md" (e.g.,
make it visible at md) — locate the ToolbarItem instance with the
visibilityAtHeight prop to apply the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Toolbar/OverflowMenu - responsive height breakpoints for show/hide

2 participants