@djangocfg/ui-core 2.1.340 → 2.1.342
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/ui-core",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.342",
|
|
4
4
|
"description": "Pure React UI component library without Next.js dependencies - for Electron, Vite, CRA apps",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ui-components",
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
"playground": "playground dev"
|
|
92
92
|
},
|
|
93
93
|
"peerDependencies": {
|
|
94
|
-
"@djangocfg/i18n": "^2.1.
|
|
94
|
+
"@djangocfg/i18n": "^2.1.342",
|
|
95
95
|
"consola": "^3.4.2",
|
|
96
96
|
"lucide-react": "^0.545.0",
|
|
97
97
|
"moment": "^2.30.1",
|
|
@@ -160,9 +160,9 @@
|
|
|
160
160
|
"vaul": "1.1.2"
|
|
161
161
|
},
|
|
162
162
|
"devDependencies": {
|
|
163
|
-
"@djangocfg/i18n": "^2.1.
|
|
163
|
+
"@djangocfg/i18n": "^2.1.342",
|
|
164
164
|
"@djangocfg/playground": "workspace:*",
|
|
165
|
-
"@djangocfg/typescript-config": "^2.1.
|
|
165
|
+
"@djangocfg/typescript-config": "^2.1.342",
|
|
166
166
|
"@types/node": "^24.7.2",
|
|
167
167
|
"@types/react": "^19.1.0",
|
|
168
168
|
"@types/react-dom": "^19.1.0",
|
|
@@ -4,56 +4,54 @@ import * as React from 'react';
|
|
|
4
4
|
import { createPortal } from 'react-dom';
|
|
5
5
|
|
|
6
6
|
export interface PortalProps {
|
|
7
|
-
/**
|
|
8
|
-
* The content to be rendered inside the portal.
|
|
9
|
-
*/
|
|
10
7
|
children: React.ReactNode;
|
|
11
8
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* Can be a DOM element, a function returning a DOM element, or a ref.
|
|
9
|
+
* Target container. Defaults to document.body.
|
|
10
|
+
* Accepts a DOM element, a function returning one, or a ref.
|
|
15
11
|
*/
|
|
16
12
|
container?: Element | (() => Element | null) | React.RefObject<Element | null> | null;
|
|
13
|
+
/** Render children in-place instead of teleporting. @default false */
|
|
14
|
+
disablePortal?: boolean;
|
|
17
15
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
16
|
+
* Keep children mounted in the DOM even when the portal is "closed"
|
|
17
|
+
* (i.e. when the parent conditionally hides them via CSS / opacity).
|
|
18
|
+
* Useful for exit animations — the node stays in the DOM while the
|
|
19
|
+
* animation plays, then the parent unmounts it via its own state.
|
|
20
20
|
* @default false
|
|
21
21
|
*/
|
|
22
|
-
|
|
22
|
+
keepMounted?: boolean;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
|
-
* Portal
|
|
27
|
-
*
|
|
26
|
+
* Portal — renders children into a different part of the DOM tree,
|
|
27
|
+
* escaping any CSS stacking context (transform, filter, will-change).
|
|
28
28
|
*
|
|
29
29
|
* @example
|
|
30
30
|
* ```tsx
|
|
31
|
-
* //
|
|
31
|
+
* // Default: teleport to document.body
|
|
32
32
|
* <Portal>
|
|
33
|
-
* <div className="fixed inset-0 z-50">Modal
|
|
33
|
+
* <div className="fixed inset-0 z-50">Modal</div>
|
|
34
34
|
* </Portal>
|
|
35
35
|
*
|
|
36
|
-
* //
|
|
37
|
-
* <Portal container={document.getElementById('modal-root')}>
|
|
38
|
-
* <div>
|
|
36
|
+
* // Custom container
|
|
37
|
+
* <Portal container={() => document.getElementById('modal-root')}>
|
|
38
|
+
* <div>Content</div>
|
|
39
39
|
* </Portal>
|
|
40
40
|
*
|
|
41
|
-
* //
|
|
42
|
-
* <Portal
|
|
43
|
-
* <div>
|
|
41
|
+
* // Keep mounted for exit animations — hide via CSS, unmount later
|
|
42
|
+
* <Portal keepMounted>
|
|
43
|
+
* <div style={{ display: isOpen ? 'block' : 'none' }}>Animated panel</div>
|
|
44
44
|
* </Portal>
|
|
45
45
|
*
|
|
46
|
-
* //
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* <Portal container={containerRef}>
|
|
50
|
-
* <div>Content in ref container</div>
|
|
46
|
+
* // Disable portal (render in-place, e.g. in tests or SSR)
|
|
47
|
+
* <Portal disablePortal>
|
|
48
|
+
* <div>In-place</div>
|
|
51
49
|
* </Portal>
|
|
52
50
|
* ```
|
|
53
51
|
*/
|
|
54
52
|
export const Portal = React.forwardRef<HTMLDivElement, PortalProps>(
|
|
55
53
|
function Portal(props, ref) {
|
|
56
|
-
const { children, container, disablePortal = false } = props;
|
|
54
|
+
const { children, container, disablePortal = false, keepMounted = false } = props;
|
|
57
55
|
const [mountNode, setMountNode] = React.useState<Element | null>(null);
|
|
58
56
|
|
|
59
57
|
React.useEffect(() => {
|
|
@@ -64,19 +62,18 @@ export const Portal = React.forwardRef<HTMLDivElement, PortalProps>(
|
|
|
64
62
|
|
|
65
63
|
if (disablePortal) {
|
|
66
64
|
if (React.isValidElement(children)) {
|
|
67
|
-
return React.cloneElement(children as React.ReactElement<{ ref?: React.Ref<HTMLDivElement> }>, {
|
|
68
|
-
ref: ref,
|
|
69
|
-
});
|
|
65
|
+
return React.cloneElement(children as React.ReactElement<{ ref?: React.Ref<HTMLDivElement> }>, { ref });
|
|
70
66
|
}
|
|
71
67
|
return <>{children}</>;
|
|
72
68
|
}
|
|
73
69
|
|
|
74
|
-
|
|
75
|
-
|
|
70
|
+
// SSR / before first effect: keepMounted renders in-place so content
|
|
71
|
+
// exists in the server HTML; otherwise return null (portal attaches client-side).
|
|
72
|
+
if (!mountNode) {
|
|
73
|
+
return keepMounted ? <>{children}</> : null;
|
|
76
74
|
}
|
|
77
75
|
|
|
78
|
-
|
|
79
|
-
return null;
|
|
76
|
+
return createPortal(children, mountNode);
|
|
80
77
|
}
|
|
81
78
|
);
|
|
82
79
|
|