component — navigation
Link Toggle Group
A segmented control rendered as anchor links inside a tablist, for view switches that are real navigations. Styled with the quebi design system.
- navigation
- tabs
- toggle
- segmented
- links
03 examples
source
link-toggle-group.tsxCopy this into your project. Resolve its dependencies from the registryDependencies in the component's API entry.
"use client"
import type { ReactNode } from "react"
import { cn } from "@/lib/utils"
/**
* LinkToggleGroup — quebi design system
*
* A segmented control rendered as a row of anchor links inside a tablist.
* Use it for view switches that are real navigations (each option has an
* href) — e.g. day/week/month, or list/board. The current segment is the
* `selected` ground with a `signal` label, the same state as ToggleGroup.
*
* Self-contained: only `@/lib/utils` and React. No sibling component deps.
*/
export type LinkToggleGroupOption<T extends string = string> = {
value: T
label: ReactNode
href: string
}
export interface LinkToggleGroupProps<T extends string = string> {
options: LinkToggleGroupOption<T>[]
current: T
ariaLabel: string
className?: string
}
export function LinkToggleGroup<T extends string = string>({
options,
current,
ariaLabel,
className,
}: LinkToggleGroupProps<T>) {
return (
<div
role="tablist"
aria-label={ariaLabel}
className={cn(
"inline-flex items-center gap-0.5 rounded-(--q-radius-control) border border-quebi-hairline p-0.5",
className,
)}
>
{options.map((opt) => {
const isActive = current === opt.value
return (
// biome-ignore lint/correctness/noRestrictedElements: these anchors are the tabs of a tablist — role="tab" and aria-selected are the component's purpose, and react-aria's Link does not accept a role override.
<a
key={opt.value}
role="tab"
aria-selected={isActive}
href={opt.href}
className={cn(
"rounded-(--q-radius-mark) px-3 py-1.5 text-sm font-medium",
"outline-none transition-colors duration-150",
"focus-visible:ring-2 focus-visible:ring-quebi-focus focus-visible:ring-offset-2 focus-visible:ring-offset-quebi-bg",
isActive
? "bg-quebi-selected text-quebi-signal"
: "text-quebi-fg-muted hover:bg-quebi-raised hover:text-quebi-fg",
)}
>
{opt.label}
</a>
)
})}
</div>
)
}