@linzjs/windows 3.4.3 → 3.5.0
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/dist/panel/Panel.scss
CHANGED
package/dist/panel/Panel.tsx
CHANGED
|
@@ -7,7 +7,16 @@ import { PanelInstanceContext, PanelSize } from "./PanelInstanceContext";
|
|
|
7
7
|
import { PanelPosition, PanelsContext } from "./PanelsContext";
|
|
8
8
|
import { PopoutWindow } from "./PopoutWindow";
|
|
9
9
|
import clsx from "clsx";
|
|
10
|
-
import React, {
|
|
10
|
+
import React, {
|
|
11
|
+
PropsWithChildren,
|
|
12
|
+
ReactElement,
|
|
13
|
+
ReactNode,
|
|
14
|
+
useCallback,
|
|
15
|
+
useContext,
|
|
16
|
+
useEffect,
|
|
17
|
+
useRef,
|
|
18
|
+
useState,
|
|
19
|
+
} from "react";
|
|
11
20
|
import { createPortal } from "react-dom";
|
|
12
21
|
import { Rnd } from "react-rnd";
|
|
13
22
|
|
|
@@ -17,16 +26,16 @@ export interface PanelProps {
|
|
|
17
26
|
size?: PanelSize;
|
|
18
27
|
className?: string;
|
|
19
28
|
children: ReactNode;
|
|
20
|
-
maxHeight?: number;
|
|
21
|
-
maxWidth?: number;
|
|
22
|
-
minHeight?: number;
|
|
23
|
-
minWidth?: number;
|
|
29
|
+
maxHeight?: number | string;
|
|
30
|
+
maxWidth?: number | string;
|
|
31
|
+
minHeight?: number | string;
|
|
32
|
+
minWidth?: number | string;
|
|
24
33
|
modal?: boolean;
|
|
34
|
+
resizeable?: boolean;
|
|
25
35
|
}
|
|
26
36
|
|
|
27
37
|
export const Panel = ({
|
|
28
38
|
title,
|
|
29
|
-
position = "tile",
|
|
30
39
|
size = { width: 320, height: 200 },
|
|
31
40
|
maxHeight,
|
|
32
41
|
maxWidth,
|
|
@@ -34,8 +43,12 @@ export const Panel = ({
|
|
|
34
43
|
minWidth = 100,
|
|
35
44
|
modal,
|
|
36
45
|
className,
|
|
46
|
+
position = modal ? "center" : "tile",
|
|
47
|
+
resizeable = modal !== true,
|
|
37
48
|
children,
|
|
38
49
|
}: PanelProps): ReactElement => {
|
|
50
|
+
const panelRef = useRef<Rnd>(null);
|
|
51
|
+
|
|
39
52
|
const { nextStackPosition, dockElements } = useContext(PanelsContext);
|
|
40
53
|
const { panelPoppedOut, bounds, zIndex, bringPanelToFront, uniqueId, setTitle, dockId, docked } =
|
|
41
54
|
useContext(PanelInstanceContext);
|
|
@@ -44,8 +57,8 @@ export const Panel = ({
|
|
|
44
57
|
switch (position) {
|
|
45
58
|
case "center":
|
|
46
59
|
return {
|
|
47
|
-
x: (window.innerWidth - size.width) / 2,
|
|
48
|
-
y: (window.innerHeight - size.height) / 2,
|
|
60
|
+
x: Math.max((window.innerWidth - size.width) / 2, 0),
|
|
61
|
+
y: Math.max((window.innerHeight - size.height) / 2, 0),
|
|
49
62
|
};
|
|
50
63
|
case "tile":
|
|
51
64
|
return nextStackPosition();
|
|
@@ -54,6 +67,24 @@ export const Panel = ({
|
|
|
54
67
|
}
|
|
55
68
|
});
|
|
56
69
|
|
|
70
|
+
const centerWindow = useCallback(() => {
|
|
71
|
+
const b = panelRef.current?.getSelfElement()?.getBoundingClientRect();
|
|
72
|
+
setPanelPosition({
|
|
73
|
+
x: Math.max((window.innerWidth - (b?.width ?? size.width)) / 2, 0),
|
|
74
|
+
y: Math.max((window.innerHeight - (b?.height ?? size.height)) / 2, 0),
|
|
75
|
+
});
|
|
76
|
+
}, [size]);
|
|
77
|
+
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
if (!panelPoppedOut && position === "center" && !resizeable) {
|
|
80
|
+
centerWindow();
|
|
81
|
+
|
|
82
|
+
window.addEventListener("resize", centerWindow);
|
|
83
|
+
return () => window.removeEventListener("resize", centerWindow);
|
|
84
|
+
}
|
|
85
|
+
return;
|
|
86
|
+
}, [centerWindow, panelPoppedOut, position, resizeable]);
|
|
87
|
+
|
|
57
88
|
const [panelSize, setPanelSize] = useState(size ?? { width: 320, height: 200 });
|
|
58
89
|
|
|
59
90
|
const resizePanel = (newPanelSize: Partial<PanelSize>) => {
|
|
@@ -71,7 +102,7 @@ export const Panel = ({
|
|
|
71
102
|
const dockElement = docked && dockId && dockElements[dockId];
|
|
72
103
|
|
|
73
104
|
return (
|
|
74
|
-
<PanelContext.Provider value={{ resizePanel }}>
|
|
105
|
+
<PanelContext.Provider value={{ resizePanel, resizeable }}>
|
|
75
106
|
{dockElement && dockElement.isConnected ? (
|
|
76
107
|
createPortal(children, dockElement)
|
|
77
108
|
) : panelPoppedOut ? (
|
|
@@ -104,6 +135,7 @@ export const Panel = ({
|
|
|
104
135
|
/>
|
|
105
136
|
)}
|
|
106
137
|
<Rnd
|
|
138
|
+
ref={panelRef}
|
|
107
139
|
className={clsx("WindowPanel", className)}
|
|
108
140
|
dragHandleClassName={"draggable-handle"}
|
|
109
141
|
maxHeight={maxHeight}
|
|
@@ -113,6 +145,8 @@ export const Panel = ({
|
|
|
113
145
|
position={panelPosition}
|
|
114
146
|
size={panelSize}
|
|
115
147
|
style={{ zIndex }}
|
|
148
|
+
disableDragging={!resizeable}
|
|
149
|
+
enableResizing={resizeable}
|
|
116
150
|
bounds={bounds ?? document.body}
|
|
117
151
|
onDragStop={(_evt, data) => {
|
|
118
152
|
setPanelPosition({ x: data.x, y: data.y });
|
|
@@ -143,6 +177,10 @@ export const Panel = ({
|
|
|
143
177
|
);
|
|
144
178
|
};
|
|
145
179
|
|
|
146
|
-
export
|
|
147
|
-
|
|
180
|
+
export interface PanelContentProps {
|
|
181
|
+
className?: string | undefined;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export const PanelContent = ({ children, className }: PropsWithChildren<PanelContentProps>) => (
|
|
185
|
+
<div className={clsx(`WindowPanel-content`, className)}>{children}</div>
|
|
148
186
|
);
|
|
@@ -3,6 +3,7 @@ import { createContext } from "react";
|
|
|
3
3
|
|
|
4
4
|
export interface PanelContextType {
|
|
5
5
|
resizePanel: (size: Partial<PanelSize>) => void;
|
|
6
|
+
resizeable: boolean;
|
|
6
7
|
}
|
|
7
8
|
|
|
8
9
|
const NoContextError = () => {
|
|
@@ -14,4 +15,5 @@ const NoContextError = () => {
|
|
|
14
15
|
*/
|
|
15
16
|
export const PanelContext = createContext<PanelContextType>({
|
|
16
17
|
resizePanel: NoContextError,
|
|
18
|
+
resizeable: true,
|
|
17
19
|
});
|
|
@@ -4,6 +4,8 @@ import { ReactNode, useContext, useState } from "react";
|
|
|
4
4
|
|
|
5
5
|
import { LuiIcon } from "@linzjs/lui";
|
|
6
6
|
import { LuiIconName } from "@linzjs/lui/dist/assets/svg-content";
|
|
7
|
+
import { PanelContext } from "./PanelContext";
|
|
8
|
+
import clsx from "clsx";
|
|
7
9
|
|
|
8
10
|
export interface PanelHeaderProps {
|
|
9
11
|
icon?: LuiIconName;
|
|
@@ -26,6 +28,7 @@ export const PanelHeader = ({
|
|
|
26
28
|
disableClose,
|
|
27
29
|
disablePopout,
|
|
28
30
|
}: PanelHeaderProps) => {
|
|
31
|
+
const { resizeable } = useContext(PanelContext);
|
|
29
32
|
const { panelClose, panelTogglePopout, panelPoppedOut, title, dock, undock, docked } =
|
|
30
33
|
useContext(PanelInstanceContext);
|
|
31
34
|
const [cursor, setCursor] = useState<"grab" | "grabbing">("grab");
|
|
@@ -36,10 +39,10 @@ export const PanelHeader = ({
|
|
|
36
39
|
|
|
37
40
|
return (
|
|
38
41
|
<div
|
|
39
|
-
className={"WindowPanel-header draggable-handle"}
|
|
42
|
+
className={clsx("WindowPanel-header", resizeable && "draggable-handle")}
|
|
40
43
|
onMouseDown={headerMouseDown}
|
|
41
44
|
onMouseUp={() => !panelPoppedOut && setCursor("grab")}
|
|
42
|
-
style={{ cursor }}
|
|
45
|
+
style={resizeable ? { cursor } : {}}
|
|
43
46
|
>
|
|
44
47
|
<div className={"WindowPanel-header-title"}>
|
|
45
48
|
{icon && <LuiIcon name={icon} alt={"icon"} size={"md"} className={"WindowPanel-header-title-icon"} />}
|