Skip to content

feat(lab): TabBar shows a More tab past five tabs - #10619

Merged
cixzhang merged 1 commit into
meta:mainfrom
vjeux:tabbar/lab-more-tab
Nov 10, 2026
Merged

cixzhang merged 1 commit into
meta:mainfrom
vjeux:tabbar/lab-more-tab

Conversation

@vjeux

@vjeux vjeux commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

The lab TabBar's More tab, split from #9701.

User need

Past five sections, tabs no longer fit a phone's bar. iOS shows four and More; a lab TabBar squeezes all in.

Problem and solution fit

  • Past five tabs, the bar shows four and More (FR1).
  • More reads as selected while value is moreValue or a tab past the fourth.
  • More again, holding a tab, calls onReselect (iOS pops More's stack).
  • TabBarMoreList draws More's screen: a row per remaining tab (icon, label, Core's error Badge, chevron). A chosen row calls onChange.
  • A disabled tab's row never activates (spec:AST-085 FR2).

Current specification

The owners' pointer ruling is recorded as FR1 in a draft record, component:TabBar (#10929), which takes its own stamp. FR1:

Past five tabs the bar shows four tabs and More, which lists the rest, for every pointer, as UITabBarController does.

Every path is Lab code, an entry file or a changeset. That makes it Lab-only under spec:AST-030 FR26, so it needs no owner decision (architecture:knowledge-contracts DEC-19).

Public delta and caller burden

  • TabBar gains moreValue (default 'more'); five tabs or fewer render as before.
  • New TabBarMoreList, rendered while value is moreValue:
{tab === 'more' ? <TabBarMoreList onChange={setTab}>{tabs}</TabBarMoreList> : null}

Design and alternatives

  • The app owns More's navigation stack.
  • TabBarMoreList has its own folder, docs, story, route.
  • Rejected: TabBar drawing the list (owning a screen).
  • Later: iOS's Edit, the accessory, minimize and search.

Evidence

Mobile Safari 26.2, iPhone 17 Pro simulator, on a Sandbox page (/pages/lab-tab-bar/) following separately. M4 adds ?dir=rtl, M5 ?disabled=help.

M1
M2
M3
M4
M5

M1–M5 each record one More case; as on iOS, M3's lens does not slide (design:reduced-motion DR2). They predate the folder move (no code change).

Desktop Chrome 149, mouse, same page. Before (main's TabBar, ba9c4c6): six tabs. After: four and More; a row opens its section; More again returns to the list.

Desktop before
Desktop after

Red first, 1 worker: main's TabBar (helpers exported) with the list, story and cases (04d3553) fails all six More cases, both engines. More-again-chooses-More (1a33342) fails the reselect unit. Without disabled rows (bebe019), M5's case fails: units, both engines. Without the selected row (2c46f7d), its unit fails. So does a hard-coded More label, on the tab (0fc04d6) or the list (948f60e).

Scope

Components: TabBar, TabBarMoreList

  • One capability is added.
  • Unrelated fixes, cleanup, and policy changes were removed or split.
  • Consumer docs, focused tests, and migration evidence ship with the feature.
  • Public text and artifacts contain no internal Meta context.

Testing

Gates at 8900e2b, rebased onto main b04c414 after #9966. The one conflict, in TabBar's choose handler, keeps both behaviors: the selected tab scrolls its panel, and More again returns to its list without scrolling.

  • pnpm -F @astryxdesign/lab run typecheck: 0 errors, docs included.
  • pnpm vitest run --project node --project ui packages/lab/src/TabBar packages/lab/src/TabBarMoreList: 82 passed.
  • Storybook typecheck: 0 errors. pnpm storybook:build: the index lists lab-tabbarmorelist--more-tab and lab-tabbarmorelist--more-disabled-row.
  • The whole TabBar interaction spec, 1 worker: Chromium 74 passed. WebKit 64 passed and 10 skipped.
  • The route-lock check (node apps/docsite/scripts/generate-data.mjs) and node scripts/generate-cli-official-packages.mjs --check: pass.
  • pnpm check:repo, ESLint and Prettier: clean. The route lock keeps its generator's format.
  • pnpm review:pre: no findings.

@vercel

vercel Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
astryx Ready Ready Preview Nov 10, 2026 7:22am UTC

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Nov 8, 2026
@github-actions

github-actions Bot commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

PR Analysis Report

🔎 Preview · 8900e2b

Storybook · Sandbox · built from this PR's head

Modified components

Component Size LoC
lab/TabBar 🔴 81.0 kB (+3.3 kB) · 1.8 kB CSS (0) —
lab/TabBarItem 3.8 kB (0) · 1.8 kB CSS (0) —
lab/TabBarMoreList · Storybook 92.6 kB (new) · 1.8 kB CSS (new) 66 (new)

Package size: measured; main has no measurement of the merge base to compare yet.

API changes: none in this pull request

Committed API report behind this build: cli 29 rows, core 36 rows; run pnpm api:report.

Not run on this PR: add ci:run-visual, ci:run-a11y or ci:run-rtl to run them.


Generated by PR Enrichment workflow | View full report

@astracat-bot

astracat-bot Bot commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

AI review status for this pull request.

Review status Updated
🟢 Reviewed (for maintainers only) Nov 10, 2026, 7:36 AM UTC

@cixzhang

cixzhang commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

/approve-spec c7ad5d6

@astracat-bot astracat-bot Bot 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.

Thanks for the careful UIKit match and the thorough tests. Approval waits on an engineering owner's decision, and three fixes are needed after it.

Owner decision needed: no current record governs the lab TabBar's More tab (four tabs plus More past five, moreValue, More again as onReselect), TabBarMoreList, Core's new @astryx.tabBar.more message, or skipping disabled tabs with the arrow keys, and this pull request is not Lab-only because it also changes Core's message catalog, a Core changeset, the Sandbox and Storybook. An engineering owner records the decision by commenting /approve-spec followed by the full head commit SHA, or names the record that governs these behaviors; the author may do so as an engineering owner.

Blocking findings:

  • Desktop behavior change needs an owner decision: past five tabs, a mouse click on the fifth slot now opens More instead of choosing that tab (TabBar.tsx lines 592-609), so gate the More tab to touch input or cite the owner decision that covers it.
  • TabBarMoreList's onChoose is a new name for the value callback that TabBar and Core's TabList call onChange, so rename it onChange (TabBarMoreList.tsx line 64).
  • The More row's badge hand-rolls Core's Badge error pill and loses its forced-colors outline and text-size growth, so render <Badge variant="error" /> there instead (TabBarMoreList.tsx lines 33-53).

[Automated review]

Comment thread packages/lab/src/TabBar/TabBar.tsx Resolved
Comment thread packages/lab/src/TabBar/TabBar.tsx Resolved

@astracat-bot astracat-bot Bot 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.

Changes requested. The /approve-spec on this head settles the direction of the More tab, TabBarMoreList, the "More" message and disabled tabs; it does not by itself cover the mouse behavior below, and three fixes remain.

Blocking findings:

  • Desktop behavior change needs an owner decision: past five tabs, a mouse click on the fifth slot now opens More (onChange('more')) instead of choosing that tab (TabBar.tsx lines 588-610), so gate the More tab to touch input or cite the owner decision that covers it.
  • TabBarMoreList's onChoose is a new name for the value callback that TabBar and Core's TabList call onChange: (value: string) => void, so rename it onChange (TabBarMoreList.tsx line 64).
  • The More row's badge hand-rolls Core's Badge error pill and loses its forced-colors outline (in high-contrast mode the count shows as a bare "2") and its growth at larger text sizes, so render <Badge variant="error" /> there instead (TabBarMoreList.tsx lines 33-53).

Thanks for the careful UIKit match and the thorough tests.

[Automated review]

@vjeux
vjeux force-pushed the tabbar/lab-more-tab branch 2 times, most recently from e182d84 to 5b7c924 Compare November 8, 2026 04:15
@cixzhang

cixzhang commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

/approve-spec 5b7c924

@astracat-bot astracat-bot Bot 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 waits on one owner decision. The /approve-spec on this head covers the rest of the draft TabBar record, and nothing else blocks.

  • Past five tabs, More also takes the fifth slot for a mouse and trackpad (packages/lab/src/TabBar/TabBar.tsx lines 588-609). The description credits this to a ruling made under a Lab grant, and no record holds that grant. A desktop behavior change needs the owner's own decision cited in the description, as a decision card number or their words with when they gave them; otherwise, please gate the More tab to touch input.

CI has not run on this draft head yet. Non-blocking notes:

  • The comment at TabBar.tsx line 603 restates isMoreSelected, and the block at lines 548-552 repeats the moreValue docs. Keep only the reason in each.
  • A disabled More row gets Core Item's native disabled, so Tab skips it. That gap is Core's to fix, not this pull request's.

[Automated review]

@vjeux
vjeux force-pushed the tabbar/lab-more-tab branch from 5b7c924 to 6a535fd Compare November 10, 2026 00:21
@cixzhang cixzhang added the ci:run A maintainer lets this outside contributor's pull request run CI (AST-030 FR17) label Nov 10, 2026
@cixzhang

Copy link
Copy Markdown
Contributor

/approve-spec 6a535fd

@astracat-bot astracat-bot Bot 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.

Changes requested: one owner decision is missing.

Blocking finding:

  • Desktop behavior change needs an owner decision: past five tabs, More replaces the fifth slot for a mouse and trackpad too (packages/lab/src/TabBar/TabBar.tsx lines 588-609), so a click there opens More instead of choosing that tab; gate More to touch input, or cite the owner decision that covers this desktop behavior in the description.

The draft component:TabBar record is approved for this head, and the More tab, moreValue, TabBarMoreList and the disabled rows otherwise match it, with the TabBar unit tests passing. Non-blocking: add Components: TabBar, TabBarMoreList under ## Scope, and see the two comment suggestions inline.

[Automated review]

Comment thread packages/lab/src/TabBar/TabBar.tsx Resolved
Comment thread packages/lab/src/TabBar/TabBar.tsx Resolved
@vjeux

vjeux commented Nov 10, 2026

Copy link
Copy Markdown
Contributor Author

The draft TabBar record moved to #10929. This pull request is now Lab-only under spec:AST-030 FR26, so it needs no owner decision (architecture:knowledge-contracts DEC-19). FR1 ("for every pointer") is recorded there, for its own stamp.

@cixzhang

Copy link
Copy Markdown
Contributor

/approve-spec 4b09a37

@astracat-bot astracat-bot Bot 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.

Waiting on one owner decision before approval.

  • Past five tabs, More takes the fifth slot for every pointer, so a mouse or trackpad click there now opens More instead of choosing that tab (packages/lab/src/TabBar/TabBar.tsx, lines 585-606); a mouse and trackpad change like this needs an explicit owner decision, so either an owner confirms that the Lab-only decision covers it or More is gated to touch input.

Everything else checks out at this head: the lab unit suites pass, the right-to-left chevrons mirror once, and a disabled tab stays disabled in the More list. Non-blocking: the WHAT IT DRAWS comment in TabBarMoreList.tsx could shrink to one sentence.

[Automated review]

@vjeux
vjeux force-pushed the tabbar/lab-more-tab branch from 4b09a37 to 8cdb2e4 Compare November 10, 2026 01:40
@cixzhang

Copy link
Copy Markdown
Contributor

/approve-spec 8cdb2e4

@cixzhang

Copy link
Copy Markdown
Contributor

(Posted by Cindy's agent, as spec owner.) TabBar is a Lab component, so under the owner's Lab grant (spec:AST-030 FR26; architecture:knowledge-contracts DEC-19) the More tab and its new experimental Lab API (moreValue, TabBarMoreList) need no owner decision. The TabBar record change (#10929) is consistency under that grant, and this head (8cdb2e4) is stamped.

@cixzhang

Copy link
Copy Markdown
Contributor

/approve-spec f9ed789

@astracat-bot astracat-bot Bot 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.

Approved pending CI: CI has not run on this head yet; it runs once the pull request leaves draft.

Past five tabs, More takes the fifth slot for every pointer, so a mouse click there opens More instead of that tab. The owner's decision for Lab-only pull requests covers that, and the More list, its disabled rows and its right-to-left chevrons check out at this head.

Non-blocking: the file headers of TabBar.tsx and TabBarMoreList.tsx list only some of the shared tab helpers; hasBadge and isDisabledItem are missing.

[Automated review]

Comment on lines +10 to +11
* @output TabBar (iOS 26's floating tab bar), TabBarItem, and the tab reading
* TabBarMoreList shares (overflowItems, badgedName)

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.

Non-blocking: this file also exports hasBadge and isDisabledItem for TabBarMoreList. Suggest: TabBarItem, and the tab helpers TabBarMoreList shares (overflowItems, badgedName, hasBadge, isDisabledItem).

With more than five tabs, the bar shows the first four and a More
tab, as UITabBarController does, at the five-tab layout. More is the
selected tab while `value` is `moreValue` or any tab past the fourth.
Choosing More again while it holds a tab is a reselect, back to its
list. TabBarMoreList, a Lab component in its own folder, is More's
screen: one row per tab past the fourth, with its icon, label, Core's
error Badge and a disclosure chevron. Choosing a row calls
`onChange`. A disabled tab's row is disabled too, so it never
activates there either. The More label is Core's
`@astryx.tabBar.more` message. TabBarMoreList's route joins the
ShadCN route lock and its entry the CLI's official packages.
@vjeux
vjeux force-pushed the tabbar/lab-more-tab branch from f9ed789 to 8900e2b Compare November 10, 2026 07:14
@cixzhang

Copy link
Copy Markdown
Contributor

/approve-spec 8900e2b

@astracat-bot astracat-bot Bot 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.

Approved pending CI: CI has not run on this head yet; it runs once the pull request leaves draft.

Past five tabs, More takes the fifth slot for every pointer, and the owner's decision for Lab-only pull requests covers that. The rebased reselect keeps both behaviors: the selected tab scrolls its panel, and More again returns to its list without scrolling. Non-blocking: the file headers of TabBar.tsx and TabBarMoreList.tsx still list only some of the shared tab helpers, leaving out hasBadge and isDisabledItem.

[Automated review]

@vjeux
vjeux marked this pull request as ready for review November 10, 2026 07:43
@cixzhang

Copy link
Copy Markdown
Contributor

/approve-spec 8900e2b

@cixzhang
cixzhang merged commit 0085c0f into meta:main Nov 10, 2026
116 checks passed
@vjeux
vjeux deleted the tabbar/lab-more-tab branch November 10, 2026 08:17

This branch was successfully deployed

1 active deployment
Preview — 8900e2bb Deployed Nov 10, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:run A maintainer lets this outside contributor's pull request run CI (AST-030 FR17) CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants