@opengeoweb/shared 20.1.0-nightly-20261018 → 20.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/index.esm.js CHANGED
@@ -1,17 +1,19 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
- import { Box, Typography, useTheme, Tooltip, IconButton, Menu, ListSubheader, MenuItem, Grid, FormControlLabel, Radio, ListItemText, ListItemIcon, DialogTitle, Button, Dialog, DialogContent, DialogActions, Paper, CircularProgress, Alert, AlertTitle, Drawer, Link, Avatar as Avatar$1, ClickAwayListener, MenuList, RadioGroup, Portal, List, ListItem, Tabs, Tab, Backdrop, Slider, ToggleButton, styled, Select, Accordion, AccordionSummary, AccordionDetails, FormLabel, Switch, TextField, InputAdornment, Chip, Stack, debounce as debounce$1, ListItemButton, Checkbox, FormControl, InputLabel, FilledInput } from '@mui/material';
2
+ import { Box, Typography, useTheme, Tooltip, IconButton, Menu, ListSubheader, MenuItem, Grid, FormControlLabel, Radio, ListItemText, ListItemIcon, DialogTitle, Button, Dialog, DialogContent, DialogActions, Paper, CircularProgress, Alert, AlertTitle, Drawer, Link, Avatar as Avatar$1, ClickAwayListener, MenuList, RadioGroup, Portal, List, ListItem, Tabs, Tab, Backdrop, Slider, ToggleButton, styled, Select, Accordion, AccordionSummary, AccordionDetails, FormLabel, Switch, TextField, InputAdornment, Chip, Stack, debounce as debounce$1, ListItemButton, Checkbox, FormControl, InputLabel, FilledInput, Card } from '@mui/material';
3
3
  import 'i18next';
4
4
  import { initReactI18next, useTranslation } from 'react-i18next';
5
5
  import React, { useRef, useEffect, useState, Component } from 'react';
6
6
  import Draggable from 'react-draggable';
7
7
  import { Resizable } from 're-resizable';
8
- import { Resize, BORDER_RADIUS, Options, Close, ChevronLeft, Exclamation, Success, Info, ChevronRight, GeoWebLogo, HamburgerMenu, Admin, useThemeContext, ThemeTypes, ArrowLeft, ArrowRight, KeyOption, ArrowUp, ArrowDown, KeyCommand, ChevronDown, Search, Clear, Cached, Filter as Filter$1, Menu as Menu$1, CalendarToday } from '@opengeoweb/theme';
8
+ import { Resize, BORDER_RADIUS, Options, Close, ChevronLeft, Exclamation, Success, Info, ChevronRight, GeoWebLogo, HamburgerMenu, Admin, useThemeContext, ThemeTypes, ArrowLeft, ArrowRight, KeyOption, ArrowUp, ArrowDown, KeyCommand, ChevronDown, Search, Clear, Cached, Filter as Filter$1, Menu as Menu$1, CalendarToday, ArrowDropDownDown, DragHandle } from '@opengeoweb/theme';
9
9
  import { throttle, isEqual, merge, escapeRegExp, debounce } from 'lodash';
10
10
  import { add as add$1, addMinutes, addHours, format, differenceInDays as differenceInDays$1, differenceInHours as differenceInHours$1, differenceInMinutes as differenceInMinutes$1, differenceInMonths as differenceInMonths$1, differenceInSeconds as differenceInSeconds$1, differenceInYears as differenceInYears$1, fromUnixTime, getHours as getHours$1, isAfter as isAfter$1, isBefore as isBefore$1, isEqual as isEqual$1, isValid as isValid$1, parseISO, roundToNearestMinutes as roundToNearestMinutes$1, set as set$1, setSeconds as setSeconds$1, parse, sub as sub$1, getUnixTime, getDay, getDayOfYear, getMonth, getWeek, getYear, isWithinInterval, startOfDay } from 'date-fns';
11
11
  import { fi as fi$1, nl as nl$1, nb, enGB } from 'date-fns/locale';
12
12
  import { DateTimePicker as DateTimePicker$1 } from '@mui/x-date-pickers';
13
13
  import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
14
14
  import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
15
+ import { useResizable } from 'react-resizable-layout';
16
+ import { ReactSortable } from 'react-sortablejs';
15
17
 
16
18
  var en = {
17
19
  "shared-choose-app-mode": "Choose your default app mode",
@@ -57,6 +59,7 @@ var en = {
57
59
  "shared-shortcut-or": "or",
58
60
  "shared-shortcut-toggle-workspace-time-scroll": "Toggle workspace time scroll ON and OFF",
59
61
  "shared-shortcut-open-location-search": "Open location search",
62
+ "shared-shortcut-open-workspace-menu": "Open workspace menu",
60
63
  "shared-shortcut-zoom-to-location": "Zoom map to location",
61
64
  "shared-shortcut-mouse-click": "+ Mouse click",
62
65
  "shared-shortcut-split-button": "click split window button",
@@ -126,6 +129,7 @@ var fi = {
126
129
  "shared-shortcut-or": "tai",
127
130
  "shared-shortcut-toggle-workspace-time-scroll": "Aseta työtilan ajan scrollaus päälle tai pois päältä",
128
131
  "shared-shortcut-open-location-search": "Avaa sijainnin haku",
132
+ "shared-shortcut-open-workspace-menu": "Avaa workspace menu",
129
133
  "shared-shortcut-zoom-to-location": "Zoomaa kartta sijaintiin",
130
134
  "shared-shortcut-mouse-click": "+ hiiren napsautus",
131
135
  "shared-shortcut-split-button": "napsauta Jaa ikkuna -painiketta",
@@ -192,6 +196,7 @@ var no = {
192
196
  "shared-shortcut-or": "eller",
193
197
  "shared-shortcut-toggle-workspace-time-scroll": "ikke oversatt",
194
198
  "shared-shortcut-open-location-search": "Åpne stedsøk",
199
+ "shared-shortcut-open-workspace-menu": "Åpne arbeidsflater",
195
200
  "shared-shortcut-zoom-to-location": "Zoom kart til sted",
196
201
  "shared-shortcut-mouse-click": "+ museklikk",
197
202
  "shared-shortcut-copy-view-preset-content-split-window": "kopier over viewpreset innhold når vindu deles",
@@ -260,6 +265,7 @@ var nl = {
260
265
  "shared-shortcut-split-button": "klik splits paneel knop",
261
266
  "shared-shortcut-toggle-workspace-time-scroll": "Zet workspace tijd scrollen AAN en UIT",
262
267
  "shared-shortcut-open-location-search": "Open locatie zoeken",
268
+ "shared-shortcut-open-workspace-menu": "Open workspace menu",
263
269
  "shared-shortcut-zoom-to-location": "Zoom kaart naar locatie",
264
270
  "shared-shortcut-mouse-click": "+ Muisklik",
265
271
  "shared-clear": "Wissen",
@@ -897,7 +903,8 @@ var ToggleMenu = function ToggleMenu(_ref) {
897
903
  _ref$buttonIcon = _ref.buttonIcon,
898
904
  buttonIcon = _ref$buttonIcon === void 0 ? jsx(Options, {}) : _ref$buttonIcon,
899
905
  _ref$isDisabled = _ref.isDisabled,
900
- isDisabled = _ref$isDisabled === void 0 ? false : _ref$isDisabled;
906
+ isDisabled = _ref$isDisabled === void 0 ? false : _ref$isDisabled,
907
+ onClose = _ref.onClose;
901
908
  var _React$useState = React.useState(null),
902
909
  anchorEl = _React$useState[0],
903
910
  setAnchorEl = _React$useState[1];
@@ -912,6 +919,7 @@ var ToggleMenu = function ToggleMenu(_ref) {
912
919
  var handleClose = function handleClose(event) {
913
920
  event.stopPropagation();
914
921
  setAnchorEl(null);
922
+ onClose == null || onClose();
915
923
  };
916
924
  var renderMenuItems = function renderMenuItems(items) {
917
925
  return items.map(function (menuItem) {
@@ -3610,6 +3618,16 @@ var ShortcutList = function ShortcutList(_ref) {
3610
3618
  type: "icon",
3611
3619
  children: "F"
3612
3620
  })
3621
+ }, {
3622
+ titleKey: 'shared-shortcut-open-workspace-menu',
3623
+ description: jsx(ShortCutSegment, {
3624
+ type: "icon",
3625
+ children: "W"
3626
+ }),
3627
+ descriptionMac: jsx(ShortCutSegment, {
3628
+ type: "icon",
3629
+ children: "W"
3630
+ })
3613
3631
  }, {
3614
3632
  titleKey: 'shared-shortcut-zoom-to-location',
3615
3633
  description: jsxs(Fragment, {
@@ -6920,6 +6938,534 @@ var DateTimePicker = function DateTimePicker(_ref) {
6920
6938
  });
6921
6939
  };
6922
6940
 
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;
6944
+ var ResizablePanel = /*#__PURE__*/React.forwardRef(function (_ref, contentRef) {
6945
+ var name = _ref.name,
6946
+ minWidthProp = _ref.minWidth,
6947
+ maxWidth = _ref.maxWidth,
6948
+ isOpen = _ref.isOpen,
6949
+ headerAction = _ref.headerAction,
6950
+ handleButtonComponent = _ref.handleButtonComponent,
6951
+ children = _ref.children,
6952
+ onSetIsOpen = _ref.onSetIsOpen,
6953
+ onSetCustomWidth = _ref.onSetCustomWidth,
6954
+ _onResizeStart = _ref.onResizeStart,
6955
+ _onResizeEnd = _ref.onResizeEnd,
6956
+ customWidth = _ref.customWidth,
6957
+ isDisplayed = _ref.isDisplayed,
6958
+ resizeOnViewCloseSignal = _ref.resizeOnViewCloseSignal,
6959
+ _ref$direction = _ref.direction,
6960
+ direction = _ref$direction === void 0 ? 'horizontal' : _ref$direction;
6961
+ var isVertical = direction === 'vertical';
6962
+ var minWidth = minWidthProp != null ? minWidthProp : isVertical ? PANEL_MIN_HEIGHT : PANEL_MIN_WIDTH;
6963
+ var sizeKey = isVertical ? 'height' : 'width';
6964
+ var containerRef = React.useRef(null);
6965
+ var widthRef = React.useRef(null);
6966
+ var isDraggingRef = React.useRef(false);
6967
+ var _React$useState = React.useState(false),
6968
+ autoSizing = _React$useState[0],
6969
+ setAutoSizing = _React$useState[1];
6970
+ var _React$useState2 = React.useState(false),
6971
+ growing = _React$useState2[0],
6972
+ setGrowing = _React$useState2[1];
6973
+ var growBasisRef = React.useRef(minWidth);
6974
+ var previousResizeSignalRef = React.useRef(resizeOnViewCloseSignal);
6975
+ var _useResizable = useResizable({
6976
+ containerRef: containerRef,
6977
+ axis: isVertical ? 'y' : 'x',
6978
+ min: minWidth,
6979
+ max: maxWidth || undefined,
6980
+ initial: customWidth != null ? customWidth : minWidth,
6981
+ onResizeStart: function onResizeStart() {
6982
+ isDraggingRef.current = true;
6983
+ setAutoSizing(false);
6984
+ _onResizeStart == null || _onResizeStart();
6985
+ },
6986
+ onResizeEnd: function onResizeEnd(_ref2) {
6987
+ var position = _ref2.position;
6988
+ isDraggingRef.current = false;
6989
+ if (position <= minWidth) {
6990
+ widthRef.current = null;
6991
+ onSetIsOpen == null || onSetIsOpen(false);
6992
+ } else {
6993
+ widthRef.current = position;
6994
+ onSetIsOpen == null || onSetIsOpen(true);
6995
+ onSetCustomWidth == null || onSetCustomWidth(position);
6996
+ }
6997
+ // Fire after the open/close calls so consumers tracking the drag
6998
+ // lifecycle (e.g. a "resizing" flag) reset only once the close above
6999
+ // has been handled.
7000
+ _onResizeEnd == null || _onResizeEnd();
7001
+ }
7002
+ }),
7003
+ containerWidth = _useResizable.position,
7004
+ setContainerWidth = _useResizable.setPosition,
7005
+ separatorProps = _useResizable.separatorProps;
7006
+ var openPanel = function openPanel() {
7007
+ var _ref3, _widthRef$current;
7008
+ var targetWidth = (_ref3 = (_widthRef$current = widthRef.current) != null ? _widthRef$current : customWidth) != null ? _ref3 : null;
7009
+ if (targetWidth != null) {
7010
+ setAutoSizing(false);
7011
+ setContainerWidth(Math.max(targetWidth, minWidth));
7012
+ onSetIsOpen == null || onSetIsOpen(true);
7013
+ return;
7014
+ }
7015
+ setAutoSizing(true);
7016
+ onSetIsOpen == null || onSetIsOpen(true);
7017
+ };
7018
+ var closePanel = React.useCallback(function () {
7019
+ setContainerWidth(minWidth);
7020
+ onSetIsOpen == null || onSetIsOpen(false);
7021
+ setAutoSizing(false);
7022
+ }, [minWidth, setContainerWidth, onSetIsOpen]);
7023
+ React.useEffect(function () {
7024
+ // While dragging, useResizable owns containerWidth based on the pointer.
7025
+ // Running the width-syncing branches here would jump away from the user's
7026
+ // drag position, so skip this effect until the drag ends.
7027
+ if (isDraggingRef.current) {
7028
+ return;
7029
+ }
7030
+ if (isOpen) {
7031
+ var _ref4, _widthRef$current2;
7032
+ var targetWidth = (_ref4 = (_widthRef$current2 = widthRef.current) != null ? _widthRef$current2 : customWidth) != null ? _ref4 : null;
7033
+ if (targetWidth != null) {
7034
+ setAutoSizing(false);
7035
+ setContainerWidth(Math.max(targetWidth, minWidth));
7036
+ } else {
7037
+ setAutoSizing(true);
7038
+ }
7039
+ } else {
7040
+ setContainerWidth(minWidth);
7041
+ setAutoSizing(false);
7042
+ }
7043
+ }, [isOpen, minWidth, setContainerWidth, customWidth]);
7044
+ // 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
7046
+ // single drag gesture without waiting for pointer release.
7047
+ React.useEffect(function () {
7048
+ if (!isDraggingRef.current) {
7049
+ return;
7050
+ }
7051
+ if (isOpen && containerWidth <= minWidth) {
7052
+ onSetIsOpen == null || onSetIsOpen(false);
7053
+ } else if (!isOpen && containerWidth > minWidth) {
7054
+ onSetIsOpen == null || onSetIsOpen(true);
7055
+ }
7056
+ }, [isOpen, containerWidth, minWidth, onSetIsOpen]);
7057
+ React.useEffect(function () {
7058
+ var viewCloseSignalChanged = previousResizeSignalRef.current !== resizeOnViewCloseSignal;
7059
+ if (!viewCloseSignalChanged) {
7060
+ return;
7061
+ }
7062
+ previousResizeSignalRef.current = resizeOnViewCloseSignal;
7063
+ var panelCanReclaimFreedSpace = isOpen && !autoSizing && !isDraggingRef.current;
7064
+ if (panelCanReclaimFreedSpace) {
7065
+ growBasisRef.current = Math.max(containerWidth, minWidth);
7066
+ setGrowing(true);
7067
+ }
7068
+ }, [resizeOnViewCloseSignal, isOpen, autoSizing, containerWidth, minWidth]);
7069
+ React.useLayoutEffect(function () {
7070
+ if (autoSizing) {
7071
+ return;
7072
+ }
7073
+ if (isDraggingRef.current) {
7074
+ return;
7075
+ }
7076
+ if (!isOpen && containerWidth > minWidth) {
7077
+ setContainerWidth(minWidth);
7078
+ return;
7079
+ }
7080
+ if (isOpen && containerWidth <= minWidth) {
7081
+ setAutoSizing(true);
7082
+ }
7083
+ }, [autoSizing, containerWidth, isOpen, minWidth, setContainerWidth]);
7084
+ React.useLayoutEffect(function () {
7085
+ if (!autoSizing || !containerRef.current) {
7086
+ return;
7087
+ }
7088
+ var raf1 = 0;
7089
+ var raf2 = 0;
7090
+ var measureContainerWidth = function measureContainerWidth() {
7091
+ if (!containerRef.current) {
7092
+ return;
7093
+ }
7094
+ var rect = containerRef.current.getBoundingClientRect();
7095
+ var calculatedWidth = Math.max(Math.round(rect[sizeKey]), minWidth);
7096
+ setContainerWidth(calculatedWidth);
7097
+ widthRef.current = calculatedWidth;
7098
+ setAutoSizing(false);
7099
+ };
7100
+ raf1 = requestAnimationFrame(function () {
7101
+ raf2 = requestAnimationFrame(measureContainerWidth);
7102
+ });
7103
+ // eslint-disable-next-line consistent-return
7104
+ return function () {
7105
+ cancelAnimationFrame(raf1);
7106
+ cancelAnimationFrame(raf2);
7107
+ };
7108
+ }, [autoSizing, minWidth, setContainerWidth, sizeKey]);
7109
+ React.useLayoutEffect(function () {
7110
+ if (!growing || !containerRef.current) {
7111
+ return;
7112
+ }
7113
+ var growRaf1 = 0;
7114
+ var growRaf2 = 0;
7115
+ var lockGrownWidth = function lockGrownWidth() {
7116
+ if (!containerRef.current) {
7117
+ return;
7118
+ }
7119
+ var rect = containerRef.current.getBoundingClientRect();
7120
+ var lockedWidth = Math.max(Math.round(rect[sizeKey]), minWidth);
7121
+ setContainerWidth(lockedWidth);
7122
+ widthRef.current = lockedWidth;
7123
+ setGrowing(false);
7124
+ };
7125
+ growRaf1 = requestAnimationFrame(function () {
7126
+ growRaf2 = requestAnimationFrame(lockGrownWidth);
7127
+ });
7128
+ // eslint-disable-next-line consistent-return
7129
+ return function () {
7130
+ cancelAnimationFrame(growRaf1);
7131
+ cancelAnimationFrame(growRaf2);
7132
+ };
7133
+ }, [growing, minWidth, setContainerWidth, sizeKey]);
7134
+ var sizeProps = function sizeProps(size, min) {
7135
+ return isVertical ? {
7136
+ width: '100%',
7137
+ height: size,
7138
+ minHeight: min,
7139
+ maxHeight: maxWidth || '100%'
7140
+ } : {
7141
+ width: size,
7142
+ minWidth: min,
7143
+ maxWidth: maxWidth || '100%'
7144
+ };
7145
+ };
7146
+ var cardStyleWhenAuto = Object.assign({
7147
+ display: isDisplayed ? 'block' : 'none',
7148
+ flex: '1 1 100%',
7149
+ boxSizing: 'border-box'
7150
+ }, sizeProps('auto', 0));
7151
+ var cardStyleWhenLocked = Object.assign({
7152
+ display: isDisplayed ? 'block' : 'none',
7153
+ flex: '0 1 auto',
7154
+ boxSizing: 'border-box'
7155
+ }, sizeProps(containerWidth, minWidth));
7156
+ var cardStyleWhenGrowing = Object.assign({
7157
+ display: isDisplayed ? 'block' : 'none',
7158
+ flex: growBasisRef.current + " 1 0px",
7159
+ boxSizing: 'border-box'
7160
+ }, sizeProps('auto', minWidth));
7161
+ var getActiveCardStyle = function getActiveCardStyle() {
7162
+ if (growing) {
7163
+ return cardStyleWhenGrowing;
7164
+ }
7165
+ if (autoSizing) {
7166
+ return cardStyleWhenAuto;
7167
+ }
7168
+ return cardStyleWhenLocked;
7169
+ };
7170
+ return jsx(Card, {
7171
+ className: "sortable-item",
7172
+ "data-autosizing": autoSizing ? 'true' : 'false',
7173
+ "data-growing": growing ? 'true' : 'false',
7174
+ "data-testid": "resizable-panel",
7175
+ ref: containerRef,
7176
+ sx: Object.assign({}, isVertical ? {} : {
7177
+ height: '100%'
7178
+ }, {
7179
+ position: 'relative'
7180
+ }, getActiveCardStyle()),
7181
+ children: jsxs(Box, {
7182
+ ref: contentRef,
7183
+ sx: {
7184
+ height: '100%',
7185
+ width: '100%'
7186
+ },
7187
+ children: [!isOpen && isVertical ? jsxs(Box, {
7188
+ "data-testid": "closed-panel-header",
7189
+ onClick: openPanel,
7190
+ sx: {
7191
+ width: '100%',
7192
+ height: '100%',
7193
+ display: 'flex',
7194
+ justifyContent: 'space-between',
7195
+ alignItems: 'center',
7196
+ cursor: 'pointer'
7197
+ },
7198
+ children: [jsx(Box, {
7199
+ onClick: function onClick(event) {
7200
+ return event.stopPropagation();
7201
+ },
7202
+ sx: {
7203
+ paddingTop: '4px'
7204
+ },
7205
+ children: handleButtonComponent
7206
+ }), jsxs(Box, {
7207
+ sx: {
7208
+ width: '100%',
7209
+ display: 'flex',
7210
+ alignItems: 'center',
7211
+ justifyContent: 'flex-end',
7212
+ paddingRight: '10px',
7213
+ overflow: 'hidden',
7214
+ marginTop: 0
7215
+ },
7216
+ children: [jsx(Box, {
7217
+ sx: {
7218
+ textOverflow: 'ellipsis',
7219
+ overflow: 'hidden',
7220
+ whiteSpace: 'nowrap',
7221
+ marginLeft: '16px',
7222
+ paddingTop: 0
7223
+ },
7224
+ children: name
7225
+ }), jsx(ArrowDropDownDown, {
7226
+ sx: {
7227
+ transform: 'rotate(180deg)'
7228
+ }
7229
+ })]
7230
+ })]
7231
+ }) : null, !isOpen && !isVertical && jsxs(Box, {
7232
+ "data-testid": "closed-panel-header",
7233
+ onClick: openPanel,
7234
+ sx: {
7235
+ display: 'flex',
7236
+ justifyContent: 'center',
7237
+ alignItems: 'center',
7238
+ writingMode: 'vertical-lr',
7239
+ transform: 'rotate(180deg)',
7240
+ paddingBottom: '10px',
7241
+ cursor: 'pointer'
7242
+ },
7243
+ children: [name, jsx(ArrowDropDownDown, {
7244
+ sx: {
7245
+ transform: 'rotate(90deg)'
7246
+ }
7247
+ }), jsx(Box, {
7248
+ onClick: function onClick(event) {
7249
+ return event.stopPropagation();
7250
+ },
7251
+ children: handleButtonComponent
7252
+ })]
7253
+ }), !!isOpen && jsx(Box, {
7254
+ "data-testid": "open-panel-header",
7255
+ sx: {
7256
+ display: 'flex',
7257
+ flexDirection: 'column',
7258
+ height: '100%'
7259
+ },
7260
+ children: jsxs(Stack, {
7261
+ sx: {
7262
+ height: '100%'
7263
+ },
7264
+ children: [jsxs(Box, {
7265
+ sx: {
7266
+ width: '100%',
7267
+ display: 'flex',
7268
+ justifyContent: 'space-between',
7269
+ flex: '0 0 auto'
7270
+ },
7271
+ children: [jsx(Box, {
7272
+ onClick: function onClick(event) {
7273
+ return event.stopPropagation();
7274
+ },
7275
+ sx: {
7276
+ paddingTop: '8px'
7277
+ },
7278
+ children: handleButtonComponent
7279
+ }), jsxs(Box, {
7280
+ onClick: closePanel,
7281
+ sx: {
7282
+ width: '100%',
7283
+ display: 'flex',
7284
+ alignItems: 'center',
7285
+ justifyContent: 'flex-end',
7286
+ paddingRight: '10px',
7287
+ overflow: 'hidden',
7288
+ marginTop: '4px',
7289
+ cursor: 'pointer'
7290
+ },
7291
+ children: [jsx(Box, {
7292
+ onClick: function onClick(event) {
7293
+ return event.stopPropagation();
7294
+ },
7295
+ children: !!headerAction && headerAction
7296
+ }), jsx(Box, {
7297
+ sx: {
7298
+ textOverflow: 'ellipsis',
7299
+ overflow: 'hidden',
7300
+ whiteSpace: 'nowrap',
7301
+ marginLeft: '16px',
7302
+ height: '100%',
7303
+ paddingTop: '3px'
7304
+ },
7305
+ children: name
7306
+ }), jsx(ArrowDropDownDown, {})]
7307
+ })]
7308
+ }), jsx(Box, {
7309
+ sx: {
7310
+ display: 'flex',
7311
+ justifyContent: 'center',
7312
+ alignItems: 'stretch',
7313
+ flex: 1,
7314
+ minHeight: 0,
7315
+ overflow: 'hidden'
7316
+ },
7317
+ children: children
7318
+ })]
7319
+ })
7320
+ }), jsx(Box, Object.assign({
7321
+ "data-testid": "resizable-panel-drag-handle"
7322
+ }, separatorProps, {
7323
+ sx: Object.assign({
7324
+ position: 'absolute'
7325
+ }, isVertical ? {
7326
+ left: 0,
7327
+ bottom: 0,
7328
+ width: '100%',
7329
+ height: '5px',
7330
+ cursor: 'row-resize'
7331
+ } : {
7332
+ right: 0,
7333
+ top: 0,
7334
+ height: '100%',
7335
+ width: '5px',
7336
+ cursor: 'col-resize'
7337
+ })
7338
+ }))]
7339
+ })
7340
+ });
7341
+ });
7342
+ ResizablePanel.displayName = 'ResizablePanel';
7343
+
7344
+ var ResizablePanelStandalone = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
7345
+ var name = _ref.name,
7346
+ children = _ref.children,
7347
+ headerAction = _ref.headerAction,
7348
+ isDisplayed = _ref.isDisplayed,
7349
+ maxWidth = _ref.maxWidth,
7350
+ minWidth = _ref.minWidth,
7351
+ handleButtonComponent = _ref.handleButtonComponent,
7352
+ onOpenChange = _ref.onOpenChange,
7353
+ onResizeStart = _ref.onResizeStart,
7354
+ onResizeEnd = _ref.onResizeEnd,
7355
+ direction = _ref.direction;
7356
+ var _React$useState = React.useState(true),
7357
+ isOpen = _React$useState[0],
7358
+ setIsOpen = _React$useState[1];
7359
+ var _React$useState2 = React.useState(undefined),
7360
+ customWidth = _React$useState2[0],
7361
+ setCustomWidth = _React$useState2[1];
7362
+ var handleSetIsOpen = React.useCallback(function (open) {
7363
+ setIsOpen(open);
7364
+ onOpenChange == null || onOpenChange(open);
7365
+ }, [onOpenChange]);
7366
+ return jsx(ResizablePanel, {
7367
+ customWidth: customWidth,
7368
+ direction: direction,
7369
+ handleButtonComponent: handleButtonComponent,
7370
+ headerAction: headerAction,
7371
+ isDisplayed: isDisplayed,
7372
+ isOpen: isOpen,
7373
+ maxWidth: maxWidth,
7374
+ minWidth: minWidth,
7375
+ name: name,
7376
+ onResizeEnd: onResizeEnd,
7377
+ onResizeStart: onResizeStart,
7378
+ onSetCustomWidth: setCustomWidth,
7379
+ onSetIsOpen: handleSetIsOpen,
7380
+ ref: ref,
7381
+ children: children
7382
+ });
7383
+ });
7384
+ ResizablePanelStandalone.displayName = 'ResizablePanelStandalone';
7385
+
7386
+ var SortablePanels = function SortablePanels(_ref) {
7387
+ var panels = _ref.panels,
7388
+ onOrderChange = _ref.onOrderChange,
7389
+ _ref$panelComponent = _ref.panelComponent,
7390
+ PanelComponent = _ref$panelComponent === void 0 ? ResizablePanelStandalone : _ref$panelComponent,
7391
+ viewId = _ref.viewId,
7392
+ _ref$direction = _ref.direction,
7393
+ direction = _ref$direction === void 0 ? 'horizontal' : _ref$direction;
7394
+ return jsx(Box, {
7395
+ sx: {
7396
+ display: 'flex',
7397
+ flexDirection: direction === 'vertical' ? 'column' : 'row',
7398
+ width: '100%',
7399
+ height: '100%',
7400
+ padding: 1
7401
+ },
7402
+ children: jsx(ReactSortable, {
7403
+ animation: 200,
7404
+ direction: direction,
7405
+ draggable: ".sortable-item",
7406
+ handle: ".drag-handle",
7407
+ list: panels.map(function (_ref2) {
7408
+ var id = _ref2.id,
7409
+ name = _ref2.name,
7410
+ isDisplayed = _ref2.isDisplayed;
7411
+ return {
7412
+ id: id,
7413
+ name: name,
7414
+ isDisplayed: isDisplayed
7415
+ };
7416
+ }),
7417
+ setList: function setList(list) {
7418
+ return onOrderChange(list.map(function (_ref3) {
7419
+ var id = _ref3.id,
7420
+ name = _ref3.name,
7421
+ isDisplayed = _ref3.isDisplayed;
7422
+ return {
7423
+ id: id,
7424
+ name: name,
7425
+ isDisplayed: isDisplayed
7426
+ };
7427
+ }));
7428
+ },
7429
+ style: {
7430
+ display: 'flex',
7431
+ flexDirection: direction === 'vertical' ? 'column' : 'row',
7432
+ gap: 4,
7433
+ width: '100%'
7434
+ },
7435
+ tag: "div",
7436
+ children: panels.map(function (panel) {
7437
+ return jsx(PanelComponent, {
7438
+ direction: direction,
7439
+ handleButtonComponent: jsx(IconButton, {
7440
+ "aria-label": "drag-handle",
7441
+ className: "drag-handle",
7442
+ size: "small",
7443
+ sx: {
7444
+ width: '24px',
7445
+ height: '24px'
7446
+ },
7447
+ children: jsx(DragHandle, {
7448
+ fontSize: "small"
7449
+ })
7450
+ }),
7451
+ headerAction: panel.headerAction,
7452
+ isDisplayed: panel.isDisplayed,
7453
+ maxWidth: panel.maxWidth,
7454
+ minWidth: panel.minWidth,
7455
+ name: panel.name,
7456
+ onOpenChange: panel.onOpenChange,
7457
+ onResizeEnd: panel.onResizeEnd,
7458
+ onResizeStart: panel.onResizeStart,
7459
+ panelId: panel.id,
7460
+ ref: panel.panelRef,
7461
+ viewId: viewId,
7462
+ children: panel.render()
7463
+ }, panel.id);
7464
+ })
7465
+ })
7466
+ });
7467
+ };
7468
+
6923
7469
  /* *
6924
7470
  * Licensed under the Apache License, Version 2.0 (the "License");
6925
7471
  * you may not use this file except in compliance with the License.
@@ -6944,4 +7490,4 @@ var SystemScope = {
6944
7490
  plugin: 'plugin'
6945
7491
  };
6946
7492
 
6947
- 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, SHARED_NAMESPACE, SearchField$1 as SearchField, SearchFieldButton, SearchHighlight, SessionStorageKey, 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 };
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 };
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare const MultipleResizablePanelsDemo: () => React.JSX.Element;
@@ -0,0 +1,23 @@
1
+ import React from 'react';
2
+ export interface ResizablePanelProps {
3
+ name: string;
4
+ minWidth?: number;
5
+ maxWidth?: number;
6
+ isOpen?: boolean;
7
+ headerAction?: React.ReactElement;
8
+ handleButtonComponent?: React.ReactElement;
9
+ children?: React.ReactNode;
10
+ onSetIsOpen?: (isOpen: boolean) => void;
11
+ onSetCustomWidth?: (width: number) => void;
12
+ onResizeStart?: () => void;
13
+ onResizeEnd?: () => void;
14
+ customWidth?: number;
15
+ isDisplayed?: boolean;
16
+ resizeOnViewCloseSignal?: number;
17
+ /**
18
+ * Direction in which the panel is resized. In 'vertical' mode the panel is
19
+ * resized by height; minWidth/maxWidth/customWidth then apply to the height.
20
+ */
21
+ direction?: 'horizontal' | 'vertical';
22
+ }
23
+ export declare const ResizablePanel: React.ForwardRefExoticComponent<ResizablePanelProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+ export interface ResizablePanelWrapperProps {
3
+ name: string;
4
+ children: React.ReactNode;
5
+ isDisplayed: boolean;
6
+ /**
7
+ * Optional. Only used by redux-aware panel components (e.g.
8
+ * SoundingsPanelConnect) to key external state. Standalone usage ignores it.
9
+ */
10
+ panelId?: string;
11
+ /**
12
+ * Optional. Only used by redux-aware panel components to key external state
13
+ * by parent view. Standalone usage ignores it.
14
+ */
15
+ viewId?: string;
16
+ headerAction?: React.ReactElement;
17
+ handleButtonComponent?: React.ReactElement;
18
+ maxWidth?: number;
19
+ minWidth?: number;
20
+ onOpenChange?: (isOpen: boolean) => void;
21
+ onResizeStart?: () => void;
22
+ onResizeEnd?: () => void;
23
+ direction?: 'horizontal' | 'vertical';
24
+ }
25
+ export type ResizablePanelComponent = React.ForwardRefExoticComponent<ResizablePanelWrapperProps & React.RefAttributes<HTMLDivElement>>;
26
+ export declare const ResizablePanelStandalone: React.ForwardRefExoticComponent<ResizablePanelWrapperProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,4 @@
1
+ export { ResizablePanel } from './ResizablePanel';
2
+ export type { ResizablePanelProps } from './ResizablePanel';
3
+ export { ResizablePanelStandalone } from './ResizablePanelStandalone';
4
+ export type { ResizablePanelWrapperProps, ResizablePanelComponent, } from './ResizablePanelStandalone';
@@ -0,0 +1,32 @@
1
+ import React from 'react';
2
+ import type { ResizablePanelComponent } from '../ResizablePanel/ResizablePanelStandalone';
3
+ export interface SortablePanelItem {
4
+ id: string;
5
+ name: string;
6
+ isDisplayed: boolean;
7
+ minWidth?: number;
8
+ maxWidth?: number;
9
+ headerAction?: React.ReactElement;
10
+ render: () => React.ReactNode;
11
+ panelRef?: React.Ref<HTMLDivElement>;
12
+ onOpenChange?: (isOpen: boolean) => void;
13
+ onResizeStart?: () => void;
14
+ onResizeEnd?: () => void;
15
+ }
16
+ export interface SortablePanelsProps {
17
+ panels: SortablePanelItem[];
18
+ onOrderChange: (newOrder: {
19
+ id: string;
20
+ name: string;
21
+ isDisplayed: boolean;
22
+ }[]) => void;
23
+ panelComponent?: ResizablePanelComponent;
24
+ /**
25
+ * Optional. Forwarded to each rendered panel component. Redux-aware panel
26
+ * components use it to scope their external state by parent view.
27
+ */
28
+ viewId?: string;
29
+ /** Direction in which panels are laid out, sorted and resized. Defaults to 'horizontal'. */
30
+ direction?: 'horizontal' | 'vertical';
31
+ }
32
+ export declare const SortablePanels: ({ panels, onOrderChange, panelComponent: PanelComponent, viewId, direction, }: SortablePanelsProps) => React.ReactElement;
@@ -0,0 +1,2 @@
1
+ export { SortablePanels } from './SortablePanels';
2
+ export type { SortablePanelsProps, SortablePanelItem } from './SortablePanels';
@@ -38,6 +38,7 @@ interface ToggleMenuProps {
38
38
  isDefaultOpen?: boolean;
39
39
  buttonIcon?: React.ReactNode;
40
40
  isDisabled?: boolean;
41
+ onClose?: () => void;
41
42
  }
42
43
  export declare const ToggleMenu: React.FC<ToggleMenuProps>;
43
44
  export {};
@@ -27,3 +27,5 @@ export * from './LegendToggleButton';
27
27
  export * from './Storybook';
28
28
  export * from './NumberWithUnitField';
29
29
  export * from './DateTimePicker';
30
+ export * from './ResizablePanel';
31
+ export * from './SortablePanels';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeoweb/shared",
3
- "version": "20.1.0-nightly-20261018",
3
+ "version": "20.2.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,8 +20,10 @@
20
20
  }
21
21
  },
22
22
  "dependencies": {
23
- "@opengeoweb/theme": "20.1.0-nightly-20261018",
23
+ "@opengeoweb/theme": "20.2.0",
24
24
  "react-draggable": "^4.4.6",
25
+ "react-resizable-layout": "^0.7.3",
26
+ "react-sortablejs": "^6.1.4",
25
27
  "re-resizable": "^6.9.11",
26
28
  "lodash": "^4.18.1",
27
29
  "axios": "^1.20.0",