@orsetra/shared-ui 1.6.2 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -63,7 +63,7 @@ export function PageWithSidePanel({
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
return (
|
|
66
|
-
<div className={cn("flex
|
|
66
|
+
<div className={cn("flex", className)}>
|
|
67
67
|
{/* Main content column — grows to fill space left by the panel */}
|
|
68
68
|
<div className="flex-1 min-w-0 flex flex-col">
|
|
69
69
|
|
package/components/ui/button.tsx
CHANGED
|
@@ -29,7 +29,7 @@ export const variants: Record<ButtonVariant, string> = {
|
|
|
29
29
|
tertiary:
|
|
30
30
|
'bg-transparent text-ibm-blue-60 hover:bg-ibm-blue-10 active:bg-ibm-blue-20 border border-ibm-blue-20',
|
|
31
31
|
tertiaryDanger:
|
|
32
|
-
'bg-transparent text-ibm-red-60 hover:bg-ibm-red-10 active:bg-ibm-red-20 border border-ibm-red-
|
|
32
|
+
'bg-transparent text-ibm-red-60 hover:bg-ibm-red-10 active:bg-ibm-red-20 border border-ibm-red-60',
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
const sizes: Record<ButtonSize, string> = {
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
|
|
3
|
-
import { ArrowLeft } from "lucide-react"
|
|
3
|
+
import { ArrowLeft, ChevronRight } from "lucide-react"
|
|
4
4
|
import Link from "next/link"
|
|
5
5
|
import type { ReactNode, ElementType } from "react"
|
|
6
6
|
import { cn } from "../../lib/utils"
|
|
7
7
|
|
|
8
|
+
export interface HeaderBreadcrumb {
|
|
9
|
+
label: string
|
|
10
|
+
href?: string
|
|
11
|
+
action?: () => void
|
|
12
|
+
}
|
|
13
|
+
|
|
8
14
|
const TAB_ACTIVE =
|
|
9
15
|
"border-b-2 border-ibm-blue-60 text-ibm-blue-60 bg-ibm-blue-10/60"
|
|
10
16
|
const TAB_INACTIVE =
|
|
@@ -47,6 +53,8 @@ export interface DetailPageHeaderProps {
|
|
|
47
53
|
className?: string
|
|
48
54
|
/** Whether to show the tab bar */
|
|
49
55
|
enableTabs?: boolean
|
|
56
|
+
/** Breadcrumb trail — replaces backLabel/backHref/backAction when provided */
|
|
57
|
+
breadcrumbs?: HeaderBreadcrumb[]
|
|
50
58
|
}
|
|
51
59
|
|
|
52
60
|
export function DetailPageHeader({
|
|
@@ -63,20 +71,48 @@ export function DetailPageHeader({
|
|
|
63
71
|
activeTab,
|
|
64
72
|
enableTabs = true,
|
|
65
73
|
className,
|
|
74
|
+
breadcrumbs,
|
|
66
75
|
}: DetailPageHeaderProps) {
|
|
67
76
|
const backCls = "inline-flex items-center gap-1.5 text-xs text-ibm-gray-50 hover:text-ibm-blue-60 transition-colors mb-3"
|
|
77
|
+
const crumbLinkCls = "hover:text-ibm-blue-60 transition-colors"
|
|
68
78
|
return (
|
|
69
79
|
<div className={cn("border-ibm-gray-20", className)}>
|
|
70
80
|
<div className="px-4 sm:px-2 pt-1 pb-0">
|
|
71
81
|
|
|
72
|
-
{/* Breadcrumb */}
|
|
73
|
-
{
|
|
82
|
+
{/* Breadcrumb — array form */}
|
|
83
|
+
{breadcrumbs && breadcrumbs.length > 0 && (
|
|
84
|
+
<div className="inline-flex items-center gap-0.5 text-xs text-ibm-gray-50 mb-3 flex-wrap">
|
|
85
|
+
<ArrowLeft className="h-3 w-3 flex-shrink-0 mr-0.5" />
|
|
86
|
+
{breadcrumbs.map((item, i) => {
|
|
87
|
+
const isLast = i === breadcrumbs.length - 1
|
|
88
|
+
let node: ReactNode
|
|
89
|
+
if (isLast) {
|
|
90
|
+
node = <span className="text-ibm-gray-70 font-medium">{item.label}</span>
|
|
91
|
+
} else if (item.action) {
|
|
92
|
+
node = <button type="button" onClick={item.action} className={crumbLinkCls}>{item.label}</button>
|
|
93
|
+
} else if (item.href) {
|
|
94
|
+
node = <Link href={item.href} className={crumbLinkCls}>{item.label}</Link>
|
|
95
|
+
} else {
|
|
96
|
+
node = <span>{item.label}</span>
|
|
97
|
+
}
|
|
98
|
+
return (
|
|
99
|
+
<span key={i} className="inline-flex items-center gap-0.5">
|
|
100
|
+
{i > 0 && <ChevronRight className="h-2.5 w-2.5 text-ibm-gray-30 flex-shrink-0" />}
|
|
101
|
+
{node}
|
|
102
|
+
</span>
|
|
103
|
+
)
|
|
104
|
+
})}
|
|
105
|
+
</div>
|
|
106
|
+
)}
|
|
107
|
+
|
|
108
|
+
{/* Breadcrumb — legacy single form */}
|
|
109
|
+
{!breadcrumbs && backAction && backLabel && (
|
|
74
110
|
<button type="button" onClick={backAction} className={backCls}>
|
|
75
111
|
<ArrowLeft className="h-3 w-3" />
|
|
76
112
|
{backLabel}
|
|
77
113
|
</button>
|
|
78
114
|
)}
|
|
79
|
-
{!backAction && backHref && backLabel && (
|
|
115
|
+
{!breadcrumbs && !backAction && backHref && backLabel && (
|
|
80
116
|
<Link href={backHref} className={backCls}>
|
|
81
117
|
<ArrowLeft className="h-3 w-3" />
|
|
82
118
|
{backLabel}
|
package/components/ui/index.ts
CHANGED
|
@@ -9,7 +9,7 @@ export { UserMenu, type UserMenuItem, type UserMenuConfig } from './user-menu'
|
|
|
9
9
|
export { Input } from './input'
|
|
10
10
|
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from './tooltip'
|
|
11
11
|
export { PageHeader } from './page-header'
|
|
12
|
-
export { DetailPageHeader, type DetailPageHeaderProps, type DetailPageHeaderTab } from './detail-page-header'
|
|
12
|
+
export { DetailPageHeader, type DetailPageHeaderProps, type DetailPageHeaderTab, type HeaderBreadcrumb } from './detail-page-header'
|
|
13
13
|
export { ChartContainer, ChartTooltip, ChartTooltipContent, ChartLegend, ChartLegendContent, type ChartConfig } from './chart'
|
|
14
14
|
export { SearchInput } from './search-input'
|
|
15
15
|
export { AssetsHeader } from './assets-header'
|