@orsetra/shared-ui 1.8.4 → 1.9.0
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.
|
@@ -6,6 +6,7 @@ import { MainSidebar, type SidebarMode } from "./sidebar/main-sidebar"
|
|
|
6
6
|
import { Sidebar, SidebarProvider, useSidebar } from "./sidebar/sidebar"
|
|
7
7
|
import { type SidebarMenus, type MainMenuItem, resolveIcon } from "./sidebar/data"
|
|
8
8
|
import { Button } from "../ui"
|
|
9
|
+
import { Logo } from "../ui/logo"
|
|
9
10
|
import { getMenuFromPath } from "../../lib/menu-utils"
|
|
10
11
|
import { useIsMobile } from "../../hooks/use-mobile"
|
|
11
12
|
import { Menu } from "lucide-react"
|
|
@@ -100,51 +101,54 @@ function LayoutContent({
|
|
|
100
101
|
const handleSecondarySidebarOpen = () => setOpen(true)
|
|
101
102
|
|
|
102
103
|
return (
|
|
103
|
-
<div className="flex h-screen w-full bg-white overflow-hidden">
|
|
104
|
-
|
|
105
|
-
<
|
|
104
|
+
<div className="flex flex-col h-screen w-full bg-white overflow-hidden">
|
|
105
|
+
<header className="h-14 bg-gray-50 border-b border-ui-border flex-shrink-0">
|
|
106
|
+
<div className="h-full flex items-center justify-between">
|
|
107
|
+
<div
|
|
108
|
+
className="h-full flex items-center justify-between flex-shrink-0 px-4 md:px-6"
|
|
109
|
+
style={{ width: 'var(--sidebar-width)' }}
|
|
110
|
+
>
|
|
111
|
+
<Logo href={main_base_url} />
|
|
112
|
+
<Button
|
|
113
|
+
variant="ghost"
|
|
114
|
+
size="sm"
|
|
115
|
+
onClick={handleMainSidebarToggle}
|
|
116
|
+
className="h-8 w-8 p-0 hover:bg-ui-background text-text-secondary"
|
|
117
|
+
title="Menu principal"
|
|
118
|
+
>
|
|
119
|
+
<Menu className="h-5 w-5" />
|
|
120
|
+
</Button>
|
|
121
|
+
</div>
|
|
122
|
+
<div className="flex-1 flex items-center justify-end px-4 md:px-6">
|
|
123
|
+
<UserPanel main_base_url={main_base_url} />
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
</header>
|
|
127
|
+
|
|
128
|
+
<div className="flex flex-1 min-h-0 overflow-hidden">
|
|
129
|
+
{!isMinimized && !isHidden && (
|
|
130
|
+
<Sidebar
|
|
131
|
+
currentMenu={currentMenu}
|
|
132
|
+
onMainMenuToggle={handleMainSidebarToggle}
|
|
133
|
+
sidebarMenus={effectiveSidebarMenus}
|
|
134
|
+
main_base_url={main_base_url}
|
|
135
|
+
sectionLabels={sectionLabels}
|
|
136
|
+
getCurrentMenuItem={getCurrentMenuItem}
|
|
137
|
+
mainMenuItems={mainMenuItems}
|
|
138
|
+
/>
|
|
139
|
+
)}
|
|
140
|
+
|
|
141
|
+
<MainSidebar
|
|
142
|
+
main_base_url={main_base_url}
|
|
143
|
+
isOpen={isMainSidebarOpen}
|
|
144
|
+
onToggle={handleMainSidebarToggle}
|
|
145
|
+
onMenuSelect={handleMenuSelect}
|
|
106
146
|
currentMenu={currentMenu}
|
|
107
|
-
|
|
147
|
+
onSecondarySidebarOpen={handleSecondarySidebarOpen}
|
|
148
|
+
mode={isHidden ? "expanded" : mode}
|
|
108
149
|
sidebarMenus={effectiveSidebarMenus}
|
|
109
|
-
main_base_url={main_base_url}
|
|
110
|
-
sectionLabels={sectionLabels}
|
|
111
|
-
getCurrentMenuItem={getCurrentMenuItem}
|
|
112
150
|
mainMenuItems={mainMenuItems}
|
|
113
151
|
/>
|
|
114
|
-
)}
|
|
115
|
-
|
|
116
|
-
<MainSidebar
|
|
117
|
-
main_base_url={main_base_url}
|
|
118
|
-
isOpen={isMainSidebarOpen}
|
|
119
|
-
onToggle={handleMainSidebarToggle}
|
|
120
|
-
onMenuSelect={handleMenuSelect}
|
|
121
|
-
currentMenu={currentMenu}
|
|
122
|
-
onSecondarySidebarOpen={handleSecondarySidebarOpen}
|
|
123
|
-
mode={isHidden ? "expanded" : mode}
|
|
124
|
-
sidebarMenus={effectiveSidebarMenus}
|
|
125
|
-
mainMenuItems={mainMenuItems}
|
|
126
|
-
/>
|
|
127
|
-
|
|
128
|
-
<div className="flex-1 flex flex-col min-w-0">
|
|
129
|
-
<header className="h-14 bg-gray-50 border-b border-ui-border flex-shrink-0">
|
|
130
|
-
<div className="h-full px-4 md:px-6 flex items-center justify-between">
|
|
131
|
-
{isHidden ? (
|
|
132
|
-
<Button
|
|
133
|
-
variant="ghost"
|
|
134
|
-
size="sm"
|
|
135
|
-
onClick={handleMainSidebarToggle}
|
|
136
|
-
className="h-8 w-8 p-0 hover:bg-ui-background text-text-secondary"
|
|
137
|
-
title="Ouvrir le menu"
|
|
138
|
-
>
|
|
139
|
-
<Menu className="h-5 w-5" />
|
|
140
|
-
</Button>
|
|
141
|
-
) : (
|
|
142
|
-
<div />
|
|
143
|
-
)}
|
|
144
|
-
|
|
145
|
-
<UserPanel main_base_url={main_base_url} />
|
|
146
|
-
</div>
|
|
147
|
-
</header>
|
|
148
152
|
|
|
149
153
|
<main className="flex-1 bg-ibm-gray-10 min-h-0 overflow-auto">
|
|
150
154
|
{children}
|
|
@@ -119,7 +119,8 @@ export function MainSidebar({
|
|
|
119
119
|
The flyout is never "in front of" the nav; it's always to its right.
|
|
120
120
|
*/}
|
|
121
121
|
<div className={cn(
|
|
122
|
-
"fixed left-0
|
|
122
|
+
"fixed left-0 z-50 flex",
|
|
123
|
+
isMinimized ? "top-14 h-[calc(100%-3.5rem)]" : "top-0 h-full",
|
|
123
124
|
"transform transition-all duration-300 ease-in-out",
|
|
124
125
|
isMinimized ? "translate-x-0" : (isOpen ? "translate-x-0" : "-translate-x-full"),
|
|
125
126
|
)}>
|
|
@@ -131,27 +132,20 @@ export function MainSidebar({
|
|
|
131
132
|
// Shadow only when flyout is not open (avoid double shadow)
|
|
132
133
|
!hoveredItem && !isMinimized && "shadow-xl",
|
|
133
134
|
)}>
|
|
134
|
-
{/* Header */}
|
|
135
|
-
|
|
136
|
-
"flex items-center h-14 bg-white sticky top-0 z-10 flex-shrink-0"
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
<
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
className="h-8 w-8 p-0 hover:bg-ui-background text-text-secondary"
|
|
149
|
-
>
|
|
150
|
-
<X className="h-4 w-4" />
|
|
151
|
-
</Button>
|
|
152
|
-
</>
|
|
153
|
-
)}
|
|
154
|
-
</div>
|
|
135
|
+
{/* Header — only in overlay (non-minimized) mode; logo lives in the global header */}
|
|
136
|
+
{!isMinimized && (
|
|
137
|
+
<div className="flex items-center justify-between h-14 bg-white sticky top-0 z-10 flex-shrink-0 px-3 lg:px-4">
|
|
138
|
+
<Logo className="text-2xl font-semibold text-text-primary" href={main_base_url} />
|
|
139
|
+
<Button
|
|
140
|
+
variant="ghost"
|
|
141
|
+
size="sm"
|
|
142
|
+
onClick={onToggle}
|
|
143
|
+
className="h-8 w-8 p-0 hover:bg-ui-background text-text-secondary"
|
|
144
|
+
>
|
|
145
|
+
<X className="h-4 w-4" />
|
|
146
|
+
</Button>
|
|
147
|
+
</div>
|
|
148
|
+
)}
|
|
155
149
|
|
|
156
150
|
{/* Nav items */}
|
|
157
151
|
<nav className={cn("flex-1 space-y-0.5 lg:space-y-1", isMinimized ? "p-2" : "p-2 lg:p-3")}>
|
|
@@ -172,8 +166,8 @@ export function MainSidebar({
|
|
|
172
166
|
"w-full flex items-center text-left transition-all duration-150 font-medium",
|
|
173
167
|
isMinimized ? "justify-center p-2 lg:p-3" : "gap-2 lg:gap-3 px-2 lg:px-3 py-1.5 lg:py-2",
|
|
174
168
|
isActive || isFlyActive
|
|
175
|
-
? "bg-
|
|
176
|
-
: "text-text-primary hover:bg-gray-
|
|
169
|
+
? "bg-ibm-blue-10 text-interactive border-l-4 border-interactive"
|
|
170
|
+
: "text-text-primary hover:bg-ibm-gray-10 border-l-4 border-transparent",
|
|
177
171
|
)
|
|
178
172
|
|
|
179
173
|
const itemContent = (
|
|
@@ -18,8 +18,6 @@ import {
|
|
|
18
18
|
TooltipProvider,
|
|
19
19
|
TooltipTrigger,
|
|
20
20
|
} from "../../ui/tooltip"
|
|
21
|
-
import { Menu } from "lucide-react"
|
|
22
|
-
import { Logo } from "../../ui/logo"
|
|
23
21
|
import { type SidebarMenus, type SubMenuItem, type MainMenuItem } from "./data"
|
|
24
22
|
import { Skeleton } from "../skeleton"
|
|
25
23
|
|
|
@@ -232,7 +230,7 @@ interface SidebarProps {
|
|
|
232
230
|
|
|
233
231
|
|
|
234
232
|
|
|
235
|
-
function Sidebar({ currentMenu,
|
|
233
|
+
function Sidebar({ currentMenu, sidebarMenus = {}, main_base_url = "", sectionLabels = {}, getCurrentMenuItem, mainMenuItems = [] }: SidebarProps = {}) {
|
|
236
234
|
const pathname = usePathname()
|
|
237
235
|
const searchParams = useSearchParams()
|
|
238
236
|
const router = useRouter()
|
|
@@ -259,36 +257,9 @@ function Sidebar({ currentMenu, onMainMenuToggle, sidebarMenus = {}, main_base_u
|
|
|
259
257
|
|
|
260
258
|
return (
|
|
261
259
|
<div
|
|
262
|
-
className="h-
|
|
260
|
+
className="h-full flex-shrink-0 flex flex-col bg-gray-50 min-w-[var(--sidebar-width-icon)] transition-[width] duration-200 overflow-visible"
|
|
263
261
|
style={{ width: isCollapsed ? "var(--sidebar-width-icon)" : "var(--sidebar-width)" }}
|
|
264
262
|
>
|
|
265
|
-
{/* Header */}
|
|
266
|
-
<div className={cn(
|
|
267
|
-
"h-14 flex items-center flex-shrink-0",
|
|
268
|
-
isCollapsed ? "justify-center px-2" : "justify-between px-4"
|
|
269
|
-
)}>
|
|
270
|
-
{isCollapsed ? (
|
|
271
|
-
<button type="button" onClick={toggleSidebar} title="Expand sidebar" className="flex items-center justify-center">
|
|
272
|
-
<Logo iconOnly />
|
|
273
|
-
</button>
|
|
274
|
-
) : (
|
|
275
|
-
<>
|
|
276
|
-
<Logo />
|
|
277
|
-
{onMainMenuToggle && (
|
|
278
|
-
<Button
|
|
279
|
-
variant="ghost"
|
|
280
|
-
size="sm"
|
|
281
|
-
onClick={onMainMenuToggle}
|
|
282
|
-
className="h-8 w-8 p-0 hover:bg-ui-background rounded-lg"
|
|
283
|
-
title="Ouvrir le menu principal"
|
|
284
|
-
>
|
|
285
|
-
<Menu className="h-4 w-4" />
|
|
286
|
-
</Button>
|
|
287
|
-
)}
|
|
288
|
-
</>
|
|
289
|
-
)}
|
|
290
|
-
</div>
|
|
291
|
-
|
|
292
263
|
{/* Section label — hidden when collapsed */}
|
|
293
264
|
{!isCollapsed && (
|
|
294
265
|
injectedItems === undefined ? (
|