@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.
@@ -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 = ({ buttonText, uniqueId = buttonText, ...openPanelOptions }: OpenPanelButtonProps) => {
12
- const { openPanel, openPanels } = useContext(PanelsContext);
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
- <button onClick={() => openPanel({ uniqueId, ...openPanelOptions })}>
16
- Show {buttonText} {openPanels.has(buttonText) ? '(Open)' : ''}
17
- </button>
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
  };
@@ -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
- (closePanelUniqueIds: string | string[]) => {
110
- const panelNames = castArray(closePanelUniqueIds);
142
+ const closePanel = useCallback((closePanelUniqueIds: string | string[]) => {
143
+ const panelIds = castArray(closePanelUniqueIds);
144
+ setPanelInstances((panelInstances) => {
111
145
  const [closedPanelInstances, stillOpenPanelInstances] = partition(panelInstances, (pi) =>
112
- panelNames.includes(pi.uniqueId),
146
+ panelIds.includes(pi.uniqueId),
113
147
  );
114
148
  if (!isEmpty(closedPanelInstances)) {
115
149
  closedPanelInstances.forEach(({ onClose }) => {
116
150
  onClose?.();
117
151
  });
118
- setPanelInstances(stillOpenPanelInstances);
152
+ return stillOpenPanelInstances;
119
153
  }
120
- },
121
- [panelInstances],
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 key={panelInstance.uniqueId} panelInstance={panelInstance} bounds={bounds}>
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}
package/package.json CHANGED
@@ -13,7 +13,7 @@
13
13
  "popout"
14
14
  ],
15
15
  "main": "./dist/index.ts",
16
- "version": "8.0.0",
16
+ "version": "8.2.0",
17
17
  "peerDependencies": {
18
18
  "@linzjs/lui": ">=21",
19
19
  "lodash-es": ">=4",