@djangocfg/layouts 2.1.255 → 2.1.256

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djangocfg/layouts",
3
- "version": "2.1.255",
3
+ "version": "2.1.256",
4
4
  "description": "Simple, straightforward layout components for Next.js - import and use with props",
5
5
  "keywords": [
6
6
  "layouts",
@@ -74,14 +74,14 @@
74
74
  "check": "tsc --noEmit"
75
75
  },
76
76
  "peerDependencies": {
77
- "@djangocfg/api": "^2.1.255",
78
- "@djangocfg/centrifugo": "^2.1.255",
79
- "@djangocfg/i18n": "^2.1.255",
80
- "@djangocfg/monitor": "^2.1.255",
81
- "@djangocfg/debuger": "^2.1.255",
82
- "@djangocfg/ui-core": "^2.1.255",
83
- "@djangocfg/ui-nextjs": "^2.1.255",
84
- "@djangocfg/ui-tools": "^2.1.255",
77
+ "@djangocfg/api": "^2.1.256",
78
+ "@djangocfg/centrifugo": "^2.1.256",
79
+ "@djangocfg/i18n": "^2.1.256",
80
+ "@djangocfg/monitor": "^2.1.256",
81
+ "@djangocfg/debuger": "^2.1.256",
82
+ "@djangocfg/ui-core": "^2.1.256",
83
+ "@djangocfg/ui-nextjs": "^2.1.256",
84
+ "@djangocfg/ui-tools": "^2.1.256",
85
85
  "@hookform/resolvers": "^5.2.2",
86
86
  "consola": "^3.4.2",
87
87
  "lucide-react": "^0.545.0",
@@ -109,15 +109,15 @@
109
109
  "uuid": "^11.1.0"
110
110
  },
111
111
  "devDependencies": {
112
- "@djangocfg/api": "^2.1.255",
113
- "@djangocfg/i18n": "^2.1.255",
114
- "@djangocfg/centrifugo": "^2.1.255",
115
- "@djangocfg/monitor": "^2.1.255",
116
- "@djangocfg/debuger": "^2.1.255",
117
- "@djangocfg/typescript-config": "^2.1.255",
118
- "@djangocfg/ui-core": "^2.1.255",
119
- "@djangocfg/ui-nextjs": "^2.1.255",
120
- "@djangocfg/ui-tools": "^2.1.255",
112
+ "@djangocfg/api": "^2.1.256",
113
+ "@djangocfg/i18n": "^2.1.256",
114
+ "@djangocfg/centrifugo": "^2.1.256",
115
+ "@djangocfg/monitor": "^2.1.256",
116
+ "@djangocfg/debuger": "^2.1.256",
117
+ "@djangocfg/typescript-config": "^2.1.256",
118
+ "@djangocfg/ui-core": "^2.1.256",
119
+ "@djangocfg/ui-nextjs": "^2.1.256",
120
+ "@djangocfg/ui-tools": "^2.1.256",
121
121
  "@types/node": "^24.7.2",
122
122
  "@types/react": "^19.1.0",
123
123
  "@types/react-dom": "^19.1.0",
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Private layout main column — optional mobile menu strip (`SidebarTrigger`) + scrollable area.
3
- * On viewports below `md`, the desktop sidebar is off-canvas; the trigger opens the `Sheet` from ui-nextjs sidebar.
2
+ * Private layout main column — on narrow viewports a fixed menu FAB (`SidebarTrigger`) + scrollable area.
3
+ * On viewports below `md`, the desktop sidebar is off-canvas; the trigger opens the `Drawer` from ui-nextjs sidebar.
4
4
  */
5
5
 
6
6
  'use client';
@@ -22,24 +22,34 @@ export function PrivateContent({
22
22
  padding = 'default',
23
23
  hasSidebar = true,
24
24
  }: PrivateContentProps) {
25
- const mobileToolbarClass = cn(
26
- 'sticky top-0 z-40 flex shrink-0 items-center gap-2 border-b border-border/50 bg-background/95 py-2 pl-2 pr-3 backdrop-blur-md supports-[backdrop-filter]:bg-background/80',
27
- 'md:hidden',
28
- );
25
+ /** Space for fixed FAB + safe area so content does not sit under the button. */
26
+ const mobileFabClearance =
27
+ hasSidebar &&
28
+ 'max-md:pt-[max(4.75rem,calc(3.25rem+env(safe-area-inset-top,0px)))]';
29
+
29
30
  const scrollAreaClass = cn(
30
31
  'min-h-0 flex-1 overflow-y-auto',
31
32
  padding === 'default' && 'p-4 sm:p-6 lg:p-8',
33
+ mobileFabClearance,
32
34
  );
33
35
 
34
- const mobileToolbar = hasSidebar ? (
35
- <div className={mobileToolbarClass}>
36
- <SidebarTrigger className="shrink-0" aria-label="Open menu" />
37
- </div>
36
+ const mobileMenuFab = hasSidebar ? (
37
+ <SidebarTrigger
38
+ variant="secondary"
39
+ className={cn(
40
+ 'fixed z-40 md:hidden',
41
+ 'left-3 top-[max(0.75rem,env(safe-area-inset-top,0px))]',
42
+ 'h-12 w-12 rounded-xl',
43
+ 'border border-border shadow-md',
44
+ '[&_svg]:!h-6 [&_svg]:!w-6',
45
+ 'touch-manipulation',
46
+ )}
47
+ />
38
48
  ) : null;
39
49
 
40
50
  return (
41
51
  <div className="flex min-h-0 min-w-0 flex-1 flex-col">
42
- {mobileToolbar}
52
+ {mobileMenuFab}
43
53
  <div className={scrollAreaClass}>{children}</div>
44
54
  </div>
45
55
  );
@@ -210,7 +210,7 @@ export function PrivateSidebar({ sidebar, header, i18n, pathname: pathnameProp }
210
210
  <div className="flex h-7 w-7 shrink-0 items-center justify-center rounded-md bg-sidebar-primary">{brandMark}</div>
211
211
  <span className="truncate text-sm font-semibold tracking-tight text-sidebar-foreground">{brandTitle}</span>
212
212
  </Link>
213
- <SidebarTrigger className="shrink-0" aria-label="Collapse sidebar" />
213
+ {!isMobile && <SidebarTrigger className="shrink-0" aria-label="Collapse sidebar" />}
214
214
  </div>
215
215
  );
216
216
 
@@ -220,12 +220,32 @@ export function PrivateSidebar({ sidebar, header, i18n, pathname: pathnameProp }
220
220
  </div>
221
221
  );
222
222
 
223
- const sidebarHeaderContent = expanded ? expandedHeader : collapsedHeader;
223
+ /** Mobile drawer: menu open/close only from the main column trigger — no duplicate toggle in the sheet. */
224
+ const mobileHeader = (
225
+ <div className="flex items-center gap-3">
226
+ <Link
227
+ href={homeHref}
228
+ className="flex min-w-0 flex-1 items-center gap-3 rounded-md py-1 outline-none ring-sidebar-ring focus-visible:ring-2"
229
+ >
230
+ <div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-md bg-sidebar-primary">{brandMark}</div>
231
+ <span className="truncate text-sm font-semibold tracking-tight text-sidebar-foreground">{brandTitle}</span>
232
+ </Link>
233
+ </div>
234
+ );
235
+
236
+ const sidebarHeaderContent = isMobile ? mobileHeader : expanded ? expandedHeader : collapsedHeader;
224
237
  const footerExtra = sidebar.footer ? <div className="mb-2">{sidebar.footer}</div> : null;
225
238
 
239
+ const sidebarHeaderClass = cn(
240
+ 'pb-2',
241
+ isMobile
242
+ ? 'px-4 pb-3 pt-[max(1.25rem,env(safe-area-inset-top,0px))]'
243
+ : 'px-2 pt-3.5',
244
+ );
245
+
226
246
  return (
227
247
  <Sidebar collapsible="icon">
228
- <SidebarHeader className="px-2 pt-3.5 pb-2">{sidebarHeaderContent}</SidebarHeader>
248
+ <SidebarHeader className={sidebarHeaderClass}>{sidebarHeaderContent}</SidebarHeader>
229
249
 
230
250
  <SidebarContent className={sidebarContentClass}>
231
251
  {menuStartSlot}