@orsetra/shared-ui 1.5.6 → 1.5.8
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.
|
@@ -197,9 +197,10 @@ function Sidebar({ currentMenu, onMainMenuToggle, sidebarMenus = {}, main_base_u
|
|
|
197
197
|
|
|
198
198
|
const filteredMainItems = React.useMemo(() => {
|
|
199
199
|
if (!isCollapsed || mainMenuItems.length === 0) return []
|
|
200
|
+
// Exclude items that match the current menu context OR appear in the secondary nav
|
|
200
201
|
const navIds = new Set(currentNavigation.map((n) => n.id))
|
|
201
|
-
return mainMenuItems.filter((item) => !navIds.has(item.id))
|
|
202
|
-
}, [isCollapsed, mainMenuItems, currentNavigation])
|
|
202
|
+
return mainMenuItems.filter((item) => item.id !== currentMenu && !navIds.has(item.id))
|
|
203
|
+
}, [isCollapsed, mainMenuItems, currentNavigation, currentMenu])
|
|
203
204
|
|
|
204
205
|
return (
|
|
205
206
|
<div
|
|
@@ -212,7 +213,9 @@ function Sidebar({ currentMenu, onMainMenuToggle, sidebarMenus = {}, main_base_u
|
|
|
212
213
|
isCollapsed ? "justify-center px-2" : "justify-between px-4"
|
|
213
214
|
)}>
|
|
214
215
|
{isCollapsed ? (
|
|
215
|
-
<
|
|
216
|
+
<button type="button" onClick={toggleSidebar} title="Expand sidebar" className="flex items-center justify-center">
|
|
217
|
+
<Logo iconOnly />
|
|
218
|
+
</button>
|
|
216
219
|
) : (
|
|
217
220
|
<>
|
|
218
221
|
<Logo />
|
|
@@ -245,41 +248,7 @@ function Sidebar({ currentMenu, onMainMenuToggle, sidebarMenus = {}, main_base_u
|
|
|
245
248
|
"flex-1 overflow-y-auto",
|
|
246
249
|
isCollapsed ? "px-1 py-3 space-y-0.5" : "px-3 py-4 space-y-1"
|
|
247
250
|
)}>
|
|
248
|
-
{/*
|
|
249
|
-
{filteredMainItems.length > 0 && (
|
|
250
|
-
<>
|
|
251
|
-
{filteredMainItems.map((item) => {
|
|
252
|
-
const rawHref = item.href || `${main_base_url}/${item.id}`
|
|
253
|
-
const href = rawHref.startsWith('http') ? new URL(rawHref).pathname : rawHref
|
|
254
|
-
const isActive = currentMenu === item.id
|
|
255
|
-
const linkEl = (
|
|
256
|
-
<Link
|
|
257
|
-
key={item.id}
|
|
258
|
-
href={href}
|
|
259
|
-
className={cn(
|
|
260
|
-
"flex items-center justify-center p-2 transition-colors border-l-4",
|
|
261
|
-
isActive
|
|
262
|
-
? "bg-interactive/10 border-interactive"
|
|
263
|
-
: "hover:bg-ui-background border-transparent"
|
|
264
|
-
)}
|
|
265
|
-
>
|
|
266
|
-
<item.icon
|
|
267
|
-
className="h-4 w-4 flex-shrink-0"
|
|
268
|
-
style={{ color: isActive ? '#0f62fe' : '#8d8d8d' }}
|
|
269
|
-
/>
|
|
270
|
-
</Link>
|
|
271
|
-
)
|
|
272
|
-
return (
|
|
273
|
-
<Tooltip key={item.id}>
|
|
274
|
-
<TooltipTrigger asChild>{linkEl}</TooltipTrigger>
|
|
275
|
-
<TooltipContent side="right" align="center">{item.label}</TooltipContent>
|
|
276
|
-
</Tooltip>
|
|
277
|
-
)
|
|
278
|
-
})}
|
|
279
|
-
<div className="border-t border-ui-border mx-1 my-2" />
|
|
280
|
-
</>
|
|
281
|
-
)}
|
|
282
|
-
|
|
251
|
+
{/* Secondary nav items */}
|
|
283
252
|
{currentNavigation.map((item) => {
|
|
284
253
|
const activeItemId = getCurrentMenuItem ? getCurrentMenuItem(pathname, searchParams) : null
|
|
285
254
|
const isActive = activeItemId
|
|
@@ -325,6 +294,35 @@ function Sidebar({ currentMenu, onMainMenuToggle, sidebarMenus = {}, main_base_u
|
|
|
325
294
|
}
|
|
326
295
|
return linkEl
|
|
327
296
|
})}
|
|
297
|
+
|
|
298
|
+
{/* Main menu items — only in collapsed mode, below secondary items, neutral color */}
|
|
299
|
+
{filteredMainItems.length > 0 && (
|
|
300
|
+
<>
|
|
301
|
+
<div className="border-t border-ui-border mx-1 my-2" />
|
|
302
|
+
{filteredMainItems.map((item) => {
|
|
303
|
+
const rawHref = item.href || `${main_base_url}/${item.id}`
|
|
304
|
+
const href = rawHref.startsWith('http') ? new URL(rawHref).pathname : rawHref
|
|
305
|
+
const linkEl = (
|
|
306
|
+
<Link
|
|
307
|
+
key={item.id}
|
|
308
|
+
href={href}
|
|
309
|
+
className="flex items-center justify-center p-2 transition-colors border-l-4 border-transparent hover:bg-ui-background"
|
|
310
|
+
>
|
|
311
|
+
<item.icon
|
|
312
|
+
className="h-4 w-4 flex-shrink-0"
|
|
313
|
+
style={{ color: '#8d8d8d' }}
|
|
314
|
+
/>
|
|
315
|
+
</Link>
|
|
316
|
+
)
|
|
317
|
+
return (
|
|
318
|
+
<Tooltip key={item.id}>
|
|
319
|
+
<TooltipTrigger asChild>{linkEl}</TooltipTrigger>
|
|
320
|
+
<TooltipContent side="right" align="center">{item.label}</TooltipContent>
|
|
321
|
+
</Tooltip>
|
|
322
|
+
)
|
|
323
|
+
})}
|
|
324
|
+
</>
|
|
325
|
+
)}
|
|
328
326
|
</nav>
|
|
329
327
|
|
|
330
328
|
{/* Collapse / expand toggle */}
|
|
@@ -29,6 +29,8 @@ export interface DetailPageHeaderProps {
|
|
|
29
29
|
icon?: ReactNode
|
|
30
30
|
/** Page title – truncated to one line */
|
|
31
31
|
title: string
|
|
32
|
+
/** Optional ReactNode rendered instead of title string (e.g. editable title) */
|
|
33
|
+
titleNode?: ReactNode
|
|
32
34
|
/** Optional subtitle – truncated to one line */
|
|
33
35
|
description?: string
|
|
34
36
|
/** Slot for badges, status buttons, action buttons placed to the right */
|
|
@@ -48,6 +50,7 @@ export function DetailPageHeader({
|
|
|
48
50
|
backLabel,
|
|
49
51
|
icon,
|
|
50
52
|
title,
|
|
53
|
+
titleNode,
|
|
51
54
|
description,
|
|
52
55
|
actions,
|
|
53
56
|
tabBar,
|
|
@@ -80,7 +83,7 @@ export function DetailPageHeader({
|
|
|
80
83
|
)}
|
|
81
84
|
<div className="min-w-0">
|
|
82
85
|
<h1 className="text-lg font-semibold text-ibm-gray-100 leading-tight truncate">
|
|
83
|
-
{title}
|
|
86
|
+
{titleNode ?? title}
|
|
84
87
|
</h1>
|
|
85
88
|
{description && (
|
|
86
89
|
<p className="text-xs text-ibm-gray-50 mt-0.5 truncate">
|