@open-pioneer/toc 0.1.0 → 0.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/CHANGELOG.md CHANGED
@@ -1,16 +1,40 @@
1
1
  # @open-pioneer/toc
2
2
 
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 70349a8: Update to new core packages major versions
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [70349a8]
12
+ - @open-pioneer/basemap-switcher@0.2.0
13
+ - @open-pioneer/map@0.2.0
14
+ - @open-pioneer/react-utils@0.2.0
15
+
16
+ ## 0.1.1
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies [08bffbc]
21
+ - Updated dependencies [a58546b]
22
+ - Updated dependencies [a58546b]
23
+ - Updated dependencies [0c4ce04]
24
+ - @open-pioneer/map@0.1.1
25
+ - @open-pioneer/basemap-switcher@0.1.1
26
+
3
27
  ## 0.1.0
4
28
 
5
29
  ### Minor Changes
6
30
 
7
- - cafb66b: Initial release.
31
+ - cafb66b: Initial release.
8
32
 
9
33
  ### Patch Changes
10
34
 
11
- - Updated dependencies [bb2f27a]
12
- - Updated dependencies [1e7545c]
13
- - Updated dependencies [182da1c]
14
- - @open-pioneer/map@0.1.0
15
- - @open-pioneer/basemap-switcher@0.1.0
16
- - @open-pioneer/react-utils@0.1.0
35
+ - Updated dependencies [bb2f27a]
36
+ - Updated dependencies [1e7545c]
37
+ - Updated dependencies [182da1c]
38
+ - @open-pioneer/map@0.1.0
39
+ - @open-pioneer/basemap-switcher@0.1.0
40
+ - @open-pioneer/react-utils@0.1.0
package/LayerList.js CHANGED
@@ -1,10 +1,9 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
- import { Text, List, Box, Flex, Checkbox, Popover, PopoverTrigger, Button, Portal, PopoverContent, PopoverArrow, PopoverCloseButton, PopoverHeader, PopoverBody } from '@open-pioneer/chakra-integration';
2
+ import { Text, List, Box, Flex, Checkbox, Tooltip, Spacer, Popover, PopoverTrigger, Button, Portal, PopoverContent, PopoverArrow, PopoverCloseButton, PopoverHeader, PopoverBody } from '@open-pioneer/chakra-integration';
3
3
  import classNames from 'classnames';
4
- import LayerGroup from 'ol/layer/Group';
5
4
  import { useIntl } from './_virtual/_virtual-pioneer-module_react-hooks.js';
6
5
  import { useCallback, useSyncExternalStore, useRef } from 'react';
7
- import { FiMoreVertical } from 'react-icons/fi';
6
+ import { FiAlertTriangle, FiMoreVertical } from 'react-icons/fi';
8
7
 
9
8
  function LayerList(props) {
10
9
  const { map, "aria-labelledby": ariaLabelledBy } = props;
@@ -35,6 +34,8 @@ function LayerItem(props) {
35
34
  const title = useTitle(layer);
36
35
  const { isVisible, setVisible } = useVisibility(layer);
37
36
  const sublayers = useSublayers(layer);
37
+ const isAvailable = useLoadState(layer) !== "error";
38
+ const notAvailableLabel = intl.formatMessage({ id: "layerNotAvailable" });
38
39
  let nestedChildren;
39
40
  if (sublayers?.length) {
40
41
  nestedChildren = createList(sublayers, intl, { ml: 4 });
@@ -54,11 +55,31 @@ function LayerItem(props) {
54
55
  /* @__PURE__ */ jsx(
55
56
  Checkbox,
56
57
  {
58
+ "aria-label": title + (!isAvailable ? " " + notAvailableLabel : ""),
57
59
  isChecked: isVisible,
60
+ isDisabled: !isAvailable,
58
61
  onChange: (event) => setVisible(event.target.checked),
59
62
  children: title
60
63
  }
61
64
  ),
65
+ !isAvailable && /* @__PURE__ */ jsx(
66
+ Tooltip,
67
+ {
68
+ className: "toc-layer-item-content-tooltip",
69
+ label: notAvailableLabel,
70
+ placement: "right",
71
+ openDelay: 500,
72
+ children: /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(
73
+ FiAlertTriangle,
74
+ {
75
+ className: "toc-layer-item-content-icon",
76
+ color: "red",
77
+ "aria-label": notAvailableLabel
78
+ }
79
+ ) })
80
+ }
81
+ ),
82
+ /* @__PURE__ */ jsx(Spacer, {}),
62
83
  layer.description && /* @__PURE__ */ jsx(LayerItemDescriptor, { layer, title, intl })
63
84
  ]
64
85
  }
@@ -70,10 +91,12 @@ function LayerItemDescriptor(props) {
70
91
  const { layer, title, intl } = props;
71
92
  const buttonLabel = intl.formatMessage({ id: "descriptionLabel" });
72
93
  const description = useLayerDescription(layer);
73
- return /* @__PURE__ */ jsxs(Popover, { children: [
94
+ const isAvailable = useLoadState(layer) !== "error";
95
+ return /* @__PURE__ */ jsxs(Popover, { placement: "bottom-start", children: [
74
96
  /* @__PURE__ */ jsx(PopoverTrigger, { children: /* @__PURE__ */ jsx(
75
97
  Button,
76
98
  {
99
+ isDisabled: !isAvailable,
77
100
  className: "toc-layer-item-details-button",
78
101
  "aria-label": buttonLabel,
79
102
  borderRadius: "full",
@@ -85,7 +108,7 @@ function LayerItemDescriptor(props) {
85
108
  ) }),
86
109
  /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsxs(PopoverContent, { className: "toc-layer-item-details", overflowY: "auto", maxHeight: "400", children: [
87
110
  /* @__PURE__ */ jsx(PopoverArrow, {}),
88
- /* @__PURE__ */ jsx(PopoverCloseButton, {}),
111
+ /* @__PURE__ */ jsx(PopoverCloseButton, { mt: 1 }),
89
112
  /* @__PURE__ */ jsx(PopoverHeader, { children: title }),
90
113
  /* @__PURE__ */ jsx(PopoverBody, { children: description })
91
114
  ] }) })
@@ -144,7 +167,7 @@ function useLayers(map) {
144
167
  );
145
168
  const getValue = useCallback(() => {
146
169
  let layers = map.layers.getOperationalLayers({ sortByDisplayOrder: true }) ?? [];
147
- layers = layers.reverse().filter(canShowOperationalLayer);
170
+ layers = layers.reverse();
148
171
  return layers;
149
172
  }, [map]);
150
173
  return useCachedExternalStore(subscribe, getValue);
@@ -168,6 +191,20 @@ function useSublayers(layer) {
168
191
  }, [layer]);
169
192
  return useCachedExternalStore(subscribe, getValue);
170
193
  }
194
+ function useLoadState(layer) {
195
+ const target = "parentLayer" in layer ? layer.parentLayer : layer;
196
+ const subscribe = useCallback(
197
+ (cb) => {
198
+ const resource = target.on("changed:loadState", cb);
199
+ return () => resource.destroy();
200
+ },
201
+ [target]
202
+ );
203
+ const getSnapshot = useCallback(() => {
204
+ return target.loadState;
205
+ }, [target]);
206
+ return useSyncExternalStore(subscribe, getSnapshot);
207
+ }
171
208
  function useCachedExternalStore(subscribe, getValue) {
172
209
  const cachedValue = useRef();
173
210
  const cachedSubscribe = useCallback(
@@ -193,9 +230,6 @@ function useCachedExternalStore(subscribe, getValue) {
193
230
  }, [getValue]);
194
231
  return useSyncExternalStore(cachedSubscribe, cachedGetSnapshot);
195
232
  }
196
- function canShowOperationalLayer(layer) {
197
- return !(layer.olLayer instanceof LayerGroup);
198
- }
199
233
  function slug(id) {
200
234
  return id.replace(/[^a-z0-9 -]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-");
201
235
  }
package/LayerList.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"LayerList.js","sources":["LayerList.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n Box,\n Button,\n Checkbox,\n Flex,\n List,\n ListProps,\n Popover,\n PopoverArrow,\n PopoverBody,\n PopoverCloseButton,\n PopoverContent,\n PopoverHeader,\n PopoverTrigger,\n Portal,\n Text\n} from \"@open-pioneer/chakra-integration\";\nimport { Layer, LayerBase, MapModel, Sublayer } from \"@open-pioneer/map\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport classNames from \"classnames\";\nimport LayerGroup from \"ol/layer/Group\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useCallback, useRef, useSyncExternalStore } from \"react\";\nimport { FiMoreVertical } from \"react-icons/fi\";\n\n/**\n * Lists the (top level) operational layers in the map.\n *\n * Layer Groups are skipped in the current implementation.\n */\nexport function LayerList(props: { map: MapModel; \"aria-labelledby\"?: string }): JSX.Element {\n const { map, \"aria-labelledby\": ariaLabelledBy } = props;\n const intl = useIntl();\n const layers = useLayers(map);\n if (!layers.length) {\n return (\n <Text className=\"toc-missing-layers\" aria-labelledby={ariaLabelledBy}>\n {intl.formatMessage({ id: \"missingLayers\" })}\n </Text>\n );\n }\n\n return createList(layers, intl, {\n \"aria-labelledby\": ariaLabelledBy\n });\n}\n\nfunction createList(layers: LayerBase[], intl: PackageIntl, listProps: ListProps) {\n const items = layers.map((layer) => <LayerItem key={layer.id} layer={layer} intl={intl} />);\n return (\n <List\n // Note: not using UnorderedList because it adds default margins\n as=\"ul\"\n className=\"toc-layer-list\"\n listStyleType=\"none\"\n {...listProps}\n >\n {items}\n </List>\n );\n}\n\n/**\n * Renders a single layer as a list item.\n *\n * The item may have further nested list items if there are sublayers present.\n */\nfunction LayerItem(props: { layer: LayerBase; intl: PackageIntl }): JSX.Element {\n const { layer, intl } = props;\n const title = useTitle(layer);\n const { isVisible, setVisible } = useVisibility(layer);\n const sublayers = useSublayers(layer);\n\n let nestedChildren;\n if (sublayers?.length) {\n nestedChildren = createList(sublayers, intl, { ml: 4 });\n }\n\n return (\n <Box as=\"li\" className={classNames(\"toc-layer-item\", `layer-${slug(layer.id)}`)}>\n <Flex\n className=\"toc-layer-item-content\"\n width=\"100%\"\n flexDirection=\"row\"\n align=\"center\"\n justifyContent=\"space-between\"\n /** Gap to prevent bleeding of the buttons hover style into the layer title */\n gap={2}\n /** Aligned to the size of the (potential) menu button in LayerItemDescriptor */\n minHeight={10}\n >\n <Checkbox\n isChecked={isVisible}\n onChange={(event) => setVisible(event.target.checked)}\n >\n {title}\n </Checkbox>\n {layer.description && (\n <LayerItemDescriptor layer={layer} title={title} intl={intl} />\n )}\n </Flex>\n {nestedChildren}\n </Box>\n );\n}\n\nfunction LayerItemDescriptor(props: {\n layer: LayerBase;\n title: string;\n intl: PackageIntl;\n}): JSX.Element {\n const { layer, title, intl } = props;\n const buttonLabel = intl.formatMessage({ id: \"descriptionLabel\" });\n const description = useLayerDescription(layer);\n\n return (\n <Popover>\n <PopoverTrigger>\n <Button\n className=\"toc-layer-item-details-button\"\n aria-label={buttonLabel}\n borderRadius=\"full\"\n iconSpacing={0}\n padding={0}\n variant=\"ghost\"\n leftIcon={<FiMoreVertical />}\n />\n </PopoverTrigger>\n <Portal>\n <PopoverContent className=\"toc-layer-item-details\" overflowY=\"auto\" maxHeight=\"400\">\n <PopoverArrow />\n <PopoverCloseButton />\n <PopoverHeader>{title}</PopoverHeader>\n <PopoverBody>{description}</PopoverBody>\n </PopoverContent>\n </Portal>\n </Popover>\n );\n}\n\nfunction useLayerDescription(layer: LayerBase): string {\n const getSnapshot = useCallback(() => layer.description, [layer]);\n const subscribe = useCallback(\n (cb: () => void) => {\n const resource = layer.on(\"changed:description\", cb);\n return () => resource.destroy();\n },\n [layer]\n );\n return useSyncExternalStore(subscribe, getSnapshot);\n}\n\n/** Returns the layers current title. */\nfunction useTitle(layer: LayerBase): string {\n const getSnapshot = useCallback(() => layer.title, [layer]);\n const subscribe = useCallback(\n (cb: () => void) => {\n const resource = layer.on(\"changed:title\", cb);\n return () => resource.destroy();\n },\n [layer]\n );\n\n return useSyncExternalStore(subscribe, getSnapshot);\n}\n\n/** Returns the layer's current visibility and a function to change it. */\nfunction useVisibility(layer: LayerBase): {\n isVisible: boolean;\n setVisible(visible: boolean): void;\n} {\n const getSnapshot = useCallback(() => layer.visible, [layer]);\n const subscribe = useCallback(\n (cb: () => void) => {\n const resource = layer.on(\"changed:visible\", cb);\n return () => resource.destroy();\n },\n [layer]\n );\n const isVisible = useSyncExternalStore(subscribe, getSnapshot);\n const setVisible = useCallback(\n (visible: boolean) => {\n layer.setVisible(visible);\n },\n [layer]\n );\n\n return {\n isVisible,\n setVisible\n };\n}\n\n/** Returns the top level operation layers (without LayerGroups). */\nfunction useLayers(map: MapModel): LayerBase[] {\n const subscribe = useCallback(\n (cb: () => void) => {\n const resource = map.layers.on(\"changed\", cb);\n return () => resource.destroy();\n },\n [map]\n );\n const getValue = useCallback(() => {\n let layers = map.layers.getOperationalLayers({ sortByDisplayOrder: true }) ?? [];\n layers = layers.reverse().filter(canShowOperationalLayer);\n return layers;\n }, [map]);\n return useCachedExternalStore(subscribe, getValue);\n}\n\n/** Returns the sublayers of the given layer (or undefined, if the sublayer cannot have any). */\nfunction useSublayers(layer: LayerBase): Sublayer[] | undefined {\n const subscribe = useCallback(\n (cb: () => void) => {\n const resource = layer.sublayers?.on(\"changed\", cb);\n return () => resource?.destroy();\n },\n [layer]\n );\n const getValue = useCallback((): Sublayer[] | undefined => {\n const sublayers = layer.sublayers;\n if (!sublayers) {\n return undefined;\n }\n\n let layers = layer.sublayers?.getSublayers({ sortByDisplayOrder: true });\n layers = layers.reverse();\n return layers;\n }, [layer]);\n return useCachedExternalStore(subscribe, getValue);\n}\n\n/**\n * This hooks wraps an external store that does not cache its own values, i.e.\n * it may return a different value each time from `getValue()`.\n *\n * The results returned from `getValue()` are cached locally; the cache\n * is only invalidated on re-subscription or if a change event has been observed.\n */\nfunction useCachedExternalStore<T>(\n subscribe: (onStoreChanged: () => void) => () => void,\n getValue: () => T\n): T {\n const cachedValue = useRef<{ value: T } | undefined>();\n\n const cachedSubscribe = useCallback(\n (cb: () => void) => {\n const cleanup = subscribe(() => {\n // Reset cache on change\n cachedValue.current = undefined;\n cb();\n });\n return () => {\n // Reset cache when (re-) subscribing\n cachedValue.current = undefined;\n cleanup();\n };\n },\n [subscribe]\n );\n const cachedGetSnapshot = useCallback(() => {\n // Return cached values if still up to date (see resets above).\n if (cachedValue.current) {\n return cachedValue.current.value;\n }\n\n // Compute values and cache the result.\n const value = getValue();\n cachedValue.current = { value };\n return value;\n }, [getValue]);\n return useSyncExternalStore(cachedSubscribe, cachedGetSnapshot);\n}\n\nfunction canShowOperationalLayer(layer: Layer) {\n return !(layer.olLayer instanceof LayerGroup);\n}\n\nfunction slug(id: string) {\n return id\n .replace(/[^a-z0-9 -]/g, \"\")\n .replace(/\\s+/g, \"-\")\n .replace(/-+/g, \"-\");\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LayerList.js","sources":["LayerList.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n Box,\n Button,\n Checkbox,\n Flex,\n List,\n ListProps,\n Popover,\n PopoverArrow,\n PopoverBody,\n PopoverCloseButton,\n PopoverContent,\n PopoverHeader,\n PopoverTrigger,\n Portal,\n Spacer,\n Text,\n Tooltip\n} from \"@open-pioneer/chakra-integration\";\nimport { Layer, LayerBase, MapModel, Sublayer } from \"@open-pioneer/map\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport classNames from \"classnames\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useCallback, useRef, useSyncExternalStore } from \"react\";\nimport { FiAlertTriangle, FiMoreVertical } from \"react-icons/fi\";\n\ntype TocLayer = Layer | Sublayer;\n\n/**\n * Lists the (top level) operational layers in the map.\n *\n * Layer Groups are skipped in the current implementation.\n */\nexport function LayerList(props: { map: MapModel; \"aria-labelledby\"?: string }): JSX.Element {\n const { map, \"aria-labelledby\": ariaLabelledBy } = props;\n const intl = useIntl();\n const layers = useLayers(map);\n if (!layers.length) {\n return (\n <Text className=\"toc-missing-layers\" aria-labelledby={ariaLabelledBy}>\n {intl.formatMessage({ id: \"missingLayers\" })}\n </Text>\n );\n }\n\n return createList(layers, intl, {\n \"aria-labelledby\": ariaLabelledBy\n });\n}\n\nfunction createList(layers: TocLayer[], intl: PackageIntl, listProps: ListProps) {\n const items = layers.map((layer) => <LayerItem key={layer.id} layer={layer} intl={intl} />);\n return (\n <List\n // Note: not using UnorderedList because it adds default margins\n as=\"ul\"\n className=\"toc-layer-list\"\n listStyleType=\"none\"\n {...listProps}\n >\n {items}\n </List>\n );\n}\n\n/**\n * Renders a single layer as a list item.\n *\n * The item may have further nested list items if there are sublayers present.\n */\nfunction LayerItem(props: { layer: TocLayer; intl: PackageIntl }): JSX.Element {\n const { layer, intl } = props;\n const title = useTitle(layer);\n const { isVisible, setVisible } = useVisibility(layer);\n const sublayers = useSublayers(layer);\n const isAvailable = useLoadState(layer) !== \"error\";\n const notAvailableLabel = intl.formatMessage({ id: \"layerNotAvailable\" });\n\n let nestedChildren;\n if (sublayers?.length) {\n nestedChildren = createList(sublayers, intl, { ml: 4 });\n }\n\n return (\n <Box as=\"li\" className={classNames(\"toc-layer-item\", `layer-${slug(layer.id)}`)}>\n <Flex\n className=\"toc-layer-item-content\"\n width=\"100%\"\n flexDirection=\"row\"\n align=\"center\"\n justifyContent=\"space-between\"\n /** Gap to prevent bleeding of the buttons hover style into the layer title */\n gap={2}\n /** Aligned to the size of the (potential) menu button in LayerItemDescriptor */\n minHeight={10}\n >\n <Checkbox\n // Keyboard navigation jumps only to Checkboxes and uses the texts inside this DOM node. The aria-labels of Tooltip and Icon is ignored by screenreader because they are no child element of the checkbox. To consider the notAvailableLabel, an aria-label at the checkbox is necessary.\n aria-label={title + (!isAvailable ? \" \" + notAvailableLabel : \"\")}\n isChecked={isVisible}\n isDisabled={!isAvailable}\n onChange={(event) => setVisible(event.target.checked)}\n >\n {title}\n </Checkbox>\n {!isAvailable && (\n <Tooltip\n className=\"toc-layer-item-content-tooltip\"\n label={notAvailableLabel}\n placement=\"right\"\n openDelay={500}\n >\n <span>\n <FiAlertTriangle\n className=\"toc-layer-item-content-icon\"\n color={\"red\"}\n aria-label={notAvailableLabel}\n />\n </span>\n </Tooltip>\n )}\n <Spacer></Spacer>\n {layer.description && (\n <LayerItemDescriptor layer={layer} title={title} intl={intl} />\n )}\n </Flex>\n {nestedChildren}\n </Box>\n );\n}\n\nfunction LayerItemDescriptor(props: {\n layer: TocLayer;\n title: string;\n intl: PackageIntl;\n}): JSX.Element {\n const { layer, title, intl } = props;\n const buttonLabel = intl.formatMessage({ id: \"descriptionLabel\" });\n const description = useLayerDescription(layer);\n const isAvailable = useLoadState(layer) !== \"error\";\n\n return (\n <Popover placement=\"bottom-start\">\n <PopoverTrigger>\n <Button\n isDisabled={!isAvailable}\n className=\"toc-layer-item-details-button\"\n aria-label={buttonLabel}\n borderRadius=\"full\"\n iconSpacing={0}\n padding={0}\n variant=\"ghost\"\n leftIcon={<FiMoreVertical />}\n />\n </PopoverTrigger>\n <Portal>\n <PopoverContent className=\"toc-layer-item-details\" overflowY=\"auto\" maxHeight=\"400\">\n <PopoverArrow />\n <PopoverCloseButton mt={1} />\n <PopoverHeader>{title}</PopoverHeader>\n <PopoverBody>{description}</PopoverBody>\n </PopoverContent>\n </Portal>\n </Popover>\n );\n}\n\nfunction useLayerDescription(layer: LayerBase): string {\n const getSnapshot = useCallback(() => layer.description, [layer]);\n const subscribe = useCallback(\n (cb: () => void) => {\n const resource = layer.on(\"changed:description\", cb);\n return () => resource.destroy();\n },\n [layer]\n );\n return useSyncExternalStore(subscribe, getSnapshot);\n}\n\n/** Returns the layers current title. */\nfunction useTitle(layer: LayerBase): string {\n const getSnapshot = useCallback(() => layer.title, [layer]);\n const subscribe = useCallback(\n (cb: () => void) => {\n const resource = layer.on(\"changed:title\", cb);\n return () => resource.destroy();\n },\n [layer]\n );\n\n return useSyncExternalStore(subscribe, getSnapshot);\n}\n\n/** Returns the layer's current visibility and a function to change it. */\nfunction useVisibility(layer: LayerBase): {\n isVisible: boolean;\n setVisible(visible: boolean): void;\n} {\n const getSnapshot = useCallback(() => layer.visible, [layer]);\n const subscribe = useCallback(\n (cb: () => void) => {\n const resource = layer.on(\"changed:visible\", cb);\n return () => resource.destroy();\n },\n [layer]\n );\n const isVisible = useSyncExternalStore(subscribe, getSnapshot);\n const setVisible = useCallback(\n (visible: boolean) => {\n layer.setVisible(visible);\n },\n [layer]\n );\n\n return {\n isVisible,\n setVisible\n };\n}\n\n/** Returns the top level operation layers (without LayerGroups). */\nfunction useLayers(map: MapModel): Layer[] {\n const subscribe = useCallback(\n (cb: () => void) => {\n const resource = map.layers.on(\"changed\", cb);\n return () => resource.destroy();\n },\n [map]\n );\n const getValue = useCallback(() => {\n let layers = map.layers.getOperationalLayers({ sortByDisplayOrder: true }) ?? [];\n layers = layers.reverse();\n return layers;\n }, [map]);\n return useCachedExternalStore(subscribe, getValue);\n}\n\n/** Returns the sublayers of the given layer (or undefined, if the sublayer cannot have any). */\nfunction useSublayers(layer: LayerBase): Sublayer[] | undefined {\n const subscribe = useCallback(\n (cb: () => void) => {\n const resource = layer.sublayers?.on(\"changed\", cb);\n return () => resource?.destroy();\n },\n [layer]\n );\n const getValue = useCallback((): Sublayer[] | undefined => {\n const sublayers = layer.sublayers;\n if (!sublayers) {\n return undefined;\n }\n\n let layers = layer.sublayers?.getSublayers({ sortByDisplayOrder: true });\n layers = layers.reverse();\n return layers;\n }, [layer]);\n return useCachedExternalStore(subscribe, getValue);\n}\n\n/** Returns the layers current state. */\nfunction useLoadState(layer: TocLayer): string {\n // for sublayers, use the state of the parent\n const target = \"parentLayer\" in layer ? layer.parentLayer : layer;\n const subscribe = useCallback(\n (cb: () => void) => {\n const resource = target.on(\"changed:loadState\", cb);\n return () => resource.destroy();\n },\n [target]\n );\n\n const getSnapshot = useCallback(() => {\n return target.loadState;\n }, [target]);\n\n return useSyncExternalStore(subscribe, getSnapshot);\n}\n\n/**\n * This hooks wraps an external store that does not cache its own values, i.e.\n * it may return a different value each time from `getValue()`.\n *\n * The results returned from `getValue()` are cached locally; the cache\n * is only invalidated on re-subscription or if a change event has been observed.\n */\nfunction useCachedExternalStore<T>(\n subscribe: (onStoreChanged: () => void) => () => void,\n getValue: () => T\n): T {\n const cachedValue = useRef<{ value: T } | undefined>();\n\n const cachedSubscribe = useCallback(\n (cb: () => void) => {\n const cleanup = subscribe(() => {\n // Reset cache on change\n cachedValue.current = undefined;\n cb();\n });\n return () => {\n // Reset cache when (re-) subscribing\n cachedValue.current = undefined;\n cleanup();\n };\n },\n [subscribe]\n );\n const cachedGetSnapshot = useCallback(() => {\n // Return cached values if still up to date (see resets above).\n if (cachedValue.current) {\n return cachedValue.current.value;\n }\n\n // Compute values and cache the result.\n const value = getValue();\n cachedValue.current = { value };\n return value;\n }, [getValue]);\n return useSyncExternalStore(cachedSubscribe, cachedGetSnapshot);\n}\n\nfunction slug(id: string) {\n return id\n .replace(/[^a-z0-9 -]/g, \"\")\n .replace(/\\s+/g, \"-\")\n .replace(/-+/g, \"-\");\n}\n"],"names":[],"mappings":"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"}
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  This package provides a UI component that displays the map content to the user and allows them to control it.
4
4
 
5
+ Unavailable operational layers are marked with an icon and will be deactivated for selection. If a layer was configured as initially visible, it remains visible.
6
+
5
7
  ## Usage
6
8
 
7
9
  To integrate the TOC (table of contents) in your app, insert the following snippet and reference a map ID:
@@ -10,6 +12,16 @@ To integrate the TOC (table of contents) in your app, insert the following snipp
10
12
  <Toc mapId="map_id" />
11
13
  ```
12
14
 
15
+ ### Tools
16
+
17
+ Additional tools are available for operational layers.
18
+ To show the toolset menu, set the `showTools` property to `true`.
19
+ The toolset contains a tool with which you can switch off the visibility of all levels at once.
20
+
21
+ ```tsx
22
+ <Toc mapId="map_id" showTools={true} />
23
+ ```
24
+
13
25
  ### Basemaps
14
26
 
15
27
  By default, the TOC shows the basemap switcher as an embedded element.
package/Toc.d.ts CHANGED
@@ -9,9 +9,18 @@ export interface TocProps extends CommonComponentProps {
9
9
  * The id of the map.
10
10
  */
11
11
  mapId: string;
12
+ /**
13
+ * Defines whether the tool component is shown in the toc.
14
+ * Defaults to `false`.
15
+ */
16
+ showTools?: boolean;
17
+ /**
18
+ * Properties for the embedded tool component.
19
+ */
20
+ toolsConfig?: ToolsConfig;
12
21
  /**
13
22
  * Defines whether the basemap switcher is shown in the toc.
14
- * Defaults to true.
23
+ * Defaults to `true`.
15
24
  */
16
25
  showBasemapSwitcher?: boolean;
17
26
  /**
@@ -20,6 +29,16 @@ export interface TocProps extends CommonComponentProps {
20
29
  */
21
30
  basemapSwitcherProps?: Omit<BasemapSwitcherProps, "mapId">;
22
31
  }
32
+ /**
33
+ * Props supported by the {@link Tools} component.
34
+ */
35
+ export interface ToolsConfig {
36
+ /**
37
+ * Optional property to show the `hide all layers` entry.
38
+ * Defaults to `true`.
39
+ */
40
+ showHideAllLayers?: boolean;
41
+ }
23
42
  /**
24
43
  * Displays the layers of the configured map.
25
44
  */
package/Toc.js CHANGED
@@ -1,16 +1,23 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { BasemapSwitcher } from '@open-pioneer/basemap-switcher';
3
- import { Box, Text, Flex } from '@open-pioneer/chakra-integration';
3
+ import { Box, Flex, Text, Spacer } from '@open-pioneer/chakra-integration';
4
4
  import { useMapModel } from '@open-pioneer/map';
5
5
  import { useCommonComponentProps, TitledSection, SectionHeading } from '@open-pioneer/react-utils';
6
6
  import { useIntl } from './_virtual/_virtual-pioneer-module_react-hooks.js';
7
7
  import { useId } from 'react';
8
8
  import { LayerList } from './LayerList.js';
9
+ import { Tools } from './Tools.js';
9
10
 
10
11
  const PADDING = 2;
11
12
  const Toc = (props) => {
12
13
  const intl = useIntl();
13
- const { mapId, showBasemapSwitcher = true, basemapSwitcherProps } = props;
14
+ const {
15
+ mapId,
16
+ showTools = false,
17
+ toolsConfig,
18
+ showBasemapSwitcher = true,
19
+ basemapSwitcherProps
20
+ } = props;
14
21
  const { containerProps } = useCommonComponentProps("toc", props);
15
22
  const basemapsHeadingId = useId();
16
23
  const operationalLayersHeadingId = useId();
@@ -41,15 +48,13 @@ const Toc = (props) => {
41
48
  const layerList = /* @__PURE__ */ jsx(Box, { className: "toc-operational-layers", children: /* @__PURE__ */ jsx(
42
49
  TitledSection,
43
50
  {
44
- title: /* @__PURE__ */ jsx(
45
- SectionHeading,
46
- {
47
- id: operationalLayersHeadingId,
48
- size: "sm",
49
- mb: PADDING,
50
- children: intl.formatMessage({ id: "operationalLayerLabel" })
51
- }
52
- ),
51
+ title: /* @__PURE__ */ jsx(SectionHeading, { id: operationalLayersHeadingId, size: "sm", mb: 2, children: /* @__PURE__ */ jsxs(Flex, { children: [
52
+ /* @__PURE__ */ jsx(Text, { my: 3, children: intl.formatMessage({
53
+ id: "operationalLayerLabel"
54
+ }) }),
55
+ /* @__PURE__ */ jsx(Spacer, {}),
56
+ showTools && /* @__PURE__ */ jsx(Tools, { mapId, ...toolsConfig })
57
+ ] }) }),
53
58
  children: /* @__PURE__ */ jsx(LayerList, { map: state.map, "aria-labelledby": operationalLayersHeadingId })
54
59
  }
55
60
  ) });
package/Toc.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Toc.js","sources":["Toc.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { BasemapSwitcher, BasemapSwitcherProps } from \"@open-pioneer/basemap-switcher\";\nimport { Box, Flex, Text } from \"@open-pioneer/chakra-integration\";\nimport { useMapModel } from \"@open-pioneer/map\";\nimport {\n CommonComponentProps,\n SectionHeading,\n TitledSection,\n useCommonComponentProps\n} from \"@open-pioneer/react-utils\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { FC, useId } from \"react\";\nimport { LayerList } from \"./LayerList\";\n\n/**\n * Props supported by the {@link Toc} component.\n */\nexport interface TocProps extends CommonComponentProps {\n /**\n * The id of the map.\n */\n mapId: string;\n\n /**\n * Defines whether the basemap switcher is shown in the toc.\n * Defaults to true.\n */\n showBasemapSwitcher?: boolean;\n\n /**\n * Properties for the embedded basemap switcher.\n * Property \"mapId\" is not applied.\n */\n basemapSwitcherProps?: Omit<BasemapSwitcherProps, \"mapId\">;\n}\n\nconst PADDING = 2;\n\n/**\n * Displays the layers of the configured map.\n */\nexport const Toc: FC<TocProps> = (props: TocProps) => {\n const intl = useIntl();\n\n const { mapId, showBasemapSwitcher = true, basemapSwitcherProps } = props;\n const { containerProps } = useCommonComponentProps(\"toc\", props);\n const basemapsHeadingId = useId();\n const operationalLayersHeadingId = useId();\n const state = useMapModel(mapId);\n\n let content: JSX.Element | null;\n switch (state.kind) {\n case \"loading\":\n content = null;\n break;\n case \"rejected\":\n content = <Text className=\"toc-error\">{intl.formatMessage({ id: \"error\" })}</Text>;\n break;\n case \"resolved\": {\n const basemapSwitcher = showBasemapSwitcher && (\n <Box className=\"toc-basemap-switcher\">\n <TitledSection\n title={\n <SectionHeading id={basemapsHeadingId} size={\"sm\"} mb={PADDING}>\n {intl.formatMessage({ id: \"basemapsLabel\" })}\n </SectionHeading>\n }\n >\n <BasemapSwitcher\n mapId={mapId}\n aria-labelledby={basemapsHeadingId}\n {...basemapSwitcherProps}\n />\n </TitledSection>\n </Box>\n );\n const layerList = (\n <Box className=\"toc-operational-layers\">\n <TitledSection\n title={\n <SectionHeading\n id={operationalLayersHeadingId}\n size={\"sm\"}\n mb={PADDING}\n >\n {intl.formatMessage({ id: \"operationalLayerLabel\" })}\n </SectionHeading>\n }\n >\n <LayerList map={state.map!} aria-labelledby={operationalLayersHeadingId} />\n </TitledSection>\n </Box>\n );\n\n content = (\n <>\n {basemapSwitcher}\n {layerList}\n </>\n );\n break;\n }\n }\n\n return (\n <Flex {...containerProps} direction=\"column\" gap={PADDING}>\n {content}\n </Flex>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;AAqCA,MAAM,OAAU,GAAA,CAAA,CAAA;AAKH,MAAA,GAAA,GAAoB,CAAC,KAAoB,KAAA;AAClD,EAAA,MAAM,OAAO,OAAQ,EAAA,CAAA;AAErB,EAAA,MAAM,EAAE,KAAA,EAAO,mBAAsB,GAAA,IAAA,EAAM,sBAAyB,GAAA,KAAA,CAAA;AACpE,EAAA,MAAM,EAAE,cAAA,EAAmB,GAAA,uBAAA,CAAwB,OAAO,KAAK,CAAA,CAAA;AAC/D,EAAA,MAAM,oBAAoB,KAAM,EAAA,CAAA;AAChC,EAAA,MAAM,6BAA6B,KAAM,EAAA,CAAA;AACzC,EAAM,MAAA,KAAA,GAAQ,YAAY,KAAK,CAAA,CAAA;AAE/B,EAAI,IAAA,OAAA,CAAA;AACJ,EAAA,QAAQ,MAAM,IAAM;AAAA,IAChB,KAAK,SAAA;AACD,MAAU,OAAA,GAAA,IAAA,CAAA;AACV,MAAA,MAAA;AAAA,IACJ,KAAK,UAAA;AACD,MAAU,OAAA,mBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,SAAA,EAAU,WAAa,EAAA,QAAA,EAAA,IAAA,CAAK,cAAc,EAAE,EAAA,EAAI,OAAQ,EAAC,CAAE,EAAA,CAAA,CAAA;AAC3E,MAAA,MAAA;AAAA,IACJ,KAAK,UAAY,EAAA;AACb,MAAA,MAAM,eAAkB,GAAA,mBAAA,oBACnB,GAAA,CAAA,GAAA,EAAA,EAAI,WAAU,sBACX,EAAA,QAAA,kBAAA,GAAA;AAAA,QAAC,aAAA;AAAA,QAAA;AAAA,UACG,KACI,kBAAA,GAAA,CAAC,cAAe,EAAA,EAAA,EAAA,EAAI,mBAAmB,IAAM,EAAA,IAAA,EAAM,EAAI,EAAA,OAAA,EAClD,eAAK,aAAc,CAAA,EAAE,EAAI,EAAA,eAAA,EAAiB,CAC/C,EAAA,CAAA;AAAA,UAGJ,QAAA,kBAAA,GAAA;AAAA,YAAC,eAAA;AAAA,YAAA;AAAA,cACG,KAAA;AAAA,cACA,iBAAiB,EAAA,iBAAA;AAAA,cAChB,GAAG,oBAAA;AAAA,aAAA;AAAA,WACR;AAAA,SAAA;AAAA,OAER,EAAA,CAAA,CAAA;AAEJ,MAAA,MAAM,SACF,mBAAA,GAAA,CAAC,GAAI,EAAA,EAAA,SAAA,EAAU,wBACX,EAAA,QAAA,kBAAA,GAAA;AAAA,QAAC,aAAA;AAAA,QAAA;AAAA,UACG,KACI,kBAAA,GAAA;AAAA,YAAC,cAAA;AAAA,YAAA;AAAA,cACG,EAAI,EAAA,0BAAA;AAAA,cACJ,IAAM,EAAA,IAAA;AAAA,cACN,EAAI,EAAA,OAAA;AAAA,cAEH,QAAK,EAAA,IAAA,CAAA,aAAA,CAAc,EAAE,EAAA,EAAI,yBAAyB,CAAA;AAAA,aAAA;AAAA,WACvD;AAAA,UAGJ,8BAAC,SAAU,EAAA,EAAA,GAAA,EAAK,KAAM,CAAA,GAAA,EAAM,mBAAiB,0BAA4B,EAAA,CAAA;AAAA,SAAA;AAAA,OAEjF,EAAA,CAAA,CAAA;AAGJ,MAAA,OAAA,mBAES,IAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA;AAAA,QAAA,eAAA;AAAA,QACA,SAAA;AAAA,OACL,EAAA,CAAA,CAAA;AAEJ,MAAA,MAAA;AAAA,KACJ;AAAA,GACJ;AAEA,EACI,uBAAA,GAAA,CAAC,QAAM,GAAG,cAAA,EAAgB,WAAU,QAAS,EAAA,GAAA,EAAK,SAC7C,QACL,EAAA,OAAA,EAAA,CAAA,CAAA;AAER;;;;"}
1
+ {"version":3,"file":"Toc.js","sources":["Toc.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { BasemapSwitcher, BasemapSwitcherProps } from \"@open-pioneer/basemap-switcher\";\nimport { Box, Flex, Spacer, Text } from \"@open-pioneer/chakra-integration\";\nimport { useMapModel } from \"@open-pioneer/map\";\nimport {\n CommonComponentProps,\n SectionHeading,\n TitledSection,\n useCommonComponentProps\n} from \"@open-pioneer/react-utils\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { FC, useId } from \"react\";\nimport { LayerList } from \"./LayerList\";\nimport { Tools } from \"./Tools\";\n\n/**\n * Props supported by the {@link Toc} component.\n */\nexport interface TocProps extends CommonComponentProps {\n /**\n * The id of the map.\n */\n mapId: string;\n\n /**\n * Defines whether the tool component is shown in the toc.\n * Defaults to `false`.\n */\n showTools?: boolean;\n\n /**\n * Properties for the embedded tool component.\n */\n toolsConfig?: ToolsConfig;\n\n /**\n * Defines whether the basemap switcher is shown in the toc.\n * Defaults to `true`.\n */\n showBasemapSwitcher?: boolean;\n\n /**\n * Properties for the embedded basemap switcher.\n * Property \"mapId\" is not applied.\n */\n basemapSwitcherProps?: Omit<BasemapSwitcherProps, \"mapId\">;\n}\n\n/**\n * Props supported by the {@link Tools} component.\n */\nexport interface ToolsConfig {\n /**\n * Optional property to show the `hide all layers` entry.\n * Defaults to `true`.\n */\n showHideAllLayers?: boolean;\n}\n\nconst PADDING = 2;\n\n/**\n * Displays the layers of the configured map.\n */\nexport const Toc: FC<TocProps> = (props: TocProps) => {\n const intl = useIntl();\n\n const {\n mapId,\n showTools = false,\n toolsConfig,\n showBasemapSwitcher = true,\n basemapSwitcherProps\n } = props;\n const { containerProps } = useCommonComponentProps(\"toc\", props);\n const basemapsHeadingId = useId();\n const operationalLayersHeadingId = useId();\n const state = useMapModel(mapId);\n\n let content: JSX.Element | null;\n switch (state.kind) {\n case \"loading\":\n content = null;\n break;\n case \"rejected\":\n content = <Text className=\"toc-error\">{intl.formatMessage({ id: \"error\" })}</Text>;\n break;\n case \"resolved\": {\n const basemapSwitcher = showBasemapSwitcher && (\n <Box className=\"toc-basemap-switcher\">\n <TitledSection\n title={\n <SectionHeading id={basemapsHeadingId} size={\"sm\"} mb={PADDING}>\n {intl.formatMessage({ id: \"basemapsLabel\" })}\n </SectionHeading>\n }\n >\n <BasemapSwitcher\n mapId={mapId}\n aria-labelledby={basemapsHeadingId}\n {...basemapSwitcherProps}\n />\n </TitledSection>\n </Box>\n );\n const layerList = (\n <Box className=\"toc-operational-layers\">\n <TitledSection\n title={\n <SectionHeading id={operationalLayersHeadingId} size={\"sm\"} mb={2}>\n <Flex>\n <Text my={3}>\n {intl.formatMessage({\n id: \"operationalLayerLabel\"\n })}\n </Text>\n <Spacer />\n {showTools && <Tools mapId={mapId} {...toolsConfig} />}\n </Flex>\n </SectionHeading>\n }\n >\n <LayerList map={state.map!} aria-labelledby={operationalLayersHeadingId} />\n </TitledSection>\n </Box>\n );\n\n content = (\n <>\n {basemapSwitcher}\n {layerList}\n </>\n );\n break;\n }\n }\n\n return (\n <Flex {...containerProps} direction=\"column\" gap={PADDING}>\n {content}\n </Flex>\n );\n};\n"],"names":[],"mappings":"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"}
package/Tools.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { FC } from "react";
2
+ import { ToolsConfig } from "./Toc";
3
+ export declare const Tools: FC<{
4
+ mapId: string;
5
+ } & ToolsConfig>;
package/Tools.js ADDED
@@ -0,0 +1,52 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { Box, Menu, MenuButton, Button, Portal, MenuList, MenuItem } from '@open-pioneer/chakra-integration';
3
+ import { FiMoreVertical } from 'react-icons/fi';
4
+ import { useIntl } from './_virtual/_virtual-pioneer-module_react-hooks.js';
5
+ import { useMapModel } from '@open-pioneer/map';
6
+
7
+ const Tools = (props) => {
8
+ const intl = useIntl();
9
+ const { mapId, showHideAllLayers = true } = props;
10
+ const { map } = useMapModel(mapId);
11
+ const noEntry = !showHideAllLayers;
12
+ return !noEntry && /* @__PURE__ */ jsx(Box, { className: "toc-tools", children: /* @__PURE__ */ jsxs(Menu, { placement: "bottom-start", children: [
13
+ /* @__PURE__ */ jsx(
14
+ MenuButton,
15
+ {
16
+ as: Button,
17
+ className: "toc-tools-button",
18
+ "aria-label": intl.formatMessage({ id: "toolsLabel" }),
19
+ borderRadius: "full",
20
+ iconSpacing: 0,
21
+ padding: 3,
22
+ variant: "ghost",
23
+ leftIcon: /* @__PURE__ */ jsx(FiMoreVertical, {})
24
+ }
25
+ ),
26
+ /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(MenuList, { className: "tools-menu", children: /* @__PURE__ */ jsx(
27
+ MenuItem,
28
+ {
29
+ "aria-label": intl.formatMessage({ id: "tools.hideAllLayers" }),
30
+ onClick: () => {
31
+ hideAllLayers(map);
32
+ },
33
+ children: intl.formatMessage({ id: "tools.hideAllLayers" })
34
+ }
35
+ ) }) })
36
+ ] }) });
37
+ };
38
+ function hideAllLayers(map) {
39
+ const hideSublayer = (sublayers) => {
40
+ sublayers?.getSublayers().forEach((layer) => {
41
+ layer.setVisible(false);
42
+ hideSublayer(layer?.sublayers);
43
+ });
44
+ };
45
+ map?.layers.getOperationalLayers().forEach((layer) => {
46
+ layer.setVisible(false);
47
+ hideSublayer(layer?.sublayers);
48
+ });
49
+ }
50
+
51
+ export { Tools };
52
+ //# sourceMappingURL=Tools.js.map
package/Tools.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tools.js","sources":["Tools.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n Menu,\n MenuButton,\n MenuList,\n MenuItem,\n Button,\n Box,\n Portal\n} from \"@open-pioneer/chakra-integration\";\nimport { FC } from \"react\";\nimport { FiMoreVertical } from \"react-icons/fi\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { MapModel, SublayersCollection, useMapModel } from \"@open-pioneer/map\";\nimport { ToolsConfig } from \"./Toc\";\n\nexport const Tools: FC<{ mapId: string } & ToolsConfig> = (props) => {\n const intl = useIntl();\n const { mapId, showHideAllLayers = true } = props;\n const { map } = useMapModel(mapId);\n\n const noEntry = !showHideAllLayers;\n\n return (\n !noEntry && (\n <Box className=\"toc-tools\">\n <Menu placement=\"bottom-start\">\n <MenuButton\n as={Button}\n className=\"toc-tools-button\"\n aria-label={intl.formatMessage({ id: \"toolsLabel\" })}\n borderRadius=\"full\"\n iconSpacing={0}\n padding={3}\n variant=\"ghost\"\n leftIcon={<FiMoreVertical />}\n />\n <Portal>\n <MenuList className=\"tools-menu\">\n <MenuItem\n aria-label={intl.formatMessage({ id: \"tools.hideAllLayers\" })}\n onClick={() => {\n hideAllLayers(map);\n }}\n >\n {intl.formatMessage({ id: \"tools.hideAllLayers\" })}\n </MenuItem>\n </MenuList>\n </Portal>\n </Menu>\n </Box>\n )\n );\n};\n\nfunction hideAllLayers(map: MapModel | undefined) {\n const hideSublayer = (sublayers: SublayersCollection | undefined) => {\n sublayers?.getSublayers().forEach((layer) => {\n layer.setVisible(false);\n\n hideSublayer(layer?.sublayers);\n });\n };\n\n map?.layers.getOperationalLayers().forEach((layer) => {\n layer.setVisible(false);\n\n hideSublayer(layer?.sublayers);\n });\n}\n"],"names":[],"mappings":";;;;;;AAiBa,MAAA,KAAA,GAA6C,CAAC,KAAU,KAAA;AACjE,EAAA,MAAM,OAAO,OAAQ,EAAA,CAAA;AACrB,EAAA,MAAM,EAAE,KAAA,EAAO,iBAAoB,GAAA,IAAA,EAAS,GAAA,KAAA,CAAA;AAC5C,EAAA,MAAM,EAAE,GAAA,EAAQ,GAAA,WAAA,CAAY,KAAK,CAAA,CAAA;AAEjC,EAAA,MAAM,UAAU,CAAC,iBAAA,CAAA;AAEjB,EACI,OAAA,CAAC,2BACI,GAAA,CAAA,GAAA,EAAA,EAAI,WAAU,WACX,EAAA,QAAA,kBAAA,IAAA,CAAC,IAAK,EAAA,EAAA,SAAA,EAAU,cACZ,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACG,EAAI,EAAA,MAAA;AAAA,QACJ,SAAU,EAAA,kBAAA;AAAA,QACV,cAAY,IAAK,CAAA,aAAA,CAAc,EAAE,EAAA,EAAI,cAAc,CAAA;AAAA,QACnD,YAAa,EAAA,MAAA;AAAA,QACb,WAAa,EAAA,CAAA;AAAA,QACb,OAAS,EAAA,CAAA;AAAA,QACT,OAAQ,EAAA,OAAA;AAAA,QACR,QAAA,sBAAW,cAAe,EAAA,EAAA,CAAA;AAAA,OAAA;AAAA,KAC9B;AAAA,oBACC,GAAA,CAAA,MAAA,EAAA,EACG,QAAC,kBAAA,GAAA,CAAA,QAAA,EAAA,EAAS,WAAU,YAChB,EAAA,QAAA,kBAAA,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACG,cAAY,IAAK,CAAA,aAAA,CAAc,EAAE,EAAA,EAAI,uBAAuB,CAAA;AAAA,QAC5D,SAAS,MAAM;AACX,UAAA,aAAA,CAAc,GAAG,CAAA,CAAA;AAAA,SACrB;AAAA,QAEC,QAAK,EAAA,IAAA,CAAA,aAAA,CAAc,EAAE,EAAA,EAAI,uBAAuB,CAAA;AAAA,OAAA;AAAA,OAEzD,CACJ,EAAA,CAAA;AAAA,GAAA,EACJ,CACJ,EAAA,CAAA,CAAA;AAGZ,EAAA;AAEA,SAAS,cAAc,GAA2B,EAAA;AAC9C,EAAM,MAAA,YAAA,GAAe,CAAC,SAA+C,KAAA;AACjE,IAAA,SAAA,EAAW,YAAa,EAAA,CAAE,OAAQ,CAAA,CAAC,KAAU,KAAA;AACzC,MAAA,KAAA,CAAM,WAAW,KAAK,CAAA,CAAA;AAEtB,MAAA,YAAA,CAAa,OAAO,SAAS,CAAA,CAAA;AAAA,KAChC,CAAA,CAAA;AAAA,GACL,CAAA;AAEA,EAAA,GAAA,EAAK,MAAO,CAAA,oBAAA,EAAuB,CAAA,OAAA,CAAQ,CAAC,KAAU,KAAA;AAClD,IAAA,KAAA,CAAM,WAAW,KAAK,CAAA,CAAA;AAEtB,IAAA,YAAA,CAAa,OAAO,SAAS,CAAA,CAAA;AAAA,GAChC,CAAA,CAAA;AACL;;;;"}
package/i18n/de.yaml CHANGED
@@ -4,3 +4,7 @@ messages:
4
4
  operationalLayerLabel: "Layer"
5
5
  missingLayers: "Es sind keine Layer vorhanden."
6
6
  error: "Beim Erstellen des Karteninhalts ist ein Fehler aufgetreten."
7
+ layerNotAvailable: "Layer nicht verfügbar"
8
+ toolsLabel: "Kartenwerkzeuge"
9
+ tools:
10
+ hideAllLayers: "Alle Karteninhalte ausblenden"
package/i18n/en.yaml CHANGED
@@ -4,3 +4,7 @@ messages:
4
4
  operationalLayerLabel: "Operational layers"
5
5
  missingLayers: "There are no layers to display."
6
6
  error: "Error while creating map content."
7
+ layerNotAvailable: "Layer not available"
8
+ toolsLabel: "Map tools"
9
+ tools:
10
+ hideAllLayers: "Hide all layers"
package/index.d.ts CHANGED
@@ -1 +1 @@
1
- export { Toc, type TocProps } from "./Toc";
1
+ export { Toc, type TocProps, type ToolsConfig } from "./Toc";
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@open-pioneer/toc",
4
- "version": "0.1.0",
4
+ "version": "0.2.0",
5
5
  "license": "Apache-2.0",
6
6
  "peerDependencies": {
7
- "@open-pioneer/chakra-integration": "^1.1.0",
8
- "@open-pioneer/runtime": "^1.1.0",
7
+ "@open-pioneer/chakra-integration": "^1.1.1",
8
+ "@open-pioneer/runtime": "^2.0.2",
9
9
  "ol": "^8.2.0",
10
10
  "react": "^18.2.0",
11
11
  "classnames": "^2.3.2",
12
- "react-icons": "^4.11.0",
13
- "@open-pioneer/map": "^0.1.0",
14
- "@open-pioneer/basemap-switcher": "^0.1.0",
15
- "@open-pioneer/react-utils": "^0.1.0"
12
+ "react-icons": "^4.12.0",
13
+ "@open-pioneer/map": "^0.2.0",
14
+ "@open-pioneer/basemap-switcher": "^0.2.0",
15
+ "@open-pioneer/react-utils": "^0.2.0"
16
16
  },
17
17
  "exports": {
18
18
  "./package.json": "./package.json",