Skip to content

feat(Page): added responsive docked nav#12327

Open
thatblindgeye wants to merge 8 commits intopatternfly:mainfrom
thatblindgeye:iss12195_dockNav
Open

feat(Page): added responsive docked nav#12327
thatblindgeye wants to merge 8 commits intopatternfly:mainfrom
thatblindgeye:iss12195_dockNav

Conversation

@thatblindgeye
Copy link
Copy Markdown
Contributor

@thatblindgeye thatblindgeye commented Apr 8, 2026

What: Closes #12195

Some notes:

  • Docked nav looks to be broken in RTL in both Core demos and the React demo I updated here
  • The button icon (hamburger icon) looks to be misaligned in the docked nav when the text is expanded; looks to be an issue in Core as well
  • Core has the docked nav documented under the Nav component, but in React it's under Page. do we have plans to tidy this up?

Additional issues:

Summary by CodeRabbit

  • New Features

    • Dock variant styling and optional text-expanded modes for Button, MenuToggle, Nav, and Page.
    • Compact mode for the masthead logo.
    • Docked Page enhancements: expandable/collapsible dock, separate dock content vs masthead, and dock text-expanded state.
  • Documentation

    • Updated Page demo to showcase docked navigation, responsive masthead, and expanded/collapsed dock patterns (added icons).
  • Tests

    • Added and reorganized unit tests for dock/compact/text-expanded behaviors across components.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 8, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds dock-related and text-expanded boolean props across Button, MenuToggle, Nav, MastheadLogo, and Page; restructures Page docked rendering to accept dockContent and expansion flags; updates docked demo and replaces avatar/menu with dock toggles; and adds unit tests asserting new modifier classes.

Changes

Cohort / File(s) Summary
Buttons
packages/react-core/src/components/Button/Button.tsx
Added isDocked?: boolean and isTextExpanded?: boolean (@beta); defaulted both to false; conditionally apply styles.modifiers.dock and styles.modifiers.textExpanded.
MenuToggle
packages/react-core/src/components/MenuToggle/MenuToggle.tsx
Added isDocked?: boolean and isTextExpanded?: boolean (@beta); defaulted to false; include dock/text-expanded modifiers in computed classes.
Nav
packages/react-core/src/components/Nav/Nav.tsx
Added isTextExpanded?: boolean (@beta) default false; conditionally apply styles.modifiers.textExpanded on the rendered <nav>.
Masthead Logo
packages/react-core/src/components/Masthead/MastheadLogo.tsx
Added isCompact?: boolean (@beta) default false; conditionally apply styles.modifiers.compact to className.
Page
packages/react-core/src/components/Page/Page.tsx
Added isDockExpanded?: boolean, isDockTextExpanded?: boolean, and dockContent?: React.ReactNode (@beta); when variant === 'docked' render masthead outside the dock, always render dock container, and apply styles.modifiers.expanded / styles.modifiers.textExpanded conditionally; pageDockMain now renders dockContent.
Demo / Example
packages/react-core/src/demos/Page.md, packages/react-core/src/demos/examples/Page/PageDockedNav.tsx
Added icon imports; rewrote docked example to use isDockExpanded/isDockTextExpanded, separate mobile vs docked mastheads, toggles wired to new props, conditional tooltips based on text-expanded state, and updated skip-to-content target.
Tests
packages/react-core/src/components/Button/__tests__/Button.test.tsx, packages/react-core/src/components/MenuToggle/__tests__/MenuToggle.test.tsx, packages/react-core/src/components/Masthead/__tests__/Masthead.test.tsx, packages/react-core/src/components/Nav/__tests__/Nav.test.tsx, packages/react-core/src/components/Page/__tests__/Page.test.tsx
Added tests verifying conditional application of new .pf-m-dock / .pf-m-text-expanded / .pf-m-compact modifier classes; expanded Page dock tests to assert dockContent/masthead placement and expanded/textExpanded behaviors.

Sequence Diagram

sequenceDiagram
    actor User
    participant Demo as PageDockedNav
    participant Page as Page
    participant Nav as Nav
    participant Button as Button
    participant MenuToggle as MenuToggle

    User->>Demo: click dock/text toggle
    Demo->>Demo: set isDockExpanded / isDockTextExpanded state
    Demo->>Page: pass isDockExpanded, isDockTextExpanded, dockContent, masthead
    Page->>Page: apply .pf-m-expanded / .pf-m-text-expanded on dock container
    Demo->>Nav: render with isTextExpanded
    Nav->>Nav: apply textExpanded modifier
    Demo->>Button: render with isDocked / isTextExpanded
    Button->>Button: apply dock/textExpanded modifiers
    Demo->>MenuToggle: render with isDocked / isTextExpanded
    MenuToggle->>MenuToggle: apply dock/textExpanded modifiers
    Demo->>User: UI updates (dock expanded/collapsed, text shown/hidden)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • mcoker
  • kmcfaul
  • nicolethoen
🚥 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 title 'feat(Page): added responsive docked nav' clearly summarizes the main change—adding a responsive docked navigation feature to the Page component.
Linked Issues check ✅ Passed The PR implements all key coding requirements: Button with isDocked/isTextExpanded props, MenuToggle with dock variants, Nav with isTextExpanded, MastheadLogo with isCompact, Page with dock layout support, and comprehensive test coverage.
Out of Scope Changes check ✅ Passed All code changes directly support the docked nav implementation. The Page demo updates, component API extensions, and test additions are all aligned with issue #12195 requirements.
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 8, 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.

🧹 Nitpick comments (2)
packages/react-core/src/demos/examples/Page/PageDockedNav.tsx (1)

427-427: Remove unnecessary fragment wrapper.

The Page component is the only child element, so the wrapping fragment (<>...</>) is unnecessary.

♻️ Proposed fix
   return (
-    <>
-      <Page
+    <Page
       variant="docked"
       isDockExpanded={isDockExpanded}
       ...
-      </Page>
-    </>
+    </Page>
   );

Also applies to: 460-461

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-core/src/demos/examples/Page/PageDockedNav.tsx` at line 427,
The fragment wrapper around the single child Page component is unnecessary;
remove the surrounding <>...</> so that Page is returned/rendered directly.
Update both locations where a fragment encloses Page in PageDockedNav.tsx (the
JSX that currently wraps <Page ... />) to eliminate the fragment and leave just
the Page element, ensuring any props or surrounding JSX remain intact.
packages/react-core/src/components/Page/Page.tsx (1)

31-31: Add JSDoc description and @beta tag for dockedMasthead prop.

The dockedMasthead prop is missing both a JSDoc description and the @beta tag, unlike the other new dock-related props (isDockExpanded, isDockTextExpanded).

📝 Proposed fix
-  dockedMasthead?: React.ReactNode;
+  /** `@beta` Docked masthead component rendered inside the dock container. Only applies when variant is docked. */
+  dockedMasthead?: React.ReactNode;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-core/src/components/Page/Page.tsx` at line 31, The prop
declaration dockedMasthead?: React.ReactNode is missing a JSDoc comment and the
`@beta` tag; add a short JSDoc description explaining it renders the masthead when
the dock is anchored (matching style of isDockExpanded/isDockTextExpanded) and
prepend `@beta` so it appears in generated docs, ensuring formatting/comments
follow the existing JSDoc conventions used in Page.tsx.
🤖 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/Page/Page.tsx`:
- Line 31: The prop declaration dockedMasthead?: React.ReactNode is missing a
JSDoc comment and the `@beta` tag; add a short JSDoc description explaining it
renders the masthead when the dock is anchored (matching style of
isDockExpanded/isDockTextExpanded) and prepend `@beta` so it appears in generated
docs, ensuring formatting/comments follow the existing JSDoc conventions used in
Page.tsx.

In `@packages/react-core/src/demos/examples/Page/PageDockedNav.tsx`:
- Line 427: The fragment wrapper around the single child Page component is
unnecessary; remove the surrounding <>...</> so that Page is returned/rendered
directly. Update both locations where a fragment encloses Page in
PageDockedNav.tsx (the JSX that currently wraps <Page ... />) to eliminate the
fragment and leave just the Page element, ensuring any props or surrounding JSX
remain intact.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d29e4335-40ec-48f1-a7ba-77f905c7e5a5

📥 Commits

Reviewing files that changed from the base of the PR and between 911223a and 10b8bcd.

📒 Files selected for processing (7)
  • packages/react-core/src/components/Button/Button.tsx
  • packages/react-core/src/components/Masthead/MastheadLogo.tsx
  • packages/react-core/src/components/MenuToggle/MenuToggle.tsx
  • packages/react-core/src/components/Nav/Nav.tsx
  • packages/react-core/src/components/Page/Page.tsx
  • packages/react-core/src/demos/Page.md
  • packages/react-core/src/demos/examples/Page/PageDockedNav.tsx

@thatblindgeye thatblindgeye marked this pull request as draft April 8, 2026 14:04
@thatblindgeye thatblindgeye requested review from kmcfaul and mcoker April 10, 2026 13:46
@thatblindgeye thatblindgeye marked this pull request as ready for review April 10, 2026 13:48
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

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

25-32: Use docked consistently in new prop descriptions.

The new JSDoc uses “dock”/“variant of dock” while the actual variant literal is 'docked'. Tightening this wording will avoid ambiguity in API docs.

Suggested wording update
-  /** `@beta` Flag indicating the dock nav is expanded on mobile. Only applies when variant is dock. */
+  /** `@beta` Flag indicating the dock nav is expanded on mobile. Only applies when variant is docked. */
   isDockExpanded?: boolean;
-  /** `@beta` Flag indicating the dock nav should display text. Only applies when variant is dock. */
+  /** `@beta` Flag indicating the dock nav should display text. Only applies when variant is docked. */
   isDockTextExpanded?: boolean;
@@
-  /** `@beta` Content to render in the vertical dock when variant of dock is used. At mobile viewports, this content will be replaced with the content passed to masthead. */
+  /** `@beta` Content to render in the vertical dock when variant="docked" is used. At mobile viewports, this content will be replaced with the content passed to masthead. */
   dockContent?: React.ReactNode;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-core/src/components/Page/Page.tsx` around lines 25 - 32,
Update the JSDoc wording to use the variant literal 'docked' consistently:
change occurrences of "dock", "variant is dock", and "variant of dock" in the
prop comments for isDockExpanded, isDockTextExpanded, masthead, and dockContent
to refer to "'docked' variant" or "variant 'docked'"; keep intent the same
(mobile behavior and when the text/masthead/dock content applies) but replace
ambiguous "dock" wording with the exact literal 'docked' everywhere.
🤖 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/Button/__tests__/Button.test.tsx`:
- Around line 569-577: Tests assert the styles.modifiers.textExpanded class for
isTextExpanded without setting dock context; update the two tests in
Button.test.tsx to reflect dock-only behavior by passing isDock={true} when
expecting the class (render(<Button isDock isTextExpanded>...)) and keeping a
test that omits isDock to assert the class is not present (render(<Button
isTextExpanded>...) expect.not.toHaveClass(styles.modifiers.textExpanded)),
referencing the Button component and props isTextExpanded and isDock and the
styles.modifiers.textExpanded symbol so the assertions match the documented
dock-only contract.

In `@packages/react-core/src/components/Nav/__tests__/Nav.test.tsx`:
- Around line 278-306: The tests for isTextExpanded are asserting docked-only
behavior but render a non-docked Nav; update both tests to render the Nav in the
docked variant context so they validate the correct contract—e.g. in the two
tests that call renderNav and render a <Nav ...> component, include the docked
variant (pass variant="docked" or the equivalent docked prop your Nav API
accepts) when constructing the Nav (the tests referencing Nav, isTextExpanded,
renderNav, and styles.modifiers.textExpanded) so the assertions run against a
docked Nav.

In `@packages/react-core/src/components/Page/__tests__/Page.test.tsx`:
- Around line 395-411: In the two tests "Does not render with dock classes when
variant is default" and "Does not render with dock classes when variant is not
passed" update the DOM queries that check for absence of the dock wrappers:
change the querySelector calls that use styles.pageDock and styles.pageDockMain
to use class selectors (prefix with '.') so they actually select by class (e.g.
querySelector('.' + styles.pageDock) and querySelector('.' +
styles.pageDockMain')); these are the assertions after obtaining the Page
element via screen.getByTestId('page') and should be adjusted in the
Page.test.tsx tests referencing styles.pageDock and styles.pageDockMain.

---

Nitpick comments:
In `@packages/react-core/src/components/Page/Page.tsx`:
- Around line 25-32: Update the JSDoc wording to use the variant literal
'docked' consistently: change occurrences of "dock", "variant is dock", and
"variant of dock" in the prop comments for isDockExpanded, isDockTextExpanded,
masthead, and dockContent to refer to "'docked' variant" or "variant 'docked'";
keep intent the same (mobile behavior and when the text/masthead/dock content
applies) but replace ambiguous "dock" wording with the exact literal 'docked'
everywhere.
🪄 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: 5d607a3f-deed-4941-b2e3-4f46cf904336

📥 Commits

Reviewing files that changed from the base of the PR and between 10b8bcd and bf172d0.

⛔ Files ignored due to path filters (1)
  • packages/react-core/src/components/Button/__tests__/__snapshots__/Button.test.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (6)
  • packages/react-core/src/components/Button/__tests__/Button.test.tsx
  • packages/react-core/src/components/Masthead/__tests__/Masthead.test.tsx
  • packages/react-core/src/components/MenuToggle/__tests__/MenuToggle.test.tsx
  • packages/react-core/src/components/Nav/__tests__/Nav.test.tsx
  • packages/react-core/src/components/Page/Page.tsx
  • packages/react-core/src/components/Page/__tests__/Page.test.tsx
✅ Files skipped from review due to trivial changes (1)
  • packages/react-core/src/components/MenuToggle/tests/MenuToggle.test.tsx

Comment on lines +278 to +306
test(`Renders with ${styles.modifiers.textExpanded} class when isTextExpanded is true`, () => {
renderNav(
<Nav isTextExpanded data-testid="text-expanded-nav">
<NavList>
{props.items.map((item) => (
<NavItem to={item.to} key={item.to}>
{item.label}
</NavItem>
))}
</NavList>
</Nav>
);
expect(screen.getByTestId('text-expanded-nav')).toHaveClass(styles.modifiers.textExpanded);
});

test(`Does not render with ${styles.modifiers.textExpanded} class when isTextExpanded is not passed`, () => {
renderNav(
<Nav data-testid="nav">
<NavList>
{props.items.map((item) => (
<NavItem to={item.to} key={item.to}>
{item.label}
</NavItem>
))}
</NavList>
</Nav>
);
expect(screen.getByTestId('nav')).not.toHaveClass(styles.modifiers.textExpanded);
});
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 | 🟠 Major

isTextExpanded tests should run in docked variant context.

These tests currently validate isTextExpanded on a non-docked Nav, which conflicts with the docked-only contract and risks cementing unsupported behavior.

Suggested test correction
-  test(`Renders with ${styles.modifiers.textExpanded} class when isTextExpanded is true`, () => {
+  test(`Renders with ${styles.modifiers.textExpanded} class when variant is docked and isTextExpanded is true`, () => {
     renderNav(
-      <Nav isTextExpanded data-testid="text-expanded-nav">
+      <Nav variant="docked" isTextExpanded data-testid="text-expanded-nav">
         <NavList>
           {props.items.map((item) => (
             <NavItem to={item.to} key={item.to}>
               {item.label}
             </NavItem>
           ))}
         </NavList>
       </Nav>
     );
     expect(screen.getByTestId('text-expanded-nav')).toHaveClass(styles.modifiers.textExpanded);
   });
 
-  test(`Does not render with ${styles.modifiers.textExpanded} class when isTextExpanded is not passed`, () => {
+  test(`Does not render with ${styles.modifiers.textExpanded} class when variant is docked and isTextExpanded is not passed`, () => {
     renderNav(
-      <Nav data-testid="nav">
+      <Nav variant="docked" data-testid="nav">
         <NavList>
           {props.items.map((item) => (
             <NavItem to={item.to} key={item.to}>
               {item.label}
             </NavItem>
           ))}
         </NavList>
       </Nav>
     );
     expect(screen.getByTestId('nav')).not.toHaveClass(styles.modifiers.textExpanded);
   });
📝 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
test(`Renders with ${styles.modifiers.textExpanded} class when isTextExpanded is true`, () => {
renderNav(
<Nav isTextExpanded data-testid="text-expanded-nav">
<NavList>
{props.items.map((item) => (
<NavItem to={item.to} key={item.to}>
{item.label}
</NavItem>
))}
</NavList>
</Nav>
);
expect(screen.getByTestId('text-expanded-nav')).toHaveClass(styles.modifiers.textExpanded);
});
test(`Does not render with ${styles.modifiers.textExpanded} class when isTextExpanded is not passed`, () => {
renderNav(
<Nav data-testid="nav">
<NavList>
{props.items.map((item) => (
<NavItem to={item.to} key={item.to}>
{item.label}
</NavItem>
))}
</NavList>
</Nav>
);
expect(screen.getByTestId('nav')).not.toHaveClass(styles.modifiers.textExpanded);
});
test(`Renders with ${styles.modifiers.textExpanded} class when variant is docked and isTextExpanded is true`, () => {
renderNav(
<Nav variant="docked" isTextExpanded data-testid="text-expanded-nav">
<NavList>
{props.items.map((item) => (
<NavItem to={item.to} key={item.to}>
{item.label}
</NavItem>
))}
</NavList>
</Nav>
);
expect(screen.getByTestId('text-expanded-nav')).toHaveClass(styles.modifiers.textExpanded);
});
test(`Does not render with ${styles.modifiers.textExpanded} class when variant is docked and isTextExpanded is not passed`, () => {
renderNav(
<Nav variant="docked" data-testid="nav">
<NavList>
{props.items.map((item) => (
<NavItem to={item.to} key={item.to}>
{item.label}
</NavItem>
))}
</NavList>
</Nav>
);
expect(screen.getByTestId('nav')).not.toHaveClass(styles.modifiers.textExpanded);
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-core/src/components/Nav/__tests__/Nav.test.tsx` around lines
278 - 306, The tests for isTextExpanded are asserting docked-only behavior but
render a non-docked Nav; update both tests to render the Nav in the docked
variant context so they validate the correct contract—e.g. in the two tests that
call renderNav and render a <Nav ...> component, include the docked variant
(pass variant="docked" or the equivalent docked prop your Nav API accepts) when
constructing the Nav (the tests referencing Nav, isTextExpanded, renderNav, and
styles.modifiers.textExpanded) so the assertions run against a docked Nav.

/** @beta Flag indicating the button is a circle button. Intended for buttons that only contain an icon.. */
isCircle?: boolean;
/** @beta Flag indicating the button is a dock variant button. For use in docked navigation. */
isDock?: boolean;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should this be isDocked or isInDock maybe?

/** Flag indicating whether the toggle is a settings toggle. This will override the icon property */
isSettings?: boolean;
/** @beta Flag indicating the toggle is a dock variant. For use in docked navigation. */
isDock?: boolean;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same here with isDocked / isInDock.

@thatblindgeye thatblindgeye requested a review from kmcfaul April 14, 2026 12:37
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

♻️ Duplicate comments (1)
packages/react-core/src/demos/examples/Page/PageDockedNav.tsx (1)

428-434: ⚠️ Potential issue | 🔴 Critical

Pass the docked masthead through dockContent.

Page only consumes dockContent in its docked branch. dockedMasthead is not part of PageProps, so it gets ignored here and can leak through ...rest onto the outer <div>, leaving the docked masthead/nav unrendered.

🛠️ Proposed fix
-        dockedMasthead={dockedMasthead}
+        dockContent={dockedMasthead}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-core/src/demos/examples/Page/PageDockedNav.tsx` around lines
428 - 434, The Page is using variant="docked" but is passing dockedMasthead as a
prop that Page doesn't accept (so it can leak via ...rest); replace the
dockedMasthead prop with dockContent and pass the docked masthead component via
dockContent={dockedMasthead} (keep other props like variant, isDockExpanded,
isDockTextExpanded, masthead, and skipToContent) so the docked masthead/nav is
rendered by Page instead of being spread onto the outer div.
🧹 Nitpick comments (1)
packages/react-core/src/components/Button/Button.tsx (1)

112-115: Keep the new dock prop contract self-consistent.

The docs still reference isDock, but the public prop is isDocked, and textExpanded is applied even when the button is not docked. That makes the new API easy to call incorrectly.

♻️ Proposed fix
-  /** `@beta` Flag indicating the dock button should display text. Only applies when isDock is true. */
+  /** `@beta` Flag indicating the dock button should display text. Only applies when isDocked is true. */
   isTextExpanded?: boolean;
...
-        isDocked && styles.modifiers.dock, // Replace wwith docked class from https://github.com/patternfly/patternfly/pull/8308
-        isTextExpanded && styles.modifiers.textExpanded,
+        isDocked && styles.modifiers.dock, // Replace with docked class from https://github.com/patternfly/patternfly/pull/8308
+        isDocked && isTextExpanded && styles.modifiers.textExpanded,

Also applies to: 274-275

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-core/src/components/Button/Button.tsx` around lines 112 - 115,
Docs and usage are inconsistent: the public prop names are isDocked and
isTextExpanded but code/docs still reference isDock and textExpanded; also
isTextExpanded is being applied even when not docked. Update all references to
use isDocked and isTextExpanded (replace any isDock/textExpanded mentions), and
change the rendering/logic in the Button component so the expanded-text behavior
is only applied when both isDocked and isTextExpanded are true (e.g.,
conditionally add classes/ARIA/children only when isDocked && isTextExpanded).
Ensure any prop forwarding or type definitions (Button props/interface) use the
corrected names and that other occurrences of the old names are replaced
accordingly.
🤖 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/demos/examples/Page/PageDockedNav.tsx`:
- Around line 174-189: The current onToggleDock handler incorrectly toggles the
mobile overlay state (isDockExpanded) for both mobile and desktop toggles; split
the behavior into two handlers: have a mobile-specific handler (e.g.,
onToggleMobileDock) that only toggles isDockExpanded, updates setIsDockExpanded,
and after a short timeout focuses mobileToggleRef; and have a desktop-specific
handler (e.g., onToggleDesktopDock) that only toggles the dock text state via
setIsDockTextExpanded and, after the same timeout, focuses dockedToggleRef;
update the mobile toggle to call onToggleMobileDock and the desktop/docked
toggle to call onToggleDesktopDock so desktop clicks no longer affect the
mobile-expanded modifier.

---

Duplicate comments:
In `@packages/react-core/src/demos/examples/Page/PageDockedNav.tsx`:
- Around line 428-434: The Page is using variant="docked" but is passing
dockedMasthead as a prop that Page doesn't accept (so it can leak via ...rest);
replace the dockedMasthead prop with dockContent and pass the docked masthead
component via dockContent={dockedMasthead} (keep other props like variant,
isDockExpanded, isDockTextExpanded, masthead, and skipToContent) so the docked
masthead/nav is rendered by Page instead of being spread onto the outer div.

---

Nitpick comments:
In `@packages/react-core/src/components/Button/Button.tsx`:
- Around line 112-115: Docs and usage are inconsistent: the public prop names
are isDocked and isTextExpanded but code/docs still reference isDock and
textExpanded; also isTextExpanded is being applied even when not docked. Update
all references to use isDocked and isTextExpanded (replace any
isDock/textExpanded mentions), and change the rendering/logic in the Button
component so the expanded-text behavior is only applied when both isDocked and
isTextExpanded are true (e.g., conditionally add classes/ARIA/children only when
isDocked && isTextExpanded). Ensure any prop forwarding or type definitions
(Button props/interface) use the corrected names and that other occurrences of
the old names are replaced accordingly.
🪄 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: 0a604384-1496-46d7-85aa-ef56cd4baf44

📥 Commits

Reviewing files that changed from the base of the PR and between 0b95e21 and 11e6885.

⛔ Files ignored due to path filters (1)
  • packages/react-core/src/components/Button/__tests__/__snapshots__/Button.test.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (12)
  • packages/react-core/src/components/Button/Button.tsx
  • packages/react-core/src/components/Button/__tests__/Button.test.tsx
  • packages/react-core/src/components/Masthead/MastheadLogo.tsx
  • packages/react-core/src/components/Masthead/__tests__/Masthead.test.tsx
  • packages/react-core/src/components/MenuToggle/MenuToggle.tsx
  • packages/react-core/src/components/MenuToggle/__tests__/MenuToggle.test.tsx
  • packages/react-core/src/components/Nav/Nav.tsx
  • packages/react-core/src/components/Nav/__tests__/Nav.test.tsx
  • packages/react-core/src/components/Page/Page.tsx
  • packages/react-core/src/components/Page/__tests__/Page.test.tsx
  • packages/react-core/src/demos/Page.md
  • packages/react-core/src/demos/examples/Page/PageDockedNav.tsx
✅ Files skipped from review due to trivial changes (2)
  • packages/react-core/src/demos/Page.md
  • packages/react-core/src/components/MenuToggle/tests/MenuToggle.test.tsx
🚧 Files skipped from review as they are similar to previous changes (6)
  • packages/react-core/src/components/Nav/tests/Nav.test.tsx
  • packages/react-core/src/components/Button/tests/Button.test.tsx
  • packages/react-core/src/components/Nav/Nav.tsx
  • packages/react-core/src/components/Masthead/tests/Masthead.test.tsx
  • packages/react-core/src/components/MenuToggle/MenuToggle.tsx
  • packages/react-core/src/components/Page/tests/Page.test.tsx

Comment on lines +174 to +189
const onToggleDock = () => {
const willBeExpanded = !isDockExpanded;
setIsDockExpanded(willBeExpanded);
setIsDockTextExpanded(!isDockTextExpanded);

const masthead = (
<Masthead id="icon-router-link" variant="docked">
// Shift focus between mobile and docked toggle buttons
setTimeout(() => {
if (willBeExpanded) {
// Opening: focus the docked toggle button
dockedToggleRef.current?.focus();
} else {
// Closing: focus the mobile toggle button
mobileToggleRef.current?.focus();
}
}, 200);
};
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 | 🟠 Major

Split the mobile and desktop dock toggles.

isDockExpanded is the mobile overlay state, but onToggleDock flips it for the desktop hamburger too. Once the docked masthead is actually rendered, clicking the desktop toggle will also apply the mobile-expanded modifier and shift focus toward the other viewport’s control. The mobile button should drive isDockExpanded; the desktop button should only toggle isDockTextExpanded.

Also applies to: 196-203, 230-236

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-core/src/demos/examples/Page/PageDockedNav.tsx` around lines
174 - 189, The current onToggleDock handler incorrectly toggles the mobile
overlay state (isDockExpanded) for both mobile and desktop toggles; split the
behavior into two handlers: have a mobile-specific handler (e.g.,
onToggleMobileDock) that only toggles isDockExpanded, updates setIsDockExpanded,
and after a short timeout focuses mobileToggleRef; and have a desktop-specific
handler (e.g., onToggleDesktopDock) that only toggles the dock text state via
setIsDockTextExpanded and, after the same timeout, focuses dockedToggleRef;
update the mobile toggle to call onToggleMobileDock and the desktop/docked
toggle to call onToggleDesktopDock so desktop clicks no longer affect the
mobile-expanded modifier.

Copy link
Copy Markdown
Contributor

@edonehoo edonehoo left a comment

Choose a reason for hiding this comment

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

some suggestions to make this is a little more concise! Feel free to correct anything I mis-assumed or tweak as you'd like

Comment on lines +83 to +85
The docked navigation pattern provides a responsive vertical navigation layout that adapts between mobile and desktop viewports. On mobile, the navigation appears as an overlay, while on desktop it displays as a persistent vertical sidebar that can toggle between icon-only and text+icon modes.

**Key implementation requirements:**
Copy link
Copy Markdown
Contributor

@edonehoo edonehoo Apr 14, 2026

Choose a reason for hiding this comment

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

Suggested change
The docked navigation pattern provides a responsive vertical navigation layout that adapts between mobile and desktop viewports. On mobile, the navigation appears as an overlay, while on desktop it displays as a persistent vertical sidebar that can toggle between icon-only and text+icon modes.
**Key implementation requirements:**
To save space in the UI, you can use docked navigation to replace text-labeled navigation items with relevant icons. On mobile (or narrow viewports), docked navigation appears as an overlay, while on desktop (or wider viewports) it displays as a persistent vertical sidebar that can toggle between icon-only and text+icon modes.
This demo includes the following features:


**Key implementation requirements:**

1. **Page component**: Set `variant="docked"` to enable the docked layout. Pass `isDockExpanded` and `isDockTextExpanded` state props to control mobile overlay and desktop text visibility.
Copy link
Copy Markdown
Contributor

@edonehoo edonehoo Apr 14, 2026

Choose a reason for hiding this comment

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

Suggested change
1. **Page component**: Set `variant="docked"` to enable the docked layout. Pass `isDockExpanded` and `isDockTextExpanded` state props to control mobile overlay and desktop text visibility.
1. A [page](/components/page) component with a docked layout, enabled with `variant="docked"`. Control the mobile overlay and label visibility with `isDockExpanded` and `isDockTextExpanded`.

are the 2 props 1:1 respective to the mobile overlay and desktop text visibility? like isDockExpanded is for use with mobile overlay and the other with desktop? Or are both used in both scenarios

Comment on lines +89 to +91
2. **Masthead structure**: Use two separate mastheads:
- **Mobile masthead**: Set `display={{ default: 'inline' }}` so it only appears on mobile. Include a hamburger toggle button, logo, and any mobile-specific actions.
- **Docked masthead**: Set `variant="docked"` for the vertical navigation sidebar. This contains the navigation toggle, nav items, and action buttons.
Copy link
Copy Markdown
Contributor

@edonehoo edonehoo Apr 14, 2026

Choose a reason for hiding this comment

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

Suggested change
2. **Masthead structure**: Use two separate mastheads:
- **Mobile masthead**: Set `display={{ default: 'inline' }}` so it only appears on mobile. Include a hamburger toggle button, logo, and any mobile-specific actions.
- **Docked masthead**: Set `variant="docked"` for the vertical navigation sidebar. This contains the navigation toggle, nav items, and action buttons.
2. Two separate [masthead](/components/masthead) components:
- **Mobile masthead**: Shown on small viewports using `display={{ default: 'inline' }}`, with a hamburger menu toggle button, brand logo, and any mobile-specific actions.
- **Docked masthead**: Uses `variant="docked"` to create a thinner navigation sidebar with a hamburger menu toggle button, nav items, and action buttons.

and any mobile-specific actions. > what does this refer to? are there examples we can give? I can't quite tell looking at the demo myself

- **Mobile masthead**: Set `display={{ default: 'inline' }}` so it only appears on mobile. Include a hamburger toggle button, logo, and any mobile-specific actions.
- **Docked masthead**: Set `variant="docked"` for the vertical navigation sidebar. This contains the navigation toggle, nav items, and action buttons.

3. **Navigation component**: Set `variant="docked"` on Nav and pass `isTextExpanded={isDockTextExpanded}` to control text visibility. NavItems should include both icons and text children—the Nav component will handle showing/hiding text based on state.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
3. **Navigation component**: Set `variant="docked"` on Nav and pass `isTextExpanded={isDockTextExpanded}` to control text visibility. NavItems should include both icons and text children—the Nav component will handle showing/hiding text based on state.
3. A [navigation](/components/navigation) component with `variant="docked"` and multiple <NavItem>` components that include both icons and text labels. To control text visibility, `isTextExpanded={isDockTextExpanded}` is passed to the `<Nav>` component. `


3. **Navigation component**: Set `variant="docked"` on Nav and pass `isTextExpanded={isDockTextExpanded}` to control text visibility. NavItems should include both icons and text children—the Nav component will handle showing/hiding text based on state.

4. **Buttons and toggles**: Use `isDocked` and `isTextExpanded` props on Button and MenuToggle components within the docked navigation. These props apply dock-specific styling that toggles between icon-only and text+icon display.
Copy link
Copy Markdown
Contributor

@edonehoo edonehoo Apr 14, 2026

Choose a reason for hiding this comment

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

Suggested change
4. **Buttons and toggles**: Use `isDocked` and `isTextExpanded` props on Button and MenuToggle components within the docked navigation. These props apply dock-specific styling that toggles between icon-only and text+icon display.
4. [Button](/components/button) and [menu toggle](/components/menus/menu-toggle) components, which use `isDocked` and `isTextExpanded` to toggle between icon-only and text+icon styles. When the nav is docked, and only icons are shown, tooltips provide full labels for the navigation items.


4. **Buttons and toggles**: Use `isDocked` and `isTextExpanded` props on Button and MenuToggle components within the docked navigation. These props apply dock-specific styling that toggles between icon-only and text+icon display.

5. **Logo variants**: Use `isCompact` prop on MastheadLogo to show an icon-only logo when the dock is collapsed, and a full logo with text when expanded.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
5. **Logo variants**: Use `isCompact` prop on MastheadLogo to show an icon-only logo when the dock is collapsed, and a full logo with text when expanded.
5. A `<MastheadLogo>` component that uses `isCompact` to show an icon-only logo when the dock is collapsed, and a full logo with text when expanded.

Comment on lines +103 to +105
8. **State management**:
- `isDockExpanded`: Controls whether the mobile overlay is shown
- `isDockTextExpanded`: Controls whether text is displayed alongside icons on desktop
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
8. **State management**:
- `isDockExpanded`: Controls whether the mobile overlay is shown
- `isDockTextExpanded`: Controls whether text is displayed alongside icons on desktop

can remove as long as you think point 1 covers these propers clearly enough


5. **Logo variants**: Use `isCompact` prop on MastheadLogo to show an icon-only logo when the dock is collapsed, and a full logo with text when expanded.

6. **Focus management**: Implement focus shifting between the mobile toggle button and docked nav toggle button when opening/closing the navigation for better keyboard accessibility.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
6. **Focus management**: Implement focus shifting between the mobile toggle button and docked nav toggle button when opening/closing the navigation for better keyboard accessibility.

Would remove this or rephrase it, since the rest of the list is more functional/specific implementation details. If you want to keep this, I would either add specifics about how this is managed, or just add it as a note after the list like this (not sure if I'm understanding the "buttons" mentioned here correctly):

Note: For better keyboard accessibility, ensure that focus shifts between the mobile hamburger menu toggle button and the docked button as the navigation is opened and closed.


6. **Focus management**: Implement focus shifting between the mobile toggle button and docked nav toggle button when opening/closing the navigation for better keyboard accessibility.

7. **Tooltips**: Only render tooltips when text is hidden (icon-only mode) to avoid showing redundant information when text labels are already visible.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
7. **Tooltips**: Only render tooltips when text is hidden (icon-only mode) to avoid showing redundant information when text labels are already visible.

integrated this into point 4, but open to alternatives

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.

Docked nav - implement responsive solution in Page layout

4 participants