@djangocfg/layouts 2.1.501 → 2.1.503
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 +15 -15
- package/src/layouts/SettingsLayout/components/SettingsRailFooter.tsx +74 -0
- package/src/layouts/SettingsLayout/components/SettingsShell.tsx +16 -5
- package/src/layouts/SettingsLayout/components/index.ts +1 -0
- package/src/layouts/SettingsLayout/sections/AccountSection.tsx +2 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@djangocfg/layouts",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.503",
|
|
4
4
|
"description": "Simple, straightforward layout components for Next.js - import and use with props",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"layouts",
|
|
@@ -89,12 +89,12 @@
|
|
|
89
89
|
"check": "tsc --noEmit"
|
|
90
90
|
},
|
|
91
91
|
"peerDependencies": {
|
|
92
|
-
"@djangocfg/analytics": "^2.1.
|
|
93
|
-
"@djangocfg/api": "^2.1.
|
|
94
|
-
"@djangocfg/centrifugo": "^2.1.
|
|
95
|
-
"@djangocfg/devtools": "^2.1.
|
|
96
|
-
"@djangocfg/i18n": "^2.1.
|
|
97
|
-
"@djangocfg/ui-core": "^2.1.
|
|
92
|
+
"@djangocfg/analytics": "^2.1.503",
|
|
93
|
+
"@djangocfg/api": "^2.1.503",
|
|
94
|
+
"@djangocfg/centrifugo": "^2.1.503",
|
|
95
|
+
"@djangocfg/devtools": "^2.1.503",
|
|
96
|
+
"@djangocfg/i18n": "^2.1.503",
|
|
97
|
+
"@djangocfg/ui-core": "^2.1.503",
|
|
98
98
|
"@hookform/resolvers": "^5.2.2",
|
|
99
99
|
"consola": "^3.4.2",
|
|
100
100
|
"lucide-react": "^0.545.0",
|
|
@@ -124,14 +124,14 @@
|
|
|
124
124
|
"uuid": "^11.1.1"
|
|
125
125
|
},
|
|
126
126
|
"devDependencies": {
|
|
127
|
-
"@djangocfg/analytics": "^2.1.
|
|
128
|
-
"@djangocfg/api": "^2.1.
|
|
129
|
-
"@djangocfg/centrifugo": "^2.1.
|
|
130
|
-
"@djangocfg/devtools": "^2.1.
|
|
131
|
-
"@djangocfg/i18n": "^2.1.
|
|
132
|
-
"@djangocfg/typescript-config": "^2.1.
|
|
133
|
-
"@djangocfg/ui-core": "^2.1.
|
|
134
|
-
"@djangocfg/ui-tools": "^2.1.
|
|
127
|
+
"@djangocfg/analytics": "^2.1.503",
|
|
128
|
+
"@djangocfg/api": "^2.1.503",
|
|
129
|
+
"@djangocfg/centrifugo": "^2.1.503",
|
|
130
|
+
"@djangocfg/devtools": "^2.1.503",
|
|
131
|
+
"@djangocfg/i18n": "^2.1.503",
|
|
132
|
+
"@djangocfg/typescript-config": "^2.1.503",
|
|
133
|
+
"@djangocfg/ui-core": "^2.1.503",
|
|
134
|
+
"@djangocfg/ui-tools": "^2.1.503",
|
|
135
135
|
"@types/node": "^25.9.5",
|
|
136
136
|
"@types/react": "19.2.15",
|
|
137
137
|
"@types/react-dom": "19.2.3",
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
import { cn } from '@djangocfg/ui-core/lib';
|
|
6
|
+
import { ThemeSegmented } from '@djangocfg/ui-core/theme';
|
|
7
|
+
|
|
8
|
+
import { LocaleSwitcherDropdown } from '../../_components/locale-switcher';
|
|
9
|
+
import { useLayoutI18nOptional } from '../../AppLayout/LayoutI18nProvider';
|
|
10
|
+
|
|
11
|
+
interface SettingsRailFooterProps {
|
|
12
|
+
/**
|
|
13
|
+
* Horizontal layout (theme + language side-by-side on a single row) for the
|
|
14
|
+
* mobile header strip. Default is the stacked vertical layout used at the
|
|
15
|
+
* bottom of the desktop rail.
|
|
16
|
+
*/
|
|
17
|
+
horizontal?: boolean;
|
|
18
|
+
className?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Global preferences pinned to the bottom-left of the settings rail — the
|
|
23
|
+
* "chrome" controls (appearance + language) that belong with the shell, not
|
|
24
|
+
* inside the Account tab. Sits below a hairline, always visible regardless of
|
|
25
|
+
* the active section (mirrors the app-shell pattern: quick prefs live in the
|
|
26
|
+
* corner, not buried in a form).
|
|
27
|
+
*
|
|
28
|
+
* Language only renders when a layout i18n context is present.
|
|
29
|
+
*/
|
|
30
|
+
export const SettingsRailFooter: React.FC<SettingsRailFooterProps> = ({
|
|
31
|
+
horizontal = false,
|
|
32
|
+
className,
|
|
33
|
+
}) => {
|
|
34
|
+
const layoutI18n = useLayoutI18nOptional();
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<div
|
|
38
|
+
className={cn(
|
|
39
|
+
'border-t border-border/70',
|
|
40
|
+
horizontal
|
|
41
|
+
? 'flex items-center justify-end gap-2'
|
|
42
|
+
: 'flex flex-col gap-2 px-1 pt-3',
|
|
43
|
+
className,
|
|
44
|
+
)}
|
|
45
|
+
>
|
|
46
|
+
{!horizontal && (
|
|
47
|
+
<span className="px-1.5 text-[11px] font-medium uppercase tracking-wider text-muted-foreground/70">
|
|
48
|
+
Preferences
|
|
49
|
+
</span>
|
|
50
|
+
)}
|
|
51
|
+
|
|
52
|
+
<div
|
|
53
|
+
className={cn(
|
|
54
|
+
horizontal ? 'flex items-center gap-2' : 'flex items-center justify-between gap-2 px-0.5',
|
|
55
|
+
)}
|
|
56
|
+
>
|
|
57
|
+
<ThemeSegmented size="compact" />
|
|
58
|
+
{layoutI18n && (
|
|
59
|
+
<LocaleSwitcherDropdown
|
|
60
|
+
locale={layoutI18n.locale}
|
|
61
|
+
locales={layoutI18n.locales}
|
|
62
|
+
onChange={layoutI18n.onLocaleChange}
|
|
63
|
+
variant="outline"
|
|
64
|
+
size="sm"
|
|
65
|
+
showCode
|
|
66
|
+
showIcon={false}
|
|
67
|
+
showFlag
|
|
68
|
+
showTriggerLabel
|
|
69
|
+
/>
|
|
70
|
+
)}
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
);
|
|
74
|
+
};
|
|
@@ -8,6 +8,7 @@ import { cn } from '@djangocfg/ui-core/lib';
|
|
|
8
8
|
import { useSettingsContext } from '../context';
|
|
9
9
|
import { SettingsNav } from './SettingsNav';
|
|
10
10
|
import { SettingsPanel } from './SettingsPanel';
|
|
11
|
+
import { SettingsRailFooter } from './SettingsRailFooter';
|
|
11
12
|
import { SettingsTabs } from './SettingsTabs';
|
|
12
13
|
|
|
13
14
|
interface SettingsShellProps {
|
|
@@ -45,8 +46,13 @@ export const SettingsShell: React.FC<SettingsShellProps> = ({ bare = false, clas
|
|
|
45
46
|
<div className={frame}>
|
|
46
47
|
<div className="shrink-0 bg-muted">
|
|
47
48
|
{/* Title row — `pr-12` leaves room for the dialog's corner close button. */}
|
|
48
|
-
<div className="px-4 pb-2 pt-3.5 pr-12">
|
|
49
|
-
<h2 className="text-base font-semibold tracking-tight text-foreground">
|
|
49
|
+
<div className="flex items-center gap-3 px-4 pb-2 pt-3.5 pr-12">
|
|
50
|
+
<h2 className="flex-1 truncate text-base font-semibold tracking-tight text-foreground">
|
|
51
|
+
{title}
|
|
52
|
+
</h2>
|
|
53
|
+
{/* Global prefs (theme + language) mirror the desktop rail footer —
|
|
54
|
+
on phones they ride the header instead of a bottom rail. */}
|
|
55
|
+
<SettingsRailFooter horizontal className="border-t-0" />
|
|
50
56
|
</div>
|
|
51
57
|
{/* Tabs on their own row (below the header), so nothing overlaps the X. */}
|
|
52
58
|
<div className="border-b border-border px-1.5 pb-2">
|
|
@@ -63,9 +69,14 @@ export const SettingsShell: React.FC<SettingsShellProps> = ({ bare = false, clas
|
|
|
63
69
|
// ── Desktop: rail + panel ──
|
|
64
70
|
return (
|
|
65
71
|
<div className={cn(frame, 'flex-row')}>
|
|
66
|
-
{/* Nav rail — recessed surface, one notch below the content panel.
|
|
67
|
-
|
|
68
|
-
|
|
72
|
+
{/* Nav rail — recessed surface, one notch below the content panel.
|
|
73
|
+
Column layout so the section list scrolls in the middle and the
|
|
74
|
+
global-preferences footer (theme + language) pins to the bottom. */}
|
|
75
|
+
<aside className="flex shrink-0 flex-col border-r border-border bg-muted p-3 md:w-52">
|
|
76
|
+
<div className="min-h-0 flex-1">
|
|
77
|
+
<SettingsNav />
|
|
78
|
+
</div>
|
|
79
|
+
<SettingsRailFooter className="mt-3" />
|
|
69
80
|
</aside>
|
|
70
81
|
|
|
71
82
|
{/* Detail panel — the lighter, primary surface. */}
|
|
@@ -9,7 +9,6 @@ import { Button, SettingRow, SettingsBlock } from '@djangocfg/ui-core/components
|
|
|
9
9
|
import { AvatarSection } from '../components/AvatarSection';
|
|
10
10
|
import { useProfileSave } from '../hooks/useProfileSave';
|
|
11
11
|
import { DeleteAccountRow } from './DeleteAccountRow';
|
|
12
|
-
import { PreferencesRows } from './PreferencesRows';
|
|
13
12
|
|
|
14
13
|
interface AccountSectionProps {
|
|
15
14
|
/** Render the "Danger zone" delete-account control. Default: true. */
|
|
@@ -80,9 +79,8 @@ export const AccountSection: React.FC<AccountSectionProps> = ({
|
|
|
80
79
|
/>
|
|
81
80
|
</SettingsBlock>
|
|
82
81
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
</SettingsBlock>
|
|
82
|
+
{/* Language + Theme moved to the settings-rail footer (bottom-left of the
|
|
83
|
+
dialog) — they are app-shell "chrome" prefs, not per-account fields. */}
|
|
86
84
|
|
|
87
85
|
<SettingsBlock title={labels.actions}>
|
|
88
86
|
<SettingRow
|