Skip to content

feat(tabs): Add last-tab-closable functionality - #14446

Merged
macandcheese merged 36 commits into
devfrom
macandcheese/14346-last-tab-closable
Jun 25, 2026
Merged

feat(tabs): Add last-tab-closable functionality#14446
macandcheese merged 36 commits into
devfrom
macandcheese/14346-last-tab-closable

Conversation

@macandcheese

Copy link
Copy Markdown
Contributor

Related Issue: #14346

Summary

This adds a property to allow the last closable Tab to be closed.

We need to open a future breaking change issue to make this the default behavior. At that time, we should deprecate this newly added last-tab-closable.

@github-actions github-actions Bot added the enhancement Issues tied to a new feature or request. label May 18, 2026

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.

Pull request overview

Adds a lastTabClosable option for calcite-tabs so apps can preserve the close affordance when only one visible closable tab remains.

Changes:

  • Adds lastTabClosable to calcite-tabs and forwards it to calcite-tab-nav.
  • Updates tab-nav close-button hiding/restoration logic.
  • Adds an e2e test for preserving the last close button.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
packages/components/src/components/tabs/tabs.tsx Defines and propagates the new tabs property.
packages/components/src/components/tab-nav/tab-nav.tsx Implements last-visible-tab close button behavior and selection handling updates.
packages/components/src/components/tabs/tabs.e2e.ts Adds coverage for retaining the close button with lastTabClosable.

Comment thread packages/components/src/components/tab-nav/tab-nav.tsx Outdated
Comment thread packages/components/src/components/tab-nav/tab-nav.tsx Outdated
@jcfranco

Copy link
Copy Markdown
Member

We need to open a future breaking change issue to make this the default behavior. At that time, we should deprecate this newly added last-tab-closable.

I don’t see why we can’t keep this option around for a while and gather feedback before making further adjustments.

WRT changing the default behavior, the request to change the tab closing behavior recently came up since the feature was introduced in v1.4.0, so I have a hunch this may not be the majority use case. Curious if others have seen stronger demand for making this the default and setting up for removal later.

cc @Esri/calcite-pes

@isaacbraun

Copy link
Copy Markdown
Contributor

Curious if others have seen stronger demand for making this the default and setting up for removal later.

I have not seen the demand, but others may have (re-pinging for timeliness) cc @Esri/calcite-pes.

Even if we keep it around for a while, we can open the issue to make it the default behavior where the reasoning could be documented which would be helpful when asking teams.

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.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

Comment thread packages/components/src/components/tabs/tabs.browser.e2e.tsx Outdated
Comment thread packages/components/src/components/tabs/tabs.browser.e2e.tsx
Comment thread packages/components/src/components/tabs/tabs.browser.e2e.tsx Outdated
Comment thread packages/components/src/components/tabs/tabs.browser.e2e.tsx Outdated
Comment thread packages/components/src/components/tab-nav/tab-nav.tsx
macandcheese and others added 5 commits June 24, 2026 12:16
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

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.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comment thread packages/components/src/components/tabs/tabs.browser.e2e.tsx Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

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.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

Comment thread packages/components/src/components/tab-nav/tab-nav.tsx
Comment thread packages/components/src/components/tab-nav/tab-nav.tsx
Comment thread packages/components/src/components/tabs/tabs.browser.e2e.tsx
@macandcheese
macandcheese force-pushed the macandcheese/14346-last-tab-closable branch from 0637f87 to bb5bf59 Compare June 24, 2026 23:04
@matgalla matgalla added pr ready for visual snapshots Adding this label will run visual snapshot testing. and removed pr ready for visual snapshots Adding this label will run visual snapshot testing. labels Jun 25, 2026

@jcfranco jcfranco left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Awesome! 🚀 Other than a few comments, this LGTM!

Comment thread packages/components/src/components/tabs/tabs.browser.e2e.tsx Outdated
Comment thread packages/components/src/components/tabs/tabs.browser.e2e.tsx Outdated
return;
}

expect(reopenedTitle.closed).toBe(false);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggestion: depending on how much direct element access is needed, locators could help simplify:

const reopenedTitle = page.locator("#tab-title-4");
const reopenedTab = page.locator("#tab-4");

await expect.element(reopenedTitle).toBeInTheDocument();

const reopenedTitleEl = await reopenedTitle.element() as TabTitle["el"];
reopenedTitleEl.closed = false;
await component.updateComplete;

await expect.element(reopenedTab).toBeInTheDocument();

await expect.element(reopenedTitle).toHaveProperty("closed", false);
await expect.element(reopenedTitle).toHaveProperty("hidden", false);
await expect.element(reopenedTitle).toHaveProperty("tabIndex", 0);

await expect.element(reopenedTab).toHaveProperty("hidden", false);
await expect.element(reopenedTab).toHaveProperty("selected", true);

Comment thread packages/components/src/components/tabs/tabs.browser.e2e.tsx Outdated
Comment thread packages/components/src/components/tabs/tabs.browser.e2e.tsx Outdated
Comment thread packages/components/src/components/tabs/tabs.tsx Outdated
Comment thread packages/components/src/components/tabs/tabs.tsx Outdated
Comment thread packages/components/src/components/tab-title/tab-title.tsx Outdated
Comment thread packages/components/src/components/tab-nav/tab-nav.tsx Outdated
Comment thread packages/components/src/components/tab-nav/tab-nav.tsx Outdated
@macandcheese
macandcheese merged commit b8144a8 into dev Jun 25, 2026
10 of 11 checks passed
@macandcheese
macandcheese deleted the macandcheese/14346-last-tab-closable branch June 25, 2026 20:08
@github-actions github-actions Bot added this to the Jun Milestone - 2026-06-30 milestone Jun 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Issues tied to a new feature or request. pr ready for visual snapshots Adding this label will run visual snapshot testing.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants