@djangocfg/layouts 2.1.264 → 2.1.267

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.
Files changed (38) hide show
  1. package/README.md +113 -4
  2. package/package.json +19 -18
  3. package/src/hooks/index.ts +1 -1
  4. package/src/hooks/usePathnameWithoutLocale.ts +35 -19
  5. package/src/layouts/AppLayout/AppLayout.tsx +15 -4
  6. package/src/layouts/AuthLayout/components/steps/SetupStep/index.tsx +50 -6
  7. package/src/layouts/ProfileLayout/ProfileLayout.tsx +206 -235
  8. package/src/layouts/ProfileLayout/components/AvatarSection.tsx +2 -3
  9. package/src/layouts/ProfileLayout/components/DeleteAccountSection.tsx +22 -106
  10. package/src/layouts/ProfileLayout/components/EditableField.tsx +15 -10
  11. package/src/layouts/ProfileLayout/components/Section.tsx +1 -1
  12. package/src/layouts/ProfileLayout/components/TwoFactorSection.tsx +255 -215
  13. package/src/layouts/ProfileLayout/context.tsx +108 -16
  14. package/src/layouts/ProfileLayout/index.ts +1 -1
  15. package/src/layouts/PublicLayout/PublicLayout.tsx +18 -0
  16. package/src/layouts/PublicLayout/components/NavActions.tsx +50 -0
  17. package/src/layouts/PublicLayout/components/NavBrand.tsx +26 -0
  18. package/src/layouts/PublicLayout/components/NavDesktopItems.tsx +207 -0
  19. package/src/layouts/PublicLayout/components/PublicMobileDrawer.tsx +1 -1
  20. package/src/layouts/PublicLayout/components/PublicNavbar.tsx +44 -6
  21. package/src/layouts/PublicLayout/components/PublicNavigation.tsx +199 -396
  22. package/src/layouts/PublicLayout/hooks/index.ts +5 -1
  23. package/src/layouts/PublicLayout/hooks/useDropdownMenu.ts +58 -0
  24. package/src/layouts/PublicLayout/hooks/useNavbarScroll.ts +61 -0
  25. package/src/layouts/PublicLayout/hooks/useNavbarViewportVars.ts +46 -0
  26. package/src/layouts/PublicLayout/index.ts +4 -0
  27. package/src/layouts/PublicLayout/navbarTypes.ts +17 -0
  28. package/src/utils/pathMatcher.ts +6 -3
  29. package/src/layouts/ProfileLayout/.claude/.sidecar/activity.jsonl +0 -2
  30. package/src/layouts/ProfileLayout/.claude/.sidecar/history/2026-03-15.md +0 -35
  31. package/src/layouts/ProfileLayout/.claude/.sidecar/review.md +0 -35
  32. package/src/layouts/ProfileLayout/.claude/.sidecar/scan.log +0 -3
  33. package/src/layouts/ProfileLayout/.claude/.sidecar/tasks/T-001.md +0 -18
  34. package/src/layouts/ProfileLayout/.claude/.sidecar/tasks/T-002.md +0 -19
  35. package/src/layouts/ProfileLayout/.claude/.sidecar/tasks/T-003.md +0 -18
  36. package/src/layouts/ProfileLayout/.claude/.sidecar/tasks/T-004.md +0 -18
  37. package/src/layouts/ProfileLayout/.claude/.sidecar/tasks/T-005.md +0 -18
  38. package/src/layouts/ProfileLayout/.claude/.sidecar/usage.json +0 -5
@@ -1,2 +1,6 @@
1
1
  export { useMobileNavPanel } from './useMobileNavPanel';
2
-
2
+ export { useDropdownMenu } from './useDropdownMenu';
3
+ export type { UseDropdownMenuReturn } from './useDropdownMenu';
4
+ export { useNavbarScroll } from './useNavbarScroll';
5
+ export type { UseNavbarScrollOptions, UseNavbarScrollReturn } from './useNavbarScroll';
6
+ export { useNavbarViewportVars } from './useNavbarViewportVars';
@@ -0,0 +1,58 @@
1
+ 'use client';
2
+
3
+ import { useCallback, useEffect, useRef, useState } from 'react';
4
+
5
+ export interface UseDropdownMenuReturn {
6
+ openDropdownKey: string | null;
7
+ scheduleOpen: (key: string) => void;
8
+ scheduleClose: (key: string) => void;
9
+ closeDropdown: () => void;
10
+ }
11
+
12
+ /** Hover-based open/close with debounce timers for desktop dropdown menus. */
13
+ export function useDropdownMenu(): UseDropdownMenuReturn {
14
+ const [openDropdownKey, setOpenDropdownKey] = useState<string | null>(null);
15
+ const openTimerRef = useRef<number | null>(null);
16
+ const closeTimerRef = useRef<number | null>(null);
17
+
18
+ const clearOpenTimer = useCallback(() => {
19
+ if (openTimerRef.current !== null) {
20
+ window.clearTimeout(openTimerRef.current);
21
+ openTimerRef.current = null;
22
+ }
23
+ }, []);
24
+
25
+ const clearCloseTimer = useCallback(() => {
26
+ if (closeTimerRef.current !== null) {
27
+ window.clearTimeout(closeTimerRef.current);
28
+ closeTimerRef.current = null;
29
+ }
30
+ }, []);
31
+
32
+ const scheduleOpen = useCallback((key: string) => {
33
+ clearOpenTimer();
34
+ clearCloseTimer();
35
+ openTimerRef.current = window.setTimeout(() => {
36
+ setOpenDropdownKey(key);
37
+ }, 80);
38
+ }, [clearOpenTimer, clearCloseTimer]);
39
+
40
+ const scheduleClose = useCallback((key: string) => {
41
+ clearOpenTimer();
42
+ clearCloseTimer();
43
+ closeTimerRef.current = window.setTimeout(() => {
44
+ setOpenDropdownKey((prev) => (prev === key ? null : prev));
45
+ }, 120);
46
+ }, [clearOpenTimer, clearCloseTimer]);
47
+
48
+ const closeDropdown = useCallback(() => setOpenDropdownKey(null), []);
49
+
50
+ useEffect(() => {
51
+ return () => {
52
+ clearOpenTimer();
53
+ clearCloseTimer();
54
+ };
55
+ }, [clearOpenTimer, clearCloseTimer]);
56
+
57
+ return { openDropdownKey, scheduleOpen, scheduleClose, closeDropdown };
58
+ }
@@ -0,0 +1,61 @@
1
+ 'use client';
2
+
3
+ import { useEffect, useRef, useState } from 'react';
4
+
5
+ export interface UseNavbarScrollOptions {
6
+ /** Slide navbar up on scroll-down, back on scroll-up. @default false */
7
+ hideNavOnScroll?: boolean;
8
+ /** Transparent at page top, opaque after threshold. @default false */
9
+ transparent?: boolean;
10
+ /** scrollY threshold for hide + transparent triggers. @default 40 */
11
+ transparentThreshold?: number;
12
+ }
13
+
14
+ export interface UseNavbarScrollReturn {
15
+ /** true → apply `-translate-y-full` to outer wrapper */
16
+ hidden: boolean;
17
+ /** true → scrollY >= threshold; drives opaque background */
18
+ scrolled: boolean;
19
+ }
20
+
21
+ export function useNavbarScroll(options: UseNavbarScrollOptions = {}): UseNavbarScrollReturn {
22
+ const { hideNavOnScroll = false, transparent = false, transparentThreshold = 40 } = options;
23
+
24
+ const [hidden, setHidden] = useState(false);
25
+ const [scrolled, setScrolled] = useState(false);
26
+ const lastScrollY = useRef(0);
27
+
28
+ useEffect(() => {
29
+ if (!hideNavOnScroll && !transparent) {
30
+ setHidden(false);
31
+ setScrolled(false);
32
+ return;
33
+ }
34
+
35
+ const handleScroll = () => {
36
+ const currentY = window.scrollY;
37
+ const delta = currentY - lastScrollY.current;
38
+
39
+ if (transparent) {
40
+ setScrolled(currentY >= transparentThreshold);
41
+ }
42
+
43
+ if (hideNavOnScroll) {
44
+ if (currentY > transparentThreshold) {
45
+ if (delta > 0) setHidden(true);
46
+ else if (delta < 0) setHidden(false);
47
+ } else {
48
+ setHidden(false);
49
+ }
50
+ }
51
+
52
+ lastScrollY.current = currentY;
53
+ };
54
+
55
+ handleScroll();
56
+ window.addEventListener('scroll', handleScroll, { passive: true });
57
+ return () => window.removeEventListener('scroll', handleScroll);
58
+ }, [hideNavOnScroll, transparent, transparentThreshold]);
59
+
60
+ return { hidden, scrolled };
61
+ }
@@ -0,0 +1,46 @@
1
+ 'use client';
2
+
3
+ import { type RefObject, useEffect } from 'react';
4
+
5
+ /**
6
+ * Tracks the bottom edge of the navbar outer element and writes CSS vars:
7
+ * --public-navbar-mobile-drawer-top
8
+ * --public-navbar-mobile-drawer-max-height
9
+ *
10
+ * @param navOuterRef - ref on the outermost navbar wrapper div
11
+ * @param deps - values that should re-trigger observer setup (position, variant, containerClassName)
12
+ */
13
+ export function useNavbarViewportVars(
14
+ navOuterRef: RefObject<HTMLDivElement | null>,
15
+ deps: readonly unknown[],
16
+ ): void {
17
+ useEffect(() => {
18
+ const update = () => {
19
+ const root = document.documentElement;
20
+ const navEl = navOuterRef.current;
21
+ if (!navEl) return;
22
+
23
+ const rect = navEl.getBoundingClientRect();
24
+ const top = Math.max(0, Math.round(rect.bottom + 8));
25
+ const maxHeight = Math.max(240, window.innerHeight - top - 12);
26
+
27
+ root.style.setProperty('--public-navbar-mobile-drawer-top', `${top}px`);
28
+ root.style.setProperty('--public-navbar-mobile-drawer-max-height', `${maxHeight}px`);
29
+ };
30
+
31
+ update();
32
+ const navEl = navOuterRef.current;
33
+ const observer = navEl ? new ResizeObserver(update) : null;
34
+ if (navEl && observer) observer.observe(navEl);
35
+ window.addEventListener('resize', update);
36
+ window.addEventListener('scroll', update, { passive: true });
37
+
38
+ return () => {
39
+ if (navEl && observer) observer.unobserve(navEl);
40
+ observer?.disconnect();
41
+ window.removeEventListener('resize', update);
42
+ window.removeEventListener('scroll', update);
43
+ };
44
+ // eslint-disable-next-line react-hooks/exhaustive-deps
45
+ }, deps);
46
+ }
@@ -10,7 +10,11 @@ export type {
10
10
  PublicNavbarVariant,
11
11
  PublicNavbarPosition,
12
12
  PublicNavbarShellConfig,
13
+ PublicNavLayout,
14
+ PublicNavbarHeight,
13
15
  } from './navbarTypes';
16
+ export type { UseNavbarScrollOptions, UseNavbarScrollReturn } from './hooks/useNavbarScroll';
17
+ export type { UseDropdownMenuReturn } from './hooks/useDropdownMenu';
14
18
  export type {
15
19
  PublicDesktopDropdownRenderer,
16
20
  PublicDesktopDropdownRenderProps,
@@ -6,6 +6,23 @@ export type PublicNavbarVariant = 'floating' | 'flush';
6
6
 
7
7
  export type PublicNavbarPosition = 'sticky' | 'fixed' | 'static';
8
8
 
9
+ /**
10
+ * Desktop nav layout variant.
11
+ * - `default` — brand left | nav **centered** (absolute) | actions right
12
+ * - `brand-left` — brand left | nav immediately after brand | actions pushed right
13
+ * - `centered` — brand + nav + actions all centered in one row
14
+ * - `split` — brand left | actions right | no desktop nav (drawer only)
15
+ */
16
+ export type PublicNavLayout = 'default' | 'brand-left' | 'centered' | 'split';
17
+
18
+ /**
19
+ * Navbar vertical padding / height.
20
+ * - `sm` → py-2
21
+ * - `md` → py-3.5 (default, matches current)
22
+ * - `lg` → py-5
23
+ */
24
+ export type PublicNavbarHeight = 'sm' | 'md' | 'lg';
25
+
9
26
  export interface PublicNavbarSurface {
10
27
  variant: PublicNavbarVariant;
11
28
  position: PublicNavbarPosition;
@@ -105,12 +105,15 @@ export function matchesPath(pathname: string, enabledPath?: string | string[]):
105
105
  if (!enabledPath) return false;
106
106
 
107
107
  const matchSinglePath = (path: string): boolean => {
108
+ // Normalize both sides — strip trailing slash (except root)
109
+ const normalPath = pathname.length > 1 ? pathname.replace(/\/+$/, '') : pathname;
110
+ const normalPattern = path.length > 1 ? path.replace(/\/+$/, '') : path;
108
111
  // If pattern contains glob characters, use pattern matching
109
- if (path.includes('*')) {
110
- return matchGlobPattern(pathname, path);
112
+ if (normalPattern.includes('*')) {
113
+ return matchGlobPattern(normalPath, normalPattern);
111
114
  }
112
115
  // Otherwise, exact or prefix match
113
- return pathname === path || pathname.startsWith(path + '/');
116
+ return normalPath === normalPattern || normalPath.startsWith(normalPattern + '/');
114
117
  };
115
118
 
116
119
  if (typeof enabledPath === 'string') {
@@ -1,2 +0,0 @@
1
- {"ts":"2026-03-15T05:27:58.550593Z","action":"update_check","tokens":0,"model":"deepseek/deepseek-v3.2","details":{}}
2
- {"ts":"2026-03-15T05:28:21.054276Z","action":"review","tokens":1533,"model":"deepseek/deepseek-v3.2","details":{"items_found":5}}
@@ -1,35 +0,0 @@
1
- # Sidecar Review -- 2026-03-15T05:28:21.052657+00:00
2
-
3
- ## Staleness
4
-
5
- - [?] Cannot assess staleness because documentation contents are unavailable. However, given the high commit activity (20 commits in 2 days), any documentation older than 30 days is almost certainly stale and contradictory to the current codebase state (e.g., new 'debuger', 'monitor', and OTP features).
6
- Files: Documentation referenced in file list
7
- Action: Provide documentation content to check modification dates against commit history. Update all documentation to reflect recent changes like the debug panel, monitoring integration, and OTP brute-force protection.
8
- (id: 46040dd3aace)
9
-
10
- ## Contradictions
11
-
12
- - [~] The commit 'updaded rq' (2026-03-14) has a typo and inconsistent formatting compared to other commits (e.g., 'chore(deps): bump django-rq version to 4.0.0'). This suggests poor documentation practices in commit messages, which can lead to confusion about project changes.
13
- Files: Commit history analysis
14
- Action: Enforce a commit message convention (e.g., Conventional Commits) and consider amending the 'updaded rq' commit for clarity. Ensure future commits are consistently formatted.
15
- (id: 6e3e54dfac9f)
16
-
17
- ## Missing Documentation
18
-
19
- - [!] No documentation content was provided for analysis. The provided metadata lists documentation files but their contents are unavailable, making it impossible to verify accuracy, check for staleness, or identify contradictions with the codebase.
20
- Files: All documentation files
21
- Action: Provide the actual content of the documentation files listed in the metadata (e.g., README.md, API docs, configuration guides) to enable a proper analysis for staleness, contradictions, and gaps.
22
- (id: fb1ef89d45a4)
23
-
24
- - [?] The top-level source directories '__tests__' and 'components' have no associated documentation content provided. Recent commits mention features like 'debuger', 'monitor', 'accounts', and 'otp', which likely reside in these directories, but their documentation cannot be verified.
25
- Files: __tests__, components
26
- Action: Review and provide documentation for the '__tests__' and 'components' directories, ensuring it covers the features mentioned in recent commits (e.g., debug panel, OTP brute-force protection, monitoring integration).
27
- (id: d538d5624ebb)
28
-
29
- - [!] No dependencies were detected, but recent git commits show active dependency management (e.g., 'bump django-cfg version to 1.7.77', 'bump django-rq version to 4.0.0'). This indicates a contradiction between the reported state and project activity, and documentation for these key dependencies is missing.
30
- Files: Dependency files (e.g., pyproject.toml, requirements.txt)
31
- Action: Provide the actual dependency files (pyproject.toml, package.json, or requirements.txt) to check for contradictions with documentation and ensure all critical packages like 'django-cfg' and 'django-rq' are documented.
32
- (id: fe7c9fa20e8b)
33
-
34
- ---
35
- Model: deepseek/deepseek-v3.2 | Tokens: 1533
@@ -1,35 +0,0 @@
1
- # Sidecar Review -- 2026-03-15T05:28:21.052657+00:00
2
-
3
- ## Staleness
4
-
5
- - [?] Cannot assess staleness because documentation contents are unavailable. However, given the high commit activity (20 commits in 2 days), any documentation older than 30 days is almost certainly stale and contradictory to the current codebase state (e.g., new 'debuger', 'monitor', and OTP features).
6
- Files: Documentation referenced in file list
7
- Action: Provide documentation content to check modification dates against commit history. Update all documentation to reflect recent changes like the debug panel, monitoring integration, and OTP brute-force protection.
8
- (id: 46040dd3aace)
9
-
10
- ## Contradictions
11
-
12
- - [~] The commit 'updaded rq' (2026-03-14) has a typo and inconsistent formatting compared to other commits (e.g., 'chore(deps): bump django-rq version to 4.0.0'). This suggests poor documentation practices in commit messages, which can lead to confusion about project changes.
13
- Files: Commit history analysis
14
- Action: Enforce a commit message convention (e.g., Conventional Commits) and consider amending the 'updaded rq' commit for clarity. Ensure future commits are consistently formatted.
15
- (id: 6e3e54dfac9f)
16
-
17
- ## Missing Documentation
18
-
19
- - [!] No documentation content was provided for analysis. The provided metadata lists documentation files but their contents are unavailable, making it impossible to verify accuracy, check for staleness, or identify contradictions with the codebase.
20
- Files: All documentation files
21
- Action: Provide the actual content of the documentation files listed in the metadata (e.g., README.md, API docs, configuration guides) to enable a proper analysis for staleness, contradictions, and gaps.
22
- (id: fb1ef89d45a4)
23
-
24
- - [?] The top-level source directories '__tests__' and 'components' have no associated documentation content provided. Recent commits mention features like 'debuger', 'monitor', 'accounts', and 'otp', which likely reside in these directories, but their documentation cannot be verified.
25
- Files: __tests__, components
26
- Action: Review and provide documentation for the '__tests__' and 'components' directories, ensuring it covers the features mentioned in recent commits (e.g., debug panel, OTP brute-force protection, monitoring integration).
27
- (id: d538d5624ebb)
28
-
29
- - [!] No dependencies were detected, but recent git commits show active dependency management (e.g., 'bump django-cfg version to 1.7.77', 'bump django-rq version to 4.0.0'). This indicates a contradiction between the reported state and project activity, and documentation for these key dependencies is missing.
30
- Files: Dependency files (e.g., pyproject.toml, requirements.txt)
31
- Action: Provide the actual dependency files (pyproject.toml, package.json, or requirements.txt) to check for contradictions with documentation and ensure all critical packages like 'django-cfg' and 'django-rq' are documented.
32
- (id: fe7c9fa20e8b)
33
-
34
- ---
35
- Model: deepseek/deepseek-v3.2 | Tokens: 1533
@@ -1,3 +0,0 @@
1
- Review generated: 5 items found
2
- Tokens used: 1533 (deepseek/deepseek-v3.2)
3
- Converted 5 items to tasks
@@ -1,18 +0,0 @@
1
- ---
2
- context_files:
3
- - All documentation files
4
- created_at: '2026-03-15T05:28:21.056182Z'
5
- id: T-001
6
- priority: high
7
- source: sidecar_review
8
- source_item_id: fb1ef89d45a4
9
- status: pending
10
- title: '[gap] No documentation content was provided for analysis. The provided metadata
11
- lists'
12
- ---
13
-
14
- No documentation content was provided for analysis. The provided metadata lists documentation files but their contents are unavailable, making it impossible to verify accuracy, check for staleness, or identify contradictions with the codebase.
15
-
16
- **Files:** All documentation files
17
-
18
- **Action:** Provide the actual content of the documentation files listed in the metadata (e.g., README.md, API docs, configuration guides) to enable a proper analysis for staleness, contradictions, and gaps.
@@ -1,19 +0,0 @@
1
- ---
2
- context_files:
3
- - __tests__
4
- - components
5
- created_at: '2026-03-15T05:28:21.057118Z'
6
- id: T-002
7
- priority: medium
8
- source: sidecar_review
9
- source_item_id: d538d5624ebb
10
- status: pending
11
- title: '[gap] The top-level source directories ''__tests__'' and ''components'' have
12
- no associated'
13
- ---
14
-
15
- The top-level source directories '__tests__' and 'components' have no associated documentation content provided. Recent commits mention features like 'debuger', 'monitor', 'accounts', and 'otp', which likely reside in these directories, but their documentation cannot be verified.
16
-
17
- **Files:** __tests__, components
18
-
19
- **Action:** Review and provide documentation for the '__tests__' and 'components' directories, ensuring it covers the features mentioned in recent commits (e.g., debug panel, OTP brute-force protection, monitoring integration).
@@ -1,18 +0,0 @@
1
- ---
2
- context_files:
3
- - Dependency files (e.g., pyproject.toml, requirements.txt)
4
- created_at: '2026-03-15T05:28:21.057738Z'
5
- id: T-003
6
- priority: high
7
- source: sidecar_review
8
- source_item_id: fe7c9fa20e8b
9
- status: pending
10
- title: '[gap] No dependencies were detected, but recent git commits show active dependency
11
- man'
12
- ---
13
-
14
- No dependencies were detected, but recent git commits show active dependency management (e.g., 'bump django-cfg version to 1.7.77', 'bump django-rq version to 4.0.0'). This indicates a contradiction between the reported state and project activity, and documentation for these key dependencies is missing.
15
-
16
- **Files:** Dependency files (e.g., pyproject.toml, requirements.txt)
17
-
18
- **Action:** Provide the actual dependency files (pyproject.toml, package.json, or requirements.txt) to check for contradictions with documentation and ensure all critical packages like 'django-cfg' and 'django-rq' are documented.
@@ -1,18 +0,0 @@
1
- ---
2
- context_files:
3
- - Documentation referenced in file list
4
- created_at: '2026-03-15T05:28:21.058352Z'
5
- id: T-004
6
- priority: medium
7
- source: sidecar_review
8
- source_item_id: 46040dd3aace
9
- status: pending
10
- title: '[staleness] Cannot assess staleness because documentation contents are unavailable.
11
- However,'
12
- ---
13
-
14
- Cannot assess staleness because documentation contents are unavailable. However, given the high commit activity (20 commits in 2 days), any documentation older than 30 days is almost certainly stale and contradictory to the current codebase state (e.g., new 'debuger', 'monitor', and OTP features).
15
-
16
- **Files:** Documentation referenced in file list
17
-
18
- **Action:** Provide documentation content to check modification dates against commit history. Update all documentation to reflect recent changes like the debug panel, monitoring integration, and OTP brute-force protection.
@@ -1,18 +0,0 @@
1
- ---
2
- context_files:
3
- - Commit history analysis
4
- created_at: '2026-03-15T05:28:21.059002Z'
5
- id: T-005
6
- priority: low
7
- source: sidecar_review
8
- source_item_id: 6e3e54dfac9f
9
- status: pending
10
- title: '[contradiction] The commit ''updaded rq'' (2026-03-14) has a typo and inconsistent
11
- formatting comp'
12
- ---
13
-
14
- The commit 'updaded rq' (2026-03-14) has a typo and inconsistent formatting compared to other commits (e.g., 'chore(deps): bump django-rq version to 4.0.0'). This suggests poor documentation practices in commit messages, which can lead to confusion about project changes.
15
-
16
- **Files:** Commit history analysis
17
-
18
- **Action:** Enforce a commit message convention (e.g., Conventional Commits) and consider amending the 'updaded rq' commit for clarity. Ensure future commits are consistently formatted.
@@ -1,5 +0,0 @@
1
- {
2
- "date": "2026-03-15",
3
- "tokens": 1533,
4
- "calls": 1
5
- }