Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Allow tab content to be retained in memory #3233

Merged
merged 6 commits into from
Feb 17, 2025

Conversation

gethinwebster
Copy link
Member

Description

Allow inactive tab content to be rendered into the DOM, for use-cases such as:

  • Eager rendering (and/or avoiding re-rendering) of heavy tab content
  • Retaining content state in memory

Related links, issue #, if available: AWSUI-25984

How has this been tested?

New unit and integ tests

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.

Copy link

codecov bot commented Jan 30, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 96.42%. Comparing base (03d0574) to head (38d3b7e).
Report is 29 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3233      +/-   ##
==========================================
- Coverage   96.44%   96.42%   -0.02%     
==========================================
  Files         791      791              
  Lines       22568    22586      +18     
  Branches     7385     7735     +350     
==========================================
+ Hits        21765    21778      +13     
+ Misses        796      754      -42     
- Partials        7       54      +47     

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

src/tabs/interfaces.ts Outdated Show resolved Hide resolved
@gethinwebster gethinwebster marked this pull request as ready for review February 6, 2025 13:42
@gethinwebster gethinwebster requested a review from a team as a code owner February 6, 2025 13:42
@gethinwebster gethinwebster requested review from taheramr and pan-kot and removed request for a team February 6, 2025 13:42
src/tabs/interfaces.ts Outdated Show resolved Hide resolved
@@ -60,6 +72,18 @@ export default function Tabs({
changeHandler: 'onChange',
});

const [viewedTabs, setViewedTabs] = useState(new Set(activeTabId));

useEffect(() => {
Copy link
Member

Choose a reason for hiding this comment

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

This effect can be removed in favour of decorating the setActiveTabId method, e.g.

const setActiveTabIdDecorated = (newActiveTabId) => {
  setActiveTabId(newActiveTabId);
  setViewedTabs(prev => new Set(prev).add(newActiveTabId));
}

This way the related state is set within one render cycle so should be better for performance and is better clear, too.

Copy link
Member Author

Choose a reason for hiding this comment

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

Given that this is a controllable component, I think we need to use an effect. Although it's unlikely, the active tab could change without setActiveTabId being called

Copy link
Member

Choose a reason for hiding this comment

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

Oh, I see. Can the visited tabs be a ref then, e.g.:

const visitedTabsRef = useRef(new Set<string>());
visitedTabsRef.current.add(activeTabId);

Since changing the tab always causes a new render no matter if done in controlled or uncontrolled way, I think this approach should work, too.

Copy link
Member Author

Choose a reason for hiding this comment

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

good point: there's no explicit re-render required here, and the updated value isn't needed until later (switching away from the tab) anyway

src/tabs/__tests__/tabs.test.tsx Outdated Show resolved Hide resolved
src/tabs/__integ__/in-memory.test.ts Outdated Show resolved Hide resolved
pages/tabs/in-memory-integ.page.tsx Outdated Show resolved Hide resolved
pages/tabs/in-memory-integ.page.tsx Outdated Show resolved Hide resolved
src/tabs/__integ__/in-memory.test.ts Outdated Show resolved Hide resolved
src/tabs/__integ__/in-memory.test.ts Outdated Show resolved Hide resolved
pan-kot
pan-kot previously approved these changes Feb 7, 2025
pan-kot
pan-kot previously approved these changes Feb 13, 2025
@gethinwebster gethinwebster added this pull request to the merge queue Feb 17, 2025
Merged via the queue into main with commit 23555ca Feb 17, 2025
38 checks passed
@gethinwebster gethinwebster deleted the tabs-content-in-dom branch February 17, 2025 18:29
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.

2 participants