@topconsultnpm/sdkui-react-beta 6.13.34 → 6.13.35

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.
@@ -11,7 +11,6 @@ export declare const StyledPanelPage: import("styled-components/dist/types").ISt
11
11
  $isOpen?: boolean;
12
12
  $padding?: string;
13
13
  $background?: string;
14
- $withMenu?: boolean;
15
14
  }>> & string;
16
15
  export declare const StyledOffCanvasPanel: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
17
16
  $isOpen: boolean;
@@ -36,26 +36,18 @@ export const StyledToolbarForm = styled.div `
36
36
  gap: 2px;
37
37
  background-color: ${TMColors.toolbar_background};
38
38
  `;
39
- export const StyledPanelPage = styled.div `
40
- position: absolute;
41
- width: calc(100% - 50px);
42
- top: ${(props) => props.$isOpen ? '50px' : '-9999px'};
43
- left: ${(props) => props.$isOpen ? '50px' : '-9999px'};
44
- visibility: ${(props) => props.$isOpen ? 'visible' : 'hidden'};
45
- bottom: 0;
46
- border-radius: 0px;
47
- background: ${(props) => props.$background ?? 'transparent'};
48
- z-index: 1500;
39
+ export const StyledPanelPage = styled.div `
40
+ position: absolute;
41
+ width: calc(100% - 50px);
42
+ top: ${(props) => props.$isOpen ? '50px' : '-9999px'};
43
+ left: ${(props) => props.$isOpen ? '50px' : '-9999px'};
44
+ visibility: ${(props) => props.$isOpen ? 'visible' : 'hidden'};
45
+ bottom: 0;
46
+ border-radius: 0px;
47
+ background: ${(props) => props.$background ?? 'transparent'};
48
+ z-index: 1500;
49
49
  overflow: hidden;
50
-
51
- @media (min-width: 768px) {
52
- padding: ${(props) => props.$padding ?? `${Gutters.defaultDesktop}px`};
53
- padding-right: ${(props) => props.$withMenu ? '0' : 'auto'};
54
- }
55
-
56
- @media (max-width: 767px) {
57
- padding: ${(props) => props.$padding ?? `${Gutters.defaultMobile}px`};
58
- }
50
+ padding: ${props => props.$padding ?? `${Gutters.getGutters()}px`};
59
51
  `;
60
52
  export const StyledOffCanvasPanel = styled.div `
61
53
  position: fixed;
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useLayoutEffect, useRef, useState } from 'react';
3
3
  import styled from 'styled-components';
4
- import { IconArrowLeft, IconClearButton, IconWindowMaximize, IconWindowMinimize, isPositiveNumber, SDKUI_Globals, SDKUI_Localizator } from '../../helper';
4
+ import { IconArrowLeft, IconClearButton, IconWindowMaximize, IconWindowMinimize, isPositiveNumber, SDKUI_Localizator } from '../../helper';
5
5
  import TMButton from './TMButton';
6
6
  const StyledPanelContainer = styled.div `
7
7
  width: 100%;
@@ -16,10 +16,10 @@ const StyledPanelContainer = styled.div `
16
16
  position: ${({ $isMaximized }) => $isMaximized ? 'fixed' : 'relative'};
17
17
  top: ${({ $isMaximized }) => $isMaximized ? '50px' : 'auto'};
18
18
  left: ${({ $isMaximized }) => $isMaximized ? '50px' : 'auto'};
19
- width: ${({ $isMaximized }) => $isMaximized ? `calc(100vw - 50px - (${SDKUI_Globals.userSettings.themeSettings.gutters}px * 2))` : '100%'};
20
- height: ${({ $isMaximized }) => $isMaximized ? `calc(100vh - 50px - (${SDKUI_Globals.userSettings.themeSettings.gutters}px * 2))` : '100%'};
19
+ width: ${({ $isMaximized }) => $isMaximized ? 'calc(100vw - 90px)' : '100%'};
20
+ height: ${({ $isMaximized }) => $isMaximized ? 'calc(100vh - 90px)' : '100%'};
21
21
  z-index: ${({ $isMaximized }) => $isMaximized ? 2000 : 'auto'};
22
- margin: ${({ $isMaximized }) => $isMaximized ? `${SDKUI_Globals.userSettings.themeSettings.gutters}px` : '0'};
22
+ margin: ${({ $isMaximized }) => $isMaximized ? '20px' : '0'};
23
23
  /* transition: all 0.2s; */
24
24
  `;
25
25
  const StyledPanelHeader = styled.div `
@@ -0,0 +1,9 @@
1
+ import { TMPanelItemConfig } from './TMPanelManagerUtils';
2
+ type TMPanelManagerProps = {
3
+ panels: Array<TMPanelItemConfig>;
4
+ initialMobilePanelId: string;
5
+ showToolbar?: boolean;
6
+ gutters?: number;
7
+ };
8
+ declare const TMPanelManager: (props: TMPanelManagerProps) => import("react/jsx-runtime").JSX.Element;
9
+ export default TMPanelManager;
@@ -0,0 +1,465 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useRef, useState } from 'react';
3
+ import { flattenPanels, isAtLeastOnePanelVisible, isPanelArray } from './TMPanelManagerUtils';
4
+ import { SDKUI_Globals, IconInfo, SDKUI_Localizator } from '../../helper';
5
+ import { useDeviceType, DeviceType } from './TMDeviceProvider';
6
+ import TMPanel from './TMPanel';
7
+ import TMPanelManagerToolbar from './TMPanelManagerToolbar';
8
+ const TMPanelManager = (props) => {
9
+ const { panels, initialMobilePanelId, showToolbar = true, gutters = SDKUI_Globals.userSettings.themeSettings.gutters } = props;
10
+ const deviceType = useDeviceType();
11
+ let isMobile = useMemo(() => { return deviceType === DeviceType.MOBILE; }, [deviceType]);
12
+ const allPanels = useMemo(() => flattenPanels(panels), [panels]);
13
+ const panelMap = useMemo(() => {
14
+ const map = new Map();
15
+ allPanels.forEach(p => map.set(p.fullId, p));
16
+ return map;
17
+ }, [allPanels]);
18
+ const panelRefs = useRef({});
19
+ // Active buttons state & panel map
20
+ const [activeButtons, setActiveButtons] = useState(() => Object.fromEntries(allPanels.map(p => [p.fullId, p.config.toolbarOptions?.isActive ?? false])));
21
+ const [originalSizes, setOriginalSizes] = useState(new Map());
22
+ const [panelsState, setPanelsState] = useState(new Map());
23
+ const [maximizedPanelPath, setMaximizedPanelPath] = useState([]);
24
+ const [isRowDragging, setIsRowDragging] = useState(null);
25
+ const [isColumnDragging, setIsColumnDragging] = useState(null);
26
+ const [updatedDisabledButton, setUpdatedDisabledButton] = useState(undefined);
27
+ const [updatedVisibleButton, setUpdatedVisibleButton] = useState(undefined);
28
+ // Initialize two new Maps to store panel state and their original sizes
29
+ useEffect(() => {
30
+ const newState = new Map();
31
+ const newOriginalSizes = new Map();
32
+ // Recursive function to initialize panel map data
33
+ const initPanelsMap = (panels, parentPath = '') => {
34
+ panels.forEach(panel => {
35
+ // Skip if the panel has no contentOptions
36
+ if (!panel.contentOptions)
37
+ return;
38
+ // Construct a unique full ID for each panel based on its parent path
39
+ const fullId = parentPath ? `${parentPath}.${panel.id}` : panel.id;
40
+ // Use default values '0' if width/height is not provided
41
+ const width = panel.contentOptions.width;
42
+ const height = panel.contentOptions.height;
43
+ // Check if the panel contains nested children
44
+ const hasChildren = Array.isArray(panel.contentOptions.content);
45
+ // Store the original width and height for future reference
46
+ newOriginalSizes.set(fullId, { width, height });
47
+ // Determine the layout orientation
48
+ // A panel is considered a "column" layout if height is 100% and width isn't.
49
+ // A panel is considered a "row" layout if width is 100% and height isn't.
50
+ const isColumn = height === '100%' && width !== '100%';
51
+ const isRow = width === '100%' && height !== '100%';
52
+ // Save the current panel's state including dimensions and layout direction
53
+ newState.set(fullId, { width, height, isColumn, isRow, });
54
+ // If the panel has nested children, recursively initialize their states
55
+ if (hasChildren) {
56
+ initPanelsMap(panel.contentOptions.content, fullId);
57
+ }
58
+ });
59
+ };
60
+ initPanelsMap(panels);
61
+ setOriginalSizes(newOriginalSizes);
62
+ setPanelsState(newState);
63
+ }, [panels]);
64
+ useEffect(() => {
65
+ // If there are no original sizes available, exit early
66
+ if (!originalSizes.size)
67
+ return;
68
+ // Clone the current state of the panels into a new Map to modify it safely
69
+ const newState = new Map(panelsState);
70
+ // Helper function to check if a panel is currently maximized
71
+ const isMaximized = (panelId) => maximizedPanelPath.includes(panelId);
72
+ // Iterate through all panel sizes stored in originalSizes
73
+ for (const [panelId, sizes] of originalSizes.entries()) {
74
+ const currentPanel = newState.get(panelId);
75
+ if (!currentPanel) {
76
+ // If for some reason the panel doesn't exist in state, skip it
77
+ continue;
78
+ }
79
+ if (isMaximized(panelId)) {
80
+ // If the panel is maximized, set its dimensions to take up the full available space
81
+ newState.set(panelId, { ...currentPanel, width: '100%', height: '100%' });
82
+ }
83
+ else if (maximizedPanelPath.length > 0) {
84
+ // If at least one panel is maximized, collapse all others to zero size
85
+ newState.set(panelId, { ...currentPanel, width: '0', height: '0' });
86
+ }
87
+ else {
88
+ // If no panels are maximized, restore their original dimensions
89
+ newState.set(panelId, { ...currentPanel, width: sizes.width, height: sizes.height });
90
+ }
91
+ }
92
+ // Apply the updated panel states
93
+ setPanelsState(newState);
94
+ // Run this effect whenever maximizedPanelPath or originalSizes change
95
+ }, [maximizedPanelPath, originalSizes]);
96
+ useEffect(() => {
97
+ const isDragging = isColumnDragging || isRowDragging;
98
+ // Handles the end of dragging (mouse release)
99
+ const onMouseUp = () => {
100
+ setIsColumnDragging(null);
101
+ setIsRowDragging(null);
102
+ document.body.style.userSelect = '';
103
+ };
104
+ // Handles column resizing during dragging
105
+ const onColumnMouseMove = (e) => {
106
+ if (!isColumnDragging)
107
+ return;
108
+ const columnKeys = getKeysByOrientation('column');
109
+ const currentIndex = columnKeys.indexOf(isColumnDragging);
110
+ const nextKey = columnKeys[currentIndex + 1];
111
+ if (!nextKey)
112
+ return;
113
+ const deltaPercent = (e.movementX / window.innerWidth) * 100;
114
+ resizePanels(columnKeys, currentIndex, nextKey, deltaPercent, 'width');
115
+ };
116
+ // Handles row resizing during dragging
117
+ const onRowMouseMove = (e) => {
118
+ if (!isRowDragging)
119
+ return;
120
+ const rowKeys = getKeysByOrientation('row');
121
+ const currentIndex = rowKeys.indexOf(isRowDragging);
122
+ const nextKey = rowKeys[currentIndex + 1];
123
+ if (!nextKey)
124
+ return;
125
+ const deltaPercent = (e.movementY / window.innerHeight) * 100;
126
+ resizePanels(rowKeys, currentIndex, nextKey, deltaPercent, 'height');
127
+ };
128
+ // Returns panel keys that match the given orientation (row or column)
129
+ const getKeysByOrientation = (type) => {
130
+ return Array.from(panelsState.entries())
131
+ .filter(([_, value]) => (type === 'row' ? value.isRow : value.isColumn))
132
+ .map(([key]) => key);
133
+ };
134
+ // Shared resizing logic for both rows and columns
135
+ const resizePanels = (keys, currentIndex, nextKey, deltaPercent, dimension) => {
136
+ setPanelsState(prev => {
137
+ const updated = new Map(prev);
138
+ const updatedOriginalSizes = new Map(originalSizes);
139
+ const currentKey = keys[currentIndex];
140
+ const currentSize = parseFloat(updated.get(currentKey)?.[dimension] || '0');
141
+ const nextSize = parseFloat(updated.get(nextKey)?.[dimension] || '0');
142
+ const total = currentSize + nextSize;
143
+ let newCurrent = Math.min(currentSize + deltaPercent, 100);
144
+ let newNext = Math.min(nextSize - deltaPercent, 100);
145
+ // Enforce minimum panel size
146
+ if (newCurrent < 5) {
147
+ newCurrent = 5;
148
+ newNext = total - newCurrent;
149
+ }
150
+ else if (newNext < 5) {
151
+ newNext = 5;
152
+ newCurrent = total - newNext;
153
+ }
154
+ // Safely get current and next panel data
155
+ const currentPanel = updated.get(currentKey);
156
+ const nextPanel = updated.get(nextKey);
157
+ // Ensure both panels exist before updating
158
+ if (!currentPanel || !nextPanel)
159
+ return prev;
160
+ // Update panel dimensions
161
+ updated.set(currentKey, { ...currentPanel, [dimension]: `${newCurrent}%` });
162
+ updated.set(nextKey, { ...nextPanel, [dimension]: `${newNext}%` });
163
+ // Update original sizes for persistence
164
+ updatedOriginalSizes.set(currentKey, { ...currentPanel, [dimension]: `${newCurrent}%` });
165
+ updatedOriginalSizes.set(nextKey, { ...nextPanel, [dimension]: `${newNext}%` });
166
+ setOriginalSizes(updatedOriginalSizes);
167
+ return updated;
168
+ });
169
+ };
170
+ // Add event listeners when dragging starts
171
+ if (isDragging) {
172
+ if (isColumnDragging) {
173
+ window.addEventListener('mousemove', onColumnMouseMove);
174
+ }
175
+ else if (isRowDragging) {
176
+ window.addEventListener('mousemove', onRowMouseMove);
177
+ }
178
+ window.addEventListener('mouseup', onMouseUp);
179
+ document.body.style.userSelect = 'none'; // Prevents text selection during drag
180
+ }
181
+ // Cleanup function to remove event listeners
182
+ return () => {
183
+ window.removeEventListener('mousemove', onColumnMouseMove);
184
+ window.removeEventListener('mousemove', onRowMouseMove);
185
+ window.removeEventListener('mouseup', onMouseUp);
186
+ document.body.style.userSelect = '';
187
+ };
188
+ }, [isColumnDragging, isRowDragging, panelsState, originalSizes]);
189
+ useEffect(() => {
190
+ if (isMobile) {
191
+ setActiveButtons(prev => {
192
+ // Clone the previous state to avoid mutating it directly
193
+ const newActive = { ...prev };
194
+ // Get the panel object from the panel map
195
+ const panel = panelMap.get(initialMobilePanelId);
196
+ Object.keys(newActive).forEach(panelId => {
197
+ newActive[panelId] = false;
198
+ });
199
+ // Toggle the selected panel's visibility
200
+ newActive[initialMobilePanelId] = true;
201
+ // If the panel is being hidden and has children, recursively hide its children
202
+ if (panel && panel.childrenIds.length > 0 && !newActive[initialMobilePanelId]) {
203
+ const hideChildrenRecursively = (ids) => {
204
+ ids.forEach(childId => {
205
+ newActive[childId] = false;
206
+ const childPanel = panelMap.get(childId);
207
+ if (childPanel?.childrenIds.length) {
208
+ hideChildrenRecursively(childPanel.childrenIds);
209
+ }
210
+ });
211
+ };
212
+ hideChildrenRecursively(panel.childrenIds);
213
+ }
214
+ // After toggling, ensure the visibility of parent panels is in sync with their children
215
+ if (panel?.parentId) {
216
+ syncParentVisibilityWithChildren(panel.parentId, newActive);
217
+ }
218
+ // Return the updated visibility map
219
+ return newActive;
220
+ });
221
+ }
222
+ }, [isMobile]);
223
+ // Handler for starting to drag a column divider (for resizing panels horizontally)
224
+ const onColumnMouseDown = (panelKey) => {
225
+ setIsColumnDragging(panelKey); // Set the state to indicate which column is being dragged
226
+ };
227
+ // Handler for starting to drag a row divider (for resizing panels vertically)
228
+ const onRowMouseDown = (rowKey) => {
229
+ setIsRowDragging(rowKey); // Set the state to indicate which row is being dragged
230
+ };
231
+ // Function to disable a toolbar button by its ID
232
+ const handleDisableButton = (id, value) => {
233
+ // Update state to inform toolbar which button should be disabled/enabled
234
+ setUpdatedDisabledButton({ id, value });
235
+ };
236
+ // Function to change the visibility of a toolbar button by its ID
237
+ const handleVisibilityButton = (id, value) => {
238
+ // Update state to inform toolbar which button should be shown/hidden
239
+ setUpdatedVisibleButton({ id, value });
240
+ };
241
+ /**
242
+ * Recursively updates the visibility status of parent panels based on the visibility of their child panels.
243
+ * If all children are hidden, the parent is hidden.
244
+ * If at least one child is visible, the parent is shown. Propagates visibility changes up the tree.
245
+ */
246
+ const syncParentVisibilityWithChildren = (panelId, visibleMap) => {
247
+ const panel = panelMap.get(panelId);
248
+ if (!panel || panel.childrenIds.length === 0)
249
+ return;
250
+ const allChildrenHidden = panel.childrenIds.every(id => !visibleMap[id]);
251
+ if (allChildrenHidden && visibleMap[panelId]) {
252
+ visibleMap[panelId] = false;
253
+ if (panel.parentId) {
254
+ syncParentVisibilityWithChildren(panel.parentId, visibleMap);
255
+ }
256
+ }
257
+ else if (!allChildrenHidden && !visibleMap[panelId]) {
258
+ visibleMap[panelId] = true;
259
+ }
260
+ };
261
+ /**
262
+ * Toggles the maximized state of a panel based on its full ID.
263
+ * If the panel is already maximized (i.e., the maximized path matches its hierarchy path),
264
+ * it will be unmaximized. Otherwise, it will be maximized along with its ancestor panels.
265
+ * The full dot-separated ID of the panel (e.g., "root.section.panel")
266
+ */
267
+ const handleToggleMaximize = (fullId) => {
268
+ // Split the full panel ID into its segments (e.g., ["root", "section", "panel"])
269
+ const segments = fullId.split('.');
270
+ // Build the full path hierarchy up to this panel (e.g., ["root", "root.section", "root.section.panel"])
271
+ const path = segments.map((_, i) => segments.slice(0, i + 1).join('.'));
272
+ // Check if this panel is already maximized by comparing path arrays
273
+ const isAlreadyMaximized = maximizedPanelPath.length === path.length && maximizedPanelPath.every((v, i) => v === path[i]);
274
+ if (isAlreadyMaximized) {
275
+ // Unmaximize by clearing the maximized path
276
+ setMaximizedPanelPath([]);
277
+ }
278
+ else {
279
+ // Maximize this panel and its parent hierarchy
280
+ setMaximizedPanelPath(path);
281
+ }
282
+ };
283
+ /**
284
+ * Toggles the active (visible) state of a panel by its ID.
285
+ * - On **desktop**, the panel's visibility is toggled independently,
286
+ * and if the panel is hidden, all its child panels are also recursively hidden.
287
+ * - On **mobile**, only one panel can be visible at a time:
288
+ * activating a panel will hide all others, including their children.
289
+ * After updating visibility, the function also ensures that each parent panel's
290
+ * visibility is synchronized with the state of its children.
291
+ *
292
+ */
293
+ const handleTogglePanel = (id) => {
294
+ // If the panel is currently maximized, toggle its maximization state first
295
+ if (maximizedPanelPath.includes(id)) {
296
+ handleToggleMaximize(id);
297
+ }
298
+ // Update the activeButtons state
299
+ setActiveButtons(prev => {
300
+ // Clone the previous state to avoid mutating it directly
301
+ const newActive = { ...prev };
302
+ // Get the panel object from the panel map
303
+ const panel = panelMap.get(id);
304
+ // Determine if the current panel is currently visible
305
+ const currentlyVisible = !!newActive[id];
306
+ // Mobile-specific behavior: only one panel can be visible at a time
307
+ if (isMobile) {
308
+ // Hide all panels
309
+ Object.keys(newActive).forEach(panelId => {
310
+ newActive[panelId] = false;
311
+ });
312
+ // Toggle the selected panel's visibility
313
+ newActive[id] = !currentlyVisible;
314
+ // If the panel is being hidden and has children, recursively hide its children
315
+ if (panel && panel.childrenIds.length > 0 && !newActive[id]) {
316
+ const hideChildrenRecursively = (ids) => {
317
+ ids.forEach(childId => {
318
+ newActive[childId] = false;
319
+ const childPanel = panelMap.get(childId);
320
+ if (childPanel?.childrenIds.length) {
321
+ hideChildrenRecursively(childPanel.childrenIds);
322
+ }
323
+ });
324
+ };
325
+ hideChildrenRecursively(panel.childrenIds);
326
+ }
327
+ }
328
+ else {
329
+ // Desktop behavior: toggle visibility of the selected panel
330
+ if (!currentlyVisible) {
331
+ // If the panel is currently not visible (we are activating it)
332
+ if (panel?.alternativePanelIds.length) {
333
+ // If the panel has alternative panels defined
334
+ panel.alternativePanelIds.forEach(altId => {
335
+ // Deactivate each alternative panel
336
+ newActive[altId] = false;
337
+ });
338
+ }
339
+ // Activate the selected panel
340
+ newActive[id] = true;
341
+ }
342
+ else {
343
+ // The panel is currently visible, so we are deactivating it
344
+ newActive[id] = false;
345
+ }
346
+ // If hiding the panel and it has children, hide them recursively
347
+ if (panel && panel.childrenIds.length > 0 && !newActive[id]) {
348
+ const hideChildrenRecursively = (ids) => {
349
+ ids.forEach(childId => {
350
+ newActive[childId] = false;
351
+ const childPanel = panelMap.get(childId);
352
+ if (childPanel?.childrenIds.length) {
353
+ hideChildrenRecursively(childPanel.childrenIds);
354
+ }
355
+ });
356
+ };
357
+ hideChildrenRecursively(panel.childrenIds);
358
+ }
359
+ }
360
+ // After toggling, ensure the visibility of parent panels is in sync with their children
361
+ if (panel?.parentId) {
362
+ syncParentVisibilityWithChildren(panel.parentId, newActive);
363
+ }
364
+ // Return the updated visibility map
365
+ return newActive;
366
+ });
367
+ };
368
+ // Render panels
369
+ const renderPanels = (panels, parentPath = '', direction = 'horizontal') => {
370
+ const visiblePanels = panels.filter(p => {
371
+ const fullId = parentPath ? `${parentPath}.${p.id}` : p.id;
372
+ return p.contentOptions?.content && activeButtons[fullId];
373
+ });
374
+ const keys = visiblePanels.map(p => (parentPath ? `${parentPath}.${p.id}` : p.id));
375
+ const totalSize = keys.reduce((sum, key) => {
376
+ const entry = panelsState.get(key);
377
+ const size = parseFloat(direction === 'horizontal' ? entry?.width || '0' : entry?.height || '0');
378
+ return sum + size;
379
+ }, 0);
380
+ const sizeMap = Object.fromEntries(keys.map(key => {
381
+ const entry = panelsState.get(key);
382
+ const size = parseFloat(direction === 'horizontal' ? entry?.width || '0' : entry?.height || '0');
383
+ const percent = totalSize > 0 ? (size / totalSize) * 100 : 0;
384
+ return [key, `${percent}%`];
385
+ }));
386
+ return panels.map(panel => {
387
+ if (!panel.contentOptions)
388
+ return null;
389
+ const fullId = parentPath ? `${parentPath}.${panel.id}` : panel.id;
390
+ const isActive = activeButtons[fullId];
391
+ const hasChildren = isPanelArray(panel.contentOptions?.content);
392
+ const isLastVisible = keys.indexOf(fullId) === keys.length - 1;
393
+ const flexDirection = direction === 'horizontal' ? 'row' : 'column';
394
+ const panelStyle = {
395
+ display: 'flex',
396
+ flexDirection,
397
+ width: direction === 'horizontal' ? (isActive ? sizeMap[fullId] : '0%') : '100%',
398
+ height: direction === 'vertical' ? (isActive ? sizeMap[fullId] : '0%') : '100%',
399
+ visibility: isActive ? 'visible' : 'hidden',
400
+ overflow: 'hidden',
401
+ position: 'relative',
402
+ };
403
+ const contentStyle = {
404
+ flexGrow: 1,
405
+ overflow: 'auto',
406
+ };
407
+ return (_jsxs("div", { ref: el => {
408
+ panelRefs.current[fullId] = el;
409
+ }, style: panelStyle, children: [_jsx("div", { style: contentStyle, children: hasChildren
410
+ ? renderPanels(panel.contentOptions.content, fullId, 'vertical')
411
+ : panel.contentOptions?.panelContainer ? _jsx(TMPanel, { title: panel.contentOptions.panelContainer.title, totalItems: panel.contentOptions.panelContainer.totalItems, displayedItemsCount: panel.contentOptions.panelContainer.displayedItemsCount, onClose: () => handleTogglePanel(fullId), onMaximize: () => handleToggleMaximize(fullId), allowMaximize: !isMobile, children: typeof panel.contentOptions.content === "function" ? panel.contentOptions.content(handleTogglePanel, handleToggleMaximize, handleVisibilityButton, handleDisableButton) : panel.contentOptions.content })
412
+ :
413
+ typeof panel.contentOptions.content === "function" ? panel.contentOptions.content(handleTogglePanel, handleToggleMaximize, handleVisibilityButton, handleDisableButton) : panel.contentOptions.content }), !isLastVisible && isActive && maximizedPanelPath.length === 0 && (_jsx("div", { style: {
414
+ cursor: direction === 'horizontal' ? 'col-resize' : 'row-resize',
415
+ userSelect: 'none',
416
+ flexShrink: 0,
417
+ backgroundColor: 'transparent',
418
+ width: direction === 'horizontal' ? '4px' : '100%',
419
+ height: direction === 'vertical' ? '4px' : '100%',
420
+ marginLeft: maximizedPanelPath.length === 0 && direction === 'horizontal' ? `${(gutters - 4) / 2}px` : undefined,
421
+ marginTop: maximizedPanelPath.length === 0 && direction === 'vertical' ? `${(gutters - 4) / 2}px` : undefined,
422
+ marginRight: maximizedPanelPath.length === 0 && direction === 'horizontal' ? `${(gutters - 4) / 2}px` : undefined,
423
+ marginBottom: maximizedPanelPath.length === 0 && direction === 'vertical' ? `${(gutters - 4) / 2}px` : undefined,
424
+ }, onMouseDown: () => {
425
+ if (direction === 'horizontal') {
426
+ onColumnMouseDown(fullId);
427
+ }
428
+ else {
429
+ onRowMouseDown(fullId);
430
+ }
431
+ } }))] }, fullId));
432
+ });
433
+ };
434
+ return (_jsxs("div", { style: { display: 'flex', flexDirection: isMobile ? 'column' : 'row', height: '100%', width: '100%' }, children: [_jsx("div", { style: {
435
+ display: 'flex',
436
+ flexGrow: 1,
437
+ width: isAtLeastOnePanelVisible(activeButtons) ? `calc(100% - ${showToolbar ? (isMobile ? 0 : 60) : 0}px)` : '0%',
438
+ height: isAtLeastOnePanelVisible(activeButtons) ? `calc(100% - ${isMobile ? 60 : 0}px)` : '0%',
439
+ visibility: isAtLeastOnePanelVisible(activeButtons) ? 'visible' : 'hidden',
440
+ flexDirection: 'row',
441
+ }, children: renderPanels(panels, '', 'horizontal') }), !isAtLeastOnePanelVisible(activeButtons) && (_jsxs("div", { style: {
442
+ width: '100%',
443
+ height: isMobile ? 'calc(100% - 60px)' : '100%',
444
+ display: 'flex',
445
+ flexDirection: 'column',
446
+ alignItems: 'center',
447
+ justifyContent: 'center',
448
+ backgroundColor: '#fff',
449
+ borderRadius: '12px',
450
+ textAlign: 'center',
451
+ color: '#555',
452
+ fontSize: '18px',
453
+ }, children: [_jsx(IconInfo, { style: { fontSize: 50 } }), _jsx("div", { children: SDKUI_Localizator.NoPanelSelected })] })), showToolbar && _jsx("div", { style: {
454
+ width: isMobile ? '100%' : '60px',
455
+ height: isMobile ? '60px' : '100%',
456
+ borderLeft: '1px solid #ccc',
457
+ display: 'flex',
458
+ flexDirection: isMobile ? 'row' : 'column',
459
+ padding: '8px',
460
+ boxSizing: 'border-box',
461
+ gap: '6px',
462
+ backgroundColor: '#f9f9f9',
463
+ }, children: _jsx(TMPanelManagerToolbar, { allPanels: allPanels, activeButtons: activeButtons, handleTogglePanel: handleTogglePanel, updatedDisabledButton: updatedDisabledButton, updatedVisibleButton: updatedVisibleButton }) })] }));
464
+ };
465
+ export default TMPanelManager;
@@ -0,0 +1,16 @@
1
+ import { TMPanelEntry } from './TMPanelManagerUtils';
2
+ interface TNPanelManagerToolbarProps {
3
+ allPanels: Array<TMPanelEntry>;
4
+ activeButtons: Record<string, boolean>;
5
+ handleTogglePanel: (id: string) => void;
6
+ updatedDisabledButton?: {
7
+ id: string;
8
+ value: boolean;
9
+ };
10
+ updatedVisibleButton?: {
11
+ id: string;
12
+ value: boolean;
13
+ };
14
+ }
15
+ declare const TMPanelManagerToolbar: (props: TNPanelManagerToolbarProps) => import("react/jsx-runtime").JSX.Element;
16
+ export default TMPanelManagerToolbar;