@orsetra/shared-ui 1.0.10 → 1.0.12

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.
@@ -5,6 +5,7 @@ import { usePathname } from "next/navigation"
5
5
  import { MainSidebar, Sidebar, SidebarProvider, useSidebar, type SidebarMode } from "./index"
6
6
  import { UserMenu, Button } from "../ui"
7
7
  import { getMenuFromPath } from "../../lib/menu-utils"
8
+ import { useIsMobile } from "../../hooks/use-mobile"
8
9
  import { Menu } from "lucide-react"
9
10
 
10
11
  export interface SidebarMenus {
@@ -22,10 +23,19 @@ interface LayoutContainerProps {
22
23
  function LayoutContent({ children, sidebarMenus, user, onSignOut, mode = 'expanded' }: LayoutContainerProps) {
23
24
  const pathname = usePathname()
24
25
  const { setOpen } = useSidebar()
26
+ const isMobile = useIsMobile()
25
27
  const [isMainSidebarOpen, setIsMainSidebarOpen] = useState(false)
26
28
  const [currentMenu, setCurrentMenu] = useState<string>("overview")
27
29
  const isMinimized = mode === 'minimized'
28
- const isHidden = mode === 'hidden'
30
+ // Force hidden mode on mobile
31
+ const isHidden = mode === 'hidden' || isMobile
32
+
33
+ // Close sidebar on route change (mobile)
34
+ useEffect(() => {
35
+ if (isMobile) {
36
+ setIsMainSidebarOpen(false)
37
+ }
38
+ }, [pathname, isMobile])
29
39
 
30
40
  useEffect(() => {
31
41
  const contextualMenu = getMenuFromPath(pathname)
@@ -49,7 +59,7 @@ function LayoutContent({ children, sidebarMenus, user, onSignOut, mode = 'expand
49
59
 
50
60
  return (
51
61
  <div className="flex h-screen w-full bg-white">
52
- {/* Sidebar secondaire - caché en mode minimized et hidden */}
62
+ {/* Desktop sidebar - hidden on mobile (isHidden is true on mobile) */}
53
63
  {!isMinimized && !isHidden && (
54
64
  <Sidebar
55
65
  currentMenu={currentMenu}
@@ -57,41 +67,27 @@ function LayoutContent({ children, sidebarMenus, user, onSignOut, mode = 'expand
57
67
  />
58
68
  )}
59
69
 
60
- {/* MainSidebar - en mode hidden, il s'ouvre comme un overlay */}
61
- {!isHidden && (
62
- <MainSidebar
63
- isOpen={isMainSidebarOpen}
64
- onToggle={handleMainSidebarToggle}
65
- onMenuSelect={handleMenuSelect}
66
- currentMenu={currentMenu}
67
- onSecondarySidebarOpen={handleSecondarySidebarOpen}
68
- mode={mode}
69
- />
70
- )}
71
-
72
- {/* MainSidebar overlay en mode hidden */}
73
- {isHidden && (
74
- <MainSidebar
75
- isOpen={isMainSidebarOpen}
76
- onToggle={handleMainSidebarToggle}
77
- onMenuSelect={handleMenuSelect}
78
- currentMenu={currentMenu}
79
- onSecondarySidebarOpen={handleSecondarySidebarOpen}
80
- mode="expanded"
81
- />
82
- )}
70
+ {/* MainSidebar - always available, opens as overlay when isHidden */}
71
+ <MainSidebar
72
+ isOpen={isMainSidebarOpen}
73
+ onToggle={handleMainSidebarToggle}
74
+ onMenuSelect={handleMenuSelect}
75
+ currentMenu={currentMenu}
76
+ onSecondarySidebarOpen={handleSecondarySidebarOpen}
77
+ mode={isHidden ? "expanded" : mode}
78
+ />
83
79
 
84
- <div className="flex-1 flex flex-col">
80
+ <div className="flex-1 flex flex-col min-w-0">
85
81
  <header className="h-14 bg-white border-b border-ui-border flex-shrink-0">
86
- <div className="h-full px-6 flex items-center justify-between">
87
- {/* Bouton menu - affiché en mode hidden */}
82
+ <div className="h-full px-4 md:px-6 flex items-center justify-between">
83
+ {/* Menu button - shown when sidebar is hidden (including on mobile) */}
88
84
  {isHidden ? (
89
85
  <Button
90
86
  variant="ghost"
91
87
  size="sm"
92
88
  onClick={handleMainSidebarToggle}
93
89
  className="h-8 w-8 p-0 hover:bg-ui-background text-text-secondary"
94
- title="Ouvrir le menu principal"
90
+ title="Ouvrir le menu"
95
91
  >
96
92
  <Menu className="h-5 w-5" />
97
93
  </Button>
@@ -38,13 +38,13 @@ const DialogContent = React.forwardRef<
38
38
  <DialogPrimitive.Content
39
39
  ref={ref}
40
40
  className={cn(
41
- "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
41
+ "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border border-gray-200 bg-white p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]",
42
42
  className
43
43
  )}
44
44
  {...props}
45
45
  >
46
46
  {children}
47
- <DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
47
+ <DialogPrimitive.Close className="absolute right-4 top-4 opacity-70 ring-offset-white transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-gray-100 data-[state=open]:text-gray-500">
48
48
  <X className="h-4 w-4" />
49
49
  <span className="sr-only">Close</span>
50
50
  </DialogPrimitive.Close>
@@ -102,7 +102,7 @@ const DialogDescription = React.forwardRef<
102
102
  >(({ className, ...props }, ref) => (
103
103
  <DialogPrimitive.Description
104
104
  ref={ref}
105
- className={cn("text-sm text-muted-foreground", className)}
105
+ className={cn("text-sm text-gray-500", className)}
106
106
  {...props}
107
107
  />
108
108
  ))
@@ -12,23 +12,23 @@ interface PageHeaderProps {
12
12
 
13
13
  export function PageHeader({ title, description, backLink, actions, statusNode}: PageHeaderProps) {
14
14
  return (
15
- <div className="mb-8">
16
- <div className="flex items-center justify-between">
17
- <div className="flex items-center space-x-3">
15
+ <div className="mb-4 sm:mb-8">
16
+ <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
17
+ <div className="flex items-center space-x-3 min-w-0">
18
18
  {backLink && (
19
- <Link href={backLink}>
20
- <ArrowLeft className="h-6 w-6 text-text-secondary" />
19
+ <Link href={backLink} className="flex-shrink-0">
20
+ <ArrowLeft className="h-5 w-5 sm:h-6 sm:w-6 text-text-secondary" />
21
21
  </Link>
22
22
  )}
23
- <div>
23
+ <div className="min-w-0">
24
24
  <div className="flex items-center space-x-3">
25
- <h1 className="text-2xl font-semibold text-text-primary">{title}</h1>
26
- {statusNode && <div className="mt-2">{statusNode}</div>}
25
+ <h1 className="text-xl sm:text-2xl font-semibold text-text-primary truncate">{title}</h1>
26
+ {statusNode && <div className="mt-2 flex-shrink-0">{statusNode}</div>}
27
27
  </div>
28
- {description && <p className="text-base text-text-secondary">{description}</p>}
28
+ {description && <p className="text-sm sm:text-base text-text-secondary line-clamp-2">{description}</p>}
29
29
  </div>
30
30
  </div>
31
- {actions && <div className="flex items-center space-x-4">{actions}</div>}
31
+ {actions && <div className="flex items-center space-x-2 sm:space-x-4 flex-shrink-0">{actions}</div>}
32
32
  </div>
33
33
  </div>
34
34
  )
@@ -19,7 +19,7 @@ const SelectTrigger = React.forwardRef<
19
19
  <SelectPrimitive.Trigger
20
20
  ref={ref}
21
21
  className={cn(
22
- "flex h-8 w-full items-center justify-between border border-ibm-gray-30 bg-white px-3 py-2 text-sm text-ibm-gray-100 placeholder:text-gray-500 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
22
+ "flex h-10 w-full items-center justify-between border border-ibm-gray-30 bg-white px-3 py-2 text-sm text-ibm-gray-100 placeholder:text-gray-500 focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
23
23
  className
24
24
  )}
25
25
  style={{ borderRadius: 0 }}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orsetra/shared-ui",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "Shared UI components for Orsetra platform",
5
5
  "main": "./index.ts",
6
6
  "types": "./index.ts",