Skip to content

fix: Reserve navigation space in app layout skeleton when trigger is hidden - #5155

Merged
amanabiy merged 2 commits into
cloudscape-design:mainfrom
TrevorBurnham:skeleton-reserve-navigation
Oct 23, 2026
Merged

amanabiy merged 2 commits into
cloudscape-design:mainfrom
TrevorBurnham:skeleton-reserve-navigation

Conversation

@TrevorBurnham

@TrevorBurnham TrevorBurnham commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Description

When the app layout widget loads asynchronously, BeforeMainSlotSkeleton decides whether to render the navigation column from toolbarProps.hasNavigation. That flag means "the toolbar shows a navigation trigger", so the skeleton reserves no navigation space in two cases where the loaded layout does show the navigation:

  • navigationTriggerHide is set (getPropsToMerge reports navigation: false).
  • The layout is not the primary instance, so toolbarProps is null and the navigation gets panel-hidden.

In both cases, all content shifts right by the navigation width when the widget loads. This has a significant impact on Lighthouse performance scores, which penalize sites for content layout shift (CLS)—and rightly so, since it's jarring for users and forces the browser to recompute the site's layout.

This PR bases the skeleton's navigation column on the layout's own navigation, navigationHide, and navigationOpen props, falling back from toolbarProps. The toolbar trigger still uses toolbarProps.hasNavigation.

Related links, issue #, if available: V2414734554

How has this been tested?

  • New unit tests in skeleton.test.tsx cover both cases. They fail without the fix.
  • Existing app-layout and app-layout-toolbar unit tests pass.
  • Manually, on #/light/app-layout-toolbar/with-content-layout?visualRefresh=true&appLayoutWidget=true&appLayoutDelayedWidget=true&navigationTriggerHide=true (production build, 1350 px wide). The screenshots below show the skeleton, captured while the widget is loading, and the layout after the widget loads.
Skeleton (widget loading) Loaded
Before before, skeleton before, loaded
After after, skeleton after, loaded

With a PerformanceObserver for layout-shift on a similar page, the shift at widget load went from 0.18 to 0 for navigationTriggerHide, and from 0.19 to 0 for a secondary layout.

Review checklist

The following items are to be evaluated by the author(s) and the reviewer(s).

Correctness

  • Changes include appropriate documentation updates.
  • Changes are backward-compatible if not indicated, see CONTRIBUTING.md.
  • Changes do not include unsupported browser features, see CONTRIBUTING.md.
  • Changes were manually tested for accessibility, see accessibility guidelines.

Security

Testing

  • Changes are covered with new/existing unit tests?
  • Changes are covered with new/existing integration tests?

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@TrevorBurnham
TrevorBurnham marked this pull request as ready for review October 17, 2026 18:29
@TrevorBurnham
TrevorBurnham requested a review from a team as a code owner October 17, 2026 18:29
@TrevorBurnham
TrevorBurnham requested review from amanabiy and removed request for a team October 17, 2026 18:29
@github-actions
github-actions Bot temporarily deployed to fork-dev-pages-react18 October 19, 2026 07:52 Inactive
@codecov

codecov Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.88%. Comparing base (af861d1) to head (fef4039).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5155      +/-   ##
==========================================
- Coverage   97.72%   93.88%   -3.85%     
==========================================
  Files         995      994       -1     
  Lines       32129    27830    -4299     
  Branches    11851    10001    -1850     
==========================================
- Hits        31399    26128    -5271     
+ Misses        684      609      -75     
- Partials       46     1093    +1047     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
github-actions Bot temporarily deployed to fork-dev-pages-react16 October 19, 2026 07:52 Inactive
@github-actions
github-actions Bot temporarily deployed to fork-dev-pages-react16 October 19, 2026 12:11 Inactive
@github-actions
github-actions Bot temporarily deployed to fork-dev-pages-react18 October 19, 2026 12:11 Inactive
@amanabiy
amanabiy requested review from amanabiy and a balanced review from Copilot October 23, 2026 08:38

Copilot AI left a comment

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.

🟢 Approval recommended

The localized fix preserves trigger behavior and includes focused regression coverage, with no unresolved findings.

No open issues 🎉

What changed in this PR

Fixes navigation-related layout shifts while the app layout widget loads by reserving skeleton space when the navigation trigger is hidden or the layout is secondary.

Changes:

  • Uses layout navigation props as a fallback for skeleton visibility and open state.
  • Preserves toolbar trigger visibility behavior.
  • Adds regression tests for hidden-trigger and secondary-layout scenarios.
File Description
src/​app-layout/​visual-refresh-toolbar/​skeleton/​skeleton-parts.tsx Adds navigation-state fallbacks while preserving toolbar trigger logic.
src/​app-layout/​__tests__/​skeleton.test.tsx Tests navigation space reservation in both reported scenarios.

Review effort: Balanced

@SpyZzey
SpyZzey requested review from a team, georgylobko and taheramr and removed request for a team and taheramr October 23, 2026 09:45
@amanabiy
amanabiy added this pull request to the merge queue Oct 23, 2026
Merged via the queue into cloudscape-design:main with commit 1f35242 Oct 23, 2026
54 checks passed

This branch was previously deployed

2 inactive deployments
fork-dev-pages-react18 — fef40395 Deployed Oct 19, 2026 by github-actions[bot]
fork-dev-pages-react16 — fef40395 Deployed Oct 19, 2026 by github-actions[bot]
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.

4 participants