@orsetra/shared-ui 1.1.25 → 1.1.26

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.
@@ -35,6 +35,20 @@ export function MainSidebar({
35
35
  }: MainSidebarProps) {
36
36
  const isMinimized = mode === 'minimized'
37
37
  const [hoveredMenu, setHoveredMenu] = React.useState<string | null>(null)
38
+ const closeTimeoutRef = React.useRef<ReturnType<typeof setTimeout> | undefined>(undefined)
39
+
40
+ React.useEffect(() => {
41
+ return () => { if (closeTimeoutRef.current) clearTimeout(closeTimeoutRef.current) }
42
+ }, [])
43
+
44
+ const handleFlyoutMouseEnter = (menuId: string) => {
45
+ if (closeTimeoutRef.current) clearTimeout(closeTimeoutRef.current)
46
+ setHoveredMenu(menuId)
47
+ }
48
+
49
+ const handleFlyoutMouseLeave = () => {
50
+ closeTimeoutRef.current = setTimeout(() => setHoveredMenu(null), 150)
51
+ }
38
52
 
39
53
  const handleMenuClick = (menuId: string) => {
40
54
  onMenuSelect(menuId)
@@ -105,12 +119,13 @@ export function MainSidebar({
105
119
  <nav className="space-y-2">
106
120
  {mainMenuItems.map((item) => {
107
121
  const Icon = item.icon
122
+ const hasSubMenu = sidebarMenus[item.id]?.length > 0
108
123
  return (
109
124
  <div
110
125
  key={item.id}
111
126
  className="relative"
112
- onMouseEnter={() => isMinimized && setHoveredMenu(item.id)}
113
- onMouseLeave={() => isMinimized && setHoveredMenu(null)}
127
+ onMouseEnter={() => hasSubMenu && handleFlyoutMouseEnter(item.id)}
128
+ onMouseLeave={() => hasSubMenu && handleFlyoutMouseLeave()}
114
129
  >
115
130
  <button
116
131
  onClick={() => handleMenuClick(item.id)}
@@ -132,8 +147,14 @@ export function MainSidebar({
132
147
  {!isMinimized && <span className="text-base">{item.label}</span>}
133
148
  </button>
134
149
 
135
- {isMinimized && hoveredMenu === item.id && sidebarMenus[item.id] && sidebarMenus[item.id].length > 0 && (
136
- <div className="absolute left-full top-0 ml-2 bg-white border border-ui-border rounded-lg shadow-xl z-50 min-w-[200px] py-2">
150
+ {hoveredMenu === item.id && hasSubMenu && (
151
+ <div
152
+ className="absolute left-full top-0 ml-2 bg-white border border-ui-border rounded-lg shadow-xl z-50 min-w-[200px] py-2"
153
+ onMouseEnter={() => handleFlyoutMouseEnter(item.id)}
154
+ onMouseLeave={handleFlyoutMouseLeave}
155
+ >
156
+ {/* Arrow pointing left toward hovered item */}
157
+ <div className="absolute -left-[5px] top-[18px] w-[10px] h-[10px] bg-white border-l border-t border-ui-border -rotate-45" />
137
158
  <div className="px-4 py-2 border-b border-ui-border">
138
159
  <h3 className="text-sm font-semibold text-text-primary">{item.label}</h3>
139
160
  </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orsetra/shared-ui",
3
- "version": "1.1.25",
3
+ "version": "1.1.26",
4
4
  "description": "Shared UI components for Orsetra platform",
5
5
  "main": "./index.ts",
6
6
  "types": "./index.ts",