@opengeoweb/shared 19.3.0 → 19.5.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,11 +1,11 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
- import { Box, Typography, useTheme, Tooltip, IconButton, Menu, ListSubheader, MenuItem, Grid, ListItemText, ListItemIcon, DialogTitle, Button, Dialog, DialogContent, DialogActions, Paper, CircularProgress, Alert, AlertTitle, Drawer, Link, Avatar as Avatar$1, ClickAwayListener, MenuList, RadioGroup, FormControlLabel, Radio, 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 } from '@mui/material';
2
+ import { Box, Typography, useTheme, Tooltip, IconButton, Menu, ListSubheader, MenuItem, Grid, ListItemText, ListItemIcon, FormControlLabel, Radio, 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 } 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 } from '@opengeoweb/theme';
8
+ import { Resize, BORDER_RADIUS, Options, ChevronUp, ChevronDown, Close, ChevronLeft, Exclamation, Success, Info, ChevronRight, GeoWebLogo, HamburgerMenu, Admin, useThemeContext, ThemeTypes, ArrowLeft, ArrowRight, KeyOption, ArrowUp, ArrowDown, KeyCommand, Search, Clear, Cached, Filter as Filter$1, Menu as Menu$1 } from '@opengeoweb/theme';
9
9
  import { throttle, isEqual, merge, escapeRegExp, debounce } from 'lodash';
10
10
  import { add as add$1, startOfDay, 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 } from 'date-fns';
11
11
  import { fi as fi$1, nl as nl$1, nb, enGB } from 'date-fns/locale';
@@ -882,6 +882,9 @@ var ToggleMenu = function ToggleMenu(_ref) {
882
882
  var _React$useState = React.useState(null),
883
883
  anchorEl = _React$useState[0],
884
884
  setAnchorEl = _React$useState[1];
885
+ var _React$useState2 = React.useState({}),
886
+ expandedSubMenus = _React$useState2[0],
887
+ setExpandedSubMenus = _React$useState2[1];
885
888
  var isOpen = Boolean(anchorEl);
886
889
  var _getPosition = getPosition(menuPosition),
887
890
  anchorOrigin = _getPosition.anchorOrigin,
@@ -893,6 +896,125 @@ var ToggleMenu = function ToggleMenu(_ref) {
893
896
  var handleClose = function handleClose(event) {
894
897
  event.stopPropagation();
895
898
  setAnchorEl(null);
899
+ setExpandedSubMenus({});
900
+ };
901
+ var toggleSubMenu = function toggleSubMenu(menuText) {
902
+ setExpandedSubMenus(function (currentExpandedSubMenus) {
903
+ var _Object$assign;
904
+ return Object.assign({}, currentExpandedSubMenus, (_Object$assign = {}, _Object$assign[menuText] = !currentExpandedSubMenus[menuText], _Object$assign));
905
+ });
906
+ };
907
+ var _renderMenuItems = function renderMenuItems(items, nestingLevel) {
908
+ if (nestingLevel === void 0) {
909
+ nestingLevel = 0;
910
+ }
911
+ return items.map(function (menuItem) {
912
+ var text = menuItem.text,
913
+ icon = menuItem.icon,
914
+ action = menuItem.action,
915
+ isDisabled = menuItem.isDisabled,
916
+ isSelected = menuItem.isSelected,
917
+ controlType = menuItem.controlType,
918
+ subMenuItems = menuItem.subMenuItems;
919
+ var hasSubMenuItems = Boolean(subMenuItems == null ? void 0 : subMenuItems.length);
920
+ var isRadioControl = controlType === 'radio';
921
+ if (hasSubMenuItems) {
922
+ var isExpanded = Boolean(expandedSubMenus[text]);
923
+ return jsxs(React.Fragment, {
924
+ children: [jsx(MenuItem, {
925
+ "aria-expanded": isExpanded,
926
+ disabled: isDisabled,
927
+ onClick: function onClick(event) {
928
+ event.stopPropagation();
929
+ toggleSubMenu(text);
930
+ },
931
+ sx: nestingLevel > 0 ? {
932
+ pl: 2 + nestingLevel * 2
933
+ } : undefined,
934
+ children: jsxs(Grid, {
935
+ container: true,
936
+ size: "grow",
937
+ spacing: 2,
938
+ sx: {
939
+ justifyContent: 'space-between'
940
+ },
941
+ children: [jsx(Grid, {
942
+ children: jsx(ListItemText, {
943
+ children: text
944
+ })
945
+ }), jsx(Grid, {
946
+ sx: {
947
+ alignItems: 'flex-end'
948
+ },
949
+ children: jsx(ListItemIcon, {
950
+ sx: {
951
+ '&.MuiListItemIcon-root': {
952
+ minWidth: '24px'
953
+ }
954
+ },
955
+ children: isExpanded ? jsx(ChevronUp, {}) : jsx(ChevronDown, {})
956
+ })
957
+ })]
958
+ })
959
+ }), isExpanded ? jsx(Box, {
960
+ children: _renderMenuItems(subMenuItems, nestingLevel + 1)
961
+ }) : null]
962
+ }, text);
963
+ }
964
+ return jsx(MenuItem, {
965
+ disabled: isDisabled,
966
+ onClick: function onClick(event) {
967
+ action(event);
968
+ handleClose(event);
969
+ },
970
+ selected: !isRadioControl && isSelected,
971
+ sx: nestingLevel > 0 ? {
972
+ pl: 2 + nestingLevel * 2
973
+ } : undefined,
974
+ children: jsxs(Grid, {
975
+ container: true,
976
+ size: "grow",
977
+ spacing: 2,
978
+ sx: {
979
+ justifyContent: 'space-between'
980
+ },
981
+ children: [jsx(Grid, {
982
+ sx: {
983
+ display: 'flex',
984
+ alignItems: 'center'
985
+ },
986
+ children: isRadioControl ? jsx(FormControlLabel, {
987
+ control: jsx(Radio, {
988
+ checked: Boolean(isSelected),
989
+ disableRipple: true,
990
+ size: "small",
991
+ tabIndex: -1
992
+ }),
993
+ label: text,
994
+ sx: {
995
+ margin: 0,
996
+ pointerEvents: 'none',
997
+ width: '100%'
998
+ }
999
+ }) : jsx(ListItemText, {
1000
+ children: text
1001
+ })
1002
+ }), icon ? jsx(Grid, {
1003
+ sx: {
1004
+ alignItems: 'flex-end'
1005
+ },
1006
+ children: jsx(ListItemIcon, {
1007
+ sx: {
1008
+ '&.MuiListItemIcon-root': {
1009
+ minWidth: '24px'
1010
+ }
1011
+ },
1012
+ children: icon
1013
+ })
1014
+ }) : null]
1015
+ })
1016
+ }, text);
1017
+ });
896
1018
  };
897
1019
  React.useEffect(function () {
898
1020
  if (isDefaultOpen) {
@@ -945,45 +1067,7 @@ var ToggleMenu = function ToggleMenu(_ref) {
945
1067
  },
946
1068
  children: menuTitle
947
1069
  })
948
- }) : null, menuItems != null && menuItems.length ? menuItems.map(function (menuItem) {
949
- var text = menuItem.text,
950
- icon = menuItem.icon,
951
- action = menuItem.action,
952
- isDisabled = menuItem.isDisabled;
953
- return jsx(MenuItem, {
954
- disabled: isDisabled,
955
- onClick: function onClick(event) {
956
- action(event);
957
- handleClose(event);
958
- },
959
- selected: menuItem.isSelected,
960
- children: jsxs(Grid, {
961
- container: true,
962
- size: "grow",
963
- spacing: 2,
964
- sx: {
965
- justifyContent: 'space-between'
966
- },
967
- children: [jsx(Grid, {
968
- children: jsx(ListItemText, {
969
- children: text
970
- })
971
- }), icon ? jsx(Grid, {
972
- sx: {
973
- alignItems: 'flex-end'
974
- },
975
- children: jsx(ListItemIcon, {
976
- sx: {
977
- '&.MuiListItemIcon-root': {
978
- minWidth: '24px'
979
- }
980
- },
981
- children: icon
982
- })
983
- }) : null]
984
- })
985
- }, text);
986
- }) : jsx("div", {}) // Needed to make the menu work without any menuItems
1070
+ }) : null, menuItems != null && menuItems.length ? _renderMenuItems(menuItems) : jsx("div", {}) // Needed to make the menu work without any menuItems
987
1071
  , secondaryMenuTitle ? jsx(ListSubheader, {
988
1072
  "data-testid": "toggleMenuSecondaryTitle",
989
1073
  children: jsx(Typography, {
@@ -992,45 +1076,7 @@ var ToggleMenu = function ToggleMenu(_ref) {
992
1076
  },
993
1077
  children: secondaryMenuTitle
994
1078
  })
995
- }) : null, secondaryMenuItems != null && secondaryMenuItems.length ? secondaryMenuItems.map(function (menuItem) {
996
- var text = menuItem.text,
997
- icon = menuItem.icon,
998
- action = menuItem.action,
999
- isDisabled = menuItem.isDisabled;
1000
- return jsx(MenuItem, {
1001
- disabled: isDisabled,
1002
- onClick: function onClick(event) {
1003
- action(event);
1004
- handleClose(event);
1005
- },
1006
- selected: menuItem.isSelected,
1007
- children: jsxs(Grid, {
1008
- container: true,
1009
- size: "grow",
1010
- spacing: 2,
1011
- sx: {
1012
- justifyContent: 'space-between'
1013
- },
1014
- children: [jsx(Grid, {
1015
- children: jsx(ListItemText, {
1016
- children: text
1017
- })
1018
- }), icon ? jsx(Grid, {
1019
- sx: {
1020
- alignItems: 'flex-end'
1021
- },
1022
- children: jsx(ListItemIcon, {
1023
- sx: {
1024
- '&.MuiListItemIcon-root': {
1025
- minWidth: '24px'
1026
- }
1027
- },
1028
- children: icon
1029
- })
1030
- }) : null]
1031
- })
1032
- }, text);
1033
- }) : jsx("div", {}) // Needed to make the menu work without any menuItems
1079
+ }) : null, secondaryMenuItems != null && secondaryMenuItems.length ? _renderMenuItems(secondaryMenuItems) : jsx("div", {}) // Needed to make the menu work without any menuItems
1034
1080
  , children]
1035
1081
  })]
1036
1082
  });
@@ -4029,6 +4075,9 @@ var TooltipSelect = function TooltipSelect(_ref) {
4029
4075
  onWheel: onWheel
4030
4076
  });
4031
4077
  return jsx(CustomTooltip, {
4078
+ disableFocusListener: true,
4079
+ disableHoverListener: true,
4080
+ disableTouchListener: true,
4032
4081
  open: tooltipOpen,
4033
4082
  placement: "top",
4034
4083
  title: tooltip,
@@ -4456,25 +4505,17 @@ var SearchField$1 = function SearchField(_ref) {
4456
4505
  }
4457
4506
  };
4458
4507
  React.useEffect(function () {
4459
- if (isURL(localSearchString)) {
4460
- setUrlIsValid(true);
4461
- }
4508
+ setUrlIsValid(isURL(localSearchString));
4462
4509
  }, [localSearchString]);
4463
- React.useEffect(function () {
4464
- var keyDownHandler = function keyDownHandler(event) {
4465
- if (event.key === 'Enter') {
4466
- event.preventDefault();
4467
- if (urlIsValid && onOpenServicePopup) {
4468
- onOpenServicePopup(localSearchString);
4469
- setLocalSearchString('');
4470
- }
4510
+ var handleKeyDown = function handleKeyDown(event) {
4511
+ if (event.key === 'Enter') {
4512
+ event.preventDefault();
4513
+ if (urlIsValid && onOpenServicePopup) {
4514
+ onOpenServicePopup(localSearchString);
4515
+ setLocalSearchString('');
4471
4516
  }
4472
- };
4473
- document.addEventListener('keydown', keyDownHandler);
4474
- return function () {
4475
- document.removeEventListener('keydown', keyDownHandler);
4476
- };
4477
- }, [urlIsValid, localSearchString, onOpenServicePopup]);
4517
+ }
4518
+ };
4478
4519
  // mirror store unless typing a URL
4479
4520
  React.useEffect(function () {
4480
4521
  if (isURL(localSearchString)) {
@@ -4490,6 +4531,7 @@ var SearchField$1 = function SearchField(_ref) {
4490
4531
  onChange: function onChange(e) {
4491
4532
  handleChange(e.target.value);
4492
4533
  },
4534
+ onKeyDown: handleKeyDown,
4493
4535
  slotProps: {
4494
4536
  input: {
4495
4537
  endAdornment: jsx(InputAdornment, {
@@ -5240,6 +5282,38 @@ var FilterOption = function FilterOption(_ref) {
5240
5282
  });
5241
5283
  };
5242
5284
 
5285
+ var LegendToggleButton = function LegendToggleButton(_ref) {
5286
+ var isLegendVisible = _ref.isLegendVisible,
5287
+ onToggle = _ref.onToggle,
5288
+ showTooltipText = _ref.showTooltipText,
5289
+ hideTooltipText = _ref.hideTooltipText,
5290
+ legendLabel = _ref.legendLabel,
5291
+ sx = _ref.sx;
5292
+ return jsx(CustomTooltip, {
5293
+ title: isLegendVisible ? hideTooltipText : showTooltipText,
5294
+ children: jsxs(CustomToggleButton, {
5295
+ "aria-label": isLegendVisible ? hideTooltipText : showTooltipText,
5296
+ onClick: onToggle,
5297
+ selected: isLegendVisible,
5298
+ size: "small",
5299
+ sx: [{
5300
+ height: '10px !important',
5301
+ '& span': {
5302
+ fontSize: '9pt',
5303
+ whiteSpace: 'nowrap',
5304
+ textOverflow: 'ellipsis',
5305
+ overflow: 'hidden'
5306
+ }
5307
+ }].concat(Array.isArray(sx) ? sx : [sx]),
5308
+ variant: "tool",
5309
+ children: [jsx(Menu$1, {}), jsx("span", {
5310
+ className: "longText",
5311
+ children: legendLabel
5312
+ })]
5313
+ })
5314
+ });
5315
+ };
5316
+
5243
5317
  var _excluded = ["isDark", "children", "sx"];
5244
5318
  var StorybookDocsWrapper = function StorybookDocsWrapper(_ref) {
5245
5319
  var _ref$isDark = _ref.isDark,
@@ -6252,6 +6326,28 @@ var index = /*#__PURE__*/Object.freeze({
6252
6326
  resolveReferenceTimeInstance: resolveReferenceTimeInstance
6253
6327
  });
6254
6328
 
6329
+ var URL_REGEX = /(https?:\/\/[^\s<>"')]+)/g;
6330
+ // Splits text on URLs and turns them into links
6331
+ var linkifyText = function linkifyText(text, keyPrefix) {
6332
+ if (keyPrefix === void 0) {
6333
+ keyPrefix = 'linkified';
6334
+ }
6335
+ return text.split(URL_REGEX).filter(function (url) {
6336
+ return url !== '';
6337
+ }).map(function (part, index) {
6338
+ return /^https?:\/\//.test(part) ? jsx(Link, {
6339
+ href: part,
6340
+ rel: "noopener noreferrer",
6341
+ target: "_blank",
6342
+ children: part
6343
+ }, keyPrefix + "-" + index) :
6344
+ // eslint-disable-next-line react/no-array-index-key
6345
+ jsx(React.Fragment, {
6346
+ children: part
6347
+ }, keyPrefix + "-" + index);
6348
+ });
6349
+ };
6350
+
6255
6351
  /* *
6256
6352
  * Licensed under the Apache License, Version 2.0 (the "License");
6257
6353
  * you may not use this file except in compliance with the License.
@@ -6471,6 +6567,54 @@ var sessionStorageProvider = {
6471
6567
  }
6472
6568
  };
6473
6569
 
6570
+ /* *
6571
+ * Licensed under the Apache License, Version 2.0 (the "License");
6572
+ * you may not use this file except in compliance with the License.
6573
+ * You may obtain a copy of the License at
6574
+ *
6575
+ * http://www.apache.org/licenses/LICENSE-2.0
6576
+ *
6577
+ * Unless required by applicable law or agreed to in writing, software
6578
+ * distributed under the License is distributed on an "AS IS" BASIS,
6579
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6580
+ * See the License for the specific language governing permissions and
6581
+ * limitations under the License.
6582
+ *
6583
+ * Copyright 2026 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
6584
+ * Copyright 2026 - Finnish Meteorological Institute (FMI)
6585
+ * Copyright 2026 - The Norwegian Meteorological Institute (MET Norway)
6586
+ * */
6587
+ // ARIA roles whose elements handle keyboard events internally
6588
+ var INTERACTIVE_ARIA_ROLES = new Set(['combobox',
6589
+ // MUI Select trigger, autocomplete inputs
6590
+ 'listbox',
6591
+ // Open select dropdown
6592
+ 'option',
6593
+ // Focused item inside an open listbox
6594
+ 'spinbutton',
6595
+ // Numeric inputs with up/down arrow navigation
6596
+ 'slider' // Range/slider controls
6597
+ ]);
6598
+ /**
6599
+ * Returns true if the element is an interactive control where keyboard events
6600
+ * have a native meaning (typing, selecting, incrementing)
6601
+ */
6602
+ var isTargetInteractiveInput = function isTargetInteractiveInput(target) {
6603
+ if (!target) {
6604
+ return false;
6605
+ }
6606
+ var el = target;
6607
+ var role = target.getAttribute == null ? void 0 : target.getAttribute('role');
6608
+ return target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.tagName === 'SELECT' || Boolean(el.isContentEditable) || (el.getAttribute == null ? void 0 : el.getAttribute('contenteditable')) === 'true' || role !== null && role !== undefined && INTERACTIVE_ARIA_ROLES.has(role);
6609
+ };
6610
+ /**
6611
+ * Returns true if keyboard focus is currently inside a floating dialog/panel
6612
+ */
6613
+ var isDialogFocused = function isDialogFocused() {
6614
+ var _document$activeEleme;
6615
+ return Boolean((_document$activeEleme = document.activeElement) == null ? void 0 : _document$activeEleme.closest('[role="dialog"]'));
6616
+ };
6617
+
6474
6618
  /* *
6475
6619
  * Licensed under the Apache License, Version 2.0 (the "License");
6476
6620
  * you may not use this file except in compliance with the License.
@@ -6495,4 +6639,4 @@ var SystemScope = {
6495
6639
  plugin: 'plugin'
6496
6640
  };
6497
6641
 
6498
- 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, DraggableComponent$1 as Draggable, ErrorBoundary, Filter, FilterChip, FilterOption, LastUpdateTime, 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, calculateDialogSizeAndPosition, calculateStartSize, index$1 as dateUtils, defaultDelay, getAxiosErrorMessage, getAxiosWarningMessage, getErrorMessage, getInitials, getLastUpdateTitle, getPosition, getWarningMessage, isAuthError, isAxiosAuthError, isAxiosError, loadAllTranslations, pollingIntervalTimeout, index as referenceTimeUtils, renderCounter, safelyInitI18nForTestsAndStories, sessionStorageProvider, sharedTranslations, showPrompt, sliderHeaderStyle, tooltipContainerStyles, useConfirmationDialog, useControlledTooltip, useDebounce, useDialogActions, useIsMounted, useMakeSureContainerStaysInsideWindow, usePoller, usePreventBrowserClose, usePrevious, useResizeObserver, useScrollingInIsolation, useUserMenu, useWheelStopPropagation };
6642
+ 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, DraggableComponent$1 as Draggable, ErrorBoundary, Filter, FilterChip, FilterOption, LastUpdateTime, LegendToggleButton, 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, calculateDialogSizeAndPosition, calculateStartSize, index$1 as dateUtils, defaultDelay, getAxiosErrorMessage, getAxiosWarningMessage, getErrorMessage, getInitials, getLastUpdateTitle, getPosition, getWarningMessage, isAuthError, isAxiosAuthError, isAxiosError, isDialogFocused, isTargetInteractiveInput, linkifyText, loadAllTranslations, pollingIntervalTimeout, index as referenceTimeUtils, renderCounter, safelyInitI18nForTestsAndStories, sessionStorageProvider, sharedTranslations, showPrompt, sliderHeaderStyle, tooltipContainerStyles, useConfirmationDialog, useControlledTooltip, useDebounce, useDialogActions, useIsMounted, useMakeSureContainerStaysInsideWindow, usePoller, usePreventBrowserClose, usePrevious, useResizeObserver, useScrollingInIsolation, useUserMenu, useWheelStopPropagation };
@@ -0,0 +1,12 @@
1
+ import type { SxProps, Theme } from '@mui/material';
2
+ import React from 'react';
3
+ export interface LegendToggleButtonProps {
4
+ isLegendVisible: boolean;
5
+ onToggle: () => void;
6
+ showTooltipText: string;
7
+ hideTooltipText: string;
8
+ legendLabel: string;
9
+ /** Container-query responsive styles — pass the container-specific breakpoint rules here */
10
+ sx?: SxProps<Theme>;
11
+ }
12
+ export declare const LegendToggleButton: ({ isLegendVisible, onToggle, showTooltipText, hideTooltipText, legendLabel, sx, }: LegendToggleButtonProps) => React.ReactElement;
@@ -0,0 +1 @@
1
+ export * from './LegendToggleButton';
@@ -12,6 +12,8 @@ export interface MenuItemType {
12
12
  icon?: React.ReactNode;
13
13
  isDisabled?: boolean;
14
14
  isSelected?: boolean;
15
+ controlType?: 'radio';
16
+ subMenuItems?: MenuItemType[];
15
17
  }
16
18
  interface ToggleMenuProps {
17
19
  buttonTestId?: string;
@@ -23,4 +23,5 @@ export * from './SearchField';
23
23
  export * from './LastUpdateTime';
24
24
  export * from './CanvasComponent';
25
25
  export * from './Filter';
26
+ export * from './LegendToggleButton';
26
27
  export * from './Storybook';
@@ -1,7 +1,9 @@
1
1
  export * from './axiosErrorUtils';
2
2
  export * as dateUtils from './dateUtils';
3
3
  export * as referenceTimeUtils from './referenceTimeUtils';
4
+ export * from './linkify';
4
5
  export * from './mapProjections';
5
6
  export { renderCounter } from './renderCounter';
6
7
  export { SessionStorageKey, sessionStorageProvider } from './sessionStorage';
7
8
  export type { SessionStorageProvider } from './sessionStorage';
9
+ export { isTargetInteractiveInput, isDialogFocused } from './keyboardUtils';
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Returns true if the element is an interactive control where keyboard events
3
+ * have a native meaning (typing, selecting, incrementing)
4
+ */
5
+ export declare const isTargetInteractiveInput: (target: Element | null) => boolean;
6
+ /**
7
+ * Returns true if keyboard focus is currently inside a floating dialog/panel
8
+ */
9
+ export declare const isDialogFocused: () => boolean;
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare const linkifyText: (text: string, keyPrefix?: string) => React.ReactNode[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeoweb/shared",
3
- "version": "19.3.0",
3
+ "version": "19.5.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": {