@linzjs/windows 8.0.0 → 8.2.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/OpenPanelButton.tsx +38 -5
- package/dist/panel/Panel.tsx +2 -1
- package/dist/panel/PanelInstanceContext.ts +2 -0
- package/dist/panel/PanelInstanceContextProvider.tsx +3 -0
- package/dist/panel/PanelsContext.tsx +10 -1
- package/dist/panel/PanelsContextProvider.tsx +55 -10
- package/dist/panel/PopinWIndow.tsx +3 -1
- package/package.json +1 -1
|
@@ -5,15 +5,48 @@ import { OpenPanelOptions, PanelsContext } from './PanelsContext';
|
|
|
5
5
|
|
|
6
6
|
interface OpenPanelButtonProps extends OpenPanelOptions {
|
|
7
7
|
uniqueId?: string;
|
|
8
|
+
testId?: string;
|
|
8
9
|
buttonText: string;
|
|
9
10
|
}
|
|
10
11
|
|
|
11
|
-
export const OpenPanelButton = ({
|
|
12
|
-
|
|
12
|
+
export const OpenPanelButton = ({
|
|
13
|
+
buttonText,
|
|
14
|
+
testId,
|
|
15
|
+
uniqueId = buttonText,
|
|
16
|
+
...openPanelOptions
|
|
17
|
+
}: OpenPanelButtonProps) => {
|
|
18
|
+
const { openPanel, closePanel, hidePanel, unhidePanel, hasOpenPanel, hasHiddenPanel } = useContext(PanelsContext);
|
|
13
19
|
|
|
20
|
+
const open = hasOpenPanel(uniqueId);
|
|
21
|
+
const hidden = hasHiddenPanel(uniqueId);
|
|
14
22
|
return (
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
|
|
23
|
+
<div>
|
|
24
|
+
<b>
|
|
25
|
+
{buttonText} {open ? '(Open)' : ''}
|
|
26
|
+
</b>
|
|
27
|
+
<br />
|
|
28
|
+
|
|
29
|
+
{!open && (
|
|
30
|
+
<button data-testid={testId + 'Open'} onClick={() => openPanel({ uniqueId, ...openPanelOptions })}>
|
|
31
|
+
Open
|
|
32
|
+
</button>
|
|
33
|
+
)}
|
|
34
|
+
{open && (
|
|
35
|
+
<>
|
|
36
|
+
<button data-testid={testId + 'Close'} onClick={() => closePanel(uniqueId)}>
|
|
37
|
+
Close
|
|
38
|
+
</button>
|
|
39
|
+
{hidden ? (
|
|
40
|
+
<button data-testid={testId + 'Unhide'} onClick={() => unhidePanel(uniqueId)}>
|
|
41
|
+
Unhide
|
|
42
|
+
</button>
|
|
43
|
+
) : (
|
|
44
|
+
<button data-testid={testId + 'Hide'} onClick={() => hidePanel(uniqueId)}>
|
|
45
|
+
Hide
|
|
46
|
+
</button>
|
|
47
|
+
)}
|
|
48
|
+
</>
|
|
49
|
+
)}
|
|
50
|
+
</div>
|
|
18
51
|
);
|
|
19
52
|
};
|
package/dist/panel/Panel.tsx
CHANGED
|
@@ -33,7 +33,7 @@ export const Panel = (props: PanelProps): ReactElement => {
|
|
|
33
33
|
const { title, size = defaultInitialSize, className, dynamicBounds, children } = props;
|
|
34
34
|
|
|
35
35
|
const { dockElements, nextStackPosition } = useContext(PanelsContext);
|
|
36
|
-
const { panelPoppedOut, uniqueId, setTitle, dockId, docked } = useContext(PanelInstanceContext);
|
|
36
|
+
const { panelPoppedOut, uniqueId, setTitle, dockId, docked, hidden } = useContext(PanelInstanceContext);
|
|
37
37
|
|
|
38
38
|
const savedState = useRestoreStateFrom({ uniqueId, panelPoppedOut: false });
|
|
39
39
|
|
|
@@ -188,6 +188,7 @@ export const Panel = (props: PanelProps): ReactElement => {
|
|
|
188
188
|
panelSize={panelSize}
|
|
189
189
|
setPanelSize={setPanelSize}
|
|
190
190
|
setInitialPanelSize={setInitialPanelSize}
|
|
191
|
+
hidden={hidden}
|
|
191
192
|
>
|
|
192
193
|
{children}
|
|
193
194
|
</PopinWindow>
|
|
@@ -16,6 +16,7 @@ export interface PanelInstanceContextType {
|
|
|
16
16
|
docked: boolean;
|
|
17
17
|
dock: (id: string) => void;
|
|
18
18
|
undock: () => void;
|
|
19
|
+
hidden: boolean;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
const NoContextError = () => {
|
|
@@ -41,4 +42,5 @@ export const PanelInstanceContext = createContext<PanelInstanceContextType>({
|
|
|
41
42
|
dockId: undefined,
|
|
42
43
|
panelPoppedOut: false,
|
|
43
44
|
zIndex: 0,
|
|
45
|
+
hidden: false,
|
|
44
46
|
});
|
|
@@ -10,8 +10,10 @@ import { useRestoreStateFrom } from './usePanelStateHandler';
|
|
|
10
10
|
export const PanelInstanceContextProvider = ({
|
|
11
11
|
panelInstance,
|
|
12
12
|
bounds,
|
|
13
|
+
hidden,
|
|
13
14
|
children,
|
|
14
15
|
}: PropsWithChildren<{
|
|
16
|
+
hidden: boolean;
|
|
15
17
|
bounds: string | Element | undefined;
|
|
16
18
|
panelInstance: PanelInstance;
|
|
17
19
|
}>): ReactElement => {
|
|
@@ -63,6 +65,7 @@ export const PanelInstanceContextProvider = ({
|
|
|
63
65
|
dockId,
|
|
64
66
|
dock,
|
|
65
67
|
undock,
|
|
68
|
+
hidden,
|
|
66
69
|
}}
|
|
67
70
|
>
|
|
68
71
|
{children}
|
|
@@ -10,6 +10,7 @@ export interface PanelInstance {
|
|
|
10
10
|
poppedOut: boolean;
|
|
11
11
|
window: Window | null;
|
|
12
12
|
onClose?: () => void;
|
|
13
|
+
hidden: boolean;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
export interface OpenPanelOptions {
|
|
@@ -21,9 +22,13 @@ export interface OpenPanelOptions {
|
|
|
21
22
|
|
|
22
23
|
export interface PanelsContextType {
|
|
23
24
|
openPanels: Set<string>;
|
|
25
|
+
hasOpenPanel: (panelId: string) => boolean;
|
|
24
26
|
// returns unique id of panel that was created/or arleady found, otherwise null on error.
|
|
25
27
|
openPanel: (args: OpenPanelOptions) => string | null;
|
|
26
|
-
closePanel: (uniqueId: string) => void;
|
|
28
|
+
closePanel: (uniqueId: string | string[]) => void;
|
|
29
|
+
hidePanel: (uniqueId: string | string[]) => void;
|
|
30
|
+
unhidePanel: (uniqueId: string | string[]) => void;
|
|
31
|
+
hasHiddenPanel: (uniqueId: string) => boolean;
|
|
27
32
|
bringPanelToFront: (panelUniqueId: string) => void;
|
|
28
33
|
nextStackPosition: () => PanelPosition;
|
|
29
34
|
dockElements: Record<string, HTMLDivElement>;
|
|
@@ -38,8 +43,12 @@ const NoContext = <T,>(): T => {
|
|
|
38
43
|
|
|
39
44
|
export const PanelsContext = createContext<PanelsContextType>({
|
|
40
45
|
openPanels: new Set(),
|
|
46
|
+
hasOpenPanel: () => false,
|
|
41
47
|
openPanel: NoContext,
|
|
42
48
|
closePanel: NoContext,
|
|
49
|
+
hidePanel: NoContext,
|
|
50
|
+
unhidePanel: NoContext,
|
|
51
|
+
hasHiddenPanel: NoContext,
|
|
43
52
|
bringPanelToFront: NoContext,
|
|
44
53
|
dockElements: {},
|
|
45
54
|
setDockElement: NoContext,
|
|
@@ -71,6 +71,36 @@ export const PanelsContextProvider = ({
|
|
|
71
71
|
[baseZIndex, panelInstances],
|
|
72
72
|
);
|
|
73
73
|
|
|
74
|
+
const showHidePanel = useCallback((hidePanelIds: string | string[], hidden: boolean) => {
|
|
75
|
+
setPanelInstances((panelInstances) => {
|
|
76
|
+
const panelIds = castArray(hidePanelIds);
|
|
77
|
+
return panelInstances.map((pi) => {
|
|
78
|
+
return panelIds.includes(pi.uniqueId) && pi.hidden !== hidden ? { ...pi, hidden } : pi;
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
}, []);
|
|
82
|
+
|
|
83
|
+
const hidePanel = useCallback(
|
|
84
|
+
(hidePanelIds: string | string[]) => {
|
|
85
|
+
showHidePanel(hidePanelIds, true);
|
|
86
|
+
},
|
|
87
|
+
[showHidePanel],
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
const unhidePanel = useCallback(
|
|
91
|
+
(hidePanelIds: string | string[]) => {
|
|
92
|
+
showHidePanel(hidePanelIds, false);
|
|
93
|
+
},
|
|
94
|
+
[showHidePanel],
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
const hasHiddenPanel = useCallback(
|
|
98
|
+
(panelId: string) => {
|
|
99
|
+
return panelInstances.find((pi) => pi.uniqueId === panelId)?.hidden === true;
|
|
100
|
+
},
|
|
101
|
+
[panelInstances],
|
|
102
|
+
);
|
|
103
|
+
|
|
74
104
|
const openPanel = useCallback(
|
|
75
105
|
({ componentFn, poppedOut = false, uniqueId = v4(), onClose }: OpenPanelOptions): string | null => {
|
|
76
106
|
try {
|
|
@@ -79,6 +109,9 @@ export const PanelsContextProvider = ({
|
|
|
79
109
|
if (existingPanelInstance.window) {
|
|
80
110
|
existingPanelInstance.window?.focus();
|
|
81
111
|
} else {
|
|
112
|
+
if (existingPanelInstance.hidden) {
|
|
113
|
+
unhidePanel(uniqueId);
|
|
114
|
+
}
|
|
82
115
|
bringPanelToFront(uniqueId);
|
|
83
116
|
}
|
|
84
117
|
return existingPanelInstance.uniqueId;
|
|
@@ -94,6 +127,7 @@ export const PanelsContextProvider = ({
|
|
|
94
127
|
poppedOut,
|
|
95
128
|
window: null,
|
|
96
129
|
onClose,
|
|
130
|
+
hidden: false,
|
|
97
131
|
},
|
|
98
132
|
]);
|
|
99
133
|
return uniqueId;
|
|
@@ -102,24 +136,24 @@ export const PanelsContextProvider = ({
|
|
|
102
136
|
return null;
|
|
103
137
|
}
|
|
104
138
|
},
|
|
105
|
-
[baseZIndex, bringPanelToFront, panelInstances],
|
|
139
|
+
[baseZIndex, bringPanelToFront, panelInstances, unhidePanel],
|
|
106
140
|
);
|
|
107
141
|
|
|
108
|
-
const closePanel = useCallback(
|
|
109
|
-
|
|
110
|
-
|
|
142
|
+
const closePanel = useCallback((closePanelUniqueIds: string | string[]) => {
|
|
143
|
+
const panelIds = castArray(closePanelUniqueIds);
|
|
144
|
+
setPanelInstances((panelInstances) => {
|
|
111
145
|
const [closedPanelInstances, stillOpenPanelInstances] = partition(panelInstances, (pi) =>
|
|
112
|
-
|
|
146
|
+
panelIds.includes(pi.uniqueId),
|
|
113
147
|
);
|
|
114
148
|
if (!isEmpty(closedPanelInstances)) {
|
|
115
149
|
closedPanelInstances.forEach(({ onClose }) => {
|
|
116
150
|
onClose?.();
|
|
117
151
|
});
|
|
118
|
-
|
|
152
|
+
return stillOpenPanelInstances;
|
|
119
153
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
);
|
|
154
|
+
return panelInstances;
|
|
155
|
+
});
|
|
156
|
+
}, []);
|
|
123
157
|
|
|
124
158
|
/**
|
|
125
159
|
* It's not easy to tell the difference between a window closing and a window popping in via events,
|
|
@@ -144,22 +178,33 @@ export const PanelsContextProvider = ({
|
|
|
144
178
|
|
|
145
179
|
const openPanels = useMemo(() => new Set(panelInstances.map((pi) => pi.uniqueId)), [panelInstances]);
|
|
146
180
|
|
|
181
|
+
const hasOpenPanel = useCallback((panelId: string): boolean => openPanels.has(panelId), [openPanels]);
|
|
182
|
+
|
|
147
183
|
return (
|
|
148
184
|
<PanelsContext.Provider
|
|
149
185
|
value={{
|
|
150
186
|
openPanels,
|
|
187
|
+
hasOpenPanel,
|
|
151
188
|
openPanel,
|
|
152
189
|
closePanel,
|
|
190
|
+
hasHiddenPanel,
|
|
153
191
|
bringPanelToFront,
|
|
154
192
|
nextStackPosition,
|
|
155
193
|
dockElements,
|
|
156
194
|
setDockElement,
|
|
157
195
|
panelStateOptions,
|
|
196
|
+
hidePanel,
|
|
197
|
+
unhidePanel,
|
|
158
198
|
}}
|
|
159
199
|
>
|
|
160
200
|
<Fragment key={'panels'}>
|
|
161
201
|
{panelInstances.map((panelInstance) => (
|
|
162
|
-
<PanelInstanceContextProvider
|
|
202
|
+
<PanelInstanceContextProvider
|
|
203
|
+
key={panelInstance.uniqueId}
|
|
204
|
+
panelInstance={panelInstance}
|
|
205
|
+
bounds={bounds}
|
|
206
|
+
hidden={panelInstance.hidden}
|
|
207
|
+
>
|
|
163
208
|
{panelInstance.componentInstance}
|
|
164
209
|
</PanelInstanceContextProvider>
|
|
165
210
|
))}
|
|
@@ -25,12 +25,14 @@ export function PopinWindow({
|
|
|
25
25
|
panelSize,
|
|
26
26
|
setPanelSize,
|
|
27
27
|
setInitialPanelSize,
|
|
28
|
+
hidden,
|
|
28
29
|
}: PanelProps & {
|
|
29
30
|
panelPosition: PanelPosition;
|
|
30
31
|
setPanelPosition: Dispatch<PanelPosition>;
|
|
31
32
|
panelSize: PanelSize;
|
|
32
33
|
setPanelSize: Dispatch<PanelSize>;
|
|
33
34
|
setInitialPanelSize: Dispatch<PanelSize>;
|
|
35
|
+
hidden: boolean;
|
|
34
36
|
}): ReactElement {
|
|
35
37
|
const panelRef = useRef<Rnd>(null);
|
|
36
38
|
|
|
@@ -113,7 +115,7 @@ export function PopinWindow({
|
|
|
113
115
|
minHeight={minHeight}
|
|
114
116
|
position={panelPosition}
|
|
115
117
|
size={panelSize.height === 'auto' ? (pick(panelSize, 'width') as PanelSize) : panelSize}
|
|
116
|
-
style={{ zIndex }}
|
|
118
|
+
style={{ zIndex, visibility: hidden ? 'hidden' : undefined }}
|
|
117
119
|
disableDragging={!resizeable}
|
|
118
120
|
enableResizing={resizeable}
|
|
119
121
|
bounds={bounds ?? document.body}
|