1- import { useEffect , useRef , useState , type MouseEvent , type PointerEvent , type ReactNode } from "react" ;
1+ import {
2+ useEffect ,
3+ useRef ,
4+ useState ,
5+ type MouseEvent ,
6+ type PointerEvent ,
7+ type ReactNode ,
8+ } from "react" ;
29import type { TabsTab } from "@base-ui/react/tabs" ;
310import { Tabs as TabsPrimitive } from "@base-ui/react/tabs" ;
411import { cn } from "../../utils/cn" ;
@@ -156,15 +163,25 @@ export function Tabs({
156163 return (
157164 < TabsPrimitive . Root
158165 { ...rootProps }
159- className = { cn ( "relative isolate min-w-0 font-medium" , className ) }
166+ className = { cn (
167+ "relative isolate min-w-0 font-medium" ,
168+ isSegmented &&
169+ ( isSm ? "rounded-md" : "rounded-lg" ) + " ring ring-kumo-hairline/70" ,
170+ className ,
171+ ) }
160172 onValueChange = { ( nextValue ) => {
161173 const stringValue = String ( nextValue ) ;
162174 onValueChange ?.( stringValue ) ;
163175 } }
164176 >
165177 { /* Background element for segmented variant */ }
166178 { isSegmented && (
167- < div className = { cn ( "absolute inset-x-0 top-1/2 z-0 -translate-y-1/2 rounded-lg bg-kumo-recessed" , isSm ? "h-6.5" : "h-9" ) } />
179+ < div
180+ className = { cn (
181+ "absolute inset-x-0 top-1/2 z-0 -translate-y-1/2 rounded-lg bg-kumo-recessed" ,
182+ isSm ? "h-6.5" : "h-9" ,
183+ ) }
184+ />
168185 ) }
169186 < TabsPrimitive . List
170187 ref = { listRef }
@@ -173,7 +190,8 @@ export function Tabs({
173190 { ...bindDrag ( ) }
174191 className = { cn (
175192 "relative flex min-w-0 shrink items-stretch" ,
176- isSegmented && "kumo-tabs-list overflow-x-auto rounded-lg bg-kumo-recessed px-0.5 ring ring-kumo-hairline/70 [--scroll-fade-width:3rem]" ,
193+ isSegmented &&
194+ "kumo-tabs-list overflow-x-auto rounded-lg bg-kumo-recessed px-0.5 [--scroll-fade-width:3rem] scroll-px-(--scroll-fade-width)" ,
177195 isSegmented && ( isSm ? "h-6.5 rounded-md" : "h-9" ) ,
178196 isOverflowing && "cursor-grab active:cursor-grabbing" ,
179197 isUnderline && "gap-4 border-b border-kumo-hairline pb-2" ,
@@ -188,13 +206,22 @@ export function Tabs({
188206 data-kumo-part = "tab"
189207 value = { tab . value }
190208 render = { tab . render }
209+ onClick = { ( e ) => {
210+ e . currentTarget . scrollIntoView ( {
211+ behavior : "smooth" ,
212+ block : "nearest" ,
213+ inline : "nearest" ,
214+ } ) ;
215+ } }
191216 className = { cn (
192217 "relative z-2 flex items-center rounded bg-transparent whitespace-nowrap focus:outline-none focus:ring-kumo-focus/50 focus-visible:ring-2 focus-visible:ring-kumo-brand" ,
193- isOverflowing ? "cursor-grab active:cursor-grabbing" : "cursor-pointer" ,
218+ isOverflowing
219+ ? "cursor-grab active:cursor-grabbing"
220+ : "cursor-pointer" ,
194221 isSm ? "text-xs" : "text-base" ,
195222 isSegmented &&
196- "my-0.5 rounded-md text-kumo-subtle hover:text-kumo-default aria-selected:text-kumo-default focus-visible:ring-inset" ,
197- isSegmented && ( isSm ? "px-2" : "px-2.5" ) ,
223+ "my-0.5 text-kumo-subtle hover:text-kumo-default aria-selected:text-kumo-default focus-visible:ring-inset" ,
224+ isSegmented && ( isSm ? "px-2 rounded-sm " : "px-2.5 rounded-md " ) ,
198225 isUnderline &&
199226 "text-kumo-subtle hover:bg-kumo-tint hover:text-kumo-default aria-selected:hover:bg-kumo-tint aria-selected:font-medium aria-selected:text-kumo-default" ,
200227 isUnderline && ( isSm ? "px-1.5 py-2.5" : "px-2 py-3" ) ,
@@ -213,7 +240,10 @@ export function Tabs({
213240 "w-(--active-tab-width) translate-x-(--active-tab-left) transition-all duration-200" ,
214241 "data-[rendered=false]:scale-90 data-[rendered=false]:opacity-0" ,
215242 isSegmented &&
216- cn ( "top-(--active-tab-top) h-(--active-tab-height) bg-kumo-base shadow-sm ring ring-kumo-line" , isSm ? "rounded" : "rounded-md" ) ,
243+ cn (
244+ "top-(--active-tab-top) h-(--active-tab-height) bg-kumo-base shadow-sm ring ring-kumo-line" ,
245+ isSm ? "rounded" : "rounded-md" ,
246+ ) ,
217247 isUnderline && "bottom-0 h-0.5 bg-kumo-brand" ,
218248 indicatorClassName ,
219249 ) }
@@ -260,7 +290,8 @@ function useHorizontalDragScroll(
260290 onPointerMoveCapture : ( event : PointerEvent < HTMLElement > ) => {
261291 const el = ref . current ;
262292 const state = dragState . current ;
263- if ( ! el || ! enabled || ! state || state . pointerId !== event . pointerId ) return ;
293+ if ( ! el || ! enabled || ! state || state . pointerId !== event . pointerId )
294+ return ;
264295
265296 const movementX = event . clientX - state . startX ;
266297 if ( ! state . dragging ) {
0 commit comments