import React, { forwardRef, useEffect, useRef } from 'react'; import { cn, focusRing, surfaceClasses } from '../common'; import { useTabsContext } from './_internal/tabsContext'; /* ───────────────────────────────────────────────────────────────────────── PixelTabsTrigger — tab button with roving tabindex + keyboard nav. ───────────────────────────────────────────────────────────────────────── */ /** Public prop bag for {@link PixelTabsTrigger}. */ export interface PixelTabsTriggerProps extends Omit, 'role' | 'value'> { /** Tab id this trigger controls — must match a {@link PixelTabsPanel} value. */ value: string; /** Optional leading icon node. */ icon?: React.ReactNode; } export const PixelTabsTrigger = forwardRef( function PixelTabsTrigger({ value, icon, children, className, onKeyDown, onClick, onFocus, ...rest }, forwardedRef) { const ctx = useTabsContext('PixelTabs.Trigger'); const s = surfaceClasses(ctx.surface); const isVertical = ctx.orientation === 'vertical'; const selected = ctx.active === value; const innerRef = useRef(null); const setRefs = (el: HTMLButtonElement | null) => { innerRef.current = el; ctx.registerTrigger(value, el); if (typeof forwardedRef === 'function') forwardedRef(el); else if (forwardedRef) (forwardedRef as React.MutableRefObject).current = el; }; useEffect(() => { return () => ctx.unregisterTrigger(value); // eslint-disable-next-line react-hooks/exhaustive-deps }, [value]); const tabRadius = ctx.surface === 'pixel' ? (isVertical ? 'rounded-l-[3px]' : 'rounded-t-[3px]') : (isVertical ? 'rounded-l-md' : 'rounded-t-md'); const sideBorder = isVertical ? 'border-r-0' : 'border-b-0'; const offset = isVertical ? '-mr-px' : '-mb-px'; const handleKey = (e: React.KeyboardEvent) => { onKeyDown?.(e); if (e.defaultPrevented) return; const prevKey = isVertical ? 'ArrowUp' : 'ArrowLeft'; const nextKey = isVertical ? 'ArrowDown' : 'ArrowRight'; switch (e.key) { case nextKey: e.preventDefault(); ctx.focusByOffset(value, 1); break; case prevKey: e.preventDefault(); ctx.focusByOffset(value, -1); break; case 'Home': e.preventDefault(); ctx.focusEdge('first'); break; case 'End': e.preventDefault(); ctx.focusEdge('last'); break; case 'Enter': case ' ': if (ctx.activationMode === 'manual') { e.preventDefault(); ctx.select(value); } break; } }; const handleFocus = (e: React.FocusEvent) => { onFocus?.(e); if (ctx.activationMode === 'automatic') { ctx.select(value); } }; const handleClick = (e: React.MouseEvent) => { onClick?.(e); ctx.select(value); }; return ( ); }, ); PixelTabsTrigger.displayName = 'PixelTabs.Trigger';