quality / commitlint (push) Skipped
quality / changes (push) Successful in 8s
quality / go (push) Skipped
quality / bird2 (push) Skipped
quality / docker-check (push) Skipped
quality / openapi (push) Successful in 22s
quality / web (push) Successful in 1m0s
CD / quality (push) Successful in 1m35s
CD / publish (push) Successful in 2m59s
Секции страниц переведены на segmented Tabs (c-tabs-9), статус грида — ToggleGroup в toolbar. Убраны календарь задач, пустые вкладки мониторинга и demo-деревья ReUI. KPI overflow как в CFDM, DetailPanel на карточке модуля, один FrameSection. Co-authored-by: Cursor <[email protected]>
69 lines
1.8 KiB
TypeScript
69 lines
1.8 KiB
TypeScript
import type { ComponentProps, ReactNode } from 'react'
|
|
|
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@evobgp/ui/components/tabs'
|
|
import { cn } from '@evobgp/ui/lib/utils'
|
|
|
|
import { Badge } from '@/components/reui/badge'
|
|
|
|
export type SegmentedTabItem = {
|
|
value: string
|
|
label: string
|
|
count?: number
|
|
badgeVariant?: ComponentProps<typeof Badge>['variant']
|
|
icon?: ReactNode
|
|
}
|
|
|
|
interface SegmentedTabsProps {
|
|
items: SegmentedTabItem[]
|
|
value?: string
|
|
defaultValue?: string
|
|
onValueChange?: (value: string) => void
|
|
children: ReactNode
|
|
className?: string
|
|
listClassName?: string
|
|
contentClassName?: string
|
|
}
|
|
|
|
/**
|
|
* Page-level section switcher — native shadcn Tabs, default (segmented) list.
|
|
* @see https://reui.io/preview/base/components/c-tabs-9
|
|
* @see https://reui.io/components/tabs
|
|
*/
|
|
export function SegmentedTabs({
|
|
items,
|
|
value,
|
|
defaultValue,
|
|
onValueChange,
|
|
children,
|
|
className,
|
|
listClassName,
|
|
contentClassName,
|
|
}: SegmentedTabsProps) {
|
|
return (
|
|
<Tabs
|
|
value={value}
|
|
defaultValue={defaultValue}
|
|
onValueChange={onValueChange}
|
|
orientation="horizontal"
|
|
className={cn('w-full min-w-0 gap-4', className)}
|
|
>
|
|
<TabsList className={cn('h-auto w-full min-w-0 justify-start', listClassName)}>
|
|
{items.map((item) => (
|
|
<TabsTrigger key={item.value} value={item.value} className="shrink-0 gap-2">
|
|
{item.icon}
|
|
{item.label}
|
|
{item.count !== undefined ? (
|
|
<Badge variant={item.badgeVariant ?? 'primary-light'} size="sm">
|
|
{item.count}
|
|
</Badge>
|
|
) : null}
|
|
</TabsTrigger>
|
|
))}
|
|
</TabsList>
|
|
<div className={cn('w-full min-w-0', contentClassName)}>{children}</div>
|
|
</Tabs>
|
|
)
|
|
}
|
|
|
|
export { TabsContent }
|