@djangocfg/layouts 2.1.339 → 2.1.341
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.
|
|
3
|
+
"version": "2.1.341",
|
|
4
4
|
"description": "Simple, straightforward layout components for Next.js - import and use with props",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"layouts",
|
|
@@ -84,13 +84,13 @@
|
|
|
84
84
|
"check": "tsc --noEmit"
|
|
85
85
|
},
|
|
86
86
|
"peerDependencies": {
|
|
87
|
-
"@djangocfg/api": "^2.1.
|
|
88
|
-
"@djangocfg/centrifugo": "^2.1.
|
|
89
|
-
"@djangocfg/debuger": "^2.1.
|
|
90
|
-
"@djangocfg/i18n": "^2.1.
|
|
91
|
-
"@djangocfg/monitor": "^2.1.
|
|
92
|
-
"@djangocfg/ui-core": "^2.1.
|
|
93
|
-
"@djangocfg/ui-nextjs": "^2.1.
|
|
87
|
+
"@djangocfg/api": "^2.1.341",
|
|
88
|
+
"@djangocfg/centrifugo": "^2.1.341",
|
|
89
|
+
"@djangocfg/debuger": "^2.1.341",
|
|
90
|
+
"@djangocfg/i18n": "^2.1.341",
|
|
91
|
+
"@djangocfg/monitor": "^2.1.341",
|
|
92
|
+
"@djangocfg/ui-core": "^2.1.341",
|
|
93
|
+
"@djangocfg/ui-nextjs": "^2.1.341",
|
|
94
94
|
"@hookform/resolvers": "^5.2.2",
|
|
95
95
|
"consola": "^3.4.2",
|
|
96
96
|
"lucide-react": "^0.545.0",
|
|
@@ -120,15 +120,15 @@
|
|
|
120
120
|
"uuid": "^11.1.0"
|
|
121
121
|
},
|
|
122
122
|
"devDependencies": {
|
|
123
|
-
"@djangocfg/api": "^2.1.
|
|
124
|
-
"@djangocfg/centrifugo": "^2.1.
|
|
125
|
-
"@djangocfg/debuger": "^2.1.
|
|
126
|
-
"@djangocfg/i18n": "^2.1.
|
|
127
|
-
"@djangocfg/monitor": "^2.1.
|
|
128
|
-
"@djangocfg/typescript-config": "^2.1.
|
|
129
|
-
"@djangocfg/ui-core": "^2.1.
|
|
130
|
-
"@djangocfg/ui-nextjs": "^2.1.
|
|
131
|
-
"@djangocfg/ui-tools": "^2.1.
|
|
123
|
+
"@djangocfg/api": "^2.1.341",
|
|
124
|
+
"@djangocfg/centrifugo": "^2.1.341",
|
|
125
|
+
"@djangocfg/debuger": "^2.1.341",
|
|
126
|
+
"@djangocfg/i18n": "^2.1.341",
|
|
127
|
+
"@djangocfg/monitor": "^2.1.341",
|
|
128
|
+
"@djangocfg/typescript-config": "^2.1.341",
|
|
129
|
+
"@djangocfg/ui-core": "^2.1.341",
|
|
130
|
+
"@djangocfg/ui-nextjs": "^2.1.341",
|
|
131
|
+
"@djangocfg/ui-tools": "^2.1.341",
|
|
132
132
|
"@types/node": "^24.7.2",
|
|
133
133
|
"@types/react": "^19.1.0",
|
|
134
134
|
"@types/react-dom": "^19.1.0",
|
|
@@ -146,6 +146,13 @@ export interface PrivateLayoutProps {
|
|
|
146
146
|
pathname?: string;
|
|
147
147
|
/** Content padding */
|
|
148
148
|
contentPadding?: 'none' | 'default';
|
|
149
|
+
/**
|
|
150
|
+
* Content scroll behaviour.
|
|
151
|
+
* - `'auto'` (default) — the shell scroll-area scrolls vertically.
|
|
152
|
+
* - `'hidden'` — shell does NOT scroll; use for full-height pages (e.g. Kanban)
|
|
153
|
+
* where children manage their own scroll surfaces.
|
|
154
|
+
*/
|
|
155
|
+
contentScroll?: 'auto' | 'hidden';
|
|
149
156
|
/**
|
|
150
157
|
* Visual style of the shell. Defaults to `'boxed'` (inset rounded card on a
|
|
151
158
|
* sidebar-coloured canvas). Pass `{ variant: 'full-bleed' }` for the legacy
|
|
@@ -167,6 +174,7 @@ export function PrivateLayout({
|
|
|
167
174
|
header,
|
|
168
175
|
pathname,
|
|
169
176
|
contentPadding = 'default',
|
|
177
|
+
contentScroll = 'auto',
|
|
170
178
|
visual,
|
|
171
179
|
requireAuth = true,
|
|
172
180
|
}: PrivateLayoutProps) {
|
|
@@ -217,6 +225,7 @@ export function PrivateLayout({
|
|
|
217
225
|
<SidebarInset className={resolveInsetClassName(visual)}>
|
|
218
226
|
<PrivateContent
|
|
219
227
|
padding={contentPadding}
|
|
228
|
+
scroll={contentScroll}
|
|
220
229
|
hasSidebar={Boolean(sidebar)}
|
|
221
230
|
visual={visual}
|
|
222
231
|
>
|
|
@@ -286,11 +295,15 @@ const BOXED_BG_CLASS: Record<NonNullable<LayoutVisualConfig['background']>, stri
|
|
|
286
295
|
};
|
|
287
296
|
|
|
288
297
|
function resolveProviderClassName(visual: LayoutVisualConfig | undefined): string | undefined {
|
|
289
|
-
|
|
298
|
+
// h-svh + overflow-hidden: lock the shell to exactly one viewport height so
|
|
299
|
+
// the inner scroll-area (PrivateContent) is the only scroll surface. Without
|
|
300
|
+
// this, SidebarProvider grows via min-h-svh and the whole page scrolls.
|
|
301
|
+
const base = 'h-svh overflow-hidden';
|
|
302
|
+
if ((visual?.variant ?? 'boxed') !== 'boxed') return base;
|
|
290
303
|
// `max-md:!bg-background` neutralises shadcn-sidebar's built-in
|
|
291
304
|
// `has-[[data-variant=inset]]:bg-sidebar` below md so the mobile Drawer shell
|
|
292
305
|
// doesn't paint the whole viewport with the canvas tint.
|
|
293
|
-
return
|
|
306
|
+
return `${base} max-md:!bg-background ${BOXED_BG_CLASS[visual?.background ?? 'sidebar']}`;
|
|
294
307
|
}
|
|
295
308
|
|
|
296
309
|
function normaliseInset(inset: LayoutVisualConfig['inset']): { x: number; y: number } {
|
|
@@ -34,6 +34,40 @@ The auth guard redirects to `header.authPath` when there's no session. Pass `req
|
|
|
34
34
|
|
|
35
35
|
---
|
|
36
36
|
|
|
37
|
+
## Content layout props
|
|
38
|
+
|
|
39
|
+
| Prop | Type | Default | Notes |
|
|
40
|
+
|---|---|---|---|
|
|
41
|
+
| `contentPadding` | `'default' \| 'none'` | `'default'` | `'default'` adds responsive horizontal + vertical padding around children. `'none'` strips all padding — children are responsible for their own spacing. |
|
|
42
|
+
| `contentScroll` | `'auto' \| 'hidden'` | `'auto'` | `'auto'` — the shell scroll-area scrolls vertically (standard pages). `'hidden'` — the shell does **not** scroll; use for full-height pages (Kanban, split-pane editors) where individual child regions manage their own scroll surfaces. Always pair with `contentPadding='none'` so children can own their own spacing too. |
|
|
43
|
+
|
|
44
|
+
### Full-height / no-scroll pages
|
|
45
|
+
|
|
46
|
+
For pages like Kanban boards where the shell must be exactly one viewport tall and columns scroll independently:
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
<PrivateLayout
|
|
50
|
+
sidebar={sidebar}
|
|
51
|
+
header={header}
|
|
52
|
+
pathname={pathname}
|
|
53
|
+
contentPadding="none"
|
|
54
|
+
contentScroll="hidden"
|
|
55
|
+
>
|
|
56
|
+
{/* Page is responsible for all padding and scroll */}
|
|
57
|
+
<div className="flex flex-col h-full">
|
|
58
|
+
<header className="px-4 sm:px-6 lg:px-8 pt-6 lg:pt-8 pb-3 border-b shrink-0">
|
|
59
|
+
...
|
|
60
|
+
</header>
|
|
61
|
+
<div className="flex-1 min-h-0 overflow-x-auto flex gap-3 px-4 sm:px-6 lg:px-8 py-4">
|
|
62
|
+
{/* Each column scrolls vertically on its own */}
|
|
63
|
+
<KanbanColumn />
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
</PrivateLayout>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
37
71
|
## Sidebar config
|
|
38
72
|
|
|
39
73
|
`SidebarConfig` (passed as `sidebar` prop):
|
|
@@ -15,6 +15,13 @@ import type { LayoutVisualConfig } from '../../types';
|
|
|
15
15
|
interface PrivateContentProps {
|
|
16
16
|
children: ReactNode;
|
|
17
17
|
padding?: 'none' | 'default';
|
|
18
|
+
/**
|
|
19
|
+
* Controls the overflow behaviour of the scroll surface.
|
|
20
|
+
* - `'auto'` (default) — content scrolls vertically inside the shell.
|
|
21
|
+
* - `'hidden'` — shell does NOT scroll; children must manage their own scroll.
|
|
22
|
+
* Use this for full-height pages like Kanban where columns scroll individually.
|
|
23
|
+
*/
|
|
24
|
+
scroll?: 'auto' | 'hidden';
|
|
18
25
|
/** When false, no mobile hamburger (e.g. layout without a sidebar). Default true. */
|
|
19
26
|
hasSidebar?: boolean;
|
|
20
27
|
/** Visual config from PrivateLayout — controls maxWidth in boxed mode. */
|
|
@@ -31,6 +38,7 @@ const MAX_WIDTH_CLASS: Record<NonNullable<LayoutVisualConfig['maxWidth']>, strin
|
|
|
31
38
|
export function PrivateContent({
|
|
32
39
|
children,
|
|
33
40
|
padding = 'default',
|
|
41
|
+
scroll = 'auto',
|
|
34
42
|
hasSidebar = true,
|
|
35
43
|
visual,
|
|
36
44
|
}: PrivateContentProps) {
|
|
@@ -55,12 +63,13 @@ export function PrivateContent({
|
|
|
55
63
|
: undefined;
|
|
56
64
|
|
|
57
65
|
const scrollAreaClass = cn(
|
|
58
|
-
'min-h-0 flex-1
|
|
59
|
-
|
|
66
|
+
'min-h-0 flex-1',
|
|
67
|
+
scroll === 'auto' ? 'overflow-y-auto' : 'overflow-hidden',
|
|
68
|
+
padding === 'default' && scroll === 'auto' && [
|
|
60
69
|
'px-4 sm:px-6 lg:px-8',
|
|
61
70
|
'pb-[calc(1rem+env(safe-area-inset-bottom,0px))] sm:pb-[calc(1.5rem+env(safe-area-inset-bottom,0px))] lg:pb-[calc(2rem+env(safe-area-inset-bottom,0px))]',
|
|
62
71
|
],
|
|
63
|
-
contentTopPaddingClass,
|
|
72
|
+
scroll === 'auto' && contentTopPaddingClass,
|
|
64
73
|
mobileFabClearance,
|
|
65
74
|
);
|
|
66
75
|
|