Skip to content

ACM-33628-UI-text-overflow-in-AppSet-Review-step-hides-action-buttons-behind-YAML-pane#6112

Merged
openshift-merge-bot[bot] merged 1 commit intostolostron:mainfrom
jeswanke:ACM-33628-UI-text-overflow-in-AppSet-Review-step-hides-action-buttons-behind-YAML-pane
May 7, 2026
Merged

ACM-33628-UI-text-overflow-in-AppSet-Review-step-hides-action-buttons-behind-YAML-pane#6112
openshift-merge-bot[bot] merged 1 commit intostolostron:mainfrom
jeswanke:ACM-33628-UI-text-overflow-in-AppSet-Review-step-hides-action-buttons-behind-YAML-pane

Conversation

@jeswanke
Copy link
Copy Markdown
Contributor

@jeswanke jeswanke commented May 6, 2026

📝 Summary

CleanShot 2026-05-06 at 15 05 31@2x

Ticket Summary (Title):
UI text overflow in AppSet Review step hides action buttons behind YAML pane

Ticket Link:
https://redhat.atlassian.net/browse/ACM-33628

Type of Change:

  • 🐞 Bug Fix
  • ✨ Feature
  • 🔧 Refactor
  • 💸 Tech Debt
  • 🧪 Test-related
  • 📄 Docs

✅ Checklist

General

  • PR title follows the convention (e.g. ACM-12340 Fix bug with...)
  • Code builds and runs locally without errors
  • No console logs, commented-out code, or unnecessary files
  • All commits are meaningful and well-labeled
  • All new display strings are externalized for localization (English only)
  • (Nice to have) JSDoc comments added for new functions and interfaces

If Feature

  • UI/UX reviewed (if applicable)
  • All acceptance criteria met
  • Unit test coverage added or updated
  • Relevant documentation or comments included

If Bugfix

  • Root cause and fix summary are documented in the ticket (for future reference / errata)
  • Fix tested thoroughly and resolves the issue
  • Test(s) added to prevent regression

🗒️ Notes for Reviewers

Summary by CodeRabbit

Release Notes

  • Style

    • Enhanced grid-based layout and spacing for the review section with improved visual organization.
    • Optimized responsive design widths for better display across all screen sizes.
  • Refactor

    • Restructured rendering logic to support flexible inline and stacked layout options in the review interface.

Signed-off-by: John Swanke <jswanke@redhat.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 6, 2026

📝 Walkthrough

Walkthrough

This PR refactors the review section's description-list layout to support dual inline and stacked rendering modes for pen controls, with corresponding CSS grid structure updates and responsive width adjustments across three files.

Changes

Description-List Layout Refactor

Layer / File(s) Summary
CSS Layout Foundation
frontend/packages/react-form-wizard/src/review/ReviewStep.css
Introduces grid-based layout for description-list rows with term/description cells, container queries for responsive inline/stacked control positioning (max-width breakpoints at 28rem and 48rem), and space-between justification for pen controls alignment.
React Component Implementation
frontend/packages/react-form-wizard/src/review/ReviewStepNavigation.tsx
Adds cloneElement and isValidElement imports; introduces renderEditButtons helper for pen/arrow button rendering; derives separate inline and stacked beforePenControls variants; refactors DescriptionListDescription path to render nested inline row with dual control clusters and empty-value class handling.
Responsive Constants
frontend/packages/react-form-wizard/src/review/utils.ts
Reduces wide-layout term widths for default, sm, md, lg, and xl breakpoints; retains 2xl width at 70ch.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description follows the template structure with ticket summary, link, and type marked as bug fix. However, critical sections remain incomplete: no root cause analysis, fix summary, test coverage details, or notes for reviewers are provided. Document the root cause of text overflow, explain how the CSS/layout changes fix it, confirm regression tests added, and provide implementation notes for reviewers.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately references the ticket (ACM-33628) and describes the specific UI issue being fixed: text overflow hiding action buttons behind a YAML pane in the Review step.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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.

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

Caution

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

⚠️ Outside diff range comments (1)
frontend/packages/react-form-wizard/src/review/ReviewStepNavigation.tsx (1)

471-494: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Both inline and stacked clusters render simultaneously; duplicate IDs and double-mounted stateful components.

Lines 485–492 render beforePenControls and renderEditButtons() twice—once in the inline cluster and once in the stacked cluster. Although CSS @container queries hide one via display: none, both remain in the DOM:

  • Duplicate DOM IDs & form associations: Any id, for=, aria-describedby, aria-controls, or <label htmlFor> inside beforePenControls now appears twice, breaking HTML validity and assistive tech associations.
  • Double-mounted components: When beforePenControls is a valid React element (line 455–458), cloneElement is called twice, creating two independent component instances. If the child is stateful, this violates the single-instance expectation.
  • Duplicate buttons: renderEditButtons() generates two sets of buttons with identical aria-label attributes. Screen readers ignore the hidden set, but event listeners, selectors, and analytics still count both.

Render a single cluster and toggle its visual position via CSS (e.g., grid row/column re-ordering within the same @container query), or conditionally render based on container size to keep only one cluster in the DOM.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/packages/react-form-wizard/src/review/ReviewStepNavigation.tsx`
around lines 471 - 494, The inline and stacked control clusters are both
rendered (beforePenControlsInline / beforePenControlsStacked and
renderEditButtons()) which duplicates IDs and mounts components twice; change
ReviewStepNavigation to render a single control cluster (one span containing the
cloned beforePenControls and the result of renderEditButtons()) and rely on
CSS/@container queries to visually position it rather than outputting two DOM
copies; update the JSX that currently emits both the inline and stacked spans to
emit a single container (reuse DescriptionListDescription or the outer div) and
remove the duplicate cloneElement/renderEditButtons calls so stateful children
and IDs exist only once.
🧹 Nitpick comments (5)
frontend/packages/react-form-wizard/src/review/ReviewStep.css (2)

123-123: 💤 Low value

Coupling to a private PatternFly custom property.

--pf-v6-c-description-list__group--RowGap is an internal PatternFly token; private custom properties (double-underscore namespaced per BEM block) are not part of the documented theming surface and can disappear or be renamed across minor PatternFly releases. Consider a fallback (var(--pf-v6-c-description-list__group--RowGap, var(--pf-t--global--spacer--sm))) so the layout doesn't lose its row gap if the variable is dropped on upgrade.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/packages/react-form-wizard/src/review/ReviewStep.css` at line 123,
The CSS currently uses a private PatternFly custom property for row-gap
(row-gap: var(--pf-v6-c-description-list__group--RowGap)); update the
declaration in ReviewStep.css to provide a safe fallback so layout won’t break
if that internal token is removed—use the original token with a documented
fallback such as var(--pf-v6-c-description-list__group--RowGap,
var(--pf-t--global--spacer--sm)) so the row-gap falls back to a stable global
spacer; locate the row-gap declaration in ReviewStep.css to make this change.

117-125: 💤 Low value

Subgrid relies on the PatternFly DL group being a grid container.

grid-template-columns: subgrid requires the parent (.pf-v6-c-description-list__group) to itself be display: grid with the term/description columns defined. PatternFly v6 horizontal DescriptionList does this today, but the selector silently degrades (subgrid → none) if PatternFly ever switches to flex/block, which would collapse the term and description into a single column.

Worth confirming pf-v6-c-description-list__group is still a grid in @patternfly/react-core@6.4.3 and that horizontal DescriptionList is what wraps these rows in the wizard.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/packages/react-form-wizard/src/review/ReviewStep.css` around lines
117 - 125, The CSS uses grid-template-columns: subgrid on
.wizard-review-pen-hover-zone--dl-group-row which requires the parent
.pf-v6-c-description-list__group to be display: grid; confirm PatternFly
`@patternfly/react-core`@6.4.3 still makes .pf-v6-c-description-list__group a grid
for horizontal DescriptionList, and add a defensive fallback: if the parent is
not grid, force a compatible grid on the parent or replace subgrid with an
explicit column template that matches the PatternFly term/description columns
(reference .wizard-review-pen-hover-zone--dl-group-row and
.pf-v6-c-description-list__group when making the change) so the term/description
layout won’t collapse if PatternFly switches to flex/block.
frontend/packages/react-form-wizard/src/review/ReviewStepNavigation.tsx (3)

418-451: 💤 Low value

renderEditButtons is invoked up to twice per render in the DL path — confirm intent.

The helper is called at line 467 (unused in the DL branch since controls is only rendered in the else at line 498) and again at lines 486 and 492. In the DL path that's two invocations producing two pairs of buttons in the DOM, each carrying the same ariaLabel/arrowAriaLabel. This is consistent with the inline/stacked CSS strategy but compounds the duplication concern raised in the parent comment. If you switch to a single-cluster CSS-positioning approach, this helper only needs to be called once.

Minor: since renderEditButtons is only consumed inside this component and not passed downward, a plain inline JSX block (or useMemo returning the element) would be more idiomatic than useCallback returning a fragment.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/packages/react-form-wizard/src/review/ReviewStepNavigation.tsx`
around lines 418 - 451, renderEditButtons is being invoked multiple times
causing duplicate button pairs in the DL path; replace the useCallback that
returns JSX with a useMemo (or an inline JSX constant) that returns the button
fragment so the element is created once, then use that single memoized element
wherever renderEditButtons was called; ensure the memo depends on ariaLabel,
arrowAriaLabel, onArrowClick, onPenClick, and onPenIconClick and that the event
handlers still call e.stopPropagation() and select the handler (onPenIconClick
?? onPenClick).

464-469: 💤 Low value

controls is dead code in the DL branch.

controls is built unconditionally but only consumed in the non-DL else branch at line 498. In the DL branch the inline/stacked clusters are constructed inline and controls is discarded. Either inline this expression into the else branch, or move it inside a useMemo/conditional so it isn't allocated when descriptionListTerm != null.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/packages/react-form-wizard/src/review/ReviewStepNavigation.tsx`
around lines 464 - 469, The const controls (which builds <span
className="wizard-review-pen-controls"> using beforePenControls and
renderEditButtons()) is allocated unconditionally but only used when
descriptionListTerm is null; move that expression into the non-DL branch where
it's consumed (the else branch that renders the inline/stacked clusters) so it's
only created when needed, or wrap it in a useMemo that returns null when
descriptionListTerm != null and lists beforePenControls and renderEditButtons
(and any other relevant props/state) as dependencies to avoid unnecessary
allocation.

453-462: 💤 Low value

cloneElement requires beforePenControls to be a single React element.

isValidElement correctly gates the clone branch, but the fallback [beforePenControls, beforePenControls] returns the same node reference twice. If a caller ever passes an array or Fragment of elements, React will warn about missing/duplicate keys and the inline/stacked rows will collide. Consider wrapping each branch in a keyed Fragment, e.g.:

-    return [beforePenControls, beforePenControls] as const
+    return [
+      <Fragment key="wizard-review-pen-bc-inline">{beforePenControls}</Fragment>,
+      <Fragment key="wizard-review-pen-bc-stacked">{beforePenControls}</Fragment>,
+    ] as const

Also worth wrapping this IIFE in useMemo keyed on beforePenControls to avoid re-cloning on every render of the hover zone.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/packages/react-form-wizard/src/review/ReviewStepNavigation.tsx`
around lines 453 - 462, The current IIFE that produces beforePenControlsInline
and beforePenControlsStacked can clone a single element safely but returns the
same node reference for non-element inputs, causing key collisions if callers
pass arrays/Fragments; update the logic (affecting beforePenControlsInline,
beforePenControlsStacked, beforePenControls, isValidElement, cloneElement) to:
1) wrap each branch result in a keyed Fragment when the input is not a single
element (so inline and stacked each get a distinct keyed wrapper) and 2) memoize
the whole computation with useMemo keyed on beforePenControls to avoid
re-cloning on every render.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontend/packages/react-form-wizard/src/review/utils.ts`:
- Around line 127-134: The COMPACT vs WIDE breakpoint maps
(REVIEW_HORIZONTAL_TERM_WIDTH_COMPACT and REVIEW_HORIZONTAL_TERM_WIDTH_WIDE)
only differ at '2xl', so the selector horizontalTermWidthModifierForInputRun
(which switches by maxLen < 64) is ineffective below 2xl; either expand the WIDE
values for smaller breakpoints (default, sm, md, lg, xl) to the intended wider
ch sizes so short labels get more room at all sizes, or simplify the logic by
keeping both maps identical and only apply a '2xl-only' widening in
horizontalTermWidthModifierForInputRun (or remove the maxLen threshold). Update
the relevant constant(s) and/or the horizontalTermWidthModifierForInputRun
function accordingly to reflect the intended behavior.

---

Outside diff comments:
In `@frontend/packages/react-form-wizard/src/review/ReviewStepNavigation.tsx`:
- Around line 471-494: The inline and stacked control clusters are both rendered
(beforePenControlsInline / beforePenControlsStacked and renderEditButtons())
which duplicates IDs and mounts components twice; change ReviewStepNavigation to
render a single control cluster (one span containing the cloned
beforePenControls and the result of renderEditButtons()) and rely on
CSS/@container queries to visually position it rather than outputting two DOM
copies; update the JSX that currently emits both the inline and stacked spans to
emit a single container (reuse DescriptionListDescription or the outer div) and
remove the duplicate cloneElement/renderEditButtons calls so stateful children
and IDs exist only once.

---

Nitpick comments:
In `@frontend/packages/react-form-wizard/src/review/ReviewStep.css`:
- Line 123: The CSS currently uses a private PatternFly custom property for
row-gap (row-gap: var(--pf-v6-c-description-list__group--RowGap)); update the
declaration in ReviewStep.css to provide a safe fallback so layout won’t break
if that internal token is removed—use the original token with a documented
fallback such as var(--pf-v6-c-description-list__group--RowGap,
var(--pf-t--global--spacer--sm)) so the row-gap falls back to a stable global
spacer; locate the row-gap declaration in ReviewStep.css to make this change.
- Around line 117-125: The CSS uses grid-template-columns: subgrid on
.wizard-review-pen-hover-zone--dl-group-row which requires the parent
.pf-v6-c-description-list__group to be display: grid; confirm PatternFly
`@patternfly/react-core`@6.4.3 still makes .pf-v6-c-description-list__group a grid
for horizontal DescriptionList, and add a defensive fallback: if the parent is
not grid, force a compatible grid on the parent or replace subgrid with an
explicit column template that matches the PatternFly term/description columns
(reference .wizard-review-pen-hover-zone--dl-group-row and
.pf-v6-c-description-list__group when making the change) so the term/description
layout won’t collapse if PatternFly switches to flex/block.

In `@frontend/packages/react-form-wizard/src/review/ReviewStepNavigation.tsx`:
- Around line 418-451: renderEditButtons is being invoked multiple times causing
duplicate button pairs in the DL path; replace the useCallback that returns JSX
with a useMemo (or an inline JSX constant) that returns the button fragment so
the element is created once, then use that single memoized element wherever
renderEditButtons was called; ensure the memo depends on ariaLabel,
arrowAriaLabel, onArrowClick, onPenClick, and onPenIconClick and that the event
handlers still call e.stopPropagation() and select the handler (onPenIconClick
?? onPenClick).
- Around line 464-469: The const controls (which builds <span
className="wizard-review-pen-controls"> using beforePenControls and
renderEditButtons()) is allocated unconditionally but only used when
descriptionListTerm is null; move that expression into the non-DL branch where
it's consumed (the else branch that renders the inline/stacked clusters) so it's
only created when needed, or wrap it in a useMemo that returns null when
descriptionListTerm != null and lists beforePenControls and renderEditButtons
(and any other relevant props/state) as dependencies to avoid unnecessary
allocation.
- Around line 453-462: The current IIFE that produces beforePenControlsInline
and beforePenControlsStacked can clone a single element safely but returns the
same node reference for non-element inputs, causing key collisions if callers
pass arrays/Fragments; update the logic (affecting beforePenControlsInline,
beforePenControlsStacked, beforePenControls, isValidElement, cloneElement) to:
1) wrap each branch result in a keyed Fragment when the input is not a single
element (so inline and stacked each get a distinct keyed wrapper) and 2) memoize
the whole computation with useMemo keyed on beforePenControls to avoid
re-cloning on every render.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 19d2bcda-088c-4a47-85ed-c4ffecd0fb7b

📥 Commits

Reviewing files that changed from the base of the PR and between 32f871a and 1dc8dc4.

📒 Files selected for processing (3)
  • frontend/packages/react-form-wizard/src/review/ReviewStep.css
  • frontend/packages/react-form-wizard/src/review/ReviewStepNavigation.tsx
  • frontend/packages/react-form-wizard/src/review/utils.ts

Comment on lines 127 to 134
const REVIEW_HORIZONTAL_TERM_WIDTH_WIDE: HorizontalTermWidthModifier = {
default: '24ch',
sm: '30ch',
md: '40ch',
lg: '56ch',
xl: '60ch',
default: '12ch',
sm: '15ch',
md: '20ch',
lg: '28ch',
xl: '30ch',
'2xl': '70ch',
}
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 | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

# Find the file in question
find . -name "utils.ts" -path "*/react-form-wizard/src/review/*"

Repository: stolostron/console

Length of output: 120


🏁 Script executed:

# Once found, let's read the relevant sections
cat -n frontend/packages/react-form-wizard/src/review/utils.ts | head -150

Repository: stolostron/console

Length of output: 6880


🏁 Script executed:

# Search for both WIDE and COMPACT constants
rg "REVIEW_HORIZONTAL_TERM_WIDTH" frontend/packages/react-form-wizard/src/review/utils.ts -A 8

Repository: stolostron/console

Length of output: 809


🏁 Script executed:

# Also search for the selector function
rg "horizontalTermWidthModifierForInputRun" frontend/packages/react-form-wizard/src/review/utils.ts -B 2 -A 10

Repository: stolostron/console

Length of output: 523


COMPACT and WIDE constants are identical except at the 2xl breakpoint (35ch vs 70ch).

The selector horizontalTermWidthModifierForInputRun chooses between them based on maxLen < 64, but this distinction only affects term width at the 2xl breakpoint. For all smaller breakpoints (default through xl), both maps return identical values, making the label-length check ineffective below 2xl.

Confirm this matches the intended overflow fix; if the intent was to widen short labels at all sizes, the WIDE values at smaller breakpoints need adjustment. If the intent was a 2xl-only widening, consider whether the COMPACT/WIDE split and the 64-char threshold remain necessary.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/packages/react-form-wizard/src/review/utils.ts` around lines 127 -
134, The COMPACT vs WIDE breakpoint maps (REVIEW_HORIZONTAL_TERM_WIDTH_COMPACT
and REVIEW_HORIZONTAL_TERM_WIDTH_WIDE) only differ at '2xl', so the selector
horizontalTermWidthModifierForInputRun (which switches by maxLen < 64) is
ineffective below 2xl; either expand the WIDE values for smaller breakpoints
(default, sm, md, lg, xl) to the intended wider ch sizes so short labels get
more room at all sizes, or simplify the logic by keeping both maps identical and
only apply a '2xl-only' widening in horizontalTermWidthModifierForInputRun (or
remove the maxLen threshold). Update the relevant constant(s) and/or the
horizontalTermWidthModifierForInputRun function accordingly to reflect the
intended behavior.

@jeswanke
Copy link
Copy Markdown
Contributor Author

jeswanke commented May 6, 2026

/retest

1 similar comment
@jeswanke
Copy link
Copy Markdown
Contributor Author

jeswanke commented May 7, 2026

/retest

@jeswanke jeswanke requested a review from fxiang1 May 7, 2026 13:02
@openshift-ci
Copy link
Copy Markdown

openshift-ci Bot commented May 7, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: fxiang1, jeswanke

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-bot openshift-merge-bot Bot merged commit c9222ff into stolostron:main May 7, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants