@linzjs/windows 1.1.2 → 1.3.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/package.json +1 -1
- package/src/modal/PrefabModal.tsx +56 -18
- package/src/panel/Panel.scss +11 -3
- package/src/panel/Panel.tsx +21 -7
- package/src/panel/PanelDock.tsx +19 -0
- package/src/panel/PanelInstanceContext.ts +8 -0
- package/src/panel/PanelInstanceContextProvider.tsx +25 -6
- package/src/panel/PanelsContext.tsx +4 -2
- package/src/panel/PanelsContextProvider.tsx +13 -12
- package/src/stories/modal/PrefabModal.tsx +17 -0
- package/src/stories/panel/ShowPanel/ShowPanel.tsx +29 -30
- package/src/stories/panel/ShowPanelDocking/ShowPanel.mdx +20 -0
- package/src/stories/panel/ShowPanelDocking/ShowPanel.stories.tsx +27 -0
- package/src/stories/panel/ShowPanelDocking/ShowPanel.tsx +63 -0
- package/src/stories/panel/ShowPanelDocking/showPanel.scss +9 -0
- package/src/stories/panel/ShowPanelResizingAgGrid/ShowPanelResizingAgGrid.mdx +1 -1
package/package.json
CHANGED
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
import { Modal } from "./Modal";
|
|
2
2
|
import { ModalCallback } from "./ModalContext";
|
|
3
3
|
import { useShowModal } from "./useShowModal";
|
|
4
|
+
import { isEmpty } from "lodash-es";
|
|
4
5
|
import { ReactElement } from "react";
|
|
5
6
|
|
|
6
7
|
import { LuiAlertModalButtons, LuiButton, LuiIcon } from "@linzjs/lui";
|
|
8
|
+
import { LuiButtonProps } from "@linzjs/lui/dist/components/LuiButton/LuiButton";
|
|
7
9
|
import { IconName } from "@linzjs/lui/dist/components/LuiIcon/LuiIcon";
|
|
8
10
|
|
|
9
11
|
export type WarningLevel = "success" | "info" | "warning" | "error";
|
|
10
12
|
|
|
11
|
-
export interface
|
|
13
|
+
export interface PrefabButton<RT> {
|
|
14
|
+
default?: boolean;
|
|
15
|
+
level?: LuiButtonProps["level"];
|
|
16
|
+
title: string;
|
|
17
|
+
value: RT;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface PrefabModalProps extends ModalCallback<string | null> {
|
|
12
21
|
level?: WarningLevel;
|
|
13
22
|
children: ReactElement;
|
|
23
|
+
buttons?: PrefabButton<any>[];
|
|
14
24
|
}
|
|
15
25
|
export const getIconForLevel = (level: "success" | "info" | "warning" | "error"): IconName => {
|
|
16
26
|
switch (level) {
|
|
@@ -25,20 +35,44 @@ export const getIconForLevel = (level: "success" | "info" | "warning" | "error")
|
|
|
25
35
|
}
|
|
26
36
|
};
|
|
27
37
|
|
|
28
|
-
export const PrefabModal = ({ level = "warning", children, resolve }: PrefabModalProps) => {
|
|
38
|
+
export const PrefabModal = ({ level = "warning", children, resolve, ...props }: PrefabModalProps) => {
|
|
29
39
|
const icon = getIconForLevel(level);
|
|
40
|
+
const buttons: PrefabButton<any>[] = props.buttons ?? [];
|
|
41
|
+
if (isEmpty(buttons)) {
|
|
42
|
+
if (level === "warning") {
|
|
43
|
+
buttons.push({
|
|
44
|
+
title: "Cancel",
|
|
45
|
+
value: null,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
buttons.push({
|
|
49
|
+
title: "Continue",
|
|
50
|
+
value: true,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
buttons.forEach((b, i) => {
|
|
55
|
+
if (!b.level) {
|
|
56
|
+
b.level = i === buttons.length - 1 ? "primary" : "secondary";
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
30
60
|
return (
|
|
31
61
|
<Modal>
|
|
32
62
|
<div className={`lui-modal lui-box-shadow lui-modal-${level}`} style={{ minWidth: 400 }}>
|
|
33
63
|
<LuiIcon name={icon} alt={"warning"} size={"lg"} className={"lui-msg-status-icon"} />
|
|
34
64
|
{children}
|
|
35
65
|
<LuiAlertModalButtons>
|
|
36
|
-
{
|
|
37
|
-
<LuiButton
|
|
38
|
-
|
|
66
|
+
{buttons.map((pf, i) => (
|
|
67
|
+
<LuiButton
|
|
68
|
+
key={i}
|
|
69
|
+
level={pf.level}
|
|
70
|
+
onClick={() => resolve(pf.value === undefined ? pf.title : pf.value)}
|
|
71
|
+
buttonProps={pf.default ? { "data-autofocus": true } : undefined}
|
|
72
|
+
>
|
|
73
|
+
{pf.title}
|
|
39
74
|
</LuiButton>
|
|
40
|
-
)}
|
|
41
|
-
<LuiButton onClick={() => resolve(true)}>Continue</LuiButton>
|
|
75
|
+
))}
|
|
42
76
|
</LuiAlertModalButtons>
|
|
43
77
|
</div>
|
|
44
78
|
</Modal>
|
|
@@ -49,17 +83,21 @@ export const usePrefabModal = () => {
|
|
|
49
83
|
const { showModal, modalOwnerRef } = useShowModal();
|
|
50
84
|
return {
|
|
51
85
|
modalOwnerRef,
|
|
52
|
-
showPrefabModal:
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return showModal(PrefabModal, {
|
|
86
|
+
showPrefabModal: <RT extends any = boolean>(
|
|
87
|
+
level: WarningLevel,
|
|
88
|
+
title: ReactElement | string,
|
|
89
|
+
content: ReactElement | string,
|
|
90
|
+
buttons?: PrefabButton<RT>[],
|
|
91
|
+
) =>
|
|
92
|
+
showModal(PrefabModal, {
|
|
60
93
|
level,
|
|
61
|
-
children
|
|
62
|
-
|
|
63
|
-
|
|
94
|
+
children: (
|
|
95
|
+
<>
|
|
96
|
+
{typeof title === "string" ? <h2>{title}</h2> : title}
|
|
97
|
+
{typeof content === "string" ? <p>{content}</p> : content}
|
|
98
|
+
</>
|
|
99
|
+
),
|
|
100
|
+
buttons,
|
|
101
|
+
}) as Promise<RT>,
|
|
64
102
|
};
|
|
65
103
|
};
|
package/src/panel/Panel.scss
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
.panelDock > .panelDock-content:not(:empty) + .panelDock-empty {
|
|
2
|
+
display: none;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.LuiFloatingWindow-children {
|
|
6
|
+
display: flex;
|
|
7
|
+
overflow: hidden;
|
|
8
|
+
text-overflow: ellipsis;
|
|
9
|
+
flex: 1;
|
|
10
|
+
}
|
|
11
|
+
|
|
1
12
|
.WindowPanel {
|
|
2
13
|
box-shadow: 0 1px 6px 0 #00000026, 0 6px 10px 0 #00000040;
|
|
3
14
|
background-color: #fff;
|
|
@@ -22,9 +33,6 @@
|
|
|
22
33
|
|
|
23
34
|
.WindowPanel-header-title {
|
|
24
35
|
white-space: nowrap;
|
|
25
|
-
overflow: hidden;
|
|
26
|
-
text-overflow: ellipsis;
|
|
27
|
-
flex: 1;
|
|
28
36
|
}
|
|
29
37
|
|
|
30
38
|
.WindowPanel-content {
|
package/src/panel/Panel.tsx
CHANGED
|
@@ -5,7 +5,8 @@ import { PanelContext } from "./PanelContext";
|
|
|
5
5
|
import { PanelInstanceContext, PanelSize } from "./PanelInstanceContext";
|
|
6
6
|
import { PanelPosition, PanelsContext } from "./PanelsContext";
|
|
7
7
|
import { PopoutWindow } from "./PopoutWindow";
|
|
8
|
-
import { ReactElement, ReactNode, useContext, useEffect, useState } from "react";
|
|
8
|
+
import { PropsWithChildren, ReactElement, ReactNode, useContext, useEffect, useState } from "react";
|
|
9
|
+
import ReactDOM from "react-dom";
|
|
9
10
|
import { Rnd } from "react-rnd";
|
|
10
11
|
|
|
11
12
|
import { LuiButton, LuiIcon } from "@linzjs/lui";
|
|
@@ -19,8 +20,9 @@ export interface PanelProps {
|
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
export const Panel = ({ title, position, size = { width: 320, height: 200 }, children }: PanelProps): ReactElement => {
|
|
22
|
-
const { nextStackPosition } = useContext(PanelsContext);
|
|
23
|
-
const { panelPoppedOut, bounds, zIndex, bringPanelToFront, uniqueId, setTitle } =
|
|
23
|
+
const { nextStackPosition, dockElements } = useContext(PanelsContext);
|
|
24
|
+
const { panelPoppedOut, bounds, zIndex, bringPanelToFront, uniqueId, setTitle, dockId, docked } =
|
|
25
|
+
useContext(PanelInstanceContext);
|
|
24
26
|
|
|
25
27
|
const [panelPosition, setPanelPosition] = useState(() => position ?? nextStackPosition());
|
|
26
28
|
const [panelSize, setPanelSize] = useState(size ?? { width: 320, height: 200 });
|
|
@@ -37,10 +39,13 @@ export const Panel = ({ title, position, size = { width: 320, height: 200 }, chi
|
|
|
37
39
|
setTitle(title);
|
|
38
40
|
}, [setTitle, title]);
|
|
39
41
|
|
|
40
|
-
|
|
42
|
+
const dockElement = docked && dockId && dockElements[dockId];
|
|
43
|
+
|
|
41
44
|
return (
|
|
42
45
|
<PanelContext.Provider value={{ resizePanel }}>
|
|
43
|
-
{
|
|
46
|
+
{dockElement && dockElement.isConnected ? (
|
|
47
|
+
ReactDOM.createPortal(children, dockElement)
|
|
48
|
+
) : panelPoppedOut ? (
|
|
44
49
|
<PopoutWindow name={uniqueId} title={title} size={panelSize}>
|
|
45
50
|
<div
|
|
46
51
|
style={{
|
|
@@ -113,10 +118,12 @@ export const PanelHeaderButton = ({ "aria-label": ariaLabel, icon, onClick }: Pa
|
|
|
113
118
|
|
|
114
119
|
export interface PanelHeaderProps {
|
|
115
120
|
extraButtons?: ReactNode;
|
|
121
|
+
dockTo?: string;
|
|
116
122
|
}
|
|
117
123
|
|
|
118
|
-
export const PanelHeader = ({ extraButtons }: PanelHeaderProps) => {
|
|
119
|
-
const { panelClose, panelTogglePopout, panelPoppedOut, title } =
|
|
124
|
+
export const PanelHeader = ({ extraButtons, dockTo, children }: PropsWithChildren<PanelHeaderProps>) => {
|
|
125
|
+
const { panelClose, panelTogglePopout, panelPoppedOut, title, dock, undock, docked } =
|
|
126
|
+
useContext(PanelInstanceContext);
|
|
120
127
|
const [cursor, setCursor] = useState<"grab" | "grabbing">("grab");
|
|
121
128
|
|
|
122
129
|
const headerMouseDown = () => {
|
|
@@ -131,9 +138,16 @@ export const PanelHeader = ({ extraButtons }: PanelHeaderProps) => {
|
|
|
131
138
|
style={{ cursor }}
|
|
132
139
|
>
|
|
133
140
|
<div className={"WindowPanel-header-title"}>{title}</div>
|
|
141
|
+
<div className={"LuiFloatingWindow-children"}>{children}</div>
|
|
134
142
|
<div className={"LuiFloatingWindow-buttons"}>{extraButtons}</div>
|
|
135
143
|
<div className={"LuiFloatingWindow-extra-buttons-divider"}>|</div>
|
|
136
144
|
<div className={"LuiFloatingWindow-buttons"}>
|
|
145
|
+
{dockTo &&
|
|
146
|
+
(docked ? (
|
|
147
|
+
<PanelHeaderButton aria-label={"Undock"} onClick={undock} icon={"ic_close_list"} />
|
|
148
|
+
) : (
|
|
149
|
+
<PanelHeaderButton aria-label={"Undock"} onClick={() => dock(dockTo)} icon={"ic_left_col"} />
|
|
150
|
+
))}
|
|
137
151
|
<PanelHeaderButton
|
|
138
152
|
aria-label={panelPoppedOut ? "Pop-in" : "Pop-out"}
|
|
139
153
|
onClick={panelTogglePopout}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { PanelsContext } from "./PanelsContext";
|
|
2
|
+
import { PropsWithChildren, ReactElement, useContext } from "react";
|
|
3
|
+
|
|
4
|
+
export interface PanelDockProps {
|
|
5
|
+
id: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const PanelDock = ({ id, children }: PropsWithChildren<PanelDockProps>): ReactElement => {
|
|
9
|
+
const { setDockElement } = useContext(PanelsContext);
|
|
10
|
+
|
|
11
|
+
const setElement = (element: HTMLDivElement) => setDockElement(id, element);
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<div className={"panelDock"}>
|
|
15
|
+
<div ref={setElement} className={"panelDock-content"} />
|
|
16
|
+
<div className={"panelDock-empty"}>{children}</div>
|
|
17
|
+
</div>
|
|
18
|
+
);
|
|
19
|
+
};
|
|
@@ -17,6 +17,10 @@ export interface PanelInstanceContextType {
|
|
|
17
17
|
bringPanelToFront: () => void;
|
|
18
18
|
panelPoppedOut: boolean;
|
|
19
19
|
zIndex: number;
|
|
20
|
+
dockId: string | undefined;
|
|
21
|
+
docked: boolean;
|
|
22
|
+
dock: (id: string) => void;
|
|
23
|
+
undock: () => void;
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
const NoContextError = () => {
|
|
@@ -36,6 +40,10 @@ export const PanelInstanceContext = createContext<PanelInstanceContextType>({
|
|
|
36
40
|
panelClose: NoContextError,
|
|
37
41
|
setPanelWindow: NoContextError,
|
|
38
42
|
bringPanelToFront: NoContextError,
|
|
43
|
+
dock: NoContextError,
|
|
44
|
+
undock: NoContextError,
|
|
45
|
+
docked: false,
|
|
46
|
+
dockId: undefined,
|
|
39
47
|
panelPoppedOut: false,
|
|
40
48
|
zIndex: 0,
|
|
41
49
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PanelInstanceContext } from "./PanelInstanceContext";
|
|
2
2
|
import { PanelInstance, PanelsContext } from "./PanelsContext";
|
|
3
|
-
import { ReactElement, ReactNode, useContext, useState } from "react";
|
|
3
|
+
import { ReactElement, ReactNode, useCallback, useContext, useState } from "react";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Provides access to closing/popping panels
|
|
@@ -14,8 +14,25 @@ export const PanelInstanceContextProvider = ({
|
|
|
14
14
|
panelInstance: PanelInstance;
|
|
15
15
|
children: ReactNode;
|
|
16
16
|
}): ReactElement => {
|
|
17
|
-
const { closePanel,
|
|
17
|
+
const { closePanel, bringPanelToFront } = useContext(PanelsContext);
|
|
18
18
|
const [title, setTitle] = useState("");
|
|
19
|
+
const [dockId, setDockId] = useState<string>();
|
|
20
|
+
const [poppedOut, setPoppedOut] = useState(false);
|
|
21
|
+
|
|
22
|
+
const togglePopOut = useCallback(() => {
|
|
23
|
+
panelInstance.window = null;
|
|
24
|
+
setPoppedOut(!poppedOut);
|
|
25
|
+
}, [panelInstance, poppedOut]);
|
|
26
|
+
|
|
27
|
+
const dock = useCallback(
|
|
28
|
+
(id: string) => {
|
|
29
|
+
if (poppedOut) togglePopOut();
|
|
30
|
+
setDockId(id);
|
|
31
|
+
},
|
|
32
|
+
[poppedOut, togglePopOut],
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
const undock = useCallback(() => setDockId(undefined), []);
|
|
19
36
|
|
|
20
37
|
return (
|
|
21
38
|
<PanelInstanceContext.Provider
|
|
@@ -30,15 +47,17 @@ export const PanelInstanceContextProvider = ({
|
|
|
30
47
|
panelInstance.window = null;
|
|
31
48
|
closePanel(panelInstance);
|
|
32
49
|
},
|
|
33
|
-
panelTogglePopout:
|
|
34
|
-
|
|
35
|
-
},
|
|
36
|
-
panelPoppedOut: panelInstance.poppedOut,
|
|
50
|
+
panelTogglePopout: togglePopOut,
|
|
51
|
+
panelPoppedOut: poppedOut,
|
|
37
52
|
setPanelWindow: (w: Window) => {
|
|
38
53
|
panelInstance.window = w;
|
|
39
54
|
},
|
|
40
55
|
bringPanelToFront: () => bringPanelToFront(panelInstance),
|
|
41
56
|
zIndex: panelInstance.zIndex,
|
|
57
|
+
docked: !poppedOut && !!dockId,
|
|
58
|
+
dockId,
|
|
59
|
+
dock,
|
|
60
|
+
undock,
|
|
42
61
|
}}
|
|
43
62
|
>
|
|
44
63
|
{children}
|
|
@@ -17,9 +17,10 @@ export interface PanelsContextType {
|
|
|
17
17
|
openPanels: Set<string>;
|
|
18
18
|
openPanel: (uniqueId: string, component: () => ReactElement) => void;
|
|
19
19
|
closePanel: (panelInstance: PanelInstance) => void;
|
|
20
|
-
togglePopOut: (panelInstance: PanelInstance) => void;
|
|
21
20
|
bringPanelToFront: (panelInstance: PanelInstance) => void;
|
|
22
21
|
nextStackPosition: () => PanelPosition;
|
|
22
|
+
dockElements: Record<string, HTMLDivElement>;
|
|
23
|
+
setDockElement: (id: string, element: HTMLDivElement) => void;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
const NoContext = () => {
|
|
@@ -30,7 +31,8 @@ export const PanelsContext = createContext<PanelsContextType>({
|
|
|
30
31
|
openPanels: new Set(),
|
|
31
32
|
openPanel: NoContext,
|
|
32
33
|
closePanel: NoContext,
|
|
33
|
-
togglePopOut: NoContext,
|
|
34
34
|
bringPanelToFront: NoContext,
|
|
35
|
+
dockElements: {},
|
|
36
|
+
setDockElement: NoContext,
|
|
35
37
|
nextStackPosition: () => ({ x: 0, y: 0 }),
|
|
36
38
|
});
|
|
@@ -25,6 +25,17 @@ export const PanelsContextProvider = ({
|
|
|
25
25
|
// Can't use a map here as we need to retain render order for performance
|
|
26
26
|
const [panelInstances, setPanelInstances] = useState<PanelInstance[]>([]);
|
|
27
27
|
|
|
28
|
+
const [dockElements, setDockElements] = useState<Record<string, HTMLDivElement>>({});
|
|
29
|
+
|
|
30
|
+
const setDockElement = useCallback(
|
|
31
|
+
(id: string, element: HTMLDivElement) => {
|
|
32
|
+
if (dockElements[id] !== element) {
|
|
33
|
+
setDockElements({ ...dockElements, [id]: element });
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
[dockElements],
|
|
37
|
+
);
|
|
38
|
+
|
|
28
39
|
const bringPanelToFront = useCallback(
|
|
29
40
|
(panelInstance: PanelInstance) => {
|
|
30
41
|
if (panelInstance.window) {
|
|
@@ -82,17 +93,6 @@ export const PanelsContextProvider = ({
|
|
|
82
93
|
[panelInstances],
|
|
83
94
|
);
|
|
84
95
|
|
|
85
|
-
const togglePopOut = useCallback(
|
|
86
|
-
(panelInstance: PanelInstance) => {
|
|
87
|
-
panelInstance.poppedOut = !panelInstance.poppedOut;
|
|
88
|
-
if (!panelInstance.poppedOut) {
|
|
89
|
-
panelInstance.window = null;
|
|
90
|
-
}
|
|
91
|
-
setPanelInstances([...panelInstances]);
|
|
92
|
-
},
|
|
93
|
-
[panelInstances],
|
|
94
|
-
);
|
|
95
|
-
|
|
96
96
|
/**
|
|
97
97
|
* It's not easy to tell the difference between a window closing and a window popping in via events,
|
|
98
98
|
* so we're periodically checking instead.
|
|
@@ -122,9 +122,10 @@ export const PanelsContextProvider = ({
|
|
|
122
122
|
openPanels,
|
|
123
123
|
openPanel,
|
|
124
124
|
closePanel,
|
|
125
|
-
togglePopOut,
|
|
126
125
|
bringPanelToFront,
|
|
127
126
|
nextStackPosition,
|
|
127
|
+
dockElements,
|
|
128
|
+
setDockElement,
|
|
128
129
|
}}
|
|
129
130
|
>
|
|
130
131
|
<Fragment key={"panels"}>
|
|
@@ -20,6 +20,7 @@ export const PrefabModalUsage = () => {
|
|
|
20
20
|
// Remember to add the modalOwnerRef!
|
|
21
21
|
return (
|
|
22
22
|
<div ref={modalOwnerRef} style={{ display: "flex", gap: 10 }}>
|
|
23
|
+
{/* Warning */}
|
|
23
24
|
<button
|
|
24
25
|
onClick={async () =>
|
|
25
26
|
alert(
|
|
@@ -34,15 +35,31 @@ export const PrefabModalUsage = () => {
|
|
|
34
35
|
>
|
|
35
36
|
Warning Prefab-Modal
|
|
36
37
|
</button>
|
|
38
|
+
{/* Info */}
|
|
37
39
|
<button onClick={() => showPrefabModal("info", "You are a fantastic person", "Keep it up!")}>
|
|
38
40
|
Info Prefab-Modal
|
|
39
41
|
</button>
|
|
42
|
+
{/* Error */}
|
|
40
43
|
<button onClick={() => showPrefabModal("error", "Something is not right", "Maybe stop doing that")}>
|
|
41
44
|
Error Prefab-Modal
|
|
42
45
|
</button>
|
|
46
|
+
{/* Success */}
|
|
43
47
|
<button onClick={() => showPrefabModal("success", "You are a success", "Keep succeeding!")}>
|
|
44
48
|
Success Prefab-Modal
|
|
45
49
|
</button>
|
|
50
|
+
{/* Custom */}
|
|
51
|
+
<button
|
|
52
|
+
onClick={async () => {
|
|
53
|
+
const result = await showPrefabModal("success", "Custom buttons", <b>Custom buttons are customary!</b>, [
|
|
54
|
+
{ value: null, title: "Nope" },
|
|
55
|
+
{ value: "barple", title: "Barple" },
|
|
56
|
+
{ value: "floople", title: "Floople", default: true },
|
|
57
|
+
]);
|
|
58
|
+
alert(result);
|
|
59
|
+
}}
|
|
60
|
+
>
|
|
61
|
+
Custom buttons
|
|
62
|
+
</button>
|
|
46
63
|
</div>
|
|
47
64
|
);
|
|
48
65
|
};
|
|
@@ -27,36 +27,35 @@ export const ShowPanelComponent = ({ data }: ShowPanelComponentProps) => (
|
|
|
27
27
|
);
|
|
28
28
|
|
|
29
29
|
/* exclude */
|
|
30
|
-
export const PanelContents = () =>
|
|
31
|
-
|
|
32
|
-
<
|
|
33
|
-
<
|
|
34
|
-
<
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
<
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
<
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
<
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
};
|
|
30
|
+
export const PanelContents = () => (
|
|
31
|
+
<table>
|
|
32
|
+
<thead>
|
|
33
|
+
<tr>
|
|
34
|
+
<th>Owner</th>
|
|
35
|
+
<th>Title</th>
|
|
36
|
+
<th>Address</th>
|
|
37
|
+
</tr>
|
|
38
|
+
</thead>
|
|
39
|
+
<tbody>
|
|
40
|
+
<tr>
|
|
41
|
+
<td>Roy</td>
|
|
42
|
+
<td>OT10A/1011</td>
|
|
43
|
+
<td>5 Grange St, Auckland</td>
|
|
44
|
+
</tr>
|
|
45
|
+
<tr>
|
|
46
|
+
<td>Ryan</td>
|
|
47
|
+
<td>OT10A/154</td>
|
|
48
|
+
<td>145 Garry St, Wellington</td>
|
|
49
|
+
</tr>
|
|
50
|
+
<tr>
|
|
51
|
+
<td>Suzy</td>
|
|
52
|
+
<td>OT10A/155</td>
|
|
53
|
+
<td>15 Aix St, Auckland</td>
|
|
54
|
+
</tr>
|
|
55
|
+
</tbody>
|
|
56
|
+
</table>
|
|
57
|
+
);
|
|
58
|
+
|
|
60
59
|
/* exclude */
|
|
61
60
|
|
|
62
61
|
// #Example: Panel Invocation
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {getBlocks, blockToString} from "../../support.js";
|
|
2
|
+
import {Meta, Source, Story} from "@storybook/blocks";
|
|
3
|
+
import * as ShowPanelStories from "./ShowPanel.stories.tsx"
|
|
4
|
+
|
|
5
|
+
import myModule from './ShowPanel.tsx?raw';
|
|
6
|
+
|
|
7
|
+
<Meta name="Docking Panel" of={ShowPanelStories}/>
|
|
8
|
+
# Panel Docking
|
|
9
|
+
## Example
|
|
10
|
+
Click to show the panel:
|
|
11
|
+
<Story of={ShowPanelStories.ShowPanelDocking}/>
|
|
12
|
+
|
|
13
|
+
## Code
|
|
14
|
+
<br/>
|
|
15
|
+
{getBlocks(myModule).map(block => (
|
|
16
|
+
<>
|
|
17
|
+
<h3>{block.split("\n")[0]}</h3>
|
|
18
|
+
<Source code={blockToString(block)} language='typescript'/>
|
|
19
|
+
</>
|
|
20
|
+
))}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { PanelsContextProvider } from "../../../panel/PanelsContextProvider";
|
|
2
|
+
import { TestShowPanel } from "./ShowPanel";
|
|
3
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof TestShowPanel> = {
|
|
6
|
+
title: "Components/Panel",
|
|
7
|
+
component: TestShowPanel,
|
|
8
|
+
argTypes: {
|
|
9
|
+
backgroundColor: { control: "color" },
|
|
10
|
+
},
|
|
11
|
+
decorators: [
|
|
12
|
+
(Story: any) => (
|
|
13
|
+
<div>
|
|
14
|
+
<PanelsContextProvider baseZIndex={500}>
|
|
15
|
+
<Story />
|
|
16
|
+
</PanelsContextProvider>
|
|
17
|
+
</div>
|
|
18
|
+
),
|
|
19
|
+
],
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default meta;
|
|
23
|
+
type Story = StoryObj<typeof meta>;
|
|
24
|
+
|
|
25
|
+
export const ShowPanelDocking: Story = {
|
|
26
|
+
args: {},
|
|
27
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import "./showPanel.scss";
|
|
2
|
+
import "@linzjs/lui/dist/scss/base.scss";
|
|
3
|
+
|
|
4
|
+
import { OpenPanelButton } from "../../../panel/OpenPanelButton";
|
|
5
|
+
import { Panel, PanelContent, PanelHeader } from "../../../panel/Panel";
|
|
6
|
+
import { PanelDock } from "../../../panel/PanelDock";
|
|
7
|
+
|
|
8
|
+
// #Example: Panel Component
|
|
9
|
+
export interface ShowPanelComponentProps {
|
|
10
|
+
data: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const ShowPanelComponent = ({ data }: ShowPanelComponentProps) => (
|
|
14
|
+
<Panel title={`Panel demo ${data}`} size={{ width: 640, height: 400 }}>
|
|
15
|
+
<PanelHeader dockTo={"leftSide"} />
|
|
16
|
+
<PanelContent>
|
|
17
|
+
<PanelContents />
|
|
18
|
+
</PanelContent>
|
|
19
|
+
</Panel>
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
/* exclude */
|
|
23
|
+
export const PanelContents = () => {
|
|
24
|
+
return (
|
|
25
|
+
<table>
|
|
26
|
+
<thead>
|
|
27
|
+
<tr>
|
|
28
|
+
<th>Owner</th>
|
|
29
|
+
<th>Title</th>
|
|
30
|
+
<th>Address</th>
|
|
31
|
+
</tr>
|
|
32
|
+
</thead>
|
|
33
|
+
<tbody>
|
|
34
|
+
<tr>
|
|
35
|
+
<td>Roy</td>
|
|
36
|
+
<td>OT10A/1011</td>
|
|
37
|
+
<td>5 Grange St, Auckland</td>
|
|
38
|
+
</tr>
|
|
39
|
+
<tr>
|
|
40
|
+
<td>Ryan</td>
|
|
41
|
+
<td>OT10A/154</td>
|
|
42
|
+
<td>145 Garry St, Wellington</td>
|
|
43
|
+
</tr>
|
|
44
|
+
<tr>
|
|
45
|
+
<td>Suzy</td>
|
|
46
|
+
<td>OT10A/155</td>
|
|
47
|
+
<td>15 Aix St, Auckland</td>
|
|
48
|
+
</tr>
|
|
49
|
+
</tbody>
|
|
50
|
+
</table>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
/* exclude */
|
|
54
|
+
|
|
55
|
+
// #Example: Panel Invocation
|
|
56
|
+
export const TestShowPanel = () => {
|
|
57
|
+
return (
|
|
58
|
+
<>
|
|
59
|
+
<OpenPanelButton buttonText={"TestPanel"} component={() => <ShowPanelComponent data={1} />} />
|
|
60
|
+
<PanelDock id={"leftSide"}>The Panel will dock in here</PanelDock>
|
|
61
|
+
</>
|
|
62
|
+
);
|
|
63
|
+
};
|
|
@@ -4,7 +4,7 @@ import * as PanelStories from "./ShowPanelResizingAgGrid.stories.tsx"
|
|
|
4
4
|
|
|
5
5
|
import myModule from './ShowPanelResizingStepAgGrid.tsx?raw';
|
|
6
6
|
|
|
7
|
-
<Meta name="
|
|
7
|
+
<Meta name="Resizing Panel step-ag-grid" of={PanelStories}/>
|
|
8
8
|
# Show Panel
|
|
9
9
|
## Example
|
|
10
10
|
Click to show the panel:
|