@djangocfg/ui-core 2.1.339 → 2.1.341
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 +4 -4
- package/src/components/overlay/dialog/index.tsx +1 -1
- package/src/components/overlay/drawer/index.tsx +1 -0
- package/src/components/overlay/hover-card/index.tsx +1 -0
- package/src/components/overlay/popover/index.tsx +1 -0
- package/src/components/overlay/sheet/index.tsx +1 -0
- package/src/components/overlay/side-panel/index.tsx +1 -0
- package/src/components/overlay/tooltip/index.tsx +1 -0
- package/src/components/specialized/portal/index.tsx +29 -32
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@djangocfg/ui-core",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.341",
|
|
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.341",
|
|
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.341",
|
|
164
164
|
"@djangocfg/playground": "workspace:*",
|
|
165
|
-
"@djangocfg/typescript-config": "^2.1.
|
|
165
|
+
"@djangocfg/typescript-config": "^2.1.341",
|
|
166
166
|
"@types/node": "^24.7.2",
|
|
167
167
|
"@types/react": "^19.1.0",
|
|
168
168
|
"@types/react-dom": "^19.1.0",
|
|
@@ -58,6 +58,7 @@ const DialogContent = React.forwardRef<
|
|
|
58
58
|
<DialogOverlay />
|
|
59
59
|
<DialogPrimitive.Content
|
|
60
60
|
ref={ref}
|
|
61
|
+
aria-describedby={undefined}
|
|
61
62
|
className={cn(
|
|
62
63
|
"fixed z-600 bg-background duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
63
64
|
fullscreen
|
|
@@ -68,7 +69,6 @@ const DialogContent = React.forwardRef<
|
|
|
68
69
|
{...props}
|
|
69
70
|
>
|
|
70
71
|
{children}
|
|
71
|
-
<DialogPrimitive.Description className="sr-only" />
|
|
72
72
|
{closeButton === undefined ? (
|
|
73
73
|
<DialogPrimitive.Close className="absolute right-4 top-4 cursor-pointer rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
|
|
74
74
|
<Cross2Icon className="h-4 w-4" />
|
|
@@ -109,6 +109,7 @@ const SidePanelContent = React.forwardRef<
|
|
|
109
109
|
<DrawerPrimitive.Portal>
|
|
110
110
|
<DrawerPrimitive.Content
|
|
111
111
|
ref={ref}
|
|
112
|
+
aria-describedby={undefined}
|
|
112
113
|
className={cn(
|
|
113
114
|
'fixed z-500 flex flex-col bg-background shadow-2xl shadow-black/20',
|
|
114
115
|
'h-full max-w-[95vw]',
|
|
@@ -19,6 +19,7 @@ const TooltipContent = React.forwardRef<
|
|
|
19
19
|
<TooltipPrimitive.Portal>
|
|
20
20
|
<TooltipPrimitive.Content
|
|
21
21
|
ref={ref}
|
|
22
|
+
aria-describedby={undefined}
|
|
22
23
|
sideOffset={sideOffset}
|
|
23
24
|
className={cn(
|
|
24
25
|
"z-[700] overflow-hidden rounded-md border border-border bg-popover px-3 py-1.5 text-xs text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
@@ -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
|
|