Skip to content

Scroll Tabs horizontally instead of wrapping - #101

Merged
cmil merged 4 commits into
mainfrom
tabs-scroll-horizontally
Oct 24, 2026
Merged

cmil merged 4 commits into
mainfrom
tabs-scroll-horizontally

Conversation

@cmil

@cmil cmil commented Oct 24, 2026 •

Copy link
Copy Markdown
Member

Closes #100

Changes

  • The tab row no longer wraps. It stays on one line, scrolls horizontally and hides the scrollbar, which matches the old dracor-frontend.
  • The grey baseline is now an inset shadow on the row itself, replacing the -mb-px overlap with the outer border. The active tab's underline therefore isn't clipped by overflow-x: auto.
  • The baseline colour comes from the --tabs-baseline CSS variable, which falls back to gray-200 (gray-700 in dark mode). The variable can be set on the row or on any ancestor, and covers both light and dark mode.
  • Whenever the location changes, the active tab is scrolled into view by adjusting scrollLeft directly. This covers deep links, browser back/forward and programmatic navigation while the tabs stay mounted. scrollIntoView is not used because it would also scroll the page. The position is measured again after webfonts load.
  • New wrap prop (default false) restores the wrapping behaviour.
  • New className prop adds classes to the tab row. They are appended without tailwind-merge, so they can't reliably override the row's own utilities. The prop documentation says so.
  • New stories Scrollable, NoActiveTab, Wrapping, BackForward and CustomBaseline, with play-function checks.

Migration note for consumers

The bottom border moved from the outer wrapper to the inner row and is now a box-shadow. CSS such as .dracor-tabs > div { border-bottom: none } no longer has any effect. Use this instead:

.dracor-tabs { --tabs-baseline: transparent; }

🤖 Generated with Claude Code

On narrow screens the tab row now stays on a single line and scrolls
horizontally with a hidden scrollbar. The baseline is drawn as an inset
shadow on the row so the active underline is not clipped by overflow.
A deep-linked active tab is scrolled into view on mount.

Adds a `wrap` prop to restore the wrapping behaviour and a `className`
prop for the tab row.

Closes #100

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.68%. Comparing base (4a849e9) to head (172db75).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #101      +/-   ##
==========================================
+ Coverage   95.45%   95.68%   +0.23%     
==========================================
  Files          34       34              
  Lines         352      371      +19     
  Branches      124      131       +7     
==========================================
+ Hits          336      355      +19     
  Misses          4        4              
  Partials       12       12              

☔ 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.

cmil and others added 3 commits October 24, 2026 14:16
Drop the unreachable scroll-left branch and ref guard, and add a story
without an active tab.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The baseline colour is read from the `--tabs-baseline` CSS variable,
  falling back to gray-200 (gray-700 in dark mode), so consumers can
  recolour or hide it without fighting class order or specificity.
- Document that `className` is appended without merging.
- Scroll the active tab into view whenever the location changes, not
  just on mount, so browser back/forward and programmatic navigation
  work while the tabs stay mounted. Scroll left as well as right.
- Measure again once webfonts have loaded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
overflow-x: auto on the tab row makes overflow-y compute to auto as
well, which clips a focus outline at the top and bottom. Draw the
focus-visible state as an inset ring inside the link instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cmil
cmil merged commit 184f3b3 into main Oct 24, 2026
5 checks passed
@cmil
cmil deleted the tabs-scroll-horizontally branch October 24, 2026 14:40
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.

Tabs: scroll horizontally instead of wrapping on narrow screens

1 participant