@orsetra/shared-ui 1.3.3 → 1.3.4

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.
@@ -4,20 +4,21 @@ import { ArrowLeft } 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
+ import { Button } from "./button"
7
8
 
8
9
  export interface DetailPageHeaderTab {
9
10
  id: string
10
11
  label: string
11
12
  icon?: ElementType
12
- /** Required when onTabChange is not provided (URL-based navigation) */
13
+ /** URL-based navigation */
13
14
  href?: string
15
+ /** State-based or programmatic navigation */
16
+ action?: () => void
14
17
  }
15
18
 
16
19
  export interface DetailPageHeaderProps {
17
- /** Back breadcrumb link destination */
18
- backHref?: string
19
- /** Back breadcrumb label */
20
- backLabel?: string
20
+ /** If provided, renders a secondary Back button on the right that calls history.back() */
21
+ backText?: string
21
22
  /** Optional icon rendered in a blue square container */
22
23
  icon?: ReactNode
23
24
  /** Page title */
@@ -26,7 +27,7 @@ export interface DetailPageHeaderProps {
26
27
  description?: string
27
28
  /** Slot for badges or status nodes placed next to the title */
28
29
  statusNode?: ReactNode
29
- /** Slot for action buttons placed to the right */
30
+ /** Slot for action buttons placed to the right, after the back button */
30
31
  actions?: ReactNode
31
32
  /** Optional tab navigation */
32
33
  tabBar?: DetailPageHeaderTab[]
@@ -34,15 +35,12 @@ export interface DetailPageHeaderProps {
34
35
  tabBarPosition?: "left" | "right"
35
36
  /** Currently active tab id */
36
37
  activeTab?: string
37
- /** State-based tab change handler. When provided, tabs render as buttons instead of Links */
38
- onTabChange?: (id: string) => void
39
38
  /** Extra classes on the root element – use to adjust spacing/height */
40
39
  className?: string
41
40
  }
42
41
 
43
42
  export function DetailPageHeader({
44
- backHref,
45
- backLabel,
43
+ backText,
46
44
  icon,
47
45
  title,
48
46
  description,
@@ -51,25 +49,13 @@ export function DetailPageHeader({
51
49
  tabBar,
52
50
  tabBarPosition = "left",
53
51
  activeTab,
54
- onTabChange,
55
52
  className,
56
53
  }: DetailPageHeaderProps) {
57
54
  return (
58
- <div className={cn("mb-4 sm:mb-6", className)}>
59
-
60
- {/* Back link */}
61
- {backHref && backLabel && (
62
- <Link
63
- href={backHref}
64
- className="inline-flex items-center gap-1.5 text-xs text-text-secondary hover:text-ibm-blue-60 transition-colors mb-3"
65
- >
66
- <ArrowLeft className="h-3.5 w-3.5" />
67
- {backLabel}
68
- </Link>
69
- )}
55
+ <div className={cn("mb-3", className)}>
70
56
 
71
57
  {/* Title row */}
72
- <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
58
+ <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
73
59
  <div className="flex items-center gap-3 min-w-0">
74
60
  {icon && (
75
61
  <div className="h-9 w-9 rounded bg-ibm-blue-10 flex items-center justify-center flex-shrink-0">
@@ -87,14 +73,26 @@ export function DetailPageHeader({
87
73
  </div>
88
74
  </div>
89
75
 
90
- {actions && (
91
- <div className="flex items-center gap-2 shrink-0">{actions}</div>
76
+ {(backText || actions) && (
77
+ <div className="flex items-center gap-2 shrink-0">
78
+ {backText && (
79
+ <Button
80
+ variant="secondary"
81
+ size="sm"
82
+ onClick={() => window.history.back()}
83
+ >
84
+ <ArrowLeft className="h-4 w-4 mr-1.5" />
85
+ {backText}
86
+ </Button>
87
+ )}
88
+ {actions}
89
+ </div>
92
90
  )}
93
91
  </div>
94
92
 
95
93
  {/* Tab bar */}
96
94
  {tabBar && tabBar.length > 0 && (
97
- <div className={cn("mt-4 flex", tabBarPosition === "right" ? "justify-end" : "justify-start")}>
95
+ <div className={cn("mt-3 flex", tabBarPosition === "right" ? "justify-end" : "justify-start")}>
98
96
  <div className="inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground">
99
97
  {tabBar.map((tab) => {
100
98
  const Icon = tab.icon
@@ -106,12 +104,12 @@ export function DetailPageHeader({
106
104
  : "hover:text-ibm-gray-100"
107
105
  )
108
106
 
109
- if (onTabChange) {
107
+ if (tab.action) {
110
108
  return (
111
109
  <button
112
110
  key={tab.id}
113
111
  type="button"
114
- onClick={() => onTabChange(tab.id)}
112
+ onClick={tab.action}
115
113
  className={triggerClass}
116
114
  >
117
115
  {Icon && <Icon className="h-4 w-4" />}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orsetra/shared-ui",
3
- "version": "1.3.3",
3
+ "version": "1.3.4",
4
4
  "description": "Shared UI components for Orsetra platform",
5
5
  "main": "./index.ts",
6
6
  "types": "./index.ts",