@djangocfg/layouts 1.2.14 → 1.2.15

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": "1.2.14",
3
+ "version": "1.2.15",
4
4
  "description": "Layout system and components for Unrealon applications",
5
5
  "author": {
6
6
  "name": "DjangoCFG",
@@ -53,9 +53,9 @@
53
53
  "check": "tsc --noEmit"
54
54
  },
55
55
  "peerDependencies": {
56
- "@djangocfg/api": "^1.2.14",
57
- "@djangocfg/og-image": "^1.2.14",
58
- "@djangocfg/ui": "^1.2.14",
56
+ "@djangocfg/api": "^1.2.15",
57
+ "@djangocfg/og-image": "^1.2.15",
58
+ "@djangocfg/ui": "^1.2.15",
59
59
  "@hookform/resolvers": "^5.2.0",
60
60
  "consola": "^3.4.2",
61
61
  "lucide-react": "^0.468.0",
@@ -76,7 +76,7 @@
76
76
  "vidstack": "0.6.15"
77
77
  },
78
78
  "devDependencies": {
79
- "@djangocfg/typescript-config": "^1.2.14",
79
+ "@djangocfg/typescript-config": "^1.2.15",
80
80
  "@types/node": "^24.7.2",
81
81
  "@types/react": "19.2.2",
82
82
  "@types/react-dom": "19.2.1",
@@ -16,36 +16,36 @@ export interface PackageInfo {
16
16
  /**
17
17
  * Package versions registry
18
18
  * Auto-synced from package.json files
19
- * Last updated: 2025-10-29T12:42:02.313Z
19
+ * Last updated: 2025-10-29T12:44:49.794Z
20
20
  */
21
21
  const PACKAGE_VERSIONS: PackageInfo[] = [
22
22
  {
23
23
  "name": "@djangocfg/ui",
24
- "version": "1.2.14"
24
+ "version": "1.2.15"
25
25
  },
26
26
  {
27
27
  "name": "@djangocfg/api",
28
- "version": "1.2.14"
28
+ "version": "1.2.15"
29
29
  },
30
30
  {
31
31
  "name": "@djangocfg/layouts",
32
- "version": "1.2.14"
32
+ "version": "1.2.15"
33
33
  },
34
34
  {
35
35
  "name": "@djangocfg/markdown",
36
- "version": "1.2.14"
36
+ "version": "1.2.15"
37
37
  },
38
38
  {
39
39
  "name": "@djangocfg/og-image",
40
- "version": "1.2.14"
40
+ "version": "1.2.15"
41
41
  },
42
42
  {
43
43
  "name": "@djangocfg/eslint-config",
44
- "version": "1.2.14"
44
+ "version": "1.2.15"
45
45
  },
46
46
  {
47
47
  "name": "@djangocfg/typescript-config",
48
- "version": "1.2.14"
48
+ "version": "1.2.15"
49
49
  }
50
50
  ];
51
51
 
@@ -201,9 +201,9 @@ const {
201
201
  | Message Type | Data | Description |
202
202
  |-------------|------|-------------|
203
203
  | `iframe-ready` | `{ url, referrer }` | iframe loaded successfully |
204
- | `iframe-auth-status` | `{ isAuthenticated, isLoading, hasUser }` | Auth status update |
205
- | `iframe-resize` | `{ height }` | Content height changed |
206
- | `iframe-navigation` | `{ path, route }` | User navigated to new page |
204
+ | `iframe-auth-status` | `{ isAuthenticated, isLoading, hasUser }` | Auth status update (sent on auth state change) |
205
+ | `iframe-resize` | `{ height }` | Content height changed (sent on ResizeObserver trigger) |
206
+ | `iframe-navigation` | `{ path }` | User navigated to new page (sent via Next.js Router.events) |
207
207
 
208
208
  ## Advanced Usage
209
209
 
@@ -278,6 +278,26 @@ import { ParentSync } from '@djangocfg/layouts';
278
278
  </AuthProvider>
279
279
  ```
280
280
 
281
+ **What ParentSync does:**
282
+
283
+ 1. **Theme Sync** (Parent → iframe): Receives theme updates from Django Unfold and applies them
284
+ 2. **Auth Status Sync** (iframe → Parent): Sends authentication status when it changes
285
+ 3. **Auto Resize** (iframe → Parent): Sends content height for iframe resizing
286
+ 4. **Navigation Tracking** (iframe → Parent): Sends route changes for "Open in New Window" button
287
+
288
+ **Navigation Tracking:**
289
+ ParentSync automatically tracks route changes using Next.js Router and sends them to the parent window:
290
+
291
+ ```typescript
292
+ // Automatically sent on every route change
293
+ window.parent.postMessage({
294
+ type: 'iframe-navigation',
295
+ data: { path: '/admin/stocks' }
296
+ }, '*');
297
+ ```
298
+
299
+ This enables the "Open in New Window" button in the Django admin to open the exact page the user is currently viewing, not just the home page.
300
+
281
301
  ## Security Considerations
282
302
 
283
303
  - All postMessage communications validate origins
@@ -122,23 +122,60 @@ function ParentSyncClient() {
122
122
  // Observe body element for size changes
123
123
  resizeObserver.observe(document.body);
124
124
 
125
- // Also observe on route changes (for Next.js)
126
- const handleRouteChange = () => {
127
- // Delay to allow content to render
128
- setTimeout(sendHeight, 100);
125
+ // Cleanup
126
+ return () => {
127
+ resizeObserver.disconnect();
129
128
  };
129
+ }, [isEmbedded, isMounted]);
130
130
 
131
- // Listen for Next.js router events if available
132
- if (typeof window !== 'undefined') {
133
- window.addEventListener('popstate', handleRouteChange);
131
+ // 4. Send navigation events to parent (for "Open in New Window" button)
132
+ useEffect(() => {
133
+ // Only send if embedded and mounted
134
+ if (!isEmbedded || !isMounted) {
135
+ return;
134
136
  }
135
137
 
136
- return () => {
137
- resizeObserver.disconnect();
138
- if (typeof window !== 'undefined') {
139
- window.removeEventListener('popstate', handleRouteChange);
140
- }
141
- };
138
+ // Import Next.js router dynamically
139
+ import('next/router').then(({ default: Router }) => {
140
+ const handleRouteChange = (url: string) => {
141
+ // console.log('[ParentSync] 🔗 Route changed:', url);
142
+
143
+ try {
144
+ window.parent.postMessage({
145
+ type: 'iframe-navigation',
146
+ data: { path: url }
147
+ }, '*');
148
+ } catch (e) {
149
+ console.error('[ParentSync] ❌ Failed to send navigation event:', e);
150
+ }
151
+
152
+ // Also send height update after route change
153
+ setTimeout(() => {
154
+ const height = document.documentElement.scrollHeight;
155
+ try {
156
+ window.parent.postMessage({
157
+ type: 'iframe-resize',
158
+ data: { height }
159
+ }, '*');
160
+ } catch (e) {
161
+ console.error('[ParentSync] ❌ Failed to send height:', e);
162
+ }
163
+ }, 100);
164
+ };
165
+
166
+ // Listen to Next.js router events
167
+ Router.events.on('routeChangeComplete', handleRouteChange);
168
+
169
+ // Send initial route
170
+ handleRouteChange(Router.asPath);
171
+
172
+ // Cleanup
173
+ return () => {
174
+ Router.events.off('routeChangeComplete', handleRouteChange);
175
+ };
176
+ }).catch(err => {
177
+ console.warn('[ParentSync] Failed to load next/router:', err);
178
+ });
142
179
  }, [isEmbedded, isMounted]);
143
180
 
144
181
  // This component doesn't render anything