Skip to content

feat: add Tabs component#127

Open
IzumiSy wants to merge 5 commits intomainfrom
add-tabs-component
Open

feat: add Tabs component#127
IzumiSy wants to merge 5 commits intomainfrom
add-tabs-component

Conversation

@IzumiSy
Copy link
Copy Markdown
Contributor

@IzumiSy IzumiSy commented Mar 26, 2026

Summary

Add Tabs compound component for tab-based navigation, backed by Base UI's Tabs primitive.

Changes

New files

  • packages/core/src/components/tabs.tsx — Tabs compound component (Pattern B) with Root, List, Tab, Panel sub-components
  • packages/core/src/components/tabs.test.tsx — 9 tests (3 snapshot + 6 behavioral)
  • docs/components/tabs.md — Component documentation
  • .changeset/add-tabs-component.md — Minor changeset

Modified files

  • packages/core/src/index.ts — Added Tabs export
  • examples/app-module/src/custom-module.tsx — Added Tabs demo to Primitive Components Demo page

Usage

import { Tabs } from "@tailor-platform/app-shell";

<Tabs.Root defaultValue="overview">
  <Tabs.List>
    <Tabs.Tab value="overview">Overview</Tabs.Tab>
    <Tabs.Tab value="projects">Projects</Tabs.Tab>
    <Tabs.Tab value="settings">Settings</Tabs.Tab>
    <Tabs.Tab value="archived" disabled>Archived</Tabs.Tab>
  </Tabs.List>
  <Tabs.Panel value="overview">Overview content</Tabs.Panel>
  <Tabs.Panel value="projects">Projects content</Tabs.Panel>
  <Tabs.Panel value="settings">Settings content</Tabs.Panel>
  <Tabs.Panel value="archived">Archived content</Tabs.Panel>
</Tabs.Root>

Sub-components

Sub-component Description
Tabs.Root Manages tab selection state (value, defaultValue, onValueChange, orientation)
Tabs.List Groups the tab buttons with styled background
Tabs.Tab Individual tab button with value and optional disabled
Tabs.Panel Content panel displayed when its matching tab is active

@IzumiSy IzumiSy changed the title feat: add Tabs compound component backed by Base UI feat: add Tabs component Mar 26, 2026
@IzumiSy
Copy link
Copy Markdown
Contributor Author

IzumiSy commented Mar 27, 2026

/review

Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Generated by API Design Review for issue #127

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 27, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@tailor-platform/app-shell@127
npm i https://pkg.pr.new/@tailor-platform/app-shell-vite-plugin@127

commit: f3d8e5a

| --------------- | ---------------------------- | -------------- | --------------------------------------- |
| `defaultValue` | `Tabs.Tab.Value` | `0` | Initial active tab value (uncontrolled) |
| `value` | `Tabs.Tab.Value` | - | Controlled active tab value |
| `onValueChange` | `(value: any) => void` | - | Callback when the active tab changes |
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Small bit from my review agent:

onValueChange docs show (value: any) => void but Base UI's actual signature is (value, eventDetails) => void. The second arg includes activationDirection and standard event details (reason, event, cancel()). Useful for transition animations or conditional side effects.

Ref: https://base-ui.com/react/components/tabs

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed — updated the docs table to reflect Base UI's actual signature: (value: Tabs.Tab.Value, eventDetails: Tabs.Root.ChangeEventDetails) => void, with a note about the activationDirection, event, reason, and cancel() fields in the second argument.

Commit: a1b2ecb

IzumiSy added 3 commits April 1, 2026 10:38
Apply Pick<> type narrowing to List, Tab, and Panel sub-components,
matching the same pattern already used by Root. This prevents Base UI
internal props from leaking into AppShell's public API surface.
Verify that a panel with keepMounted remains in the DOM even when its
tab is not active.
@IzumiSy IzumiSy force-pushed the add-tabs-component branch from f3d8e5a to 0daf45c Compare April 1, 2026 01:39
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