shadcn.io is not affiliated with official shadcn/ui
Shadcn Segment Group for React and Tailwind
Follows the selected item.
Installation
bunx --bun shadcn@latest add https://kit.dev/r/segment-group.jsonpnpm dlx shadcn@latest add https://kit.dev/r/segment-group.jsonnpx shadcn@latest add https://kit.dev/r/segment-group.jsonyarn shadcn@latest add https://kit.dev/r/segment-group.jsonInstall the following dependencies:
bun add @ark-ui/reactpnpm add @ark-ui/reactnpm install @ark-ui/reactyarn add @ark-ui/reactCopy and paste the following code into your project.
"use client";
import {
SegmentGroup as ArkSegmentGroup,
useSegmentGroupContext,
} from "@ark-ui/react/segment-group";
import type React from "react";
import { cn } from "@/lib/utils";
export const useSegmentGroup = useSegmentGroupContext;
type SegmentGroupVariant = "default" | "underline";
interface SegmentGroupProps
extends React.ComponentProps<typeof ArkSegmentGroup.Root> {
/**
* The visual variant of the segment group.
*
* @default "default"
*/
variant?: SegmentGroupVariant;
}
export const SegmentGroup = (props: SegmentGroupProps) => {
const {
orientation = "horizontal",
variant = "default",
className,
children,
...rest
} = props;
return (
<ArkSegmentGroup.Root
className={cn(
"group/segment-group relative",
"flex gap-2",
"isolate",
"data-[orientation=vertical]:flex-col",
"data-disabled:opacity-64",
"data-[variant=underline]:gap-1 data-[variant=underline]:border-input",
"data-[orientation=horizontal]:data-[variant=underline]:border-b",
"data-[orientation=vertical]:data-[variant=underline]:border-l",
className
)}
data-slot="segment-group"
data-variant={variant}
orientation={orientation}
{...rest}
>
<SegmentGroupIndicator />
{children}
</ArkSegmentGroup.Root>
);
};
export const SegmentGroupItem = (
props: React.ComponentProps<typeof ArkSegmentGroup.Item>
) => {
const { className, children, ...rest } = props;
return (
<ArkSegmentGroup.Item
className={cn(
"relative",
"cursor-pointer",
"data-[orientation=vertical]:w-full data-[orientation=vertical]:justify-start",
"rounded-[inherit] border border-transparent",
"outline-none data-focus-visible:border-primary data-focus-visible:ring-[3px] data-focus-visible:ring-ring/32",
"data-disabled:pointer-events-none data-disabled:opacity-64",
className
)}
data-slot="segment-group-item"
{...rest}
>
{children}
<ArkSegmentGroup.ItemControl />
<ArkSegmentGroup.ItemHiddenInput />
</ArkSegmentGroup.Item>
);
};
export const SegmentGroupItemText = (
props: React.ComponentProps<typeof ArkSegmentGroup.ItemText>
) => {
const { className, ...rest } = props;
return (
<ArkSegmentGroup.ItemText
className={cn("relative z-1", className)}
data-slot="segment-group-item-text"
{...rest}
/>
);
};
export const SegmentGroupIndicator = (
props: React.ComponentProps<typeof ArkSegmentGroup.Indicator>
) => {
const { className, ...rest } = props;
return (
<ArkSegmentGroup.Indicator
className={cn(
"absolute top-(--top) left-(--left) z-0",
"h-(--height) w-(--width)",
"rounded-[inherit]",
"bg-input",
"transition-[width,height,left,top] duration-150 ease-out",
"[transition-property:var(--transition-property,width,height,left,top)]",
"group-data-[variant=underline]/segment-group:bg-primary",
"data-[orientation=horizontal]:group-data-[variant=underline]/segment-group:top-[calc(var(--top)+var(--height)-1px)]",
"data-[orientation=vertical]:group-data-[variant=underline]/segment-group:right-[calc(var(--left)+var(--width)-1px)]",
"data-[orientation=vertical]:group-data-[variant=underline]/segment-group:-translate-x-px",
"data-[orientation=horizontal]:group-data-[variant=underline]/segment-group:h-0.5",
"data-[orientation=vertical]:group-data-[variant=underline]/segment-group:w-0.5",
"motion-reduce:transition-none!",
className
)}
data-slot="segment-group-indicator"
{...rest}
/>
);
};Update the import paths to match your project setup.
Usage
import {
SegmentGroup,
SegmentGroupItem,
SegmentGroupItemText,
} from "@/components/ui/segment-group";const SegmentGroupDemo = () => (
<SegmentGroup className="rounded-lg" defaultValue="Profile">
{items.map((item) => (
<SegmentGroupItem className="px-2 py-1.5 text-sm" key={item} value={item}>
<SegmentGroupItemText>{item}</SegmentGroupItemText>
</SegmentGroupItem>
))}
</SegmentGroup>
);
const items = ["Profile", "Account", "Security", "Notifications"];Demos
Controlled
Custom Indicator
Disabled
Disabled Item
Indicator On Hover
Orientation Horizontal
Orientation Vertical
Variant Underline
Variant Underline Orientation Vertical
API Reference
SegmentGroup
div
PropType
AttributeType
SegmentGroupItem
label
PropType
AttributeType
SegmentGroupItemText
span
PropType
AttributeType
SegmentGroupIndicator
div
PropType
AttributeType
CSS variableType
useSegmentGroup
PropType