@djangocfg/layouts 2.1.347 → 2.1.348

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.347",
3
+ "version": "2.1.348",
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.347",
88
- "@djangocfg/centrifugo": "^2.1.347",
89
- "@djangocfg/debuger": "^2.1.347",
90
- "@djangocfg/i18n": "^2.1.347",
91
- "@djangocfg/monitor": "^2.1.347",
92
- "@djangocfg/ui-core": "^2.1.347",
93
- "@djangocfg/ui-nextjs": "^2.1.347",
87
+ "@djangocfg/api": "^2.1.348",
88
+ "@djangocfg/centrifugo": "^2.1.348",
89
+ "@djangocfg/debuger": "^2.1.348",
90
+ "@djangocfg/i18n": "^2.1.348",
91
+ "@djangocfg/monitor": "^2.1.348",
92
+ "@djangocfg/ui-core": "^2.1.348",
93
+ "@djangocfg/ui-nextjs": "^2.1.348",
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.347",
124
- "@djangocfg/centrifugo": "^2.1.347",
125
- "@djangocfg/debuger": "^2.1.347",
126
- "@djangocfg/i18n": "^2.1.347",
127
- "@djangocfg/monitor": "^2.1.347",
128
- "@djangocfg/typescript-config": "^2.1.347",
129
- "@djangocfg/ui-core": "^2.1.347",
130
- "@djangocfg/ui-nextjs": "^2.1.347",
131
- "@djangocfg/ui-tools": "^2.1.347",
123
+ "@djangocfg/api": "^2.1.348",
124
+ "@djangocfg/centrifugo": "^2.1.348",
125
+ "@djangocfg/debuger": "^2.1.348",
126
+ "@djangocfg/i18n": "^2.1.348",
127
+ "@djangocfg/monitor": "^2.1.348",
128
+ "@djangocfg/typescript-config": "^2.1.348",
129
+ "@djangocfg/ui-core": "^2.1.348",
130
+ "@djangocfg/ui-nextjs": "^2.1.348",
131
+ "@djangocfg/ui-tools": "^2.1.348",
132
132
  "@types/node": "^24.7.2",
133
133
  "@types/react": "^19.1.0",
134
134
  "@types/react-dom": "^19.1.0",
@@ -2,6 +2,8 @@
2
2
 
3
3
  import React, { useEffect, useState } from 'react';
4
4
 
5
+ import { LocaleSwitcher } from '../../../_components/LocaleSwitcher';
6
+ import { useLayoutI18nOptional } from '../../../AppLayout/LayoutI18nProvider';
5
7
  import { AUTH } from '../../constants';
6
8
  import type { AuthStep } from '../../types';
7
9
 
@@ -44,12 +46,32 @@ export const AuthContainer: React.FC<AuthContainerProps> = ({
44
46
  }
45
47
  }, [isEntering]);
46
48
 
49
+ // Locale picker is mounted as the first child so it sits at the very
50
+ // top of the form column — visually paired with the form chrome (not
51
+ // floating in a viewport corner). Renders automatically when
52
+ // LayoutI18nProvider is mounted (BaseApp does this when the host app
53
+ // passes `i18n`); no prop gating needed.
54
+ const i18n = useLayoutI18nOptional();
55
+
47
56
  return (
48
57
  <div
49
58
  className={`auth-container ${className}`}
50
59
  data-entering={isEntering}
51
60
  data-step={step}
52
61
  >
62
+ {i18n ? (
63
+ <div className="auth-container__meta">
64
+ <LocaleSwitcher
65
+ variant="dropdown"
66
+ buttonVariant="ghost"
67
+ size="sm"
68
+ showFlag
69
+ showCode={false}
70
+ showTriggerLabel
71
+ className="auth-locale-trigger"
72
+ />
73
+ </div>
74
+ ) : null}
53
75
  {children}
54
76
  </div>
55
77
  );
@@ -26,6 +26,25 @@
26
26
  gap: 1.25rem;
27
27
  }
28
28
 
29
+ /* Meta row at the top of the form — currently hosts the locale picker.
30
+ Right-aligned, tight, not eating much vertical space; feels like a
31
+ tab/utility chip rather than a floating control. */
32
+ .auth-container__meta {
33
+ display: flex;
34
+ justify-content: flex-end;
35
+ margin-bottom: -0.5rem;
36
+ }
37
+
38
+ .auth-locale-trigger {
39
+ height: 1.75rem;
40
+ padding-inline: 0.5rem;
41
+ font-size: 0.75rem;
42
+ color: hsl(var(--muted-foreground));
43
+ }
44
+ .auth-locale-trigger:hover {
45
+ color: hsl(var(--foreground));
46
+ }
47
+
29
48
  .auth-container[data-entering="true"] {
30
49
  animation: authSlideIn 0.45s var(--spring-smooth) both;
31
50
  }
@@ -43,6 +43,45 @@
43
43
  outline: 1px solid hsl(var(--border));
44
44
  box-shadow: 0 4px 24px hsl(0 0% 0% / 0.08);
45
45
  overflow: hidden;
46
+ /* Apple-style frosted entry — the card "condenses" out of the
47
+ background. Uses the same spring curve (0.16, 1, 0.3, 1) that
48
+ iOS modal sheets ride on. We animate filter+transform+opacity
49
+ together so it reads as one continuous gesture, not three
50
+ stacked tweens. willChange hints the compositor to promote the
51
+ element ahead of the run; reset to auto on completion (CSS
52
+ `forwards` keeps the end state implicitly). */
53
+ animation: authShellCardEntry 700ms cubic-bezier(0.16, 1, 0.3, 1) both;
54
+ will-change: transform, filter, opacity;
55
+ }
56
+
57
+ @keyframes authShellCardEntry {
58
+ 0% {
59
+ opacity: 0;
60
+ transform: translateY(24px) scale(0.96);
61
+ filter: blur(10px);
62
+ }
63
+ 60% {
64
+ /* Mid-keyframe lets the blur clear faster than the slide so the
65
+ form contents become readable while the card is still settling
66
+ — feels responsive instead of waiting on the animation. */
67
+ filter: blur(0);
68
+ }
69
+ 100% {
70
+ opacity: 1;
71
+ transform: translateY(0) scale(1);
72
+ filter: blur(0);
73
+ }
74
+ }
75
+
76
+ /* Respect reduced-motion preference — fall back to a plain fade. */
77
+ @media (prefers-reduced-motion: reduce) {
78
+ .auth-shell-split__card {
79
+ animation: authShellCardEntryReduced 200ms ease-out both;
80
+ }
81
+ @keyframes authShellCardEntryReduced {
82
+ from { opacity: 0; }
83
+ to { opacity: 1; }
84
+ }
46
85
  }
47
86
 
48
87
  /* Form column */