@opengeoweb/shared 20.2.0 → 21.0.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/index.esm.js CHANGED
@@ -60,6 +60,7 @@ var en = {
60
60
  "shared-shortcut-toggle-workspace-time-scroll": "Toggle workspace time scroll ON and OFF",
61
61
  "shared-shortcut-open-location-search": "Open location search",
62
62
  "shared-shortcut-open-workspace-menu": "Open workspace menu",
63
+ "shared-shortcut-open-view-preset-menu": "Open view presets menu",
63
64
  "shared-shortcut-zoom-to-location": "Zoom map to location",
64
65
  "shared-shortcut-mouse-click": "+ Mouse click",
65
66
  "shared-shortcut-split-button": "click split window button",
@@ -130,6 +131,7 @@ var fi = {
130
131
  "shared-shortcut-toggle-workspace-time-scroll": "Aseta työtilan ajan scrollaus päälle tai pois päältä",
131
132
  "shared-shortcut-open-location-search": "Avaa sijainnin haku",
132
133
  "shared-shortcut-open-workspace-menu": "Avaa workspace menu",
134
+ "shared-shortcut-open-view-preset-menu": "Avaa view preset menu",
133
135
  "shared-shortcut-zoom-to-location": "Zoomaa kartta sijaintiin",
134
136
  "shared-shortcut-mouse-click": "+ hiiren napsautus",
135
137
  "shared-shortcut-split-button": "napsauta Jaa ikkuna -painiketta",
@@ -197,6 +199,7 @@ var no = {
197
199
  "shared-shortcut-toggle-workspace-time-scroll": "ikke oversatt",
198
200
  "shared-shortcut-open-location-search": "Åpne stedsøk",
199
201
  "shared-shortcut-open-workspace-menu": "Åpne arbeidsflater",
202
+ "shared-shortcut-open-view-preset-menu": "Åpne snarveier",
200
203
  "shared-shortcut-zoom-to-location": "Zoom kart til sted",
201
204
  "shared-shortcut-mouse-click": "+ museklikk",
202
205
  "shared-shortcut-copy-view-preset-content-split-window": "kopier over viewpreset innhold når vindu deles",
@@ -266,6 +269,7 @@ var nl = {
266
269
  "shared-shortcut-toggle-workspace-time-scroll": "Zet workspace tijd scrollen AAN en UIT",
267
270
  "shared-shortcut-open-location-search": "Open locatie zoeken",
268
271
  "shared-shortcut-open-workspace-menu": "Open workspace menu",
272
+ "shared-shortcut-open-view-preset-menu": "Open view presets menu",
269
273
  "shared-shortcut-zoom-to-location": "Zoom kaart naar locatie",
270
274
  "shared-shortcut-mouse-click": "+ Muisklik",
271
275
  "shared-clear": "Wissen",
@@ -3628,6 +3632,16 @@ var ShortcutList = function ShortcutList(_ref) {
3628
3632
  type: "icon",
3629
3633
  children: "W"
3630
3634
  })
3635
+ }, {
3636
+ titleKey: 'shared-shortcut-open-view-preset-menu',
3637
+ description: jsx(ShortCutSegment, {
3638
+ type: "icon",
3639
+ children: "P"
3640
+ }),
3641
+ descriptionMac: jsx(ShortCutSegment, {
3642
+ type: "icon",
3643
+ children: "P"
3644
+ })
3631
3645
  }, {
3632
3646
  titleKey: 'shared-shortcut-zoom-to-location',
3633
3647
  description: jsxs(Fragment, {
@@ -6938,9 +6952,7 @@ var DateTimePicker = function DateTimePicker(_ref) {
6938
6952
  });
6939
6953
  };
6940
6954
 
6941
- var PANEL_MIN_WIDTH = 24;
6942
- // Tall enough to show the drag handle and title of a collapsed vertical panel
6943
- var PANEL_MIN_HEIGHT = 36;
6955
+ var PANEL_COLLAPSED_SIZE = 24;
6944
6956
  var ResizablePanel = /*#__PURE__*/React.forwardRef(function (_ref, contentRef) {
6945
6957
  var name = _ref.name,
6946
6958
  minWidthProp = _ref.minWidth,
@@ -6953,16 +6965,21 @@ var ResizablePanel = /*#__PURE__*/React.forwardRef(function (_ref, contentRef) {
6953
6965
  onSetCustomWidth = _ref.onSetCustomWidth,
6954
6966
  _onResizeStart = _ref.onResizeStart,
6955
6967
  _onResizeEnd = _ref.onResizeEnd,
6956
- customWidth = _ref.customWidth,
6968
+ customWidthProp = _ref.customWidth,
6969
+ initialSize = _ref.initialSize,
6970
+ _ref$allowOverflow = _ref.allowOverflow,
6971
+ allowOverflow = _ref$allowOverflow === void 0 ? false : _ref$allowOverflow,
6957
6972
  isDisplayed = _ref.isDisplayed,
6958
6973
  resizeOnViewCloseSignal = _ref.resizeOnViewCloseSignal,
6959
6974
  _ref$direction = _ref.direction,
6960
6975
  direction = _ref$direction === void 0 ? 'horizontal' : _ref$direction;
6976
+ var customWidth = initialSize != null ? initialSize : customWidthProp;
6961
6977
  var isVertical = direction === 'vertical';
6962
- var minWidth = minWidthProp != null ? minWidthProp : isVertical ? PANEL_MIN_HEIGHT : PANEL_MIN_WIDTH;
6978
+ var openMin = Math.max(PANEL_COLLAPSED_SIZE, minWidthProp != null ? minWidthProp : PANEL_COLLAPSED_SIZE);
6963
6979
  var sizeKey = isVertical ? 'height' : 'width';
6964
6980
  var containerRef = React.useRef(null);
6965
6981
  var widthRef = React.useRef(null);
6982
+ var previousCustomWidthRef = React.useRef(customWidth);
6966
6983
  var isDraggingRef = React.useRef(false);
6967
6984
  var _React$useState = React.useState(false),
6968
6985
  autoSizing = _React$useState[0],
@@ -6970,14 +6987,14 @@ var ResizablePanel = /*#__PURE__*/React.forwardRef(function (_ref, contentRef) {
6970
6987
  var _React$useState2 = React.useState(false),
6971
6988
  growing = _React$useState2[0],
6972
6989
  setGrowing = _React$useState2[1];
6973
- var growBasisRef = React.useRef(minWidth);
6990
+ var growBasisRef = React.useRef(openMin);
6974
6991
  var previousResizeSignalRef = React.useRef(resizeOnViewCloseSignal);
6975
6992
  var _useResizable = useResizable({
6976
6993
  containerRef: containerRef,
6977
6994
  axis: isVertical ? 'y' : 'x',
6978
- min: minWidth,
6995
+ min: PANEL_COLLAPSED_SIZE,
6979
6996
  max: maxWidth || undefined,
6980
- initial: customWidth != null ? customWidth : minWidth,
6997
+ initial: customWidth != null ? customWidth : openMin,
6981
6998
  onResizeStart: function onResizeStart() {
6982
6999
  isDraggingRef.current = true;
6983
7000
  setAutoSizing(false);
@@ -6986,13 +7003,13 @@ var ResizablePanel = /*#__PURE__*/React.forwardRef(function (_ref, contentRef) {
6986
7003
  onResizeEnd: function onResizeEnd(_ref2) {
6987
7004
  var position = _ref2.position;
6988
7005
  isDraggingRef.current = false;
6989
- if (position <= minWidth) {
7006
+ if (position <= PANEL_COLLAPSED_SIZE) {
6990
7007
  widthRef.current = null;
6991
7008
  onSetIsOpen == null || onSetIsOpen(false);
6992
7009
  } else {
6993
- widthRef.current = position;
7010
+ widthRef.current = Math.max(position, openMin);
6994
7011
  onSetIsOpen == null || onSetIsOpen(true);
6995
- onSetCustomWidth == null || onSetCustomWidth(position);
7012
+ onSetCustomWidth == null || onSetCustomWidth(Math.max(position, openMin));
6996
7013
  }
6997
7014
  // Fire after the open/close calls so consumers tracking the drag
6998
7015
  // lifecycle (e.g. a "resizing" flag) reset only once the close above
@@ -7008,7 +7025,7 @@ var ResizablePanel = /*#__PURE__*/React.forwardRef(function (_ref, contentRef) {
7008
7025
  var targetWidth = (_ref3 = (_widthRef$current = widthRef.current) != null ? _widthRef$current : customWidth) != null ? _ref3 : null;
7009
7026
  if (targetWidth != null) {
7010
7027
  setAutoSizing(false);
7011
- setContainerWidth(Math.max(targetWidth, minWidth));
7028
+ setContainerWidth(Math.max(targetWidth, openMin));
7012
7029
  onSetIsOpen == null || onSetIsOpen(true);
7013
7030
  return;
7014
7031
  }
@@ -7016,11 +7033,15 @@ var ResizablePanel = /*#__PURE__*/React.forwardRef(function (_ref, contentRef) {
7016
7033
  onSetIsOpen == null || onSetIsOpen(true);
7017
7034
  };
7018
7035
  var closePanel = React.useCallback(function () {
7019
- setContainerWidth(minWidth);
7036
+ setContainerWidth(PANEL_COLLAPSED_SIZE);
7020
7037
  onSetIsOpen == null || onSetIsOpen(false);
7021
7038
  setAutoSizing(false);
7022
- }, [minWidth, setContainerWidth, onSetIsOpen]);
7039
+ }, [setContainerWidth, onSetIsOpen]);
7023
7040
  React.useEffect(function () {
7041
+ if (previousCustomWidthRef.current !== customWidth) {
7042
+ previousCustomWidthRef.current = customWidth;
7043
+ widthRef.current = customWidth != null ? customWidth : null;
7044
+ }
7024
7045
  // While dragging, useResizable owns containerWidth based on the pointer.
7025
7046
  // Running the width-syncing branches here would jump away from the user's
7026
7047
  // drag position, so skip this effect until the drag ends.
@@ -7032,28 +7053,28 @@ var ResizablePanel = /*#__PURE__*/React.forwardRef(function (_ref, contentRef) {
7032
7053
  var targetWidth = (_ref4 = (_widthRef$current2 = widthRef.current) != null ? _widthRef$current2 : customWidth) != null ? _ref4 : null;
7033
7054
  if (targetWidth != null) {
7034
7055
  setAutoSizing(false);
7035
- setContainerWidth(Math.max(targetWidth, minWidth));
7056
+ setContainerWidth(Math.max(targetWidth, openMin));
7036
7057
  } else {
7037
7058
  setAutoSizing(true);
7038
7059
  }
7039
7060
  } else {
7040
- setContainerWidth(minWidth);
7061
+ setContainerWidth(PANEL_COLLAPSED_SIZE);
7041
7062
  setAutoSizing(false);
7042
7063
  }
7043
- }, [isOpen, minWidth, setContainerWidth, customWidth]);
7064
+ }, [isOpen, openMin, setContainerWidth, customWidth]);
7044
7065
  // Flip open/closed state during an active drag as the width crosses the
7045
- // minWidth threshold, so the panel can close and re-open within a
7066
+ // collapsed-size threshold, so the panel can close and re-open within a
7046
7067
  // single drag gesture without waiting for pointer release.
7047
7068
  React.useEffect(function () {
7048
7069
  if (!isDraggingRef.current) {
7049
7070
  return;
7050
7071
  }
7051
- if (isOpen && containerWidth <= minWidth) {
7072
+ if (isOpen && containerWidth <= PANEL_COLLAPSED_SIZE) {
7052
7073
  onSetIsOpen == null || onSetIsOpen(false);
7053
- } else if (!isOpen && containerWidth > minWidth) {
7074
+ } else if (!isOpen && containerWidth > PANEL_COLLAPSED_SIZE) {
7054
7075
  onSetIsOpen == null || onSetIsOpen(true);
7055
7076
  }
7056
- }, [isOpen, containerWidth, minWidth, onSetIsOpen]);
7077
+ }, [isOpen, containerWidth, onSetIsOpen]);
7057
7078
  React.useEffect(function () {
7058
7079
  var viewCloseSignalChanged = previousResizeSignalRef.current !== resizeOnViewCloseSignal;
7059
7080
  if (!viewCloseSignalChanged) {
@@ -7062,10 +7083,10 @@ var ResizablePanel = /*#__PURE__*/React.forwardRef(function (_ref, contentRef) {
7062
7083
  previousResizeSignalRef.current = resizeOnViewCloseSignal;
7063
7084
  var panelCanReclaimFreedSpace = isOpen && !autoSizing && !isDraggingRef.current;
7064
7085
  if (panelCanReclaimFreedSpace) {
7065
- growBasisRef.current = Math.max(containerWidth, minWidth);
7086
+ growBasisRef.current = Math.max(containerWidth, openMin);
7066
7087
  setGrowing(true);
7067
7088
  }
7068
- }, [resizeOnViewCloseSignal, isOpen, autoSizing, containerWidth, minWidth]);
7089
+ }, [resizeOnViewCloseSignal, isOpen, autoSizing, containerWidth, openMin]);
7069
7090
  React.useLayoutEffect(function () {
7070
7091
  if (autoSizing) {
7071
7092
  return;
@@ -7073,14 +7094,14 @@ var ResizablePanel = /*#__PURE__*/React.forwardRef(function (_ref, contentRef) {
7073
7094
  if (isDraggingRef.current) {
7074
7095
  return;
7075
7096
  }
7076
- if (!isOpen && containerWidth > minWidth) {
7077
- setContainerWidth(minWidth);
7097
+ if (!isOpen && containerWidth > PANEL_COLLAPSED_SIZE) {
7098
+ setContainerWidth(PANEL_COLLAPSED_SIZE);
7078
7099
  return;
7079
7100
  }
7080
- if (isOpen && containerWidth <= minWidth) {
7101
+ if (isOpen && containerWidth <= PANEL_COLLAPSED_SIZE) {
7081
7102
  setAutoSizing(true);
7082
7103
  }
7083
- }, [autoSizing, containerWidth, isOpen, minWidth, setContainerWidth]);
7104
+ }, [autoSizing, containerWidth, isOpen, setContainerWidth]);
7084
7105
  React.useLayoutEffect(function () {
7085
7106
  if (!autoSizing || !containerRef.current) {
7086
7107
  return;
@@ -7092,7 +7113,7 @@ var ResizablePanel = /*#__PURE__*/React.forwardRef(function (_ref, contentRef) {
7092
7113
  return;
7093
7114
  }
7094
7115
  var rect = containerRef.current.getBoundingClientRect();
7095
- var calculatedWidth = Math.max(Math.round(rect[sizeKey]), minWidth);
7116
+ var calculatedWidth = Math.max(Math.round(rect[sizeKey]), openMin);
7096
7117
  setContainerWidth(calculatedWidth);
7097
7118
  widthRef.current = calculatedWidth;
7098
7119
  setAutoSizing(false);
@@ -7105,7 +7126,7 @@ var ResizablePanel = /*#__PURE__*/React.forwardRef(function (_ref, contentRef) {
7105
7126
  cancelAnimationFrame(raf1);
7106
7127
  cancelAnimationFrame(raf2);
7107
7128
  };
7108
- }, [autoSizing, minWidth, setContainerWidth, sizeKey]);
7129
+ }, [autoSizing, openMin, setContainerWidth, sizeKey]);
7109
7130
  React.useLayoutEffect(function () {
7110
7131
  if (!growing || !containerRef.current) {
7111
7132
  return;
@@ -7117,7 +7138,7 @@ var ResizablePanel = /*#__PURE__*/React.forwardRef(function (_ref, contentRef) {
7117
7138
  return;
7118
7139
  }
7119
7140
  var rect = containerRef.current.getBoundingClientRect();
7120
- var lockedWidth = Math.max(Math.round(rect[sizeKey]), minWidth);
7141
+ var lockedWidth = Math.max(Math.round(rect[sizeKey]), openMin);
7121
7142
  setContainerWidth(lockedWidth);
7122
7143
  widthRef.current = lockedWidth;
7123
7144
  setGrowing(false);
@@ -7130,34 +7151,34 @@ var ResizablePanel = /*#__PURE__*/React.forwardRef(function (_ref, contentRef) {
7130
7151
  cancelAnimationFrame(growRaf1);
7131
7152
  cancelAnimationFrame(growRaf2);
7132
7153
  };
7133
- }, [growing, minWidth, setContainerWidth, sizeKey]);
7154
+ }, [growing, openMin, setContainerWidth, sizeKey]);
7134
7155
  var sizeProps = function sizeProps(size, min) {
7135
7156
  return isVertical ? {
7136
7157
  width: '100%',
7137
7158
  height: size,
7138
7159
  minHeight: min,
7139
- maxHeight: maxWidth || '100%'
7160
+ maxHeight: maxWidth || (allowOverflow ? undefined : '100%')
7140
7161
  } : {
7141
7162
  width: size,
7142
7163
  minWidth: min,
7143
- maxWidth: maxWidth || '100%'
7164
+ maxWidth: maxWidth || (allowOverflow ? undefined : '100%')
7144
7165
  };
7145
7166
  };
7146
7167
  var cardStyleWhenAuto = Object.assign({
7147
7168
  display: isDisplayed ? 'block' : 'none',
7148
7169
  flex: '1 1 100%',
7149
7170
  boxSizing: 'border-box'
7150
- }, sizeProps('auto', 0));
7171
+ }, sizeProps('auto', isOpen ? openMin : PANEL_COLLAPSED_SIZE));
7151
7172
  var cardStyleWhenLocked = Object.assign({
7152
7173
  display: isDisplayed ? 'block' : 'none',
7153
- flex: '0 1 auto',
7174
+ flex: allowOverflow ? '0 0 auto' : '0 1 auto',
7154
7175
  boxSizing: 'border-box'
7155
- }, sizeProps(containerWidth, minWidth));
7176
+ }, sizeProps(isOpen ? Math.max(containerWidth, openMin) : containerWidth, isOpen ? openMin : PANEL_COLLAPSED_SIZE));
7156
7177
  var cardStyleWhenGrowing = Object.assign({
7157
7178
  display: isDisplayed ? 'block' : 'none',
7158
7179
  flex: growBasisRef.current + " 1 0px",
7159
7180
  boxSizing: 'border-box'
7160
- }, sizeProps('auto', minWidth));
7181
+ }, sizeProps('auto', isOpen ? openMin : PANEL_COLLAPSED_SIZE));
7161
7182
  var getActiveCardStyle = function getActiveCardStyle() {
7162
7183
  if (growing) {
7163
7184
  return cardStyleWhenGrowing;
@@ -7200,7 +7221,8 @@ var ResizablePanel = /*#__PURE__*/React.forwardRef(function (_ref, contentRef) {
7200
7221
  return event.stopPropagation();
7201
7222
  },
7202
7223
  sx: {
7203
- paddingTop: '4px'
7224
+ display: 'flex',
7225
+ alignItems: 'center'
7204
7226
  },
7205
7227
  children: handleButtonComponent
7206
7228
  }), jsxs(Box, {
@@ -7352,7 +7374,10 @@ var ResizablePanelStandalone = /*#__PURE__*/React.forwardRef(function (_ref, ref
7352
7374
  onOpenChange = _ref.onOpenChange,
7353
7375
  onResizeStart = _ref.onResizeStart,
7354
7376
  onResizeEnd = _ref.onResizeEnd,
7355
- direction = _ref.direction;
7377
+ direction = _ref.direction,
7378
+ initialSize = _ref.initialSize,
7379
+ allowOverflow = _ref.allowOverflow,
7380
+ onSizeChange = _ref.onSizeChange;
7356
7381
  var _React$useState = React.useState(true),
7357
7382
  isOpen = _React$useState[0],
7358
7383
  setIsOpen = _React$useState[1];
@@ -7364,10 +7389,12 @@ var ResizablePanelStandalone = /*#__PURE__*/React.forwardRef(function (_ref, ref
7364
7389
  onOpenChange == null || onOpenChange(open);
7365
7390
  }, [onOpenChange]);
7366
7391
  return jsx(ResizablePanel, {
7392
+ allowOverflow: allowOverflow,
7367
7393
  customWidth: customWidth,
7368
7394
  direction: direction,
7369
7395
  handleButtonComponent: handleButtonComponent,
7370
7396
  headerAction: headerAction,
7397
+ initialSize: initialSize,
7371
7398
  isDisplayed: isDisplayed,
7372
7399
  isOpen: isOpen,
7373
7400
  maxWidth: maxWidth,
@@ -7375,7 +7402,10 @@ var ResizablePanelStandalone = /*#__PURE__*/React.forwardRef(function (_ref, ref
7375
7402
  name: name,
7376
7403
  onResizeEnd: onResizeEnd,
7377
7404
  onResizeStart: onResizeStart,
7378
- onSetCustomWidth: setCustomWidth,
7405
+ onSetCustomWidth: function onSetCustomWidth(size) {
7406
+ setCustomWidth(size);
7407
+ onSizeChange == null || onSizeChange(size);
7408
+ },
7379
7409
  onSetIsOpen: handleSetIsOpen,
7380
7410
  ref: ref,
7381
7411
  children: children
@@ -7383,6 +7413,234 @@ var ResizablePanelStandalone = /*#__PURE__*/React.forwardRef(function (_ref, ref
7383
7413
  });
7384
7414
  ResizablePanelStandalone.displayName = 'ResizablePanelStandalone';
7385
7415
 
7416
+ /* *
7417
+ * Licensed under the Apache License, Version 2.0 (the "License");
7418
+ * you may not use this file except in compliance with the License.
7419
+ * You may obtain a copy of the License at
7420
+ *
7421
+ * http://www.apache.org/licenses/LICENSE-2.0
7422
+ *
7423
+ * Unless required by applicable law or agreed to in writing, software
7424
+ * distributed under the License is distributed on an "AS IS" BASIS,
7425
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7426
+ * See the License for the specific language governing permissions and
7427
+ * limitations under the License.
7428
+ *
7429
+ * Copyright 2026 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
7430
+ * Copyright 2026 - Finnish Meteorological Institute (FMI)
7431
+ * Copyright 2026 - The Norwegian Meteorological Institute (MET Norway)
7432
+ * */
7433
+ var SORTABLE_PANEL_GAP = 4;
7434
+ /** Equal shares, or proportional growth, constrained by each panel's limits. */
7435
+ var allocatePanelSpace = function allocatePanelSpace(panels, available) {
7436
+ // Find the common scale whose clamped shares fill the available space.
7437
+ // If minima exceed the viewport they deliberately produce overflow.
7438
+ var low = 0;
7439
+ var high = Math.max(0, available);
7440
+ var sizeAt = function sizeAt(panel, scale) {
7441
+ var _panel$maximum, _panel$weight;
7442
+ return Math.max(panel.minimum, Math.min((_panel$maximum = panel.maximum) != null ? _panel$maximum : Infinity, scale * ((_panel$weight = panel.weight) != null ? _panel$weight : 1)));
7443
+ };
7444
+ var _loop = function _loop() {
7445
+ var scale = (low + high) / 2;
7446
+ var used = panels.reduce(function (sum, panel) {
7447
+ return sum + sizeAt(panel, scale);
7448
+ }, 0);
7449
+ if (used > available) {
7450
+ high = scale;
7451
+ } else {
7452
+ low = scale;
7453
+ }
7454
+ };
7455
+ for (var iteration = 0; iteration < 60; iteration += 1) {
7456
+ _loop();
7457
+ }
7458
+ return Object.fromEntries(panels.map(function (panel) {
7459
+ return [panel.id, Math.floor(sizeAt(panel, low) + 1e-7)];
7460
+ }));
7461
+ };
7462
+ var usePanelSizes = function usePanelSizes(panels, direction, sizing, growSignal) {
7463
+ var viewportRef = React.useRef(null);
7464
+ var rootRef = React.useRef(null);
7465
+ var latestPanels = React.useRef(panels);
7466
+ var cached = React.useRef({});
7467
+ var localOpen = React.useRef({});
7468
+ var userResized = React.useRef(false);
7469
+ var previousExtent = React.useRef(undefined);
7470
+ var previousGrowSignal = React.useRef(growSignal);
7471
+ var _React$useState = React.useState({}),
7472
+ sizes = _React$useState[0],
7473
+ setSizes = _React$useState[1];
7474
+ var measure = React.useCallback(function (grow) {
7475
+ if (grow === void 0) {
7476
+ grow = false;
7477
+ }
7478
+ var viewport = viewportRef.current;
7479
+ var root = rootRef.current;
7480
+ if (!sizing || !viewport || !root) {
7481
+ return;
7482
+ }
7483
+ var vertical = direction === 'vertical';
7484
+ var extent = vertical ? viewport.clientHeight : viewport.clientWidth;
7485
+ var extentChanged = extent > 0 && previousExtent.current !== extent;
7486
+ if (extent > 0) {
7487
+ previousExtent.current = extent;
7488
+ }
7489
+ var visible = latestPanels.current.filter(function (panel) {
7490
+ return panel.isDisplayed;
7491
+ });
7492
+ var rootStyle = window.getComputedStyle(root);
7493
+ var spacing = (parseFloat(vertical ? rootStyle.paddingTop : rootStyle.paddingLeft) || 0) + (parseFloat(vertical ? rootStyle.paddingBottom : rootStyle.paddingRight) || 0) + Math.max(0, visible.length - 1) * SORTABLE_PANEL_GAP;
7494
+ var minimum = function minimum(panel) {
7495
+ var _panel$minWidth;
7496
+ return Math.max(PANEL_COLLAPSED_SIZE, (_panel$minWidth = panel.minWidth) != null ? _panel$minWidth : PANEL_COLLAPSED_SIZE);
7497
+ };
7498
+ var open = function open(panel) {
7499
+ var _localOpen$current$pa;
7500
+ return (_localOpen$current$pa = localOpen.current[panel.id]) != null ? _localOpen$current$pa : panel.isOpen !== false;
7501
+ };
7502
+ var next = Object.assign({}, cached.current);
7503
+ latestPanels.current.forEach(function (panel) {
7504
+ var _next$panel$id;
7505
+ if (((_next$panel$id = next[panel.id]) == null ? void 0 : _next$panel$id.savedSize) !== panel.customSize) {
7506
+ delete next[panel.id];
7507
+ }
7508
+ if (panel.customSize !== undefined && !next[panel.id]) {
7509
+ var _panel$maxWidth;
7510
+ next[panel.id] = {
7511
+ size: Math.max(minimum(panel), Math.min((_panel$maxWidth = panel.maxWidth) != null ? _panel$maxWidth : Infinity, panel.customSize)),
7512
+ savedSize: panel.customSize
7513
+ };
7514
+ }
7515
+ });
7516
+ var pending = visible.filter(function (panel) {
7517
+ return extent > 0 && open(panel) && panel.customSize === undefined && (!next[panel.id] || extentChanged && sizing === 'untilManualResize' && !userResized.current);
7518
+ });
7519
+ var pendingIds = new Set(pending.map(function (panel) {
7520
+ return panel.id;
7521
+ }));
7522
+ var used = visible.reduce(function (sum, panel) {
7523
+ var _next$panel$id$size, _next$panel$id2;
7524
+ if (!open(panel)) {
7525
+ return sum + PANEL_COLLAPSED_SIZE;
7526
+ }
7527
+ return sum + (pendingIds.has(panel.id) ? 0 : (_next$panel$id$size = (_next$panel$id2 = next[panel.id]) == null ? void 0 : _next$panel$id2.size) != null ? _next$panel$id$size : minimum(panel));
7528
+ }, 0);
7529
+ var allocated = allocatePanelSpace(pending.map(function (panel) {
7530
+ return {
7531
+ id: panel.id,
7532
+ minimum: minimum(panel),
7533
+ maximum: panel.maxWidth
7534
+ };
7535
+ }), extent - spacing - used);
7536
+ pending.forEach(function (panel) {
7537
+ next[panel.id] = {
7538
+ size: allocated[panel.id]
7539
+ };
7540
+ });
7541
+ if (grow && extent > 0) {
7542
+ var closedSize = visible.filter(function (panel) {
7543
+ return !open(panel);
7544
+ }).length * PANEL_COLLAPSED_SIZE;
7545
+ var grown = allocatePanelSpace(visible.filter(open).map(function (panel) {
7546
+ var _next$panel$id$size2, _next$panel$id3, _next$panel$id$size3, _next$panel$id4;
7547
+ return {
7548
+ id: panel.id,
7549
+ minimum: (_next$panel$id$size2 = (_next$panel$id3 = next[panel.id]) == null ? void 0 : _next$panel$id3.size) != null ? _next$panel$id$size2 : minimum(panel),
7550
+ maximum: panel.maxWidth,
7551
+ weight: (_next$panel$id$size3 = (_next$panel$id4 = next[panel.id]) == null ? void 0 : _next$panel$id4.size) != null ? _next$panel$id$size3 : minimum(panel)
7552
+ };
7553
+ }), extent - spacing - closedSize);
7554
+ Object.entries(grown).forEach(function (_ref) {
7555
+ var id = _ref[0],
7556
+ size = _ref[1];
7557
+ next[id] = Object.assign({}, next[id], {
7558
+ size: size
7559
+ });
7560
+ });
7561
+ }
7562
+ var ids = new Set(latestPanels.current.map(function (panel) {
7563
+ return panel.id;
7564
+ }));
7565
+ Object.keys(next).forEach(function (id) {
7566
+ if (!ids.has(id)) {
7567
+ delete next[id];
7568
+ delete localOpen.current[id];
7569
+ }
7570
+ });
7571
+ cached.current = next;
7572
+ var nextSizes = Object.fromEntries(Object.entries(next).map(function (_ref2) {
7573
+ var id = _ref2[0],
7574
+ value = _ref2[1];
7575
+ return [id, value.size];
7576
+ }));
7577
+ setSizes(function (previous) {
7578
+ return Object.keys(previous).length === Object.keys(nextSizes).length && Object.entries(nextSizes).every(function (_ref3) {
7579
+ var id = _ref3[0],
7580
+ size = _ref3[1];
7581
+ return previous[id] === size;
7582
+ }) ? previous : nextSizes;
7583
+ });
7584
+ }, [direction, sizing]);
7585
+ React.useLayoutEffect(function () {
7586
+ panels.forEach(function (panel) {
7587
+ var previous = latestPanels.current.find(function (_ref4) {
7588
+ var id = _ref4.id;
7589
+ return id === panel.id;
7590
+ });
7591
+ if ((previous == null ? void 0 : previous.isOpen) !== panel.isOpen) {
7592
+ delete localOpen.current[panel.id];
7593
+ }
7594
+ });
7595
+ latestPanels.current = panels;
7596
+ var grow = previousGrowSignal.current !== growSignal;
7597
+ previousGrowSignal.current = growSignal;
7598
+ measure(grow);
7599
+ }, [panels, growSignal, measure]);
7600
+ React.useLayoutEffect(function () {
7601
+ var viewport = viewportRef.current;
7602
+ if (!sizing || !viewport || typeof ResizeObserver === 'undefined') {
7603
+ return undefined;
7604
+ }
7605
+ var observer = new ResizeObserver(function () {
7606
+ return measure();
7607
+ });
7608
+ observer.observe(viewport);
7609
+ return function () {
7610
+ return observer.disconnect();
7611
+ };
7612
+ }, [sizing, measure]);
7613
+ var onSizeChange = React.useCallback(function (id, size) {
7614
+ var _latestPanels$current;
7615
+ userResized.current = true;
7616
+ cached.current[id] = {
7617
+ size: size,
7618
+ savedSize: (_latestPanels$current = latestPanels.current.find(function (panel) {
7619
+ return panel.id === id;
7620
+ })) == null ? void 0 : _latestPanels$current.customSize
7621
+ };
7622
+ setSizes(function (previous) {
7623
+ var _Object$assign;
7624
+ return Object.assign({}, previous, (_Object$assign = {}, _Object$assign[id] = size, _Object$assign));
7625
+ });
7626
+ }, []);
7627
+ var onResizeStart = React.useCallback(function () {
7628
+ userResized.current = true;
7629
+ }, []);
7630
+ var onOpenChange = React.useCallback(function (id, open) {
7631
+ localOpen.current[id] = open;
7632
+ measure();
7633
+ }, [measure]);
7634
+ return {
7635
+ viewportRef: viewportRef,
7636
+ rootRef: rootRef,
7637
+ sizes: sizes,
7638
+ onSizeChange: onSizeChange,
7639
+ onOpenChange: onOpenChange,
7640
+ onResizeStart: onResizeStart
7641
+ };
7642
+ };
7643
+
7386
7644
  var SortablePanels = function SortablePanels(_ref) {
7387
7645
  var panels = _ref.panels,
7388
7646
  onOrderChange = _ref.onOrderChange,
@@ -7390,15 +7648,36 @@ var SortablePanels = function SortablePanels(_ref) {
7390
7648
  PanelComponent = _ref$panelComponent === void 0 ? ResizablePanelStandalone : _ref$panelComponent,
7391
7649
  viewId = _ref.viewId,
7392
7650
  _ref$direction = _ref.direction,
7393
- direction = _ref$direction === void 0 ? 'horizontal' : _ref$direction;
7394
- return jsx(Box, {
7395
- sx: {
7651
+ direction = _ref$direction === void 0 ? 'horizontal' : _ref$direction,
7652
+ sizing = _ref.sizing,
7653
+ _ref$allowOverflow = _ref.allowOverflow,
7654
+ allowOverflow = _ref$allowOverflow === void 0 ? false : _ref$allowOverflow,
7655
+ resizeOnViewCloseSignal = _ref.resizeOnViewCloseSignal;
7656
+ var _usePanelSizes = usePanelSizes(panels, direction, sizing, resizeOnViewCloseSignal),
7657
+ viewportRef = _usePanelSizes.viewportRef,
7658
+ rootRef = _usePanelSizes.rootRef,
7659
+ sizes = _usePanelSizes.sizes,
7660
+ onSizeChange = _usePanelSizes.onSizeChange,
7661
+ _onOpenChange = _usePanelSizes.onOpenChange,
7662
+ _onResizeStart = _usePanelSizes.onResizeStart;
7663
+ var content = jsx(Box, {
7664
+ ref: rootRef,
7665
+ sx: Object.assign({
7396
7666
  display: 'flex',
7397
7667
  flexDirection: direction === 'vertical' ? 'column' : 'row',
7398
7668
  width: '100%',
7399
- height: '100%',
7669
+ // Vertical lists must grow with their panels so the scroll container
7670
+ // includes the final panel and the bottom padding.
7671
+ height: direction === 'vertical' && allowOverflow ? 'auto' : '100%',
7672
+ boxSizing: 'border-box'
7673
+ }, direction === 'vertical' && allowOverflow && {
7674
+ minHeight: '100%'
7675
+ }, {
7400
7676
  padding: 1
7401
- },
7677
+ }, sizing && direction === 'horizontal' && allowOverflow && {
7678
+ width: 'max-content',
7679
+ minWidth: '100%'
7680
+ }),
7402
7681
  children: jsx(ReactSortable, {
7403
7682
  animation: 200,
7404
7683
  direction: direction,
@@ -7426,15 +7705,20 @@ var SortablePanels = function SortablePanels(_ref) {
7426
7705
  };
7427
7706
  }));
7428
7707
  },
7429
- style: {
7708
+ style: Object.assign({
7430
7709
  display: 'flex',
7431
7710
  flexDirection: direction === 'vertical' ? 'column' : 'row',
7432
- gap: 4,
7433
- width: '100%'
7434
- },
7711
+ gap: SORTABLE_PANEL_GAP,
7712
+ width: '100%',
7713
+ minWidth: 0,
7714
+ minHeight: 0
7715
+ }, direction === 'vertical' && allowOverflow && {
7716
+ flexShrink: 0
7717
+ }),
7435
7718
  tag: "div",
7436
7719
  children: panels.map(function (panel) {
7437
7720
  return jsx(PanelComponent, {
7721
+ allowOverflow: allowOverflow,
7438
7722
  direction: direction,
7439
7723
  handleButtonComponent: jsx(IconButton, {
7440
7724
  "aria-label": "drag-handle",
@@ -7449,13 +7733,27 @@ var SortablePanels = function SortablePanels(_ref) {
7449
7733
  })
7450
7734
  }),
7451
7735
  headerAction: panel.headerAction,
7736
+ initialSize: sizing ? sizes[panel.id] : undefined,
7452
7737
  isDisplayed: panel.isDisplayed,
7453
7738
  maxWidth: panel.maxWidth,
7454
7739
  minWidth: panel.minWidth,
7455
7740
  name: panel.name,
7456
- onOpenChange: panel.onOpenChange,
7741
+ onOpenChange: function onOpenChange(open) {
7742
+ if (sizing) {
7743
+ _onOpenChange(panel.id, open);
7744
+ }
7745
+ panel.onOpenChange == null || panel.onOpenChange(open);
7746
+ },
7457
7747
  onResizeEnd: panel.onResizeEnd,
7458
- onResizeStart: panel.onResizeStart,
7748
+ onResizeStart: function onResizeStart() {
7749
+ if (sizing) {
7750
+ _onResizeStart();
7751
+ }
7752
+ panel.onResizeStart == null || panel.onResizeStart();
7753
+ },
7754
+ onSizeChange: sizing ? function (size) {
7755
+ return onSizeChange(panel.id, size);
7756
+ } : undefined,
7459
7757
  panelId: panel.id,
7460
7758
  ref: panel.panelRef,
7461
7759
  viewId: viewId,
@@ -7464,6 +7762,17 @@ var SortablePanels = function SortablePanels(_ref) {
7464
7762
  })
7465
7763
  })
7466
7764
  });
7765
+ return sizing ? jsx(Box, {
7766
+ ref: viewportRef,
7767
+ sx: {
7768
+ width: '100%',
7769
+ height: '100%',
7770
+ minHeight: 0,
7771
+ minWidth: 0,
7772
+ overflow: allowOverflow ? 'auto' : 'hidden'
7773
+ },
7774
+ children: content
7775
+ }) : content;
7467
7776
  };
7468
7777
 
7469
7778
  /* *
@@ -7490,4 +7799,4 @@ var SystemScope = {
7490
7799
  plugin: 'plugin'
7491
7800
  };
7492
7801
 
7493
- export { AlertBanner, AlertIcon, AppHeader, AppLayout, Avatar, CanvasComponent, ConfirmationButtons, ConfirmationDialog, ConfirmationServiceProvider, CustomAccordion, CustomDialog, CustomDialogHeader, CustomIconButton, CustomSlider, CustomToggleButton, CustomTooltip, DEBOUNCE_TIMEOUT, DEFAULT_ERROR_MESSAGE, DEFAULT_FILTER_HEIGHT, DateTimePicker, DraggableComponent$1 as Draggable, ErrorBoundary, Filter, FilterChip, FilterOption, LastUpdateTime, LegendToggleButton, NumberWithUnitField, PROJECTION, ResizeComponent as Resizable, ResizablePanel, ResizablePanelStandalone, SHARED_NAMESPACE, SearchField$1 as SearchField, SearchFieldButton, SearchHighlight, SessionStorageKey, SortablePanels, StatusTag, StorybookDocsWrapper, StyledSelect, SwitchButton, SystemScope, ToggleMenu, ToolContainer, DraggableComponent as ToolContainerDraggable, ToolFooter, ToolHeader, TooltipSelect, UserMenu, UserMenuItemCheatSheet, MenuItemTheme as UserMenuItemTheme, adjustPosition, browserNavigation, calculateDialogSizeAndPosition, calculateStartSize, convertNumericInputValue, index$1 as dateUtils, defaultDelay, getAllowedKeys, getAxiosErrorMessage, getAxiosWarningMessage, getErrorMessage, getInitials, getLastUpdateTitle, getPosition, getWarningMessage, isAuthError, isAxiosAuthError, isAxiosError, isDialogFocused, isTargetInteractiveInput, linkifyText, loadAllTranslations, pickerDateToUTC, pollingIntervalTimeout, index as referenceTimeUtils, renderCounter, safelyInitI18nForTestsAndStories, sessionStorageProvider, sharedTranslations, showPrompt, sliderHeaderStyle, tooltipContainerStyles, useConfirmationDialog, useControlledTooltip, useDebounce, useDialogActions, useIsMounted, useMakeSureContainerStaysInsideWindow, usePoller, usePreventBrowserClose, usePrevious, useResizeObserver, useScrollingInIsolation, useUserMenu, useWheelStopPropagation, utcToPickerDate };
7802
+ export { AlertBanner, AlertIcon, AppHeader, AppLayout, Avatar, CanvasComponent, ConfirmationButtons, ConfirmationDialog, ConfirmationServiceProvider, CustomAccordion, CustomDialog, CustomDialogHeader, CustomIconButton, CustomSlider, CustomToggleButton, CustomTooltip, DEBOUNCE_TIMEOUT, DEFAULT_ERROR_MESSAGE, DEFAULT_FILTER_HEIGHT, DateTimePicker, DraggableComponent$1 as Draggable, ErrorBoundary, Filter, FilterChip, FilterOption, LastUpdateTime, LegendToggleButton, NumberWithUnitField, PANEL_COLLAPSED_SIZE, PROJECTION, ResizeComponent as Resizable, ResizablePanel, ResizablePanelStandalone, SHARED_NAMESPACE, SearchField$1 as SearchField, SearchFieldButton, SearchHighlight, SessionStorageKey, SortablePanels, StatusTag, StorybookDocsWrapper, StyledSelect, SwitchButton, SystemScope, ToggleMenu, ToolContainer, DraggableComponent as ToolContainerDraggable, ToolFooter, ToolHeader, TooltipSelect, UserMenu, UserMenuItemCheatSheet, MenuItemTheme as UserMenuItemTheme, adjustPosition, browserNavigation, calculateDialogSizeAndPosition, calculateStartSize, convertNumericInputValue, index$1 as dateUtils, defaultDelay, getAllowedKeys, getAxiosErrorMessage, getAxiosWarningMessage, getErrorMessage, getInitials, getLastUpdateTitle, getPosition, getWarningMessage, isAuthError, isAxiosAuthError, isAxiosError, isDialogFocused, isTargetInteractiveInput, linkifyText, loadAllTranslations, pickerDateToUTC, pollingIntervalTimeout, index as referenceTimeUtils, renderCounter, safelyInitI18nForTestsAndStories, sessionStorageProvider, sharedTranslations, showPrompt, sliderHeaderStyle, tooltipContainerStyles, useConfirmationDialog, useControlledTooltip, useDebounce, useDialogActions, useIsMounted, useMakeSureContainerStaysInsideWindow, usePoller, usePreventBrowserClose, usePrevious, useResizeObserver, useScrollingInIsolation, useUserMenu, useWheelStopPropagation, utcToPickerDate };
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  export interface ResizablePanelProps {
3
3
  name: string;
4
+ /** Minimum expanded width, or height in vertical mode. */
4
5
  minWidth?: number;
5
6
  maxWidth?: number;
6
7
  isOpen?: boolean;
@@ -12,6 +13,9 @@ export interface ResizablePanelProps {
12
13
  onResizeStart?: () => void;
13
14
  onResizeEnd?: () => void;
14
15
  customWidth?: number;
16
+ /** Size allocated by the parent layout, including temporary growth. */
17
+ initialSize?: number;
18
+ allowOverflow?: boolean;
15
19
  isDisplayed?: boolean;
16
20
  resizeOnViewCloseSignal?: number;
17
21
  /**
@@ -20,4 +24,5 @@ export interface ResizablePanelProps {
20
24
  */
21
25
  direction?: 'horizontal' | 'vertical';
22
26
  }
27
+ export declare const PANEL_COLLAPSED_SIZE = 24;
23
28
  export declare const ResizablePanel: React.ForwardRefExoticComponent<ResizablePanelProps & React.RefAttributes<HTMLDivElement>>;
@@ -17,6 +17,9 @@ export interface ResizablePanelWrapperProps {
17
17
  handleButtonComponent?: React.ReactElement;
18
18
  maxWidth?: number;
19
19
  minWidth?: number;
20
+ initialSize?: number;
21
+ allowOverflow?: boolean;
22
+ onSizeChange?: (size: number) => void;
20
23
  onOpenChange?: (isOpen: boolean) => void;
21
24
  onResizeStart?: () => void;
22
25
  onResizeEnd?: () => void;
@@ -1,4 +1,4 @@
1
- export { ResizablePanel } from './ResizablePanel';
1
+ export { ResizablePanel, PANEL_COLLAPSED_SIZE } from './ResizablePanel';
2
2
  export type { ResizablePanelProps } from './ResizablePanel';
3
3
  export { ResizablePanelStandalone } from './ResizablePanelStandalone';
4
4
  export type { ResizablePanelWrapperProps, ResizablePanelComponent, } from './ResizablePanelStandalone';
@@ -4,6 +4,8 @@ export interface SortablePanelItem {
4
4
  id: string;
5
5
  name: string;
6
6
  isDisplayed: boolean;
7
+ isOpen?: boolean;
8
+ customSize?: number;
7
9
  minWidth?: number;
8
10
  maxWidth?: number;
9
11
  headerAction?: React.ReactElement;
@@ -28,5 +30,11 @@ export interface SortablePanelsProps {
28
30
  viewId?: string;
29
31
  /** Direction in which panels are laid out, sorted and resized. Defaults to 'horizontal'. */
30
32
  direction?: 'horizontal' | 'vertical';
33
+ /** Fit unsized panels once, or follow the viewport until a manual resize. */
34
+ sizing?: 'initial' | 'untilManualResize';
35
+ /** Preserve panel sizes and scroll when they exceed the available space. */
36
+ allowOverflow?: boolean;
37
+ /** Explicitly grow open panels in proportion to their current sizes. */
38
+ resizeOnViewCloseSignal?: number;
31
39
  }
32
- export declare const SortablePanels: ({ panels, onOrderChange, panelComponent: PanelComponent, viewId, direction, }: SortablePanelsProps) => React.ReactElement;
40
+ export declare const SortablePanels: ({ panels, onOrderChange, panelComponent: PanelComponent, viewId, direction, sizing, allowOverflow, resizeOnViewCloseSignal, }: SortablePanelsProps) => React.ReactElement;
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import type { SortablePanelItem } from './SortablePanels';
3
+ export declare const SORTABLE_PANEL_GAP = 4;
4
+ interface Allocation {
5
+ id: string;
6
+ minimum: number;
7
+ maximum?: number;
8
+ weight?: number;
9
+ }
10
+ /** Equal shares, or proportional growth, constrained by each panel's limits. */
11
+ export declare const allocatePanelSpace: (panels: Allocation[], available: number) => Record<string, number>;
12
+ export declare const usePanelSizes: (panels: SortablePanelItem[], direction: "horizontal" | "vertical", sizing: "initial" | "untilManualResize" | undefined, growSignal: number | undefined) => {
13
+ viewportRef: React.RefObject<HTMLDivElement | null>;
14
+ rootRef: React.RefObject<HTMLDivElement | null>;
15
+ sizes: Record<string, number>;
16
+ onSizeChange: (id: string, size: number) => void;
17
+ onResizeStart: () => void;
18
+ onOpenChange: (id: string, open: boolean) => void;
19
+ };
20
+ export {};
@@ -40,6 +40,7 @@ export interface ConfigType {
40
40
  GW_FEATURE_MENU_FE_VERSION?: boolean;
41
41
  GW_FEATURE_DISPLAY_SEARCH_ON_MAP?: boolean;
42
42
  GW_FEATURE_INITIALIZE_SENTRY?: boolean;
43
+ GW_FEATURE_SENTRY_DSN?: string;
43
44
  GW_FEATURE_ENABLE_SPECIAL_THEMES?: boolean;
44
45
  GW_FEATURE_TAF_AUTOTAF_ENABLED?: boolean;
45
46
  GW_WARNINGS_MARITIME_WARNINGS?: boolean;
@@ -49,6 +50,7 @@ export interface ConfigType {
49
50
  GW_HIDE_AIRMET_MENU?: boolean;
50
51
  GW_FEATURE_WARNINGS_EVENT?: boolean;
51
52
  GW_FEATURE_SILENT_LOGIN?: boolean;
53
+ GW_FEATURE_TEMPLATE_PRESETS?: boolean;
52
54
  GW_LANGUAGE?: string;
53
55
  GW_EXTERNAL_APPLICATIONS_MENU_LINKS?: string;
54
56
  GW_PLUGIN_BACKEND_URL?: string;
@@ -100,7 +102,9 @@ export interface Plot {
100
102
  title: string;
101
103
  plotId: string;
102
104
  enabled?: boolean;
105
+ isOpen?: boolean;
103
106
  parameters?: PlotParameter[];
107
+ customSize?: number;
104
108
  }
105
109
  export interface PlotParameter {
106
110
  id?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeoweb/shared",
3
- "version": "20.2.0",
3
+ "version": "21.0.0",
4
4
  "description": "GeoWeb shared library with shared components and utils for the opengeoweb project",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -20,7 +20,7 @@
20
20
  }
21
21
  },
22
22
  "dependencies": {
23
- "@opengeoweb/theme": "20.2.0",
23
+ "@opengeoweb/theme": "21.0.0",
24
24
  "react-draggable": "^4.4.6",
25
25
  "react-resizable-layout": "^0.7.3",
26
26
  "react-sortablejs": "^6.1.4",